/**
* How long until a HELLO verification attempt should time out?
+ * Must be rather small, otherwise a partially successful HELLO
+ * validation (some addresses working) might not be available
+ * before a client's request for a connection fails for good.
+ * Besides, if a single request to an address takes a long time,
+ * then the peer is unlikely worthwhile anyway.
*/
-#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_UNIT_MINUTES
+#define HELLO_VERIFICATION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
/**
* How often do we re-add (cheaper) plugins to our list of plugins
msize = ntohs (msg->size);
if (msize + tsize > size)
break;
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transmitting message of type %u to client.\n",
+ ntohs (msg->type));
+#endif
client->message_queue_head = q->next;
if (q->next == NULL)
client->message_queue_tail = NULL;
GNUNET_free (q);
client->message_count--;
}
- GNUNET_assert (tsize > 0);
if (NULL != q)
{
+ GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
th = GNUNET_SERVER_notify_transmit_ready (client->client,
msize,
GNUNET_TIME_UNIT_FOREVER_REL,
}
client->message_count++;
msize = ntohs (msg->size);
+ GNUNET_assert (msize >= sizeof (struct GNUNET_MessageHeader));
q = GNUNET_malloc (sizeof (struct ClientMessageQueueEntry) + msize);
memcpy (&q[1], msg, msize);
/* append to message queue */
if (min_remaining.value < GNUNET_TIME_UNIT_FOREVER_REL.value)
plugin->address_update_task
= GNUNET_SCHEDULER_add_delayed (plugin->env.sched,
- GNUNET_NO,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_TASK,
min_remaining,
&expire_address_task, plugin);
struct ValidationList *pos;
struct ValidationList *prev;
struct GNUNET_TIME_Absolute now;
+ struct GNUNET_TIME_Absolute first;
struct GNUNET_HELLO_Message *hello;
struct GNUNET_PeerIdentity pid;
struct NeighbourList *n;
/* finally, reschedule cleanup if needed; list is
ordered by timeout, so we need the last element... */
- pos = pending_validations;
- while ((pos != NULL) && (pos->next != NULL))
- pos = pos->next;
- if (NULL != pos)
- GNUNET_SCHEDULER_add_delayed (sched,
- GNUNET_NO,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_TASK,
- GNUNET_TIME_absolute_get_remaining
- (pos->timeout), &cleanup_validation, NULL);
+ if (NULL != pending_validations)
+ {
+ first = pending_validations->timeout;
+ pos = pending_validations;
+ while (pos != NULL)
+ {
+ first = GNUNET_TIME_absolute_min (first, pos->timeout);
+ pos = pos->next;
+ }
+ GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_absolute_get_remaining (first),
+ &cleanup_validation, NULL);
+ }
}
uint32_t challenge,
const char *sender_addr)
{
- int all_done;
+ unsigned int not_done;
int matched;
struct ValidationList *pos;
struct ValidationAddress *va;
GNUNET_i2s(peer));
return;
}
- all_done = GNUNET_YES;
+ not_done = 0;
matched = GNUNET_NO;
va = pos->addresses;
while (va != NULL)
{
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Confirmed validity of peer address.\n");
+ "Confirmed validity of address, peer `%4s' has address `%s'.\n",
+ GNUNET_i2s (peer),
+ GNUNET_a2s ((const struct sockaddr*) &va[1],
+ va->addr_len));
#endif
GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK,
_("Another peer saw us using the address `%s' via `%s'. If this is not plausible, this address should be listed in the configuration as implausible to avoid MiM attacks.\n"),
matched = GNUNET_YES;
}
if (va->ok != GNUNET_YES)
- all_done = GNUNET_NO;
+ not_done++;
va = va->next;
}
if (GNUNET_NO == matched)
("Received `%s' message but have no record of a matching `%s' message. Ignoring.\n"),
"PONG", "PING");
}
- if (GNUNET_YES == all_done)
+ if (0 == not_done)
{
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "All addresses validated, will now construct `%s' for `%4s'.\n",
+ "HELLO",
+ GNUNET_i2s (peer));
+#endif
pos->timeout.value = 0;
- GNUNET_SCHEDULER_add_delayed (sched,
- GNUNET_NO,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_TASK,
- GNUNET_TIME_UNIT_ZERO,
- &cleanup_validation, NULL);
+ GNUNET_SCHEDULER_add_with_priority (sched,
+ GNUNET_SCHEDULER_PRIORITY_IDLE,
+ &cleanup_validation, NULL);
+ }
+ else
+ {
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Still waiting for %u additional `%s' messages before constructing `%s' for `%4s'.\n",
+ not_done,
+ "PONG",
+ "HELLO",
+ GNUNET_i2s (peer));
+#endif
}
}
GNUNET_assert (GNUNET_OK ==
GNUNET_HELLO_get_id (chvc->hello,
&apeer));
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Ready to validate addresses from `%s' message for peer `%4s'\n",
+ "HELLO", GNUNET_i2s (&apeer));
+#endif
va = chvc->e->addresses;
while (va != NULL)
{
#if DEBUG_TRANSPORT
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Establishing `%s' connection to validate `%s' of `%4s'\n",
+ "Establishing `%s' connection to validate `%s' address `%s' of `%4s'\n",
va->transport_name,
"HELLO",
+ GNUNET_a2s ((const struct sockaddr*) &va[1],
+ va->addr_len),
GNUNET_i2s (&apeer));
#endif
tp = find_transport (va->transport_name);
va->ok = GNUNET_SYSERR;
va = va->next;
}
- if (chvc->e->next == NULL)
- GNUNET_SCHEDULER_add_delayed (sched,
- GNUNET_NO,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_TASK,
- GNUNET_TIME_absolute_get_remaining
- (chvc->e->timeout), &cleanup_validation,
- NULL);
+ GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_absolute_get_remaining (chvc->e->timeout),
+ &cleanup_validation, NULL);
GNUNET_free (chvc);
}
n->quota_in = (GNUNET_CONSTANTS_DEFAULT_BPM_IN_OUT + 59999) / (60 * 1000);
add_plugins (n);
n->timeout_task = GNUNET_SCHEDULER_add_delayed (sched,
- GNUNET_NO,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_TASK,
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
&neighbour_timeout_task, n);
transmit_to_peer (NULL, 0,
* reducing the rate at which they read from the socket
* and generally forward to our receive callback.
*
+ * @param cls the "struct TransportPlugin *" we gave to the plugin
* @param plugin_context value to pass to this plugin
* to respond to the given peer (use is optional,
* but may speed up processing)
n->peer_timeout =
GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT);
n->timeout_task =
- GNUNET_SCHEDULER_add_delayed (sched, GNUNET_NO,
- GNUNET_SCHEDULER_PRIORITY_IDLE,
- GNUNET_SCHEDULER_NO_TASK,
+ GNUNET_SCHEDULER_add_delayed (sched,
GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
&neighbour_timeout_task, n);
update_quota (n);
}
GNUNET_free (im);
}
- GNUNET_assert (NULL != service_context->neighbour);
+ GNUNET_assert ( (service_context == NULL) ||
+ (NULL != service_context->neighbour) );
return service_context;
}
}
+/**
+ * Function called when the service shuts down. Unloads our plugins.
+ *
+ * @param cls closure, unused
+ * @param tc task context (unused)
+ */
+static void
+unload_plugins (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct TransportPlugin *plug;
+ struct AddressList *al;
+
+#if DEBUG_TRANSPORT
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Transport service is unloading plugins...\n");
+#endif
+ while (NULL != (plug = plugins))
+ {
+ plugins = plug->next;
+ GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
+ GNUNET_free (plug->lib_name);
+ GNUNET_free (plug->short_name);
+ while (NULL != (al = plug->addresses))
+ {
+ plug->addresses = al->next;
+ GNUNET_free (al);
+ }
+ GNUNET_free (plug);
+ }
+ if (my_private_key != NULL)
+ GNUNET_CRYPTO_rsa_key_free (my_private_key);
+ GNUNET_free_non_null (our_hello);
+}
+
+
/**
* Initiate transport service.
*
}
GNUNET_free (plugs);
}
+ GNUNET_SCHEDULER_add_delayed (sched,
+ GNUNET_TIME_UNIT_FOREVER_REL,
+ &unload_plugins, NULL);
if (no_transports)
refresh_hello ();
#if DEBUG_TRANSPORT
}
-/**
- * Function called when the service shuts
- * down. Unloads our plugins.
- *
- * @param cls closure
- * @param cfg configuration to use
- */
-static void
-unload_plugins (void *cls,
- const struct GNUNET_CONFIGURATION_Handle *cfg)
-{
- struct TransportPlugin *plug;
- struct AddressList *al;
-
-#if DEBUG_TRANSPORT
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "Transport service is unloading plugins...\n");
-#endif
- while (NULL != (plug = plugins))
- {
- plugins = plug->next;
- GNUNET_break (NULL == GNUNET_PLUGIN_unload (plug->lib_name, plug->api));
- GNUNET_free (plug->lib_name);
- GNUNET_free (plug->short_name);
- while (NULL != (al = plug->addresses))
- {
- plug->addresses = al->next;
- GNUNET_free (al);
- }
- GNUNET_free (plug);
- }
- if (my_private_key != NULL)
- GNUNET_CRYPTO_rsa_key_free (my_private_key);
- GNUNET_free_non_null (our_hello);
-}
-
-
/**
* The main function for the transport service.
*
GNUNET_SERVICE_run (argc,
argv,
"transport",
- &run, NULL, &unload_plugins, NULL)) ? 0 : 1;
+ &run, NULL)) ? 0 : 1;
}
/* end of gnunet-service-transport.c */