diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-06-01 11:34:21 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-06-01 11:34:21 +0000 |
commit | 9c9ca63a3ec703c46e6de365599904a64abaa68d (patch) | |
tree | 44f45e4692f7786f01a192d4c1772d4a463882b8 /src/topology | |
parent | 726e2e428a2bbd4a377db28ddac27c338420ee0d (diff) | |
download | gnunet-9c9ca63a3ec703c46e6de365599904a64abaa68d.tar.gz gnunet-9c9ca63a3ec703c46e6de365599904a64abaa68d.zip |
-trying to fix #2391: limit connect rate from topology
Diffstat (limited to 'src/topology')
-rw-r--r-- | src/topology/gnunet-daemon-topology.c | 68 |
1 files changed, 65 insertions, 3 deletions
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 | |||
@@ -34,6 +34,11 @@ | |||
34 | 34 | ||
35 | 35 | ||
36 | /** | 36 | /** |
37 | * Minimum required delay between calls to GNUNET_TRANSPORT_try_connect. | ||
38 | */ | ||
39 | #define MAX_CONNECT_FREQUENCY_DELAY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 250) | ||
40 | |||
41 | /** | ||
37 | * For how long do we blacklist a peer after a failed connection | 42 | * For how long do we blacklist a peer after a failed connection |
38 | * attempt? This is the baseline factor which is then multiplied by | 43 | * attempt? This is the baseline factor which is then multiplied by |
39 | * two to the power of the number of failed attempts. | 44 | * two to the power of the number of failed attempts. |
@@ -122,6 +127,11 @@ struct Peer | |||
122 | GNUNET_SCHEDULER_TaskIdentifier hello_delay_task; | 127 | GNUNET_SCHEDULER_TaskIdentifier hello_delay_task; |
123 | 128 | ||
124 | /** | 129 | /** |
130 | * Task for issuing GNUNET_TRANSPORT_try_connect for this peer. | ||
131 | */ | ||
132 | GNUNET_SCHEDULER_TaskIdentifier attempt_connect_task; | ||
133 | |||
134 | /** | ||
125 | * ID of task we use to clear peers from the greylist. | 135 | * ID of task we use to clear peers from the greylist. |
126 | */ | 136 | */ |
127 | GNUNET_SCHEDULER_TaskIdentifier greylist_clean_task; | 137 | GNUNET_SCHEDULER_TaskIdentifier greylist_clean_task; |
@@ -188,6 +198,11 @@ static struct GNUNET_STATISTICS_Handle *stats; | |||
188 | static struct GNUNET_TRANSPORT_Blacklist *blacklist; | 198 | static struct GNUNET_TRANSPORT_Blacklist *blacklist; |
189 | 199 | ||
190 | /** | 200 | /** |
201 | * When can we next ask transport to create a connection? | ||
202 | */ | ||
203 | static struct GNUNET_TIME_Absolute next_connect_attempt; | ||
204 | |||
205 | /** | ||
191 | * Task scheduled to try to add peers. | 206 | * Task scheduled to try to add peers. |
192 | */ | 207 | */ |
193 | static GNUNET_SCHEDULER_TaskIdentifier add_task; | 208 | static GNUNET_SCHEDULER_TaskIdentifier add_task; |
@@ -312,6 +327,8 @@ free_peer (void *cls, const GNUNET_HashCode * pid, void *value) | |||
312 | GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); | 327 | GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); |
313 | if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) | 328 | if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) |
314 | GNUNET_SCHEDULER_cancel (pos->hello_delay_task); | 329 | GNUNET_SCHEDULER_cancel (pos->hello_delay_task); |
330 | if (pos->attempt_connect_task != GNUNET_SCHEDULER_NO_TASK) | ||
331 | GNUNET_SCHEDULER_cancel (pos->hello_delay_task); | ||
315 | if (pos->greylist_clean_task != GNUNET_SCHEDULER_NO_TASK) | 332 | if (pos->greylist_clean_task != GNUNET_SCHEDULER_NO_TASK) |
316 | GNUNET_SCHEDULER_cancel (pos->greylist_clean_task); | 333 | GNUNET_SCHEDULER_cancel (pos->greylist_clean_task); |
317 | GNUNET_free_non_null (pos->hello); | 334 | GNUNET_free_non_null (pos->hello); |
@@ -379,6 +396,50 @@ attempt_connect (struct Peer *pos) | |||
379 | 396 | ||
380 | 397 | ||
381 | /** | 398 | /** |
399 | * Try to connect to the specified peer. | ||
400 | * | ||
401 | * @param pos peer to connect to | ||
402 | */ | ||
403 | static void | ||
404 | do_attempt_connect (void *cls, | ||
405 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
406 | { | ||
407 | struct Peer *pos = cls; | ||
408 | struct GNUNET_TIME_Relative delay; | ||
409 | |||
410 | pos->attempt_connect_task = GNUNET_SCHEDULER_NO_TASK; | ||
411 | if (GNUNET_YES == pos->is_connected) | ||
412 | return; | ||
413 | delay = GNUNET_TIME_absolute_get_remaining (next_connect_attempt); | ||
414 | if (delay.rel_value > 0) | ||
415 | { | ||
416 | pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (delay, | ||
417 | &do_attempt_connect, | ||
418 | pos); | ||
419 | return; | ||
420 | } | ||
421 | next_connect_attempt = GNUNET_TIME_relative_to_absolute (MAX_CONNECT_FREQUENCY_DELAY); | ||
422 | attempt_connect (pos); | ||
423 | } | ||
424 | |||
425 | |||
426 | /** | ||
427 | * Schedule a task to try to connect to the specified peer. | ||
428 | * | ||
429 | * @param pos peer to connect to | ||
430 | */ | ||
431 | static void | ||
432 | schedule_attempt_connect (struct Peer *pos) | ||
433 | { | ||
434 | if (GNUNET_SCHEDULER_NO_TASK != pos->attempt_connect_task) | ||
435 | return; | ||
436 | pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (next_connect_attempt), | ||
437 | &do_attempt_connect, | ||
438 | pos); | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
382 | * Discard peer entries for greylisted peers | 443 | * Discard peer entries for greylisted peers |
383 | * where the greylisting has expired. | 444 | * where the greylisting has expired. |
384 | * | 445 | * |
@@ -395,7 +456,7 @@ remove_from_greylist (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
395 | rem = GNUNET_TIME_absolute_get_remaining (pos->greylisted_until); | 456 | rem = GNUNET_TIME_absolute_get_remaining (pos->greylisted_until); |
396 | if (rem.rel_value == 0) | 457 | if (rem.rel_value == 0) |
397 | { | 458 | { |
398 | attempt_connect (pos); | 459 | schedule_attempt_connect (pos); |
399 | } | 460 | } |
400 | else | 461 | else |
401 | { | 462 | { |
@@ -685,7 +746,7 @@ try_add_peers (void *cls, const GNUNET_HashCode * pid, void *value) | |||
685 | { | 746 | { |
686 | struct Peer *pos = value; | 747 | struct Peer *pos = value; |
687 | 748 | ||
688 | attempt_connect (pos); | 749 | schedule_attempt_connect (pos); |
689 | return GNUNET_YES; | 750 | return GNUNET_YES; |
690 | } | 751 | } |
691 | 752 | ||
@@ -705,6 +766,7 @@ add_peer_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
705 | GNUNET_CONTAINER_multihashmap_iterate (peers, &try_add_peers, NULL); | 766 | GNUNET_CONTAINER_multihashmap_iterate (peers, &try_add_peers, NULL); |
706 | } | 767 | } |
707 | 768 | ||
769 | |||
708 | /** | 770 | /** |
709 | * Method called whenever a peer disconnects. | 771 | * Method called whenever a peer disconnects. |
710 | * | 772 | * |
@@ -910,7 +972,7 @@ process_peer (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
910 | } | 972 | } |
911 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Considering connecting to peer `%s'\n", | 973 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Considering connecting to peer `%s'\n", |
912 | GNUNET_i2s (peer)); | 974 | GNUNET_i2s (peer)); |
913 | attempt_connect (pos); | 975 | schedule_attempt_connect (pos); |
914 | } | 976 | } |
915 | 977 | ||
916 | 978 | ||