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 | |
parent | e8bc962b2ed43e194ba124537573da236786e82c (diff) | |
download | gnunet-541caf3dec54aaee621fed935e667f9ee423ef31.tar.gz gnunet-541caf3dec54aaee621fed935e667f9ee423ef31.zip |
towards fixing blacklisting APIs and implementation
-rw-r--r-- | TODO | 16 | ||||
-rw-r--r-- | src/core/core.h | 13 | ||||
-rw-r--r-- | src/core/core_api.c | 28 | ||||
-rw-r--r-- | src/core/gnunet-service-core.c | 14 | ||||
-rw-r--r-- | src/core/test_core_api.c | 6 | ||||
-rw-r--r-- | src/core/test_core_api_start_only.c | 6 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs.c | 1 | ||||
-rw-r--r-- | src/hostlist/gnunet-daemon-hostlist.c | 2 | ||||
-rw-r--r-- | src/include/gnunet_core_service.h | 4 | ||||
-rw-r--r-- | src/include/gnunet_protocols.h | 15 | ||||
-rw-r--r-- | src/include/gnunet_transport_service.h | 97 | ||||
-rw-r--r-- | src/testing/test_testing_topology.c | 3 | ||||
-rw-r--r-- | src/testing/testing.c | 4 | ||||
-rw-r--r-- | src/topology/gnunet-daemon-topology.c | 278 | ||||
-rw-r--r-- | src/transport/Makefile.am | 3 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_blacklist.c | 142 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_blacklist.h | 35 | ||||
-rw-r--r-- | src/transport/transport.h | 17 | ||||
-rw-r--r-- | src/transport/transport_api_blacklist.c | 385 |
19 files changed, 347 insertions, 722 deletions
@@ -2,20 +2,10 @@ | |||
2 | * PEERINFO: [CG] | 2 | * PEERINFO: [CG] |
3 | - trust: need *fast* way to check/update trust in peers | 3 | - trust: need *fast* way to check/update trust in peers |
4 | (async peerinfo would not be right; certainly not with the current API) | 4 | (async peerinfo would not be right; certainly not with the current API) |
5 | * TRANSPORT: [CG] | ||
6 | - need to implement and test new blacklisting code (server-side only, client API exists) | ||
5 | * TOPOLOGY: [CG] | 7 | * TOPOLOGY: [CG] |
6 | - If the topology daemon crashes, peers that were put on the | 8 | - needs more testing (especially F2F topology) -- need transport blacklisting to be implemented first! |
7 | blacklist with transport will never be removed from it (until | ||
8 | transport service dies); we should use the blacklist notification | ||
9 | API to learn about the exact set of blacklisted peers at all times | ||
10 | (FIXME: the transport_api implementation of blacklisting | ||
11 | also does not work nicely for this since it won't let us know about | ||
12 | disconnect-reconnect events and the implicit whitelisting | ||
13 | that might happen here; that's not so bad since we will | ||
14 | re-blacklist on pre-connect attempts anyway, so this is | ||
15 | a minor issue; OTOH, we might want to be more explicit about | ||
16 | allowing/forbidding connects on pre-connect to avoid | ||
17 | entering connect attempts to just be blacklisted shortly afterwards). | ||
18 | - needs more testing (especially F2F topology) | ||
19 | * FS: [CG] | 9 | * FS: [CG] |
20 | - support recursive download even if filename is NULL and we hence | 10 | - support recursive download even if filename is NULL and we hence |
21 | do not generate files on disk (use temp_filename) | 11 | do not generate files on disk (use temp_filename) |
diff --git a/src/core/core.h b/src/core/core.h index 45d138140..f91995734 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
@@ -43,13 +43,12 @@ | |||
43 | * transmitted to the client. | 43 | * transmitted to the client. |
44 | */ | 44 | */ |
45 | #define GNUNET_CORE_OPTION_NOTHING 0 | 45 | #define GNUNET_CORE_OPTION_NOTHING 0 |
46 | #define GNUNET_CORE_OPTION_SEND_PRE_CONNECT 1 | 46 | #define GNUNET_CORE_OPTION_SEND_CONNECT 1 |
47 | #define GNUNET_CORE_OPTION_SEND_CONNECT 2 | 47 | #define GNUNET_CORE_OPTION_SEND_DISCONNECT 2 |
48 | #define GNUNET_CORE_OPTION_SEND_DISCONNECT 4 | 48 | #define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 4 |
49 | #define GNUNET_CORE_OPTION_SEND_FULL_INBOUND 8 | 49 | #define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 8 |
50 | #define GNUNET_CORE_OPTION_SEND_HDR_INBOUND 16 | 50 | #define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 16 |
51 | #define GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND 32 | 51 | #define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 32 |
52 | #define GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND 64 | ||
53 | 52 | ||
54 | 53 | ||
55 | /** | 54 | /** |
diff --git a/src/core/core_api.c b/src/core/core_api.c index 4672c7843..42e8f1c06 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c | |||
@@ -56,12 +56,6 @@ struct GNUNET_CORE_Handle | |||
56 | GNUNET_CORE_StartupCallback init; | 56 | GNUNET_CORE_StartupCallback init; |
57 | 57 | ||
58 | /** | 58 | /** |
59 | * Function to call whenever we're notified about a peer connecting | ||
60 | * (pre-connects, no session key exchange yet). | ||
61 | */ | ||
62 | GNUNET_CORE_ConnectEventHandler pre_connects; | ||
63 | |||
64 | /** | ||
65 | * Function to call whenever we're notified about a peer connecting. | 59 | * Function to call whenever we're notified about a peer connecting. |
66 | */ | 60 | */ |
67 | GNUNET_CORE_ConnectEventHandler connects; | 61 | GNUNET_CORE_ConnectEventHandler connects; |
@@ -406,23 +400,6 @@ main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | |||
406 | #endif | 400 | #endif |
407 | switch (ntohs (msg->type)) | 401 | switch (ntohs (msg->type)) |
408 | { | 402 | { |
409 | case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT: | ||
410 | if (NULL == h->pre_connects) | ||
411 | { | ||
412 | GNUNET_break (0); | ||
413 | break; | ||
414 | } | ||
415 | if (msize != sizeof (struct ConnectNotifyMessage)) | ||
416 | { | ||
417 | GNUNET_break (0); | ||
418 | break; | ||
419 | } | ||
420 | cnm = (const struct ConnectNotifyMessage *) msg; | ||
421 | h->pre_connects (h->cls, | ||
422 | &cnm->peer, | ||
423 | GNUNET_TIME_relative_ntoh (cnm->latency), | ||
424 | ntohl (cnm->distance)); | ||
425 | break; | ||
426 | case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT: | 403 | case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT: |
427 | if (NULL == h->connects) | 404 | if (NULL == h->connects) |
428 | { | 405 | { |
@@ -662,8 +639,6 @@ transmit_start (void *cls, size_t size, void *buf) | |||
662 | init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT); | 639 | init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT); |
663 | init->header.size = htons (msize); | 640 | init->header.size = htons (msize); |
664 | opt = GNUNET_CORE_OPTION_NOTHING; | 641 | opt = GNUNET_CORE_OPTION_NOTHING; |
665 | if (h->pre_connects != NULL) | ||
666 | opt |= GNUNET_CORE_OPTION_SEND_PRE_CONNECT; | ||
667 | if (h->connects != NULL) | 642 | if (h->connects != NULL) |
668 | opt |= GNUNET_CORE_OPTION_SEND_CONNECT; | 643 | opt |= GNUNET_CORE_OPTION_SEND_CONNECT; |
669 | if (h->disconnects != NULL) | 644 | if (h->disconnects != NULL) |
@@ -705,7 +680,6 @@ transmit_start (void *cls, size_t size, void *buf) | |||
705 | * @param cls closure for the various callbacks that follow (including handlers in the handlers array) | 680 | * @param cls closure for the various callbacks that follow (including handlers in the handlers array) |
706 | * @param init callback to call on timeout or once we have successfully | 681 | * @param init callback to call on timeout or once we have successfully |
707 | * connected to the core service; note that timeout is only meaningful if init is not NULL | 682 | * connected to the core service; note that timeout is only meaningful if init is not NULL |
708 | * @param pre_connects function to call on peer pre-connect (no session key yet), can be NULL | ||
709 | * @param connects function to call on peer connect, can be NULL | 683 | * @param connects function to call on peer connect, can be NULL |
710 | * @param disconnects function to call on peer disconnect / timeout, can be NULL | 684 | * @param disconnects function to call on peer disconnect / timeout, can be NULL |
711 | * @param inbound_notify function to call for all inbound messages, can be NULL | 685 | * @param inbound_notify function to call for all inbound messages, can be NULL |
@@ -726,7 +700,6 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, | |||
726 | struct GNUNET_TIME_Relative timeout, | 700 | struct GNUNET_TIME_Relative timeout, |
727 | void *cls, | 701 | void *cls, |
728 | GNUNET_CORE_StartupCallback init, | 702 | GNUNET_CORE_StartupCallback init, |
729 | GNUNET_CORE_ConnectEventHandler pre_connects, | ||
730 | GNUNET_CORE_ConnectEventHandler connects, | 703 | GNUNET_CORE_ConnectEventHandler connects, |
731 | GNUNET_CORE_DisconnectEventHandler disconnects, | 704 | GNUNET_CORE_DisconnectEventHandler disconnects, |
732 | GNUNET_CORE_MessageCallback inbound_notify, | 705 | GNUNET_CORE_MessageCallback inbound_notify, |
@@ -742,7 +715,6 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, | |||
742 | h->cfg = cfg; | 715 | h->cfg = cfg; |
743 | h->cls = cls; | 716 | h->cls = cls; |
744 | h->init = init; | 717 | h->init = init; |
745 | h->pre_connects = pre_connects; | ||
746 | h->connects = connects; | 718 | h->connects = connects; |
747 | h->disconnects = disconnects; | 719 | h->disconnects = disconnects; |
748 | h->inbound_notify = inbound_notify; | 720 | h->inbound_notify = inbound_notify; |
diff --git a/src/core/gnunet-service-core.c b/src/core/gnunet-service-core.c index 044b7496e..bad6f05d3 100644 --- a/src/core/gnunet-service-core.c +++ b/src/core/gnunet-service-core.c | |||
@@ -3450,13 +3450,6 @@ handle_transport_receive (void *cls, | |||
3450 | (n->status != PEER_STATE_KEY_CONFIRMED)) | 3450 | (n->status != PEER_STATE_KEY_CONFIRMED)) |
3451 | { | 3451 | { |
3452 | GNUNET_break_op (0); | 3452 | GNUNET_break_op (0); |
3453 | /* blacklist briefly (?); might help recover (?) */ | ||
3454 | GNUNET_TRANSPORT_blacklist (sched, cfg, | ||
3455 | &n->peer, | ||
3456 | GNUNET_TIME_UNIT_SECONDS, | ||
3457 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, | ||
3458 | 5), | ||
3459 | NULL, NULL); | ||
3460 | return; | 3453 | return; |
3461 | } | 3454 | } |
3462 | handle_encrypted_message (n, (const struct EncryptedMessage *) message); | 3455 | handle_encrypted_message (n, (const struct EncryptedMessage *) message); |
@@ -3626,7 +3619,6 @@ handle_transport_notify_connect (void *cls, | |||
3626 | unsigned int distance) | 3619 | unsigned int distance) |
3627 | { | 3620 | { |
3628 | struct Neighbour *n; | 3621 | struct Neighbour *n; |
3629 | struct ConnectNotifyMessage cnm; | ||
3630 | 3622 | ||
3631 | if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity))) | 3623 | if (0 == memcmp (peer, &my_identity, sizeof (struct GNUNET_PeerIdentity))) |
3632 | { | 3624 | { |
@@ -3665,12 +3657,6 @@ handle_transport_notify_connect (void *cls, | |||
3665 | "Received connection from `%4s'.\n", | 3657 | "Received connection from `%4s'.\n", |
3666 | GNUNET_i2s (&n->peer)); | 3658 | GNUNET_i2s (&n->peer)); |
3667 | #endif | 3659 | #endif |
3668 | cnm.header.size = htons (sizeof (struct ConnectNotifyMessage)); | ||
3669 | cnm.header.type = htons (GNUNET_MESSAGE_TYPE_CORE_NOTIFY_PRE_CONNECT); | ||
3670 | cnm.distance = htonl (n->last_distance); | ||
3671 | cnm.latency = GNUNET_TIME_relative_hton (n->last_latency); | ||
3672 | cnm.peer = *peer; | ||
3673 | send_to_all_clients (&cnm.header, GNUNET_YES, GNUNET_CORE_OPTION_SEND_PRE_CONNECT); | ||
3674 | GNUNET_TRANSPORT_set_quota (transport, | 3660 | GNUNET_TRANSPORT_set_quota (transport, |
3675 | &n->peer, | 3661 | &n->peer, |
3676 | n->bw_in, | 3662 | n->bw_in, |
diff --git a/src/core/test_core_api.c b/src/core/test_core_api.c index 78d6b7fe1..6b8387461 100644 --- a/src/core/test_core_api.c +++ b/src/core/test_core_api.c | |||
@@ -229,8 +229,7 @@ init_notify (void *cls, | |||
229 | p2.cfg, | 229 | p2.cfg, |
230 | TIMEOUT, | 230 | TIMEOUT, |
231 | &p2, | 231 | &p2, |
232 | &init_notify, | 232 | &init_notify, |
233 | NULL, | ||
234 | &connect_notify, | 233 | &connect_notify, |
235 | &disconnect_notify, | 234 | &disconnect_notify, |
236 | &inbound_notify, | 235 | &inbound_notify, |
@@ -325,8 +324,7 @@ run (void *cls, | |||
325 | TIMEOUT, | 324 | TIMEOUT, |
326 | &p1, | 325 | &p1, |
327 | &init_notify, | 326 | &init_notify, |
328 | NULL, | 327 | &connect_notify, |
329 | &connect_notify, | ||
330 | &disconnect_notify, | 328 | &disconnect_notify, |
331 | &inbound_notify, | 329 | &inbound_notify, |
332 | GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); | 330 | GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); |
diff --git a/src/core/test_core_api_start_only.c b/src/core/test_core_api_start_only.c index e8bfdd4e5..86eff056c 100644 --- a/src/core/test_core_api_start_only.c +++ b/src/core/test_core_api_start_only.c | |||
@@ -130,8 +130,7 @@ init_notify (void *cls, | |||
130 | p2.cfg, | 130 | p2.cfg, |
131 | TIMEOUT, | 131 | TIMEOUT, |
132 | &p2, | 132 | &p2, |
133 | &init_notify, | 133 | &init_notify, |
134 | NULL, | ||
135 | &connect_notify, | 134 | &connect_notify, |
136 | &disconnect_notify, | 135 | &disconnect_notify, |
137 | &inbound_notify, | 136 | &inbound_notify, |
@@ -185,8 +184,7 @@ run (void *cls, | |||
185 | TIMEOUT, | 184 | TIMEOUT, |
186 | &p1, | 185 | &p1, |
187 | &init_notify, | 186 | &init_notify, |
188 | NULL, | 187 | &connect_notify, |
189 | &connect_notify, | ||
190 | &disconnect_notify, | 188 | &disconnect_notify, |
191 | &inbound_notify, | 189 | &inbound_notify, |
192 | GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); | 190 | GNUNET_YES, &outbound_notify, GNUNET_YES, handlers); |
diff --git a/src/fs/gnunet-service-fs.c b/src/fs/gnunet-service-fs.c index faf436bc0..0d1d3d9e4 100644 --- a/src/fs/gnunet-service-fs.c +++ b/src/fs/gnunet-service-fs.c | |||
@@ -3025,7 +3025,6 @@ main_init (struct GNUNET_SCHEDULER_Handle *s, | |||
3025 | GNUNET_TIME_UNIT_FOREVER_REL, | 3025 | GNUNET_TIME_UNIT_FOREVER_REL, |
3026 | NULL, | 3026 | NULL, |
3027 | NULL, | 3027 | NULL, |
3028 | NULL, | ||
3029 | &peer_connect_handler, | 3028 | &peer_connect_handler, |
3030 | &peer_disconnect_handler, | 3029 | &peer_disconnect_handler, |
3031 | NULL, GNUNET_NO, | 3030 | NULL, GNUNET_NO, |
diff --git a/src/hostlist/gnunet-daemon-hostlist.c b/src/hostlist/gnunet-daemon-hostlist.c index c06ee5f56..ca0f11cae 100644 --- a/src/hostlist/gnunet-daemon-hostlist.c +++ b/src/hostlist/gnunet-daemon-hostlist.c | |||
@@ -296,7 +296,7 @@ run (void *cls, | |||
296 | GNUNET_TIME_UNIT_FOREVER_REL, | 296 | GNUNET_TIME_UNIT_FOREVER_REL, |
297 | NULL, | 297 | NULL, |
298 | &core_init, | 298 | &core_init, |
299 | NULL, &connect_handler, &disconnect_handler, | 299 | &connect_handler, &disconnect_handler, |
300 | NULL, GNUNET_NO, | 300 | NULL, GNUNET_NO, |
301 | NULL, GNUNET_NO, | 301 | NULL, GNUNET_NO, |
302 | learning? learn_handlers : no_learn_handlers); | 302 | learning? learn_handlers : no_learn_handlers); |
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h index 47b8d6f98..b7dc6f7da 100644 --- a/src/include/gnunet_core_service.h +++ b/src/include/gnunet_core_service.h | |||
@@ -51,7 +51,7 @@ struct GNUNET_CORE_Handle; | |||
51 | 51 | ||
52 | 52 | ||
53 | /** | 53 | /** |
54 | * Method called whenever a given peer either connects. | 54 | * Method called whenever a given peer connects. |
55 | * | 55 | * |
56 | * @param cls closure | 56 | * @param cls closure |
57 | * @param peer peer identity this notification is about | 57 | * @param peer peer identity this notification is about |
@@ -164,7 +164,6 @@ typedef void | |||
164 | * @param cls closure for the various callbacks that follow (including handlers in the handlers array) | 164 | * @param cls closure for the various callbacks that follow (including handlers in the handlers array) |
165 | * @param init callback to call on timeout or once we have successfully | 165 | * @param init callback to call on timeout or once we have successfully |
166 | * connected to the core service; note that timeout is only meaningful if init is not NULL | 166 | * connected to the core service; note that timeout is only meaningful if init is not NULL |
167 | * @param pre_connects function to call on peer pre-connect (no session key yet), can be NULL | ||
168 | * @param connects function to call on peer connect, can be NULL | 167 | * @param connects function to call on peer connect, can be NULL |
169 | * @param disconnects function to call on peer disconnect / timeout, can be NULL | 168 | * @param disconnects function to call on peer disconnect / timeout, can be NULL |
170 | * @param inbound_notify function to call for all inbound messages, can be NULL | 169 | * @param inbound_notify function to call for all inbound messages, can be NULL |
@@ -200,7 +199,6 @@ GNUNET_CORE_connect (struct GNUNET_SCHEDULER_Handle *sched, | |||
200 | struct GNUNET_TIME_Relative timeout, | 199 | struct GNUNET_TIME_Relative timeout, |
201 | void *cls, | 200 | void *cls, |
202 | GNUNET_CORE_StartupCallback init, | 201 | GNUNET_CORE_StartupCallback init, |
203 | GNUNET_CORE_ConnectEventHandler pre_connects, | ||
204 | GNUNET_CORE_ConnectEventHandler connects, | 202 | GNUNET_CORE_ConnectEventHandler connects, |
205 | GNUNET_CORE_DisconnectEventHandler disconnects, | 203 | GNUNET_CORE_DisconnectEventHandler disconnects, |
206 | GNUNET_CORE_MessageCallback inbound_notify, | 204 | GNUNET_CORE_MessageCallback inbound_notify, |
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h index 602137f98..d992c9fb7 100644 --- a/src/include/gnunet_protocols.h +++ b/src/include/gnunet_protocols.h | |||
@@ -174,16 +174,19 @@ extern "C" | |||
174 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY 28 | 174 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_ADDRESS_REPLY 28 |
175 | 175 | ||
176 | /** | 176 | /** |
177 | * Change in blacklisting status of a peer. | 177 | * Register a client that wants to do blacklisting. |
178 | */ | 178 | */ |
179 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST 29 | 179 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT 29 |
180 | 180 | ||
181 | /** | 181 | /** |
182 | * Request to transport to notify us about any blacklisting status | 182 | * Query to a blacklisting client (is this peer blacklisted)? |
183 | * changes on this connection (and to immediately send all | ||
184 | * active blacklist entries). | ||
185 | */ | 183 | */ |
186 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_NOTIFY 30 | 184 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY 30 |
185 | |||
186 | /** | ||
187 | * Reply from blacklisting client (answer to blacklist query). | ||
188 | */ | ||
189 | #define GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY 31 | ||
187 | 190 | ||
188 | /** | 191 | /** |
189 | * Transport PING message | 192 | * Transport PING message |
diff --git a/src/include/gnunet_transport_service.h b/src/include/gnunet_transport_service.h index 711ebb599..57bdecd17 100644 --- a/src/include/gnunet_transport_service.h +++ b/src/include/gnunet_transport_service.h | |||
@@ -299,99 +299,52 @@ GNUNET_TRANSPORT_address_lookup (struct GNUNET_SCHEDULER_Handle *sched, | |||
299 | 299 | ||
300 | 300 | ||
301 | /** | 301 | /** |
302 | * Handle for blacklisting requests. | 302 | * Handle for blacklisting peers. |
303 | */ | 303 | */ |
304 | struct GNUNET_TRANSPORT_BlacklistRequest; | 304 | struct GNUNET_TRANSPORT_Blacklist; |
305 | 305 | ||
306 | 306 | ||
307 | /** | 307 | /** |
308 | * Blacklist a peer for a given period of time. All connections | 308 | * Function that decides if a connection is acceptable or not. |
309 | * (inbound and outbound) to a peer that is blacklisted will be | ||
310 | * dropped (as soon as we learn who the connection is for). A second | ||
311 | * call to this function for the same peer overrides previous | ||
312 | * blacklisting requests. | ||
313 | * | ||
314 | * @param sched scheduler to use | ||
315 | * @param cfg configuration to use | ||
316 | * @param peer identity of peer to blacklist | ||
317 | * @param duration how long to blacklist, use GNUNET_TIME_UNIT_ZERO to | ||
318 | * re-enable connections | ||
319 | * @param timeout when should this operation (trying to establish the | ||
320 | * blacklisting time out) | ||
321 | * @param cont continuation to call once the request has been processed | ||
322 | * @param cont_cls closure for cont | ||
323 | * @return NULL on error, otherwise handle for cancellation | ||
324 | */ | ||
325 | struct GNUNET_TRANSPORT_BlacklistRequest * | ||
326 | GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched, | ||
327 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
328 | const struct GNUNET_PeerIdentity *peer, | ||
329 | struct GNUNET_TIME_Relative duration, | ||
330 | struct GNUNET_TIME_Relative timeout, | ||
331 | GNUNET_SCHEDULER_Task cont, | ||
332 | void *cont_cls); | ||
333 | |||
334 | |||
335 | /** | ||
336 | * Abort transmitting the blacklist request. Note that this function | ||
337 | * is NOT for removing a peer from the blacklist (for that, call | ||
338 | * GNUNET_TRANSPORT_blacklist with a duration of zero). This function | ||
339 | * is only for aborting the transmission of a blacklist request | ||
340 | * (i.e. because of shutdown). | ||
341 | * | ||
342 | * @param br handle of the request that is to be cancelled | ||
343 | */ | ||
344 | void | ||
345 | GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_BlacklistRequest * br); | ||
346 | |||
347 | |||
348 | /** | ||
349 | * Handle for blacklist notifications. | ||
350 | */ | ||
351 | struct GNUNET_TRANSPORT_BlacklistNotification; | ||
352 | |||
353 | |||
354 | /** | ||
355 | * Signature of function called whenever the blacklist status of | ||
356 | * a peer changes. This includes changes to the duration of the | ||
357 | * blacklist status as well as the expiration of an existing | ||
358 | * blacklist status. | ||
359 | * | 309 | * |
360 | * @param cls closure | 310 | * @param cls closure |
361 | * @param peer identity of peer with the change | 311 | * @param pid peer to approve or disapproave |
362 | * @param until GNUNET_TIME_UNIT_ZERO_ABS if the peer is no | 312 | * @return GNUNET_OK if the connection is allowed |
363 | * longer blacklisted, otherwise the time at | ||
364 | * which the current blacklisting will expire | ||
365 | */ | 313 | */ |
366 | typedef void (*GNUNET_TRANSPORT_BlacklistCallback)(void *cls, | 314 | typedef int (*GNUNET_TRANSPORT_BlacklistCallback)(void *cls, |
367 | const struct GNUNET_PeerIdentity *peer, | 315 | const struct GNUNET_PeerIdentity *pid); |
368 | struct GNUNET_TIME_Absolute until); | ||
369 | 316 | ||
370 | 317 | ||
371 | /** | 318 | /** |
372 | * Call a function whenever a peer's blacklisting status changes. | 319 | * Install a blacklist callback. The service will be queried for all |
320 | * existing connections as well as any fresh connections to check if | ||
321 | * they are permitted. If the blacklisting callback is unregistered, | ||
322 | * all hosts that were denied in the past will automatically be | ||
323 | * whitelisted again. Cancelling the blacklist handle is also the | ||
324 | * only way to re-enable connections from peers that were previously | ||
325 | * blacklisted. | ||
373 | * | 326 | * |
374 | * @param sched scheduler to use | 327 | * @param sched scheduler to use |
375 | * @param cfg configuration to use | 328 | * @param cfg configuration to use |
376 | * @param bc function to call on status changes | 329 | * @param cb callback to invoke to check if connections are allowed |
377 | * @param bc_cls closure for bc | 330 | * @param cb_cls closure for cb |
378 | * @return NULL on error, otherwise handle for cancellation | 331 | * @return NULL on error, otherwise handle for cancellation |
379 | */ | 332 | */ |
380 | struct GNUNET_TRANSPORT_BlacklistNotification * | 333 | struct GNUNET_TRANSPORT_Blacklist * |
381 | GNUNET_TRANSPORT_blacklist_notify (struct GNUNET_SCHEDULER_Handle *sched, | 334 | GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched, |
382 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 335 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
383 | GNUNET_TRANSPORT_BlacklistCallback bc, | 336 | GNUNET_TRANSPORT_BlacklistCallback cb, |
384 | void *bc_cls); | 337 | void *cb_cls); |
385 | 338 | ||
386 | 339 | ||
387 | /** | 340 | /** |
388 | * Stop calling the notification callback associated with | 341 | * Abort the blacklist. Note that this function is the only way for |
389 | * the given blacklist notification. | 342 | * removing a peer from the blacklist. |
390 | * | 343 | * |
391 | * @param bn handle of the request that is to be cancelled | 344 | * @param br handle of the request that is to be cancelled |
392 | */ | 345 | */ |
393 | void | 346 | void |
394 | GNUNET_TRANSPORT_blacklist_notify_cancel (struct GNUNET_TRANSPORT_BlacklistNotification * bn); | 347 | GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br); |
395 | 348 | ||
396 | 349 | ||
397 | 350 | ||
diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c index 7f5411fc4..4c7fc01ba 100644 --- a/src/testing/test_testing_topology.c +++ b/src/testing/test_testing_topology.c | |||
@@ -392,8 +392,7 @@ setup_handlers () | |||
392 | temp_daemon->cfg, | 392 | temp_daemon->cfg, |
393 | TIMEOUT, | 393 | TIMEOUT, |
394 | new_connection, | 394 | new_connection, |
395 | &init_notify, | 395 | &init_notify, |
396 | NULL, | ||
397 | NULL, | 396 | NULL, |
398 | NULL, | 397 | NULL, |
399 | NULL, | 398 | NULL, |
diff --git a/src/testing/testing.c b/src/testing/testing.c index 2b9b560fa..eae5076e0 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c | |||
@@ -265,7 +265,7 @@ start_fsm (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
265 | ARM_START_WAIT, | 265 | ARM_START_WAIT, |
266 | d, | 266 | d, |
267 | &testing_init, | 267 | &testing_init, |
268 | NULL, NULL, NULL, | 268 | NULL, NULL, |
269 | NULL, GNUNET_NO, | 269 | NULL, GNUNET_NO, |
270 | NULL, GNUNET_NO, no_handlers); | 270 | NULL, GNUNET_NO, no_handlers); |
271 | break; | 271 | break; |
@@ -904,7 +904,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1, | |||
904 | timeout, | 904 | timeout, |
905 | ctx, | 905 | ctx, |
906 | NULL, | 906 | NULL, |
907 | NULL, &connect_notify, NULL, | 907 | &connect_notify, NULL, |
908 | NULL, GNUNET_NO, | 908 | NULL, GNUNET_NO, |
909 | NULL, GNUNET_NO, no_handlers); | 909 | NULL, GNUNET_NO, no_handlers); |
910 | if (ctx->d1core == NULL) | 910 | if (ctx->d1core == NULL) |
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, |
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 70c6c6c75..71e6470e3 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am | |||
@@ -57,8 +57,7 @@ gnunet_transport_LDADD = \ | |||
57 | $(GN_LIBINTL) | 57 | $(GN_LIBINTL) |
58 | 58 | ||
59 | gnunet_service_transport_SOURCES = \ | 59 | gnunet_service_transport_SOURCES = \ |
60 | gnunet-service-transport.c plugin_transport.h \ | 60 | gnunet-service-transport.c plugin_transport.h |
61 | gnunet-service-transport_blacklist.c gnunet-service-transport_blacklist.h | ||
62 | gnunet_service_transport_LDADD = \ | 61 | gnunet_service_transport_LDADD = \ |
63 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ | 62 | $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \ |
64 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ | 63 | $(top_builddir)/src/statistics/libgnunetstatistics.la \ |
diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index 8f78f498f..08ed2c9d2 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c | |||
@@ -43,32 +43,75 @@ struct BlacklistEntry | |||
43 | struct GNUNET_PeerIdentity peer; | 43 | struct GNUNET_PeerIdentity peer; |
44 | 44 | ||
45 | /** | 45 | /** |
46 | * How long until this entry times out? | 46 | * Client responsible for this entry. |
47 | */ | 47 | */ |
48 | struct GNUNET_TIME_Absolute until; | 48 | struct GNUNET_SERVER_Client *client; |
49 | |||
50 | }; | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Information kept for each client registered to perform | ||
55 | * blacklisting. | ||
56 | */ | ||
57 | struct Blacklisters | ||
58 | { | ||
59 | /** | ||
60 | * This is a linked list. | ||
61 | */ | ||
62 | struct Blacklisters *next; | ||
63 | |||
64 | /** | ||
65 | * This is a linked list. | ||
66 | */ | ||
67 | struct Blacklisters *prev; | ||
49 | 68 | ||
50 | /** | 69 | /** |
51 | * Task scheduled to run the moment the time does run out. | 70 | * Client responsible for this entry. |
52 | */ | 71 | */ |
53 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | 72 | struct GNUNET_SERVER_Client *client; |
73 | |||
54 | }; | 74 | }; |
55 | 75 | ||
56 | 76 | ||
57 | /** | 77 | /** |
78 | * State of blacklist check to be performed for each | ||
79 | * connecting peer. | ||
80 | */ | ||
81 | struct BlacklistCheck | ||
82 | { | ||
83 | |||
84 | |||
85 | |||
86 | /** | ||
87 | * Identity of the peer being checked. | ||
88 | */ | ||
89 | struct GNUNET_PeerIdentity peer; | ||
90 | |||
91 | /** | ||
92 | * Clients we still need to ask. | ||
93 | */ | ||
94 | struct GNUNET_SERVER_Client *pending; | ||
95 | |||
96 | }; | ||
97 | |||
98 | |||
99 | |||
100 | /** | ||
58 | * Map of blacklisted peers (maps from peer identities | 101 | * Map of blacklisted peers (maps from peer identities |
59 | * to 'struct BlacklistEntry*' values). | 102 | * to 'struct BlacklistEntry*' values). |
60 | */ | 103 | */ |
61 | static struct GNUNET_CONTAINER_MultiHashMap *blacklist; | 104 | static struct GNUNET_CONTAINER_MultiHashMap *blacklist; |
62 | 105 | ||
63 | /** | 106 | /** |
64 | * Notifications for blacklisting. | 107 | * Head of DLL of blacklisting clients. |
65 | */ | 108 | */ |
66 | static struct GNUNET_SERVER_NotificationContext *blacklist_notifiers; | 109 | static struct Blacklisters *bl_head; |
67 | 110 | ||
68 | /** | 111 | /** |
69 | * Our scheduler. | 112 | * Tail of DLL of blacklisting clients. |
70 | */ | 113 | */ |
71 | static struct GNUNET_SCHEDULER_Handle *sched; | 114 | static struct Blacklisters *bl_tail; |
72 | 115 | ||
73 | 116 | ||
74 | /** | 117 | /** |
@@ -86,8 +129,6 @@ free_blacklist_entry (void *cls, | |||
86 | { | 129 | { |
87 | struct BlacklistEntry *be = value; | 130 | struct BlacklistEntry *be = value; |
88 | 131 | ||
89 | GNUNET_SCHEDULER_cancel (sched, | ||
90 | be->timeout_task); | ||
91 | GNUNET_free (be); | 132 | GNUNET_free (be); |
92 | return GNUNET_YES; | 133 | return GNUNET_YES; |
93 | } | 134 | } |
@@ -108,37 +149,28 @@ shutdown_task (void *cls, | |||
108 | NULL); | 149 | NULL); |
109 | GNUNET_CONTAINER_multihashmap_destroy (blacklist); | 150 | GNUNET_CONTAINER_multihashmap_destroy (blacklist); |
110 | blacklist = NULL; | 151 | blacklist = NULL; |
111 | GNUNET_SERVER_notification_context_destroy (blacklist_notifiers); | ||
112 | blacklist_notifiers = NULL; | ||
113 | } | 152 | } |
114 | 153 | ||
115 | 154 | ||
116 | /** | 155 | /** |
117 | * Task run when a blacklist entry times out. | 156 | * Handle a request to start a blacklist. |
118 | * | 157 | * |
119 | * @param cls closure (the 'struct BlacklistEntry*') | 158 | * @param cls closure (always NULL) |
120 | * @param tc scheduler context (unused) | 159 | * @param client identification of the client |
160 | * @param message the actual message | ||
121 | */ | 161 | */ |
122 | static void | 162 | void |
123 | timeout_task (void *cls, | 163 | GNUNET_TRANSPORT_handle_blacklist_init (void *cls, |
124 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 164 | struct GNUNET_SERVER_Client *client, |
165 | const struct GNUNET_MessageHeader *message) | ||
125 | { | 166 | { |
126 | struct BlacklistEntry *be = cls; | 167 | struct Blacklisters *bl; |
127 | struct BlacklistMessage msg; | 168 | |
128 | 169 | bl = GNUNET_malloc (sizeof (struct Blacklisters)); | |
129 | be->timeout_task = GNUNET_SCHEDULER_NO_TASK; | 170 | bl->client = client; |
130 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST); | 171 | GNUNET_SERVER_client_keep (client); |
131 | msg.header.size = htons (sizeof (struct BlacklistMessage)); | 172 | GNUNET_CONTAINER_DLL_insert (bl_head, bl_tail, bl); |
132 | msg.reserved = htonl (0); | 173 | /* FIXME: confirm that all existing connections are OK! */ |
133 | msg.peer = be->peer; | ||
134 | msg.until = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_ZERO_ABS); | ||
135 | GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove (blacklist, | ||
136 | &be->peer.hashPubKey, | ||
137 | be)); | ||
138 | GNUNET_free (be); | ||
139 | GNUNET_SERVER_notification_context_broadcast (blacklist_notifiers, | ||
140 | &msg.header, | ||
141 | GNUNET_NO); | ||
142 | } | 174 | } |
143 | 175 | ||
144 | 176 | ||
@@ -150,38 +182,33 @@ timeout_task (void *cls, | |||
150 | * @param message the actual message | 182 | * @param message the actual message |
151 | */ | 183 | */ |
152 | void | 184 | void |
153 | GNUNET_TRANSPORT_handle_blacklist (void *cls, | 185 | GNUNET_TRANSPORT_handle_blacklist_reply (void *cls, |
154 | struct GNUNET_SERVER_Client *client, | 186 | struct GNUNET_SERVER_Client *client, |
155 | const struct GNUNET_MessageHeader *message) | 187 | const struct GNUNET_MessageHeader *message) |
156 | { | 188 | { |
157 | struct BlacklistEntry *be; | 189 | struct Blacklisters *bl; |
158 | const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; | 190 | const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; |
159 | 191 | ||
160 | be = GNUNET_CONTAINER_multihashmap_get (blacklist, | 192 | bl = bl_head; |
161 | &msg->peer.hashPubKey); | 193 | while ( (bl != NULL) && |
162 | if (be != NULL) | 194 | (bl->client != client) ) |
195 | bl = bl->next; | ||
196 | if (bl == NULL) | ||
163 | { | 197 | { |
164 | GNUNET_SCHEDULER_cancel (sched, | 198 | GNUNET_SERVER_client_done (client, GNUNET_SYSERR); |
165 | be->timeout_task); | 199 | return; |
166 | } | 200 | } |
167 | else | 201 | if (ntohl (msg->is_allowed) == GNUNET_SYSERR) |
168 | { | 202 | { |
169 | be = GNUNET_malloc (sizeof (struct BlacklistEntry)); | 203 | be = GNUNET_malloc (sizeof (struct BlacklistEntry)); |
170 | be->peer = msg->peer; | 204 | be->peer = msg->peer; |
205 | be->client = client; | ||
171 | GNUNET_CONTAINER_multihashmap_put (blacklist, | 206 | GNUNET_CONTAINER_multihashmap_put (blacklist, |
172 | &msg->peer.hashPubKey, | 207 | &msg->peer.hashPubKey, |
173 | be, | 208 | be, |
174 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 209 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
175 | } | 210 | } |
176 | be->until = GNUNET_TIME_absolute_ntoh (msg->until); | 211 | /* FIXME: trigger continuation... */ |
177 | be->timeout_task = GNUNET_SCHEDULER_add_delayed (sched, | ||
178 | GNUNET_TIME_absolute_get_remaining (be->until), | ||
179 | &timeout_task, | ||
180 | be); | ||
181 | GNUNET_SERVER_notification_context_broadcast (blacklist_notifiers, | ||
182 | &msg->header, | ||
183 | GNUNET_NO); | ||
184 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | ||
185 | } | 212 | } |
186 | 213 | ||
187 | 214 | ||
@@ -243,7 +270,9 @@ GNUNET_TRANSPORT_handle_blacklist_notify (void *cls, | |||
243 | int | 270 | int |
244 | GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id) | 271 | GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id) |
245 | { | 272 | { |
246 | return GNUNET_CONTAINER_multihashmap_contains (blacklist, &id->hashPubKey); | 273 | if (GNUNET_CONTAINER_multihashmap_contains (blacklist, &id->hashPubKey)) |
274 | return GNUNET_YES; | ||
275 | |||
247 | } | 276 | } |
248 | 277 | ||
249 | 278 | ||
@@ -263,7 +292,6 @@ GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SERVER_Handle *server, | |||
263 | GNUNET_TIME_UNIT_FOREVER_REL, | 292 | GNUNET_TIME_UNIT_FOREVER_REL, |
264 | &shutdown_task, | 293 | &shutdown_task, |
265 | NULL); | 294 | NULL); |
266 | blacklist_notifiers = GNUNET_SERVER_notification_context_create (server, 0); | ||
267 | } | 295 | } |
268 | 296 | ||
269 | 297 | ||
diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h index 92f81a2e9..32e26431e 100644 --- a/src/transport/gnunet-service-transport_blacklist.h +++ b/src/transport/gnunet-service-transport_blacklist.h | |||
@@ -31,16 +31,16 @@ | |||
31 | #include "transport.h" | 31 | #include "transport.h" |
32 | 32 | ||
33 | /** | 33 | /** |
34 | * Handle a request to blacklist a peer. | 34 | * Handle a request to start a blacklist. |
35 | * | 35 | * |
36 | * @param cls closure (always NULL) | 36 | * @param cls closure (always NULL) |
37 | * @param client identification of the client | 37 | * @param client identification of the client |
38 | * @param message the actual message | 38 | * @param message the actual message |
39 | */ | 39 | */ |
40 | void | 40 | void |
41 | GNUNET_TRANSPORT_handle_blacklist (void *cls, | 41 | GNUNET_TRANSPORT_handle_blacklist_init (void *cls, |
42 | struct GNUNET_SERVER_Client *client, | 42 | struct GNUNET_SERVER_Client *client, |
43 | const struct GNUNET_MessageHeader *message); | 43 | const struct GNUNET_MessageHeader *message); |
44 | 44 | ||
45 | 45 | ||
46 | /** | 46 | /** |
@@ -51,30 +51,9 @@ GNUNET_TRANSPORT_handle_blacklist (void *cls, | |||
51 | * @param message the actual message | 51 | * @param message the actual message |
52 | */ | 52 | */ |
53 | void | 53 | void |
54 | GNUNET_TRANSPORT_handle_blacklist_notify (void *cls, | 54 | GNUNET_TRANSPORT_handle_blacklist_reply (void *cls, |
55 | struct GNUNET_SERVER_Client *client, | 55 | struct GNUNET_SERVER_Client *client, |
56 | const struct GNUNET_MessageHeader *message); | 56 | const struct GNUNET_MessageHeader *message); |
57 | |||
58 | |||
59 | /** | ||
60 | * Is the given peer currently blacklisted? | ||
61 | * | ||
62 | * @param id identity of the peer | ||
63 | * @return GNUNET_YES if the peer is blacklisted, GNUNET_NO if not | ||
64 | */ | ||
65 | int | ||
66 | GNUNET_TRANSPORT_blacklist_check (const struct GNUNET_PeerIdentity *id); | ||
67 | |||
68 | |||
69 | /** | ||
70 | * Initialize the blacklisting subsystem. | ||
71 | * | ||
72 | * @param server server we handle requests from (transport service server) | ||
73 | * @param s scheduler to use | ||
74 | */ | ||
75 | void | ||
76 | GNUNET_TRANSPORT_blacklist_init (struct GNUNET_SERVER_Handle *server, | ||
77 | struct GNUNET_SCHEDULER_Handle *s); | ||
78 | 57 | ||
79 | 58 | ||
80 | #endif | 59 | #endif |
diff --git a/src/transport/transport.h b/src/transport/transport.h index d66b87b35..b2ef01bb5 100644 --- a/src/transport/transport.h +++ b/src/transport/transport.h | |||
@@ -268,27 +268,22 @@ struct BlacklistMessage | |||
268 | { | 268 | { |
269 | 269 | ||
270 | /** | 270 | /** |
271 | * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST | 271 | * Type will be GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY or |
272 | * GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY. | ||
272 | */ | 273 | */ |
273 | struct GNUNET_MessageHeader header; | 274 | struct GNUNET_MessageHeader header; |
274 | 275 | ||
275 | /** | 276 | /** |
276 | * Reserved (for alignment). | 277 | * 0 for the query, GNUNET_OK (allowed) or GNUNET_SYSERR (disallowed) |
278 | * for the response. | ||
277 | */ | 279 | */ |
278 | uint32_t reserved GNUNET_PACKED; | 280 | uint32_t is_allowed GNUNET_PACKED; |
279 | 281 | ||
280 | /** | 282 | /** |
281 | * Which peer is being blacklisted (or has seen its | 283 | * Which peer is being blacklisted or queried? |
282 | * blacklisting expire)? | ||
283 | */ | 284 | */ |
284 | struct GNUNET_PeerIdentity peer; | 285 | struct GNUNET_PeerIdentity peer; |
285 | 286 | ||
286 | /** | ||
287 | * Until what time is this peer blacklisted (zero for | ||
288 | * no longer blacklisted). | ||
289 | */ | ||
290 | struct GNUNET_TIME_AbsoluteNBO until; | ||
291 | |||
292 | }; | 287 | }; |
293 | 288 | ||
294 | 289 | ||
diff --git a/src/transport/transport_api_blacklist.c b/src/transport/transport_api_blacklist.c index c8838f1b6..5d2d616e8 100644 --- a/src/transport/transport_api_blacklist.c +++ b/src/transport/transport_api_blacklist.c | |||
@@ -36,7 +36,7 @@ | |||
36 | /** | 36 | /** |
37 | * Handle for blacklisting requests. | 37 | * Handle for blacklisting requests. |
38 | */ | 38 | */ |
39 | struct GNUNET_TRANSPORT_BlacklistRequest | 39 | struct GNUNET_TRANSPORT_Blacklist |
40 | { | 40 | { |
41 | 41 | ||
42 | /** | 42 | /** |
@@ -45,342 +45,255 @@ struct GNUNET_TRANSPORT_BlacklistRequest | |||
45 | struct GNUNET_CLIENT_Connection * client; | 45 | struct GNUNET_CLIENT_Connection * client; |
46 | 46 | ||
47 | /** | 47 | /** |
48 | * Function to call when done. | 48 | * Scheduler to use. |
49 | */ | ||
50 | GNUNET_SCHEDULER_Task cont; | ||
51 | |||
52 | /** | ||
53 | * Clsoure for 'cont'. | ||
54 | */ | 49 | */ |
55 | void *cont_cls; | 50 | struct GNUNET_SCHEDULER_Handle *sched; |
56 | 51 | ||
57 | /** | 52 | /** |
58 | * Scheduler to use. | 53 | * Configuration to use. |
59 | */ | 54 | */ |
60 | struct GNUNET_SCHEDULER_Handle *sched; | 55 | const struct GNUNET_CONFIGURATION_Handle *cfg; |
61 | 56 | ||
62 | /** | 57 | /** |
63 | * Pending handle for the blacklisting request. | 58 | * Pending handle for the current request. |
64 | */ | 59 | */ |
65 | struct GNUNET_CLIENT_TransmitHandle *th; | 60 | struct GNUNET_CLIENT_TransmitHandle *th; |
66 | 61 | ||
67 | /** | 62 | /** |
68 | * How long should 'peer' be blacklisted? | 63 | * Function to call for determining if a peer is allowed |
64 | * to communicate with us. | ||
69 | */ | 65 | */ |
70 | struct GNUNET_TIME_Absolute duration; | 66 | GNUNET_TRANSPORT_BlacklistCallback cb; |
71 | 67 | ||
72 | /** | 68 | /** |
73 | * Which peer is being blacklisted? | 69 | * Closure for 'cb'. |
70 | */ | ||
71 | void *cb_cls; | ||
72 | |||
73 | /** | ||
74 | * Peer currently under consideration. | ||
74 | */ | 75 | */ |
75 | struct GNUNET_PeerIdentity peer; | 76 | struct GNUNET_PeerIdentity peer; |
76 | 77 | ||
77 | }; | 78 | }; |
78 | 79 | ||
79 | 80 | ||
80 | /** | 81 | /** |
81 | * Function called to notify a client about the socket | 82 | * Establish blacklist connection to transport service. |
82 | * begin ready to queue more data. "buf" will be | ||
83 | * NULL and "size" zero if the socket was closed for | ||
84 | * writing in the meantime. | ||
85 | * | 83 | * |
86 | * @param cls closure | 84 | * @param br overall handle |
87 | * @param size number of bytes available in buf | ||
88 | * @param buf where the callee should write the message | ||
89 | * @return number of bytes written to buf | ||
90 | */ | 85 | */ |
91 | static size_t | 86 | static void |
92 | transmit_blacklist_request (void *cls, | 87 | reconnect (struct GNUNET_TRANSPORT_Blacklist *br); |
93 | size_t size, void *buf) | ||
94 | { | ||
95 | struct GNUNET_TRANSPORT_BlacklistRequest *br = cls; | ||
96 | struct BlacklistMessage req; | ||
97 | |||
98 | if (buf == NULL) | ||
99 | { | ||
100 | GNUNET_SCHEDULER_add_continuation (br->sched, | ||
101 | br->cont, | ||
102 | br->cont_cls, | ||
103 | GNUNET_SCHEDULER_REASON_TIMEOUT); | ||
104 | GNUNET_free (br); | ||
105 | return 0; | ||
106 | } | ||
107 | req.header.size = htons (sizeof (req)); | ||
108 | req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST); | ||
109 | req.reserved = htonl (0); | ||
110 | req.peer = br->peer; | ||
111 | req.until = GNUNET_TIME_absolute_hton (br->duration); | ||
112 | memcpy (buf, &req, sizeof (req)); | ||
113 | GNUNET_SCHEDULER_add_continuation (br->sched, | ||
114 | br->cont, | ||
115 | br->cont_cls, | ||
116 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | ||
117 | GNUNET_free (br); | ||
118 | return sizeof (req); | ||
119 | } | ||
120 | 88 | ||
121 | 89 | ||
122 | /** | 90 | /** |
123 | * Blacklist a peer for a given period of time. All connections | 91 | * Send our reply to a blacklisting request. |
124 | * (inbound and outbound) to a peer that is blacklisted will be | ||
125 | * dropped (as soon as we learn who the connection is for). A second | ||
126 | * call to this function for the same peer overrides previous | ||
127 | * blacklisting requests. | ||
128 | * | 92 | * |
129 | * @param sched scheduler to use | 93 | * @param br our overall context |
130 | * @param cfg configuration to use | ||
131 | * @param peer identity of peer to blacklist | ||
132 | * @param duration how long to blacklist, use GNUNET_TIME_UNIT_ZERO to | ||
133 | * re-enable connections | ||
134 | * @param timeout when should this operation (trying to establish the | ||
135 | * blacklisting time out) | ||
136 | * @param cont continuation to call once the request has been processed | ||
137 | * @param cont_cls closure for cont | ||
138 | * @return NULL on error, otherwise handle for cancellation | ||
139 | */ | 94 | */ |
140 | struct GNUNET_TRANSPORT_BlacklistRequest * | 95 | static void |
141 | GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched, | 96 | reply (struct GNUNET_TRANSPORT_Blacklist *br); |
142 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
143 | const struct GNUNET_PeerIdentity *peer, | ||
144 | struct GNUNET_TIME_Relative duration, | ||
145 | struct GNUNET_TIME_Relative timeout, | ||
146 | GNUNET_SCHEDULER_Task cont, | ||
147 | void *cont_cls) | ||
148 | { | ||
149 | struct GNUNET_CLIENT_Connection * client; | ||
150 | struct GNUNET_TRANSPORT_BlacklistRequest *ret; | ||
151 | |||
152 | client = GNUNET_CLIENT_connect (sched, "transport", cfg); | ||
153 | if (NULL == client) | ||
154 | return NULL; | ||
155 | ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_BlacklistRequest)); | ||
156 | ret->client = client; | ||
157 | ret->peer = *peer; | ||
158 | ret->duration = GNUNET_TIME_relative_to_absolute (duration); | ||
159 | ret->sched = sched; | ||
160 | ret->cont = cont; | ||
161 | ret->cont_cls = cont_cls; | ||
162 | ret->th = GNUNET_CLIENT_notify_transmit_ready (client, | ||
163 | sizeof (struct BlacklistMessage), | ||
164 | timeout, | ||
165 | GNUNET_YES, | ||
166 | &transmit_blacklist_request, | ||
167 | ret); | ||
168 | GNUNET_assert (NULL != ret->th); | ||
169 | return ret; | ||
170 | } | ||
171 | 97 | ||
172 | 98 | ||
173 | /** | 99 | /** |
174 | * Abort transmitting the blacklist request. Note that this function | 100 | * Handle blacklist queries. |
175 | * is NOT for removing a peer from the blacklist (for that, call | ||
176 | * GNUNET_TRANSPORT_blacklist with a duration of zero). This function | ||
177 | * is only for aborting the transmission of a blacklist request | ||
178 | * (i.e. because of shutdown). | ||
179 | * | 101 | * |
180 | * @param br handle of the request that is to be cancelled | 102 | * @param cls our overall handle |
103 | * @param msg query | ||
181 | */ | 104 | */ |
182 | void | 105 | static void |
183 | GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_BlacklistRequest * br) | 106 | query_handler (void *cls, |
184 | { | 107 | const struct GNUNET_MessageHeader *msg) |
185 | GNUNET_CLIENT_notify_transmit_ready_cancel (br->th); | ||
186 | GNUNET_free (br); | ||
187 | } | ||
188 | |||
189 | |||
190 | /** | ||
191 | * Handle for blacklist notifications. | ||
192 | */ | ||
193 | struct GNUNET_TRANSPORT_BlacklistNotification | ||
194 | { | 108 | { |
195 | 109 | struct GNUNET_TRANSPORT_Blacklist *br = cls; | |
196 | /** | 110 | const struct BlacklistMessage *bm; |
197 | * Function to call whenever there is a change. | ||
198 | */ | ||
199 | GNUNET_TRANSPORT_BlacklistCallback notify; | ||
200 | |||
201 | /** | ||
202 | * Closure for notify. | ||
203 | */ | ||
204 | void *notify_cls; | ||
205 | |||
206 | /** | ||
207 | * Scheduler to use. | ||
208 | */ | ||
209 | struct GNUNET_SCHEDULER_Handle *sched; | ||
210 | |||
211 | /** | ||
212 | * Configuration to use. | ||
213 | */ | ||
214 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
215 | 111 | ||
216 | /** | 112 | if ( (ntohs(msg->size) != sizeof (struct BlacklistMessage)) || |
217 | * Connection to transport service. | 113 | (ntohs(msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY) ) |
218 | */ | 114 | { |
219 | struct GNUNET_CLIENT_Connection * client; | 115 | reconnect (br); |
220 | 116 | return; | |
221 | /** | 117 | } |
222 | * Pending handle for the notification request. | 118 | bm = (const struct BlacklistMessage *)msg; |
223 | */ | 119 | GNUNET_break (0 == ntohl (bm->is_allowed)); |
224 | struct GNUNET_CLIENT_TransmitHandle *th; | 120 | br->peer = bm->peer; |
225 | }; | 121 | reply (br); |
122 | } | ||
226 | 123 | ||
227 | 124 | ||
228 | /** | 125 | /** |
229 | * Send a request to receive blacklisting notifications | 126 | * Receive blacklist queries from transport service. |
230 | * | 127 | * |
231 | * @param bn context to initialize | 128 | * @param br overall handle |
232 | */ | 129 | */ |
233 | static void | 130 | static void |
234 | request_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn); | 131 | receive (struct GNUNET_TRANSPORT_Blacklist *br) |
132 | { | ||
133 | GNUNET_CLIENT_receive (br->client, | ||
134 | &query_handler, | ||
135 | br, | ||
136 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
137 | } | ||
235 | 138 | ||
236 | 139 | ||
237 | /** | 140 | /** |
238 | * Destroy the existing connection to the transport service and | 141 | * Transmit the blacklist initialization request to the service. |
239 | * setup a new one (the existing one had serious problems). | 142 | * |
240 | * | 143 | * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*) |
241 | * @param bn context to re-initialize | 144 | * @param size number of bytes available in buf |
145 | * @param buf where the callee should write the message | ||
146 | * @return number of bytes written to buf | ||
242 | */ | 147 | */ |
243 | static void | 148 | static size_t |
244 | retry_get_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn) | 149 | transmit_blacklist_init (void *cls, |
150 | size_t size, void *buf) | ||
245 | { | 151 | { |
246 | GNUNET_CLIENT_disconnect (bn->client, GNUNET_NO); | 152 | struct GNUNET_TRANSPORT_Blacklist *br = cls; |
247 | bn->client = GNUNET_CLIENT_connect (bn->sched, "transport", bn->cfg); | 153 | struct GNUNET_MessageHeader req; |
248 | request_notifications (bn); | 154 | |
155 | if (buf == NULL) | ||
156 | { | ||
157 | reconnect (br); | ||
158 | return 0; | ||
159 | } | ||
160 | req.size = htons (sizeof (struct GNUNET_MessageHeader)); | ||
161 | req.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_INIT); | ||
162 | memcpy (buf, &req, sizeof (req)); | ||
163 | receive (br); | ||
164 | return sizeof (req); | ||
249 | } | 165 | } |
250 | 166 | ||
251 | 167 | ||
252 | /** | 168 | /** |
253 | * Function called whenever we get a blacklisting notification. | 169 | * Establish blacklist connection to transport service. |
254 | * Pass it on to the callback and wait for more. | ||
255 | * | 170 | * |
256 | * @param cls our 'struct GNUNET_TRANSPORT_BlacklistNotification *' | 171 | * @param br overall handle |
257 | * @param msg the blacklisting notification, NULL on error | ||
258 | */ | 172 | */ |
259 | static void | 173 | static void |
260 | recv_blacklist_info (void *cls, | 174 | reconnect (struct GNUNET_TRANSPORT_Blacklist *br) |
261 | const struct GNUNET_MessageHeader *msg) | ||
262 | { | 175 | { |
263 | struct GNUNET_TRANSPORT_BlacklistNotification *bn = cls; | 176 | if (br->client != NULL) |
264 | const struct BlacklistMessage *req; | 177 | GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); |
265 | 178 | br->client = GNUNET_CLIENT_connect (br->sched, | |
266 | if ( (msg == NULL) || | 179 | "transport", |
267 | (sizeof(struct BlacklistMessage) != ntohs(msg->size)) || | 180 | br->cfg); |
268 | (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST != ntohs(msg->type)) ) | 181 | br->th = GNUNET_CLIENT_notify_transmit_ready (br->client, |
269 | { | 182 | sizeof (struct GNUNET_MessageHeader), |
270 | retry_get_notifications (bn); | 183 | GNUNET_TIME_UNIT_FOREVER_REL, |
271 | return; | 184 | GNUNET_YES, |
272 | } | 185 | &transmit_blacklist_init, |
273 | req = (const struct BlacklistMessage*) msg; | 186 | br); |
274 | bn->notify (bn->notify_cls, | ||
275 | &req->peer, | ||
276 | GNUNET_TIME_absolute_ntoh (req->until)); | ||
277 | GNUNET_CLIENT_receive (bn->client, | ||
278 | &recv_blacklist_info, | ||
279 | bn, | ||
280 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
281 | } | 187 | } |
282 | 188 | ||
283 | 189 | ||
284 | /** | 190 | /** |
285 | * Function called to notify a client about the socket | 191 | * Transmit the blacklist response to the service. |
286 | * begin ready to queue more data. "buf" will be | ||
287 | * NULL and "size" zero if the socket was closed for | ||
288 | * writing in the meantime. | ||
289 | * | 192 | * |
290 | * @param cls closure | 193 | * @param cls closure (struct GNUNET_TRANSPORT_Blacklist*) |
291 | * @param size number of bytes available in buf | 194 | * @param size number of bytes available in buf |
292 | * @param buf where the callee should write the message | 195 | * @param buf where the callee should write the message |
293 | * @return number of bytes written to buf | 196 | * @return number of bytes written to buf |
294 | */ | 197 | */ |
295 | static size_t | 198 | static size_t |
296 | transmit_notify_request (void *cls, | 199 | transmit_blacklist_reply (void *cls, |
297 | size_t size, void *buf) | 200 | size_t size, void *buf) |
298 | { | 201 | { |
299 | struct GNUNET_TRANSPORT_BlacklistNotification *bn = cls; | 202 | struct GNUNET_TRANSPORT_Blacklist *br = cls; |
300 | struct GNUNET_MessageHeader hdr; | 203 | struct BlacklistMessage req; |
301 | 204 | ||
302 | bn->th = NULL; | ||
303 | if (buf == NULL) | 205 | if (buf == NULL) |
304 | { | 206 | { |
305 | retry_get_notifications (bn); | 207 | reconnect (br); |
306 | return 0; | 208 | return 0; |
307 | } | 209 | } |
308 | GNUNET_assert (size >= sizeof(hdr)); | 210 | req.header.size = htons (sizeof (req)); |
309 | hdr.size = htons (sizeof (hdr)); | 211 | req.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_REPLY); |
310 | hdr.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_NOTIFY); | 212 | req.is_allowed = htonl (br->cb (br->cb_cls, &br->peer)); |
311 | memcpy (buf, &hdr, sizeof(hdr)); | 213 | req.peer = br->peer; |
312 | return sizeof(hdr); | 214 | memcpy (buf, &req, sizeof (req)); |
215 | receive (br); | ||
216 | return sizeof (req); | ||
313 | } | 217 | } |
314 | 218 | ||
315 | 219 | ||
316 | /** | 220 | /** |
317 | * Send a request to receive blacklisting notifications | 221 | * Send our reply to a blacklisting request. |
318 | * | 222 | * |
319 | * @param bn context to initialize | 223 | * @param br our overall context |
320 | */ | 224 | */ |
321 | static void | 225 | static void |
322 | request_notifications (struct GNUNET_TRANSPORT_BlacklistNotification *bn) | 226 | reply (struct GNUNET_TRANSPORT_Blacklist *br) |
323 | { | 227 | { |
324 | GNUNET_assert (bn->client != NULL); | 228 | br->th = GNUNET_CLIENT_notify_transmit_ready (br->client, |
325 | bn->th = GNUNET_CLIENT_notify_transmit_ready (bn->client, | 229 | sizeof (struct BlacklistMessage), |
326 | sizeof (struct GNUNET_MessageHeader), | ||
327 | GNUNET_TIME_UNIT_FOREVER_REL, | 230 | GNUNET_TIME_UNIT_FOREVER_REL, |
328 | GNUNET_YES, | 231 | GNUNET_NO, |
329 | &transmit_notify_request, | 232 | &transmit_blacklist_reply, |
330 | bn); | 233 | br); |
331 | GNUNET_assert (bn->th != NULL); | 234 | if (br->th == NULL) |
332 | GNUNET_CLIENT_receive (bn->client, | 235 | { |
333 | &recv_blacklist_info, | 236 | reconnect (br); |
334 | bn, | 237 | return; |
335 | GNUNET_TIME_UNIT_FOREVER_REL); | 238 | } |
336 | } | 239 | } |
337 | 240 | ||
338 | 241 | ||
339 | /** | 242 | /** |
340 | * Call a function whenever a peer's blacklisting status changes. | 243 | * Install a blacklist callback. The service will be queried for all |
244 | * existing connections as well as any fresh connections to check if | ||
245 | * they are permitted. If the blacklisting callback is unregistered, | ||
246 | * all hosts that were denied in the past will automatically be | ||
247 | * whitelisted again. Cancelling the blacklist handle is also the | ||
248 | * only way to re-enable connections from peers that were previously | ||
249 | * blacklisted. | ||
341 | * | 250 | * |
342 | * @param sched scheduler to use | 251 | * @param sched scheduler to use |
343 | * @param cfg configuration to use | 252 | * @param cfg configuration to use |
344 | * @param bc function to call on status changes | 253 | * @param cb callback to invoke to check if connections are allowed |
345 | * @param bc_cls closure for bc | 254 | * @param cb_cls closure for cb |
346 | * @return NULL on error, otherwise handle for cancellation | 255 | * @return NULL on error, otherwise handle for cancellation |
347 | */ | 256 | */ |
348 | struct GNUNET_TRANSPORT_BlacklistNotification * | 257 | struct GNUNET_TRANSPORT_Blacklist * |
349 | GNUNET_TRANSPORT_blacklist_notify (struct GNUNET_SCHEDULER_Handle *sched, | 258 | GNUNET_TRANSPORT_blacklist (struct GNUNET_SCHEDULER_Handle *sched, |
350 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 259 | const struct GNUNET_CONFIGURATION_Handle *cfg, |
351 | GNUNET_TRANSPORT_BlacklistCallback bc, | 260 | GNUNET_TRANSPORT_BlacklistCallback cb, |
352 | void *bc_cls) | 261 | void *cb_cls) |
353 | { | 262 | { |
354 | struct GNUNET_TRANSPORT_BlacklistNotification *ret; | ||
355 | struct GNUNET_CLIENT_Connection * client; | 263 | struct GNUNET_CLIENT_Connection * client; |
264 | struct GNUNET_TRANSPORT_Blacklist *ret; | ||
356 | 265 | ||
357 | client = GNUNET_CLIENT_connect (sched, "transport", cfg); | 266 | client = GNUNET_CLIENT_connect (sched, "transport", cfg); |
358 | if (NULL == client) | 267 | if (NULL == client) |
359 | return NULL; | 268 | return NULL; |
360 | ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_BlacklistNotification)); | 269 | ret = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_Blacklist)); |
361 | ret->client = client; | 270 | ret->client = client; |
362 | ret->sched = sched; | 271 | ret->sched = sched; |
363 | ret->cfg = cfg; | 272 | ret->cfg = cfg; |
364 | ret->notify = bc; | 273 | ret->th = GNUNET_CLIENT_notify_transmit_ready (client, |
365 | ret->notify_cls = bc_cls; | 274 | sizeof (struct GNUNET_MessageHeader), |
366 | request_notifications (ret); | 275 | GNUNET_TIME_UNIT_FOREVER_REL, |
276 | GNUNET_YES, | ||
277 | &transmit_blacklist_init, | ||
278 | ret); | ||
367 | return ret; | 279 | return ret; |
368 | } | 280 | } |
369 | 281 | ||
370 | 282 | ||
371 | /** | 283 | /** |
372 | * Stop calling the notification callback associated with | 284 | * Abort the blacklist. Note that this function is the only way for |
373 | * the given blacklist notification. | 285 | * removing a peer from the blacklist. |
374 | * | 286 | * |
375 | * @param bn handle of the request that is to be cancelled | 287 | * @param br handle of the request that is to be cancelled |
376 | */ | 288 | */ |
377 | void | 289 | void |
378 | GNUNET_TRANSPORT_blacklist_notify_cancel (struct GNUNET_TRANSPORT_BlacklistNotification * bn) | 290 | GNUNET_TRANSPORT_blacklist_cancel (struct GNUNET_TRANSPORT_Blacklist *br) |
379 | { | 291 | { |
380 | if (bn->th != NULL) | 292 | if (br->th != NULL) |
381 | GNUNET_CLIENT_notify_transmit_ready_cancel (bn->th); | 293 | GNUNET_CLIENT_notify_transmit_ready_cancel (br->th); |
382 | GNUNET_CLIENT_disconnect (bn->client, GNUNET_NO); | 294 | GNUNET_CLIENT_disconnect (br->client, GNUNET_NO); |
383 | GNUNET_free (bn); | 295 | GNUNET_free (br); |
384 | } | 296 | } |
385 | 297 | ||
298 | |||
386 | /* end of transport_api_blacklist.c */ | 299 | /* end of transport_api_blacklist.c */ |