From: Christian Grothoff Date: Fri, 1 Jun 2012 11:34:21 +0000 (+0000) Subject: -trying to fix #2391: limit connect rate from topology X-Git-Tag: initial-import-from-subversion-38251~13308 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=9c9ca63a3ec703c46e6de365599904a64abaa68d;p=oweals%2Fgnunet.git -trying to fix #2391: limit connect rate from topology --- diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index a9dbd3573..15ca9f87b 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c @@ -33,6 +33,11 @@ #include "gnunet_util_lib.h" +/** + * Minimum required delay between calls to GNUNET_TRANSPORT_try_connect. + */ +#define MAX_CONNECT_FREQUENCY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250) + /** * For how long do we blacklist a peer after a failed connection * attempt? This is the baseline factor which is then multiplied by @@ -121,6 +126,11 @@ struct Peer */ GNUNET_SCHEDULER_TaskIdentifier hello_delay_task; + /** + * Task for issuing GNUNET_TRANSPORT_try_connect for this peer. + */ + GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task; + /** * ID of task we use to clear peers from the greylist. */ @@ -187,6 +197,11 @@ static struct GNUNET_STATISTICS_Handle *stats; */ static struct GNUNET_TRANSPORT_Blacklist *blacklist; +/** + * When can we next ask transport to create a connection? + */ +static struct GNUNET_TIME_Absolute next_connect_attempt; + /** * Task scheduled to try to add peers. */ @@ -312,6 +327,8 @@ free_peer (void *cls, const GNUNET_HashCode * pid, void *value) GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (pos->hello_delay_task); + if (pos->attempt_connect_task != GNUNET_SCHEDULER_NO_TASK) + GNUNET_SCHEDULER_cancel (pos->hello_delay_task); if (pos->greylist_clean_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (pos->greylist_clean_task); GNUNET_free_non_null (pos->hello); @@ -378,6 +395,50 @@ attempt_connect (struct Peer *pos) } +/** + * Try to connect to the specified peer. + * + * @param pos peer to connect to + */ +static void +do_attempt_connect (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct Peer *pos = cls; + struct GNUNET_TIME_Relative delay; + + pos->attempt_connect_task = GNUNET_SCHEDULER_NO_TASK; + if (GNUNET_YES == pos->is_connected) + return; + delay = GNUNET_TIME_absolute_get_remaining (next_connect_attempt); + if (delay.rel_value > 0) + { + pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (delay, + &do_attempt_connect, + pos); + return; + } + next_connect_attempt = GNUNET_TIME_relative_to_absolute (MAX_CONNECT_FREQUENCY_DELAY); + attempt_connect (pos); +} + + +/** + * Schedule a task to try to connect to the specified peer. + * + * @param pos peer to connect to + */ +static void +schedule_attempt_connect (struct Peer *pos) +{ + if (GNUNET_SCHEDULER_NO_TASK != pos->attempt_connect_task) + return; + pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (next_connect_attempt), + &do_attempt_connect, + pos); +} + + /** * Discard peer entries for greylisted peers * where the greylisting has expired. @@ -395,7 +456,7 @@ remove_from_greylist (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) rem = GNUNET_TIME_absolute_get_remaining (pos->greylisted_until); if (rem.rel_value == 0) { - attempt_connect (pos); + schedule_attempt_connect (pos); } else { @@ -685,7 +746,7 @@ try_add_peers (void *cls, const GNUNET_HashCode * pid, void *value) { struct Peer *pos = value; - attempt_connect (pos); + schedule_attempt_connect (pos); return GNUNET_YES; } @@ -705,6 +766,7 @@ add_peer_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) GNUNET_CONTAINER_multihashmap_iterate (peers, &try_add_peers, NULL); } + /** * Method called whenever a peer disconnects. * @@ -910,7 +972,7 @@ process_peer (void *cls, const struct GNUNET_PeerIdentity *peer, } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Considering connecting to peer `%s'\n", GNUNET_i2s (peer)); - attempt_connect (pos); + schedule_attempt_connect (pos); }