diff options
author | Christian Grothoff <christian@grothoff.org> | 2010-04-18 20:23:40 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2010-04-18 20:23:40 +0000 |
commit | 541caf3dec54aaee621fed935e667f9ee423ef31 (patch) | |
tree | 6f80958e68541ce071bc557bbfc168644963c473 /src/topology/gnunet-daemon-topology.c | |
parent | e8bc962b2ed43e194ba124537573da236786e82c (diff) | |
download | gnunet-541caf3dec54aaee621fed935e667f9ee423ef31.tar.gz gnunet-541caf3dec54aaee621fed935e667f9ee423ef31.zip |
towards fixing blacklisting APIs and implementation
Diffstat (limited to 'src/topology/gnunet-daemon-topology.c')
-rw-r--r-- | src/topology/gnunet-daemon-topology.c | 278 |
1 files changed, 47 insertions, 231 deletions
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c index b175d82ae..0aca503c1 100644 --- a/src/topology/gnunet-daemon-topology.c +++ b/src/topology/gnunet-daemon-topology.c | |||
@@ -106,12 +106,6 @@ struct Peer | |||
106 | struct GNUNET_CONTAINER_BloomFilter *filter; | 106 | struct GNUNET_CONTAINER_BloomFilter *filter; |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * Our request handle for *whitelisting* this peer (NULL if | ||
110 | * no whitelisting request is pending). | ||
111 | */ | ||
112 | struct GNUNET_TRANSPORT_BlacklistRequest *wh; | ||
113 | |||
114 | /** | ||
115 | * Until what time should we not try to connect again | 109 | * Until what time should we not try to connect again |
116 | * to this peer? | 110 | * to this peer? |
117 | */ | 111 | */ |
@@ -153,39 +147,6 @@ struct Peer | |||
153 | */ | 147 | */ |
154 | int is_connected; | 148 | int is_connected; |
155 | 149 | ||
156 | /** | ||
157 | * Are we currently blocking this peer (via blacklist)? | ||
158 | */ | ||
159 | int is_blocked; | ||
160 | |||
161 | }; | ||
162 | |||
163 | |||
164 | /** | ||
165 | * Entry in linked list of active 'disconnect' requests that we have issued. | ||
166 | */ | ||
167 | struct DisconnectList | ||
168 | { | ||
169 | /** | ||
170 | * This is a doubly-linked list. | ||
171 | */ | ||
172 | struct DisconnectList *next; | ||
173 | |||
174 | /** | ||
175 | * This is a doubly-linked list. | ||
176 | */ | ||
177 | struct DisconnectList *prev; | ||
178 | |||
179 | /** | ||
180 | * Our request handle. | ||
181 | */ | ||
182 | struct GNUNET_TRANSPORT_BlacklistRequest *rh; | ||
183 | |||
184 | /** | ||
185 | * Peer we tried to disconnect. | ||
186 | */ | ||
187 | struct GNUNET_PeerIdentity peer; | ||
188 | |||
189 | }; | 150 | }; |
190 | 151 | ||
191 | 152 | ||
@@ -233,6 +194,11 @@ static struct GNUNET_CONTAINER_MultiHashMap *peers; | |||
233 | static struct GNUNET_STATISTICS_Handle *stats; | 194 | static struct GNUNET_STATISTICS_Handle *stats; |
234 | 195 | ||
235 | /** | 196 | /** |
197 | * Blacklist (NULL if we have none). | ||
198 | */ | ||
199 | static struct GNUNET_TRANSPORT_Blacklist *blacklist; | ||
200 | |||
201 | /** | ||
236 | * Flag to disallow non-friend connections (pure F2F mode). | 202 | * Flag to disallow non-friend connections (pure F2F mode). |
237 | */ | 203 | */ |
238 | static int friends_only; | 204 | static int friends_only; |
@@ -263,119 +229,31 @@ static unsigned int friend_count; | |||
263 | */ | 229 | */ |
264 | static int autoconnect; | 230 | static int autoconnect; |
265 | 231 | ||
266 | /** | ||
267 | * Head of doubly-linked list of active 'disconnect' requests that we have issued. | ||
268 | */ | ||
269 | static struct DisconnectList *disconnect_head; | ||
270 | |||
271 | /** | ||
272 | * Head of doubly-linked list of active 'disconnect' requests that we have issued. | ||
273 | */ | ||
274 | static struct DisconnectList *disconnect_tail; | ||
275 | |||
276 | 232 | ||
277 | /** | 233 | /** |
278 | * Function called once our request to 'disconnect' a peer | 234 | * Function that decides if a connection is acceptable or not. |
279 | * has completed. | 235 | * If we have a blacklist, only friends are allowed, so the check |
236 | * is rather simple. | ||
280 | * | 237 | * |
281 | * @param cls our 'struct DisconnectList' | 238 | * @param cls closure |
282 | * @param tc unused | 239 | * @param pid peer to approve or disapproave |
240 | * @return GNUNET_OK if the connection is allowed | ||
283 | */ | 241 | */ |
284 | static void | 242 | static int |
285 | disconnect_done (void *cls, | 243 | blacklist_check (void *cls, |
286 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 244 | const struct GNUNET_PeerIdentity *pid) |
287 | { | 245 | { |
288 | struct DisconnectList *dl = cls; | 246 | struct Peer *pos; |
289 | 247 | ||
248 | pos = GNUNET_CONTAINER_multihashmap_get (peers, &pid->hashPubKey); | ||
249 | if ( (pos != NULL) && | ||
250 | (pos->is_friend == GNUNET_YES) ) | ||
251 | return GNUNET_OK; | ||
290 | GNUNET_STATISTICS_update (stats, | 252 | GNUNET_STATISTICS_update (stats, |
291 | gettext_noop ("# peers blacklisted"), | 253 | gettext_noop ("# peers blacklisted"), |
292 | 1, | 254 | 1, |
293 | GNUNET_NO); | 255 | GNUNET_NO); |
294 | GNUNET_CONTAINER_DLL_remove (disconnect_head, | 256 | return GNUNET_SYSERR; |
295 | disconnect_tail, | ||
296 | dl); | ||
297 | GNUNET_free (dl); | ||
298 | } | ||
299 | |||
300 | |||
301 | /** | ||
302 | * Force a disconnect from the specified peer. | ||
303 | * | ||
304 | * @param pl peer to disconnect | ||
305 | */ | ||
306 | static void | ||
307 | force_disconnect (struct Peer *pl) | ||
308 | { | ||
309 | const struct GNUNET_PeerIdentity *peer = &pl->pid; | ||
310 | struct DisconnectList *dl; | ||
311 | |||
312 | if (NULL != pl->wh) | ||
313 | { | ||
314 | GNUNET_TRANSPORT_blacklist_cancel (pl->wh); | ||
315 | pl->wh = NULL; | ||
316 | } | ||
317 | pl->is_blocked = GNUNET_YES; | ||
318 | dl = GNUNET_malloc (sizeof (struct DisconnectList)); | ||
319 | dl->peer = *peer; | ||
320 | GNUNET_CONTAINER_DLL_insert (disconnect_head, | ||
321 | disconnect_tail, | ||
322 | dl); | ||
323 | dl->rh = GNUNET_TRANSPORT_blacklist (sched, cfg, | ||
324 | peer, | ||
325 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
326 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
327 | &disconnect_done, | ||
328 | dl); | ||
329 | } | ||
330 | |||
331 | |||
332 | |||
333 | /** | ||
334 | * Function called once our request to 'whitelist' a peer | ||
335 | * has completed. | ||
336 | * | ||
337 | * @param cls our 'struct Peer' | ||
338 | * @param tc unused | ||
339 | */ | ||
340 | static void | ||
341 | whitelist_done (void *cls, | ||
342 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
343 | { | ||
344 | struct Peer *pl = cls; | ||
345 | |||
346 | pl->wh = NULL; | ||
347 | GNUNET_STATISTICS_update (stats, | ||
348 | gettext_noop ("# peers blacklisted"), | ||
349 | -1, | ||
350 | GNUNET_NO); | ||
351 | } | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Whitelist the given peer (if it was blacklisted before). | ||
356 | * | ||
357 | * @param cls closure (not used) | ||
358 | * @param pid identity of the peer | ||
359 | * @param value peer to free | ||
360 | * @return GNUNET_YES (always: continue to iterate) | ||
361 | */ | ||
362 | static int | ||
363 | whitelist_peer (void *cls, | ||
364 | const GNUNET_HashCode *pid, | ||
365 | void *value) | ||
366 | { | ||
367 | struct Peer *pl = value; | ||
368 | |||
369 | if (! pl->is_blocked) | ||
370 | return GNUNET_YES; | ||
371 | pl->wh = GNUNET_TRANSPORT_blacklist (sched, cfg, | ||
372 | &pl->pid, | ||
373 | GNUNET_TIME_UNIT_ZERO, | ||
374 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
375 | &whitelist_done, | ||
376 | pl); | ||
377 | pl->is_blocked = GNUNET_NO; | ||
378 | return GNUNET_YES; | ||
379 | } | 257 | } |
380 | 258 | ||
381 | 259 | ||
@@ -386,22 +264,11 @@ whitelist_peer (void *cls, | |||
386 | static void | 264 | static void |
387 | whitelist_peers () | 265 | whitelist_peers () |
388 | { | 266 | { |
389 | struct DisconnectList *dl; | 267 | if (blacklist != NULL) |
390 | |||
391 | /* first, cancel all blacklisting requests */ | ||
392 | while (NULL != (dl = disconnect_head)) | ||
393 | { | 268 | { |
394 | GNUNET_CONTAINER_DLL_remove (disconnect_head, | 269 | GNUNET_TRANSPORT_blacklist_cancel (blacklist); |
395 | disconnect_tail, | 270 | blacklist = NULL; |
396 | dl); | ||
397 | GNUNET_TRANSPORT_blacklist_cancel (dl->rh); | ||
398 | GNUNET_free (dl); | ||
399 | } | 271 | } |
400 | /* then, specifically whitelist all peers that we | ||
401 | know to have blacklisted */ | ||
402 | GNUNET_CONTAINER_multihashmap_iterate (peers, | ||
403 | &whitelist_peer, | ||
404 | NULL); | ||
405 | } | 272 | } |
406 | 273 | ||
407 | 274 | ||
@@ -477,8 +344,6 @@ free_peer (void *cls, | |||
477 | pos)); | 344 | pos)); |
478 | if (pos->hello_req != NULL) | 345 | if (pos->hello_req != NULL) |
479 | GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); | 346 | GNUNET_CORE_notify_transmit_ready_cancel (pos->hello_req); |
480 | if (pos->wh != NULL) | ||
481 | GNUNET_TRANSPORT_blacklist_cancel (pos->wh); | ||
482 | if (pos->connect_req != NULL) | 347 | if (pos->connect_req != NULL) |
483 | GNUNET_CORE_peer_request_connect_cancel (pos->connect_req); | 348 | GNUNET_CORE_peer_request_connect_cancel (pos->connect_req); |
484 | if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) | 349 | if (pos->hello_delay_task != GNUNET_SCHEDULER_NO_TASK) |
@@ -521,8 +386,6 @@ attempt_connect (struct Peer *pos) | |||
521 | return; | 386 | return; |
522 | if (GNUNET_OK != is_connection_allowed (pos)) | 387 | if (GNUNET_OK != is_connection_allowed (pos)) |
523 | return; | 388 | return; |
524 | if (GNUNET_YES == pos->is_blocked) | ||
525 | return; | ||
526 | if (GNUNET_TIME_absolute_get_remaining (pos->greylisted_until).value > 0) | 389 | if (GNUNET_TIME_absolute_get_remaining (pos->greylisted_until).value > 0) |
527 | return; | 390 | return; |
528 | if (GNUNET_YES == pos->is_friend) | 391 | if (GNUNET_YES == pos->is_friend) |
@@ -593,7 +456,6 @@ remove_from_greylist (void *cls, | |||
593 | pos); | 456 | pos); |
594 | } | 457 | } |
595 | if ( (GNUNET_NO == pos->is_friend) && | 458 | if ( (GNUNET_NO == pos->is_friend) && |
596 | (GNUNET_NO == pos->is_blocked) && | ||
597 | (GNUNET_NO == pos->is_connected) ) | 459 | (GNUNET_NO == pos->is_connected) ) |
598 | { | 460 | { |
599 | free_peer (NULL, &pos->pid.hashPubKey, pos); | 461 | free_peer (NULL, &pos->pid.hashPubKey, pos); |
@@ -863,18 +725,7 @@ connect_notify (void *cls, | |||
863 | if (pos == NULL) | 725 | if (pos == NULL) |
864 | { | 726 | { |
865 | pos = make_peer (peer, NULL, GNUNET_NO); | 727 | pos = make_peer (peer, NULL, GNUNET_NO); |
866 | if (GNUNET_OK != is_connection_allowed (pos)) | 728 | GNUNET_break (GNUNET_OK == is_connection_allowed (pos)); |
867 | { | ||
868 | GNUNET_assert (pos->is_friend == GNUNET_NO); | ||
869 | pos->is_connected = GNUNET_YES; | ||
870 | #if DEBUG_TOPOLOGY | ||
871 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
872 | "Connection to `%s' is forbidden, forcing disconnect!\n", | ||
873 | GNUNET_i2s (peer)); | ||
874 | #endif | ||
875 | force_disconnect (pos); | ||
876 | return; | ||
877 | } | ||
878 | } | 729 | } |
879 | else | 730 | else |
880 | { | 731 | { |
@@ -899,35 +750,6 @@ connect_notify (void *cls, | |||
899 | 750 | ||
900 | 751 | ||
901 | /** | 752 | /** |
902 | * Disconnect from all non-friends (we're below quota). | ||
903 | * | ||
904 | * @param cls closure, not used | ||
905 | * @param pid identity of a peer | ||
906 | * @param value 'struct Peer*' for the peer | ||
907 | * @return GNUNET_YES (continue to iterate) | ||
908 | */ | ||
909 | static int | ||
910 | drop_non_friends (void *cls, | ||
911 | const GNUNET_HashCode *pid, | ||
912 | void *value) | ||
913 | { | ||
914 | struct Peer *pos = value; | ||
915 | |||
916 | if ( (GNUNET_NO == pos->is_friend) && | ||
917 | (GNUNET_YES == pos->is_connected) ) | ||
918 | { | ||
919 | #if DEBUG_TOPOLOGY | ||
920 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
921 | "Connection to `%s' is not from a friend, forcing disconnect!\n", | ||
922 | GNUNET_i2s (&pos->pid)); | ||
923 | #endif | ||
924 | force_disconnect (pos); | ||
925 | } | ||
926 | return GNUNET_YES; | ||
927 | } | ||
928 | |||
929 | |||
930 | /** | ||
931 | * Try to add more peers to our connection set. | 753 | * Try to add more peers to our connection set. |
932 | * | 754 | * |
933 | * @param cls closure, not used | 755 | * @param cls closure, not used |
@@ -995,17 +817,10 @@ disconnect_notify (void *cls, | |||
995 | GNUNET_CONTAINER_multihashmap_iterate (peers, | 817 | GNUNET_CONTAINER_multihashmap_iterate (peers, |
996 | &try_add_peers, | 818 | &try_add_peers, |
997 | NULL); | 819 | NULL); |
998 | if (friend_count < minimum_friend_count) | 820 | if ( (friend_count < minimum_friend_count) && |
999 | { | 821 | (blacklist == NULL) ) |
1000 | /* disconnect from all non-friends */ | 822 | blacklist = GNUNET_TRANSPORT_blacklist (sched, cfg, |
1001 | #if DEBUG_TOPOLOGY | 823 | &blacklist_check, NULL); |
1002 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1003 | "Not enough friendly connections, dropping all non-friend connections\n"); | ||
1004 | #endif | ||
1005 | GNUNET_CONTAINER_multihashmap_iterate (peers, | ||
1006 | &drop_non_friends, | ||
1007 | NULL); | ||
1008 | } | ||
1009 | } | 824 | } |
1010 | 825 | ||
1011 | 826 | ||
@@ -1389,13 +1204,21 @@ handle_encrypted_hello (void *cls, | |||
1389 | GNUNET_NO); | 1204 | GNUNET_NO); |
1390 | peer = GNUNET_CONTAINER_multihashmap_get (peers, | 1205 | peer = GNUNET_CONTAINER_multihashmap_get (peers, |
1391 | &pid.hashPubKey); | 1206 | &pid.hashPubKey); |
1392 | if ( (peer != NULL) && | 1207 | if (peer == NULL) |
1393 | (peer->is_blocked) ) | 1208 | { |
1394 | return GNUNET_OK; /* ignore: currently blocked */ | 1209 | if ( (GNUNET_YES == friends_only) || |
1395 | if ( (GNUNET_YES == friends_only) && | 1210 | (friend_count < minimum_friend_count) ) |
1396 | ( (peer == NULL) || | 1211 | return GNUNET_OK; |
1397 | (GNUNET_YES != peer->is_friend) ) ) | 1212 | } |
1398 | return GNUNET_OK; /* ignore: not a friend */ | 1213 | else |
1214 | { | ||
1215 | if ( (GNUNET_YES != peer->is_friend) && | ||
1216 | (GNUNET_YES == friends_only) ) | ||
1217 | return GNUNET_OK; | ||
1218 | if ( (GNUNET_YES != peer->is_friend) && | ||
1219 | (friend_count < minimum_friend_count) ) | ||
1220 | return GNUNET_OK; | ||
1221 | } | ||
1399 | if (transport != NULL) | 1222 | if (transport != NULL) |
1400 | GNUNET_TRANSPORT_offer_hello (transport, | 1223 | GNUNET_TRANSPORT_offer_hello (transport, |
1401 | message); | 1224 | message); |
@@ -1468,8 +1291,6 @@ static void | |||
1468 | cleaning_task (void *cls, | 1291 | cleaning_task (void *cls, |
1469 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 1292 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
1470 | { | 1293 | { |
1471 | struct DisconnectList *dl; | ||
1472 | |||
1473 | if (NULL != peerinfo_notify) | 1294 | if (NULL != peerinfo_notify) |
1474 | { | 1295 | { |
1475 | GNUNET_PEERINFO_notify_cancel (peerinfo_notify); | 1296 | GNUNET_PEERINFO_notify_cancel (peerinfo_notify); |
@@ -1486,14 +1307,7 @@ cleaning_task (void *cls, | |||
1486 | GNUNET_CORE_disconnect (handle); | 1307 | GNUNET_CORE_disconnect (handle); |
1487 | handle = NULL; | 1308 | handle = NULL; |
1488 | } | 1309 | } |
1489 | while (NULL != (dl = disconnect_head)) | 1310 | whitelist_peers (); |
1490 | { | ||
1491 | GNUNET_CONTAINER_DLL_remove (disconnect_head, | ||
1492 | disconnect_tail, | ||
1493 | dl); | ||
1494 | GNUNET_TRANSPORT_blacklist_cancel (dl->rh); | ||
1495 | GNUNET_free (dl); | ||
1496 | } | ||
1497 | if (stats != NULL) | 1311 | if (stats != NULL) |
1498 | { | 1312 | { |
1499 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); | 1313 | GNUNET_STATISTICS_destroy (stats, GNUNET_NO); |
@@ -1560,6 +1374,9 @@ run (void *cls, | |||
1560 | minimum_friend_count, | 1374 | minimum_friend_count, |
1561 | autoconnect ? "autoconnect enabled" : "autoconnect disabled"); | 1375 | autoconnect ? "autoconnect enabled" : "autoconnect disabled"); |
1562 | #endif | 1376 | #endif |
1377 | if (friend_count < minimum_friend_count) | ||
1378 | blacklist = GNUNET_TRANSPORT_blacklist (sched, cfg, | ||
1379 | &blacklist_check, NULL); | ||
1563 | transport = GNUNET_TRANSPORT_connect (sched, | 1380 | transport = GNUNET_TRANSPORT_connect (sched, |
1564 | cfg, | 1381 | cfg, |
1565 | NULL, | 1382 | NULL, |
@@ -1571,7 +1388,6 @@ run (void *cls, | |||
1571 | GNUNET_TIME_UNIT_FOREVER_REL, | 1388 | GNUNET_TIME_UNIT_FOREVER_REL, |
1572 | NULL, | 1389 | NULL, |
1573 | &core_init, | 1390 | &core_init, |
1574 | NULL, | ||
1575 | &connect_notify, | 1391 | &connect_notify, |
1576 | &disconnect_notify, | 1392 | &disconnect_notify, |
1577 | NULL, GNUNET_NO, | 1393 | NULL, GNUNET_NO, |