aboutsummaryrefslogtreecommitdiff
path: root/src/topology
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2010-01-22 17:54:18 +0000
committerChristian Grothoff <christian@grothoff.org>2010-01-22 17:54:18 +0000
commit6776eda81f7712d24b4a54943642cf90af7ee4d8 (patch)
treee284d5e72edb9319ed18592386c1aabc1dd3ddb3 /src/topology
parent45f0267ad9a0e19c0445e0a2e228aab438bf517f (diff)
downloadgnunet-6776eda81f7712d24b4a54943642cf90af7ee4d8.tar.gz
gnunet-6776eda81f7712d24b4a54943642cf90af7ee4d8.zip
stuff
Diffstat (limited to 'src/topology')
-rw-r--r--src/topology/gnunet-daemon-topology.c100
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 */
274static void 276static void
275force_disconnect (const struct GNUNET_PeerIdentity *peer) 277force_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 */
310static void
311whitelist_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 */
324static void
325whitelist_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 }