diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-01-22 17:54:18 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-01-22 17:54:18 +0000 |
commit | 6776eda81f7712d24b4a54943642cf90af7ee4d8 (patch) | |
tree | e284d5e72edb9319ed18592386c1aabc1dd3ddb3 /src/topology | |
parent | 45f0267ad9a0e19c0445e0a2e228aab438bf517f (diff) | |
download | gnunet-6776eda81f7712d24b4a54943642cf90af7ee4d8.tar.gz gnunet-6776eda81f7712d24b4a54943642cf90af7ee4d8.zip |
stuff
Diffstat (limited to 'src/topology')
-rw-r--r-- | src/topology/gnunet-daemon-topology.c | 100 |
1 files changed, 87 insertions, 13 deletions
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index 3bcc29704..727d53815 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c | |||
@@ -22,14 +22,6 @@ | |||
22 | * @file topology/gnunet-daemon-topology.c | 22 | * @file topology/gnunet-daemon-topology.c |
23 | * @brief code for maintaining the mesh topology | 23 | * @brief code for maintaining the mesh topology |
24 | * @author Christian Grothoff | 24 | * @author Christian Grothoff |
25 | * | ||
26 | * OPTIMIZATIONS: | ||
27 | * - move code to use hash table instead of linked list | ||
28 | * - instead of periodically discarding blacklisted entries, | ||
29 | * simply add task that is triggered at the right time (earlier free, | ||
30 | * more balanced load) | ||
31 | * - check if new HELLO learned is different from old HELLO | ||
32 | * before resetting entire state! | ||
33 | */ | 25 | */ |
34 | 26 | ||
35 | #include <stdlib.h> | 27 | #include <stdlib.h> |
@@ -101,6 +93,12 @@ struct PeerList | |||
101 | struct GNUNET_CONTAINER_BloomFilter *filter; | 93 | struct GNUNET_CONTAINER_BloomFilter *filter; |
102 | 94 | ||
103 | /** | 95 | /** |
96 | * Our request handle for *whitelisting* this peer (NULL if | ||
97 | * no whitelisting request is pending). | ||
98 | */ | ||
99 | struct GNUNET_TRANSPORT_BlacklistRequest *wh; | ||
100 | |||
101 | /** | ||
104 | * Is this peer listed here because he is a friend? | 102 | * Is this peer listed here because he is a friend? |
105 | */ | 103 | */ |
106 | int is_friend; | 104 | int is_friend; |
@@ -111,6 +109,11 @@ struct PeerList | |||
111 | int is_connected; | 109 | int is_connected; |
112 | 110 | ||
113 | /** | 111 | /** |
112 | * Are we currently blocking this peer (via blacklist)? | ||
113 | */ | ||
114 | int is_blocked; | ||
115 | |||
116 | /** | ||
114 | * Until what time should we not try to connect again | 117 | * Until what time should we not try to connect again |
115 | * to this peer? | 118 | * to this peer? |
116 | */ | 119 | */ |
@@ -269,13 +272,19 @@ disconnect_done (void *cls, | |||
269 | 272 | ||
270 | /** | 273 | /** |
271 | * Force a disconnect from the specified peer. | 274 | * Force a disconnect from the specified peer. |
272 | * FIXME: this policy change is never undone; how do we reconnect ever? | ||
273 | */ | 275 | */ |
274 | static void | 276 | static void |
275 | force_disconnect (const struct GNUNET_PeerIdentity *peer) | 277 | force_disconnect (struct PeerList *pl) |
276 | { | 278 | { |
279 | const struct GNUNET_PeerIdentity *peer = &pl->id; | ||
277 | struct DisconnectList *dl; | 280 | struct DisconnectList *dl; |
278 | 281 | ||
282 | if (NULL != dl->wh) | ||
283 | { | ||
284 | GNUNET_TRANSPORT_blacklist_cancel (dl->wh); | ||
285 | dl->wh = NULL; | ||
286 | } | ||
287 | pl->is_blocked = GNUNET_YES; | ||
279 | dl = GNUNET_malloc (sizeof (struct DisconnectList)); | 288 | dl = GNUNET_malloc (sizeof (struct DisconnectList)); |
280 | dl->peer = *peer; | 289 | dl->peer = *peer; |
281 | GNUNET_CONTAINER_DLL_insert (disconnect_head, | 290 | GNUNET_CONTAINER_DLL_insert (disconnect_head, |
@@ -290,6 +299,63 @@ force_disconnect (const struct GNUNET_PeerIdentity *peer) | |||
290 | } | 299 | } |
291 | 300 | ||
292 | 301 | ||
302 | |||
303 | /** | ||
304 | * Function called once our request to 'whitelist' a peer | ||
305 | * has completed. | ||
306 | * | ||
307 | * @param cls our 'struct PeerList' | ||
308 | * @param tc unused | ||
309 | */ | ||
310 | static void | ||
311 | whitelist_done (void *cls, | ||
312 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
313 | { | ||
314 | struct PeerList *pl = cls; | ||
315 | |||
316 | pl->wh = NULL; | ||
317 | } | ||
318 | |||
319 | |||
320 | /** | ||
321 | * Whitelist all peers that we blacklisted; we've passed | ||
322 | * the minimum number of friends. | ||
323 | */ | ||
324 | static void | ||
325 | whitelist_peers () | ||
326 | { | ||
327 | struct PeerList *pl; | ||
328 | struct DisconnectList *dl; | ||
329 | |||
330 | /* first, cancel all blacklisting requests */ | ||
331 | while (NULL != (dl = disconnect_head)) | ||
332 | { | ||
333 | GNUNET_CONTAINER_DLL_remove (disconnect_head, | ||
334 | disconnect_tail, | ||
335 | dl); | ||
336 | GNUNET_TRANSPORT_blacklist_cancel (dl->rh); | ||
337 | GNUNET_free (dl); | ||
338 | } | ||
339 | /* then, specifically whitelist all peers that we | ||
340 | know to have blacklisted */ | ||
341 | pl = peers; | ||
342 | while (pl != NULL) | ||
343 | { | ||
344 | if (pl->is_blocked) | ||
345 | { | ||
346 | pl->wh = GNUNET_TRANSPORT_blacklist (sched, cfg, | ||
347 | peer, | ||
348 | GNUNET_TIME_UNIT_FOREVER_ZERO, | ||
349 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
350 | &whitelist_done, | ||
351 | pl); | ||
352 | pl->is_blocked = GNUNET_NO; | ||
353 | } | ||
354 | pl = pl->next; | ||
355 | } | ||
356 | } | ||
357 | |||
358 | |||
293 | /** | 359 | /** |
294 | * Function called by core when our attempt to connect succeeded. | 360 | * Function called by core when our attempt to connect succeeded. |
295 | */ | 361 | */ |
@@ -434,6 +500,8 @@ free_peer (struct PeerList *peer) | |||
434 | prev->next = pos->next; | 500 | prev->next = pos->next; |
435 | if (pos->hello_req != NULL) | 501 | if (pos->hello_req != NULL) |
436 | GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); | 502 | GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); |
503 | if (pos->wh != NULL) | ||
504 | GNUNET_TRANSPORT_blacklist_cancel (pos->wh); | ||
437 | if (pos->connect_req != NULL) | 505 | if (pos->connect_req != NULL) |
438 | GNUNET_CORE_peer_request_connect_cancel (pos->connect_req); | 506 | GNUNET_CORE_peer_request_connect_cancel (pos->connect_req); |
439 | if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) | 507 | if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) |
@@ -611,7 +679,7 @@ connect_notify (void *cls, | |||
611 | "Connection to `%s' is forbidden, forcing disconnect!\n", | 679 | "Connection to `%s' is forbidden, forcing disconnect!\n", |
612 | GNUNET_i2s (peer)); | 680 | GNUNET_i2s (peer)); |
613 | #endif | 681 | #endif |
614 | force_disconnect (&pos->id); | 682 | force_disconnect (pos); |
615 | return; | 683 | return; |
616 | } | 684 | } |
617 | } | 685 | } |
@@ -622,7 +690,12 @@ connect_notify (void *cls, | |||
622 | } | 690 | } |
623 | pos->is_connected = GNUNET_YES; | 691 | pos->is_connected = GNUNET_YES; |
624 | if (pos->is_friend) | 692 | if (pos->is_friend) |
625 | friend_count++; | 693 | { |
694 | if ( (friend_count == minimum_friend_count - 1) && | ||
695 | (GNUNET_YES != friends_only) ) | ||
696 | whitelist_peers (); | ||
697 | friend_count++; | ||
698 | } | ||
626 | reschedule_hellos (pos); | 699 | reschedule_hellos (pos); |
627 | } | 700 | } |
628 | 701 | ||
@@ -646,7 +719,7 @@ drop_non_friends () | |||
646 | "Connection to `%s' is not from a friend, forcing disconnect!\n", | 719 | "Connection to `%s' is not from a friend, forcing disconnect!\n", |
647 | GNUNET_i2s (&pos->id)); | 720 | GNUNET_i2s (&pos->id)); |
648 | #endif | 721 | #endif |
649 | force_disconnect (&pos->id); | 722 | force_disconnect (pos); |
650 | } | 723 | } |
651 | pos = pos->next; | 724 | pos = pos->next; |
652 | } | 725 | } |
@@ -884,6 +957,7 @@ discard_old_blacklist_entries (void *cls, | |||
884 | next = pos->next; | 957 | next = pos->next; |
885 | if ( (GNUNET_NO == pos->is_friend) && | 958 | if ( (GNUNET_NO == pos->is_friend) && |
886 | (GNUNET_NO == pos->is_connected) && | 959 | (GNUNET_NO == pos->is_connected) && |
960 | (GNUNET_NO == pos->is_blocked) && | ||
887 | (0 == GNUNET_TIME_absolute_get_remaining (pos->blacklisted_until).value) ) | 961 | (0 == GNUNET_TIME_absolute_get_remaining (pos->blacklisted_until).value) ) |
888 | free_peer (pos); | 962 | free_peer (pos); |
889 | } | 963 | } |