aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-18 14:08:39 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-18 14:08:39 +0000
commit8bd00cee8c4335f9598ef6e97a06736c925862a7 (patch)
tree657258e0b9f88de9a81dfda64dc6629f3a0d370b /src
parent060807231ea955a26c481700811dc265908a3138 (diff)
downloadgnunet-8bd00cee8c4335f9598ef6e97a06736c925862a7.tar.gz
gnunet-8bd00cee8c4335f9598ef6e97a06736c925862a7.zip
fix blacklist checking logic, integrating tracking of sessions with blacklist module and fixing dangling session issue which caused misc. problems when blacklists were in use
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-transport.c248
-rw-r--r--src/transport/gnunet-service-transport_ats.c2
-rw-r--r--src/transport/gnunet-service-transport_blacklist.c182
-rw-r--r--src/transport/gnunet-service-transport_blacklist.h27
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c145
-rw-r--r--src/transport/gnunet-service-transport_validation.c15
-rw-r--r--src/transport/test_transport_api_blacklisting.c4
-rw-r--r--src/transport/test_transport_api_data.conf2
-rw-r--r--src/transport/test_transport_api_tcp_peer1.conf2
-rw-r--r--src/transport/test_transport_api_tcp_peer2.conf2
10 files changed, 322 insertions, 307 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 46503a5bf..7dfd994b4 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -69,53 +69,10 @@ struct SessionKiller
69 /** 69 /**
70 * The kill task. 70 * The kill task.
71 */ 71 */
72 struct GNUNET_SCHEDULER_Task * task; 72 struct GNUNET_SCHEDULER_Task *task;
73}; 73};
74 74
75 75
76/**
77 * We track active blacklist checks in a DLL so we can cancel them if
78 * necessary. We typically check against the blacklist a few times
79 * during connection setup, as the check is asynchronous and the
80 * blacklist may change its mind before the connection goes fully up.
81 * Similarly, the session may die during the asynchronous check, so
82 * we use this list to then cancel ongoing checks.
83 */
84struct BlacklistCheckContext
85{
86 /**
87 * We keep these in a DLL.
88 */
89 struct BlacklistCheckContext *prev;
90
91 /**
92 * We keep these in a DLL.
93 */
94 struct BlacklistCheckContext *next;
95
96 /**
97 * Handle with the blacklist subsystem.
98 */
99 struct GST_BlacklistCheck *blc;
100
101 /**
102 * The address we are checking.
103 */
104 struct GNUNET_HELLO_Address *address;
105
106 /**
107 * Session associated with the address (or NULL).
108 */
109 struct Session *session;
110
111 /**
112 * Message to process in the continuation if the
113 * blacklist check is ok, can be NULL.
114 */
115 struct GNUNET_MessageHeader *msg;
116
117};
118
119/* globals */ 76/* globals */
120 77
121/** 78/**
@@ -178,20 +135,6 @@ static struct SessionKiller *sk_tail;
178 */ 135 */
179struct GNUNET_ATS_InterfaceScanner *GST_is; 136struct GNUNET_ATS_InterfaceScanner *GST_is;
180 137
181/**
182 * Head of DLL of blacklist checks we have pending for
183 * incoming sessions and/or SYN requests. We may
184 * want to move this into the blacklist-logic at some
185 * point.
186 */
187struct BlacklistCheckContext *bc_head;
188
189/**
190 * Tail of DLL of blacklist checks we have pending for
191 * incoming sessions and/or SYN requests.
192 */
193struct BlacklistCheckContext *bc_tail;
194
195 138
196/** 139/**
197 * Transmit our HELLO message to the given (connected) neighbour. 140 * Transmit our HELLO message to the given (connected) neighbour.
@@ -323,44 +266,6 @@ kill_session_task (void *cls,
323 266
324 267
325/** 268/**
326 * Cancel all blacklist checks that are pending for the given address and session.
327 * NOTE: Consider moving the "bc_*" logic into blacklist.h?
328 *
329 * @param address address to remove from check
330 * @param sesssion session that must match to remove for check
331 */
332static void
333cancel_pending_blacklist_checks (const struct GNUNET_HELLO_Address *address,
334 struct Session *session)
335{
336 struct BlacklistCheckContext *blctx;
337 struct BlacklistCheckContext *next;
338
339 next = bc_head;
340 for (blctx = next; NULL != blctx; blctx = next)
341 {
342 next = blctx->next;
343 if ( (NULL != blctx->address) &&
344 (0 == GNUNET_HELLO_address_cmp(blctx->address, address)) &&
345 (blctx->session == session))
346 {
347 GNUNET_CONTAINER_DLL_remove (bc_head,
348 bc_tail,
349 blctx);
350 if (NULL != blctx->blc)
351 {
352 GST_blacklist_test_cancel (blctx->blc);
353 blctx->blc = NULL;
354 }
355 GNUNET_HELLO_address_free (blctx->address);
356 GNUNET_free_non_null (blctx->msg);
357 GNUNET_free (blctx);
358 }
359 }
360}
361
362
363/**
364 * Force plugin to terminate session due to communication 269 * Force plugin to terminate session due to communication
365 * issue. 270 * issue.
366 * 271 *
@@ -398,54 +303,49 @@ kill_session (const char *plugin_name,
398 * Black list check result for try_connect call 303 * Black list check result for try_connect call
399 * If connection to the peer is allowed request adddress and ??? 304 * If connection to the peer is allowed request adddress and ???
400 * 305 *
401 * @param cls blc_ctx bl context 306 * @param cls the message
402 * @param peer the peer 307 * @param peer the peer
308 * @param address the address
309 * @param session the session
403 * @param result the result 310 * @param result the result
404 */ 311 */
405static void 312static void
406connect_bl_check_cont (void *cls, 313connect_bl_check_cont (void *cls,
407 const struct GNUNET_PeerIdentity *peer, 314 const struct GNUNET_PeerIdentity *peer,
315 const struct GNUNET_HELLO_Address *address,
316 struct Session *session,
408 int result) 317 int result)
409{ 318{
410 struct BlacklistCheckContext *blctx = cls; 319 struct GNUNET_MessageHeader *msg = cls;
411 320
412 GNUNET_CONTAINER_DLL_remove (bc_head,
413 bc_tail,
414 blctx);
415 blctx->blc = NULL;
416 if (GNUNET_OK == result) 321 if (GNUNET_OK == result)
417 { 322 {
418 /* Blacklist allows to speak to this peer, forward SYN to neighbours */ 323 /* Blacklist allows to speak to this peer, forward SYN to neighbours */
419 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 324 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
420 "Received SYN message from peer `%s' at `%s'\n", 325 "Received SYN message from peer `%s' at `%s'\n",
421 GNUNET_i2s (peer), 326 GNUNET_i2s (peer),
422 GST_plugins_a2s (blctx->address)); 327 GST_plugins_a2s (address));
423 if (GNUNET_OK != 328 if (GNUNET_OK !=
424 GST_neighbours_handle_session_syn (blctx->msg, 329 GST_neighbours_handle_session_syn (msg,
425 &blctx->address->peer)) 330 peer))
426 { 331 {
427 cancel_pending_blacklist_checks (blctx->address, 332 GST_blacklist_abort_matching (address,
428 blctx->session); 333 session);
429 kill_session (blctx->address->transport_name, 334 kill_session (address->transport_name,
430 blctx->session); 335 session);
431 } 336 }
337 GNUNET_free (msg);
338 return;
432 } 339 }
433 else 340 GNUNET_free (msg);
434 { 341 if (GNUNET_SYSERR == result)
435 /* Blacklist denies to speak to this peer */ 342 return; /* check was aborted, session destroyed */
436 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 343 /* Blacklist denies to speak to this peer */
437 "Discarding SYN message from `%s' due to denied blacklist check\n", 344 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
438 GNUNET_i2s (peer)); 345 "Discarding SYN message from `%s' due to denied blacklist check\n",
439 cancel_pending_blacklist_checks (blctx->address, 346 GNUNET_i2s (peer));
440 blctx->session); 347 kill_session (address->transport_name,
441 kill_session (blctx->address->transport_name, 348 session);
442 blctx->session);
443 }
444
445 if (NULL != blctx->address)
446 GNUNET_HELLO_address_free (blctx->address);
447 GNUNET_free (blctx->msg);
448 GNUNET_free (blctx);
449} 349}
450 350
451 351
@@ -470,8 +370,6 @@ GST_receive_callback (void *cls,
470{ 370{
471 const char *plugin_name = cls; 371 const char *plugin_name = cls;
472 struct GNUNET_TIME_Relative ret; 372 struct GNUNET_TIME_Relative ret;
473 struct BlacklistCheckContext *blctx;
474 struct GST_BlacklistCheck *blc;
475 uint16_t type; 373 uint16_t type;
476 374
477 ret = GNUNET_TIME_UNIT_ZERO; 375 ret = GNUNET_TIME_UNIT_ZERO;
@@ -498,8 +396,8 @@ GST_receive_callback (void *cls,
498 if (GNUNET_OK != GST_validation_handle_hello (message)) 396 if (GNUNET_OK != GST_validation_handle_hello (message))
499 { 397 {
500 GNUNET_break_op (0); 398 GNUNET_break_op (0);
501 cancel_pending_blacklist_checks (address, 399 GST_blacklist_abort_matching (address,
502 session); 400 session);
503 } 401 }
504 return ret; 402 return ret;
505 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING: 403 case GNUNET_MESSAGE_TYPE_TRANSPORT_PING:
@@ -512,8 +410,8 @@ GST_receive_callback (void *cls,
512 address, 410 address,
513 session)) 411 session))
514 { 412 {
515 cancel_pending_blacklist_checks (address, 413 GST_blacklist_abort_matching (address,
516 session); 414 session);
517 kill_session (plugin_name, 415 kill_session (plugin_name,
518 session); 416 session);
519 } 417 }
@@ -524,31 +422,20 @@ GST_receive_callback (void *cls,
524 GST_plugins_a2s (address)); 422 GST_plugins_a2s (address));
525 if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message)) 423 if (GNUNET_OK != GST_validation_handle_pong (&address->peer, message))
526 { 424 {
527 GNUNET_break_op(0); 425 GNUNET_break_op (0);
528 cancel_pending_blacklist_checks (address, session); 426 GST_blacklist_abort_matching (address,
427 session);
529 kill_session (plugin_name, session); 428 kill_session (plugin_name, session);
530 } 429 }
531 break; 430 break;
532 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN: 431 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN:
533 /* Do blacklist check if communication with this peer is allowed */ 432 /* Do blacklist check if communication with this peer is allowed */
534 blctx = GNUNET_new (struct BlacklistCheckContext); 433 (void) GST_blacklist_test_allowed (&address->peer,
535 blctx->address = GNUNET_HELLO_address_copy (address); 434 NULL,
536 blctx->session = session; 435 &connect_bl_check_cont,
537 blctx->msg = GNUNET_malloc (ntohs(message->size)); 436 GNUNET_copy_message (message),
538 memcpy (blctx->msg, 437 address,
539 message, 438 session);
540 ntohs (message->size));
541 GNUNET_CONTAINER_DLL_insert (bc_head,
542 bc_tail,
543 blctx);
544 if (NULL !=
545 (blc = GST_blacklist_test_allowed (&address->peer,
546 NULL,
547 &connect_bl_check_cont,
548 blctx)))
549 {
550 blctx->blc = blc;
551 }
552 break; 439 break;
553 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK: 440 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_SYN_ACK:
554 if (GNUNET_OK != 441 if (GNUNET_OK !=
@@ -556,7 +443,7 @@ GST_receive_callback (void *cls,
556 address, 443 address,
557 session)) 444 session))
558 { 445 {
559 cancel_pending_blacklist_checks (address, session); 446 GST_blacklist_abort_matching (address, session);
560 kill_session (plugin_name, session); 447 kill_session (plugin_name, session);
561 } 448 }
562 break; 449 break;
@@ -567,7 +454,7 @@ GST_receive_callback (void *cls,
567 session)) 454 session))
568 { 455 {
569 GNUNET_break_op(0); 456 GNUNET_break_op(0);
570 cancel_pending_blacklist_checks (address, session); 457 GST_blacklist_abort_matching (address, session);
571 kill_session (plugin_name, session); 458 kill_session (plugin_name, session);
572 } 459 }
573 break; 460 break;
@@ -684,7 +571,7 @@ plugin_env_session_end (void *cls,
684 571
685 GST_neighbours_session_terminated (&address->peer, session); 572 GST_neighbours_session_terminated (&address->peer, session);
686 GST_ats_del_session (address, session); 573 GST_ats_del_session (address, session);
687 cancel_pending_blacklist_checks (address, session); 574 GST_blacklist_abort_matching (address, session);
688 575
689 for (sk = sk_head; NULL != sk; sk = sk->next) 576 for (sk = sk_head; NULL != sk; sk = sk->next)
690 { 577 {
@@ -704,39 +591,34 @@ plugin_env_session_end (void *cls,
704 * plugin gave us a new session in #plugin_env_session_start(). If 591 * plugin gave us a new session in #plugin_env_session_start(). If
705 * connection to the peer is disallowed, kill the session. 592 * connection to the peer is disallowed, kill the session.
706 * 593 *
707 * @param cls blc_ctx bl context 594 * @param cls NULL
708 * @param peer the peer 595 * @param peer the peer
596 * @param address address associated with the request
597 * @param session session associated with the request
709 * @param result the result 598 * @param result the result
710 */ 599 */
711static void 600static void
712plugin_env_session_start_bl_check_cont (void *cls, 601plugin_env_session_start_bl_check_cont (void *cls,
713 const struct GNUNET_PeerIdentity *peer, 602 const struct GNUNET_PeerIdentity *peer,
603 const struct GNUNET_HELLO_Address *address,
604 struct Session *session,
714 int result) 605 int result)
715{ 606{
716 struct BlacklistCheckContext *blctx = cls;
717
718 GNUNET_CONTAINER_DLL_remove (bc_head,
719 bc_tail,
720 blctx);
721 blctx->blc = NULL;
722 if (GNUNET_OK != result) 607 if (GNUNET_OK != result)
723 { 608 {
724 cancel_pending_blacklist_checks (blctx->address, 609 kill_session (address->transport_name,
725 blctx->session); 610 session);
726 kill_session (blctx->address->transport_name, 611 return;
727 blctx->session);
728 } 612 }
729 else if (GNUNET_YES != 613 if (GNUNET_YES !=
730 GNUNET_HELLO_address_check_option (blctx->address, 614 GNUNET_HELLO_address_check_option (address,
731 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 615 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
732 { 616 {
733 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 617 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
734 "Informing verifier about inbound session's address `%s'\n", 618 "Informing verifier about inbound session's address `%s'\n",
735 GST_plugins_a2s (blctx->address)); 619 GST_plugins_a2s (address));
736 GST_validation_handle_address (blctx->address); 620 GST_validation_handle_address (address);
737 } 621 }
738 GNUNET_HELLO_address_free (blctx->address);
739 GNUNET_free (blctx);
740} 622}
741 623
742 624
@@ -754,8 +636,6 @@ plugin_env_session_start (void *cls,
754 struct Session *session, 636 struct Session *session,
755 enum GNUNET_ATS_Network_Type scope) 637 enum GNUNET_ATS_Network_Type scope)
756{ 638{
757 struct BlacklistCheckContext *blctx;
758 struct GST_BlacklistCheck *blc;
759 struct GNUNET_ATS_Properties prop; 639 struct GNUNET_ATS_Properties prop;
760 640
761 if (NULL == address) 641 if (NULL == address)
@@ -788,20 +668,12 @@ plugin_env_session_start (void *cls,
788 &prop); 668 &prop);
789 } 669 }
790 /* Do blacklist check if communication with this peer is allowed */ 670 /* Do blacklist check if communication with this peer is allowed */
791 blctx = GNUNET_new (struct BlacklistCheckContext); 671 (void) GST_blacklist_test_allowed (&address->peer,
792 blctx->address = GNUNET_HELLO_address_copy (address); 672 address->transport_name,
793 blctx->session = session; 673 &plugin_env_session_start_bl_check_cont,
794 GNUNET_CONTAINER_DLL_insert (bc_head, 674 NULL,
795 bc_tail, 675 address,
796 blctx); 676 session);
797 if (NULL !=
798 (blc = GST_blacklist_test_allowed (&address->peer,
799 address->transport_name,
800 &plugin_env_session_start_bl_check_cont,
801 blctx)))
802 {
803 blctx->blc = blc;
804 }
805} 677}
806 678
807 679
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index 5301090ff..3a321e786 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -303,7 +303,7 @@ GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
303 ai = find_ai (address, session); 303 ai = find_ai (address, session);
304 if (NULL == ai) 304 if (NULL == ai)
305 { 305 {
306 GNUNET_break (0); 306 GNUNET_assert (0);
307 return; 307 return;
308 } 308 }
309 if (NULL == ai->ar) 309 if (NULL == ai->ar)
diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c
index 195e3439f..22d62570a 100644
--- a/src/transport/gnunet-service-transport_blacklist.c
+++ b/src/transport/gnunet-service-transport_blacklist.c
@@ -146,6 +146,16 @@ struct GST_BlacklistCheck
146 void *cont_cls; 146 void *cont_cls;
147 147
148 /** 148 /**
149 * Address for #GST_blacklist_abort_matching(), can be NULL.
150 */
151 struct GNUNET_HELLO_Address *address;
152
153 /**
154 * Session for #GST_blacklist_abort_matching(), can be NULL.
155 */
156 struct Session *session;
157
158 /**
149 * Current transmission request handle for this client, or NULL if no 159 * Current transmission request handle for this client, or NULL if no
150 * request is pending. 160 * request is pending.
151 */ 161 */
@@ -159,7 +169,7 @@ struct GST_BlacklistCheck
159 /** 169 /**
160 * Current task performing the check. 170 * Current task performing the check.
161 */ 171 */
162 struct GNUNET_SCHEDULER_Task * task; 172 struct GNUNET_SCHEDULER_Task *task;
163 173
164}; 174};
165 175
@@ -198,7 +208,8 @@ static struct GNUNET_CONTAINER_MultiPeerMap *blacklist;
198 * @param tc unused 208 * @param tc unused
199 */ 209 */
200static void 210static void
201do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 211do_blacklist_check (void *cls,
212 const struct GNUNET_SCHEDULER_TaskContext *tc);
202 213
203 214
204/** 215/**
@@ -209,7 +220,8 @@ do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
209 * @param client identification of the client 220 * @param client identification of the client
210 */ 221 */
211static void 222static void
212client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) 223client_disconnect_notification (void *cls,
224 struct GNUNET_SERVER_Client *client)
213{ 225{
214 struct Blacklisters *bl; 226 struct Blacklisters *bl;
215 struct GST_BlacklistCheck *bc; 227 struct GST_BlacklistCheck *bc;
@@ -220,17 +232,17 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client)
220 { 232 {
221 if (bl->client != client) 233 if (bl->client != client)
222 continue; 234 continue;
223 for (bc = bc_head; bc != NULL; bc = bc->next) 235 for (bc = bc_head; NULL != bc; bc = bc->next)
224 { 236 {
225 if (bc->bl_pos != bl) 237 if (bc->bl_pos != bl)
226 continue; 238 continue;
227 bc->bl_pos = bl->next; 239 bc->bl_pos = bl->next;
228 if (bc->th != NULL) 240 if (NULL != bc->th)
229 { 241 {
230 GNUNET_SERVER_notify_transmit_ready_cancel (bc->th); 242 GNUNET_SERVER_notify_transmit_ready_cancel (bc->th);
231 bc->th = NULL; 243 bc->th = NULL;
232 } 244 }
233 if (bc->task == NULL) 245 if (NULL == bc->task)
234 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); 246 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc);
235 } 247 }
236 GNUNET_CONTAINER_DLL_remove (bl_head, bl_tail, bl); 248 GNUNET_CONTAINER_DLL_remove (bl_head, bl_tail, bl);
@@ -383,17 +395,20 @@ GST_blacklist_stop ()
383 * @return number of bytes copied to @a buf 395 * @return number of bytes copied to @a buf
384 */ 396 */
385static size_t 397static size_t
386transmit_blacklist_message (void *cls, size_t size, void *buf) 398transmit_blacklist_message (void *cls,
399 size_t size,
400 void *buf)
387{ 401{
388 struct GST_BlacklistCheck *bc = cls; 402 struct GST_BlacklistCheck *bc = cls;
389 struct Blacklisters *bl; 403 struct Blacklisters *bl;
390 struct BlacklistMessage bm; 404 struct BlacklistMessage bm;
391 405
392 bc->th = NULL; 406 bc->th = NULL;
393 if (size == 0) 407 if (0 == size)
394 { 408 {
395 GNUNET_assert (bc->task == NULL); 409 GNUNET_assert (NULL == bc->task);
396 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); 410 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
411 bc);
397 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 412 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
398 "Failed to send blacklist test for peer `%s' to client\n", 413 "Failed to send blacklist test for peer `%s' to client\n",
399 GNUNET_i2s (&bc->peer)); 414 GNUNET_i2s (&bc->peer));
@@ -401,16 +416,20 @@ transmit_blacklist_message (void *cls, size_t size, void *buf)
401 } 416 }
402 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 417 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
403 "Sending blacklist test for peer `%s' to client %p\n", 418 "Sending blacklist test for peer `%s' to client %p\n",
404 GNUNET_i2s (&bc->peer), bc->bl_pos->client); 419 GNUNET_i2s (&bc->peer),
420 bc->bl_pos->client);
405 bl = bc->bl_pos; 421 bl = bc->bl_pos;
406 bm.header.size = htons (sizeof (struct BlacklistMessage)); 422 bm.header.size = htons (sizeof (struct BlacklistMessage));
407 bm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY); 423 bm.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_BLACKLIST_QUERY);
408 bm.is_allowed = htonl (0); 424 bm.is_allowed = htonl (0);
409 bm.peer = bc->peer; 425 bm.peer = bc->peer;
410 memcpy (buf, &bm, sizeof (bm)); 426 memcpy (buf,
427 &bm,
428 sizeof (bm));
411 if (GNUNET_YES == bl->call_receive_done) 429 if (GNUNET_YES == bl->call_receive_done)
412 { 430 {
413 GNUNET_SERVER_receive_done (bl->client, GNUNET_OK); 431 GNUNET_SERVER_receive_done (bl->client,
432 GNUNET_OK);
414 bl->call_receive_done = GNUNET_NO; 433 bl->call_receive_done = GNUNET_NO;
415 } 434 }
416 435
@@ -434,25 +453,30 @@ do_blacklist_check (void *cls,
434 453
435 bc->task = NULL; 454 bc->task = NULL;
436 bl = bc->bl_pos; 455 bl = bc->bl_pos;
437 if (bl == NULL) 456 if (NULL == bl)
438 { 457 {
439 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 458 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
440 "No other blacklist clients active, will allow neighbour `%s'\n", 459 "No other blacklist clients active, will allow neighbour `%s'\n",
441 GNUNET_i2s (&bc->peer)); 460 GNUNET_i2s (&bc->peer));
442 461
443 bc->cont (bc->cont_cls, &bc->peer, GNUNET_OK); 462 bc->cont (bc->cont_cls,
444 GNUNET_CONTAINER_DLL_remove(bc_head, bc_tail, bc); 463 &bc->peer,
445 GNUNET_free (bc); 464 bc->address,
465 bc->session,
466 GNUNET_OK);
467 GST_blacklist_test_cancel (bc);
446 return; 468 return;
447 } 469 }
448 if ((bl->bc != NULL) || (bl->waiting_for_reply != GNUNET_NO)) 470 if ( (NULL != bl->bc) ||
471 (GNUNET_NO != bl->waiting_for_reply) )
449 return; /* someone else busy with this client */ 472 return; /* someone else busy with this client */
450 bl->bc = bc; 473 bl->bc = bc;
451 bc->th = 474 bc->th =
452 GNUNET_SERVER_notify_transmit_ready (bl->client, 475 GNUNET_SERVER_notify_transmit_ready (bl->client,
453 sizeof (struct BlacklistMessage), 476 sizeof (struct BlacklistMessage),
454 GNUNET_TIME_UNIT_FOREVER_REL, 477 GNUNET_TIME_UNIT_FOREVER_REL,
455 &transmit_blacklist_message, bc); 478 &transmit_blacklist_message,
479 bc);
456} 480}
457 481
458 482
@@ -462,25 +486,30 @@ do_blacklist_check (void *cls,
462 * 486 *
463 * @param cls unused 487 * @param cls unused
464 * @param peer the neighbour that was investigated 488 * @param peer the neighbour that was investigated
489 * @param address address associated with the request
490 * @param session session associated with the request
465 * @param allowed #GNUNET_OK if we can keep it, 491 * @param allowed #GNUNET_OK if we can keep it,
466 * #GNUNET_NO if we must shutdown the connection 492 * #GNUNET_NO if we must shutdown the connection
467 */ 493 */
468static void 494static void
469confirm_or_drop_neighbour (void *cls, 495confirm_or_drop_neighbour (void *cls,
470 const struct GNUNET_PeerIdentity *peer, 496 const struct GNUNET_PeerIdentity *peer,
497 const struct GNUNET_HELLO_Address *address,
498 struct Session *session,
471 int allowed) 499 int allowed)
472{ 500{
473 if (GNUNET_OK == allowed) 501 if (GNUNET_OK == allowed)
474 return; /* we're done */ 502 return; /* we're done */
475 GNUNET_STATISTICS_update (GST_stats, 503 GNUNET_STATISTICS_update (GST_stats,
476 gettext_noop ("# disconnects due to blacklist"), 1, 504 gettext_noop ("# disconnects due to blacklist"),
505 1,
477 GNUNET_NO); 506 GNUNET_NO);
478 GST_neighbours_force_disconnect (peer); 507 GST_neighbours_force_disconnect (peer);
479} 508}
480 509
481 510
482/** 511/**
483 * Closure for 'test_connection_ok'. 512 * Closure for #test_connection_ok().
484 */ 513 */
485struct TestConnectionContext 514struct TestConnectionContext
486{ 515{
@@ -525,6 +554,7 @@ test_connection_ok (void *cls,
525 bc_tail, 554 bc_tail,
526 bc); 555 bc);
527 bc->peer = *peer; 556 bc->peer = *peer;
557 bc->address = GNUNET_HELLO_address_copy (address);
528 bc->cont = &confirm_or_drop_neighbour; 558 bc->cont = &confirm_or_drop_neighbour;
529 bc->cont_cls = NULL; 559 bc->cont_cls = NULL;
530 bc->bl_pos = tcc->bl; 560 bc->bl_pos = tcc->bl;
@@ -548,7 +578,8 @@ test_connection_ok (void *cls,
548 * @param message the blacklist-init message that was sent 578 * @param message the blacklist-init message that was sent
549 */ 579 */
550void 580void
551GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client, 581GST_blacklist_handle_init (void *cls,
582 struct GNUNET_SERVER_Client *client,
552 const struct GNUNET_MessageHeader *message) 583 const struct GNUNET_MessageHeader *message)
553{ 584{
554 struct Blacklisters *bl; 585 struct Blacklisters *bl;
@@ -590,7 +621,8 @@ GST_blacklist_handle_init (void *cls, struct GNUNET_SERVER_Client *client,
590 * @param message the blacklist-init message that was sent 621 * @param message the blacklist-init message that was sent
591 */ 622 */
592void 623void
593GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client, 624GST_blacklist_handle_reply (void *cls,
625 struct GNUNET_SERVER_Client *client,
594 const struct GNUNET_MessageHeader *message) 626 const struct GNUNET_MessageHeader *message)
595{ 627{
596 const struct BlacklistMessage *msg = 628 const struct BlacklistMessage *msg =
@@ -605,14 +637,15 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
605 { 637 {
606 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
607 "Blacklist client disconnected\n"); 639 "Blacklist client disconnected\n");
608 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 640 GNUNET_SERVER_receive_done (client,
641 GNUNET_SYSERR);
609 return; 642 return;
610 } 643 }
611 644
612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 645 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
613 "Blacklist client %p sent reply for `%s'\n", 646 "Blacklist client %p sent reply for `%s'\n",
614 client, 647 client,
615 GNUNET_i2s(&msg->peer)); 648 GNUNET_i2s (&msg->peer));
616 649
617 bc = bl->bc; 650 bc = bl->bc;
618 bl->bc = NULL; 651 bl->bc = NULL;
@@ -622,32 +655,48 @@ GST_blacklist_handle_reply (void *cls, struct GNUNET_SERVER_Client *client,
622 { 655 {
623 /* only run this if the blacklist check has not been 656 /* only run this if the blacklist check has not been
624 * cancelled in the meantime... */ 657 * cancelled in the meantime... */
658 GNUNET_assert (bc->bl_pos == bl);
625 if (ntohl (msg->is_allowed) == GNUNET_SYSERR) 659 if (ntohl (msg->is_allowed) == GNUNET_SYSERR)
626 { 660 {
627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
628 "Blacklist check failed, peer not allowed\n"); 662 "Blacklist check failed, peer not allowed\n");
629 bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); 663 /* For the duration of the continuation, make the ongoing
630 GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); 664 check invisible (to avoid double-cancellation); then
665 add it back again so we can re-use GST_blacklist_test_cancel() */
666 GNUNET_CONTAINER_DLL_remove (bc_head,
667 bc_tail,
668 bc);
669 bc->cont (bc->cont_cls,
670 &bc->peer,
671 bc->address,
672 bc->session,
673 GNUNET_NO);
674 GNUNET_CONTAINER_DLL_insert (bc_head,
675 bc_tail,
676 bc);
677 GST_blacklist_test_cancel (bc);
631 GNUNET_SERVER_receive_done (bl->client, GNUNET_OK); 678 GNUNET_SERVER_receive_done (bl->client, GNUNET_OK);
632 bl->call_receive_done = GNUNET_NO; 679 bl->call_receive_done = GNUNET_NO;
633 GNUNET_free (bc);
634 return; 680 return;
635 } 681 }
636 else 682 else
637 { 683 {
638 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 684 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
639 "Blacklist check succeeded, continuing with checks\n"); 685 "Blacklist check succeeded, continuing with checks\n");
640 GNUNET_SERVER_receive_done (bl->client, GNUNET_OK); 686 GNUNET_SERVER_receive_done (bl->client,
687 GNUNET_OK);
641 bl->call_receive_done = GNUNET_NO; 688 bl->call_receive_done = GNUNET_NO;
642 bc->bl_pos = bc->bl_pos->next; 689 bc->bl_pos = bl->next;
643 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); 690 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
691 bc);
644 } 692 }
645 } 693 }
646 /* check if any other blacklist checks are waiting for this blacklister */ 694 /* check if any other blacklist checks are waiting for this blacklister */
647 for (bc = bc_head; bc != NULL; bc = bc->next) 695 for (bc = bc_head; bc != NULL; bc = bc->next)
648 if ((bc->bl_pos == bl) && (NULL == bc->task)) 696 if ((bc->bl_pos == bl) && (NULL == bc->task))
649 { 697 {
650 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); 698 bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check,
699 bc);
651 break; 700 break;
652 } 701 }
653} 702}
@@ -688,6 +737,38 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer,
688 737
689 738
690/** 739/**
740 * Abort blacklist if @a address and @a session match.
741 *
742 * @param address address used to abort matching checks
743 * @param session session used to abort matching checks
744 */
745void
746GST_blacklist_abort_matching (const struct GNUNET_HELLO_Address *address,
747 struct Session *session)
748{
749 struct GST_BlacklistCheck *bc;
750 struct GST_BlacklistCheck *n;
751
752 n = bc_head;
753 while (NULL != (bc = n))
754 {
755 n = bc->next;
756 if ( (bc->session == session) &&
757 (0 == GNUNET_HELLO_address_cmp (bc->address,
758 address)) )
759 {
760 bc->cont (bc->cont_cls,
761 &bc->peer,
762 bc->address,
763 bc->session,
764 GNUNET_SYSERR);
765 GST_blacklist_test_cancel (bc);
766 }
767 }
768}
769
770
771/**
691 * Test if the given blacklist entry matches. If so, 772 * Test if the given blacklist entry matches. If so,
692 * abort the iteration. 773 * abort the iteration.
693 * 774 *
@@ -725,8 +806,9 @@ test_blacklisted (void *cls,
725 /* blacklist check for specific transport */ 806 /* blacklist check for specific transport */
726 if ((NULL != transport_name) && (NULL != value)) 807 if ((NULL != transport_name) && (NULL != value))
727 { 808 {
728 if (0 == strcmp (transport_name, be)) 809 if (0 == strcmp (transport_name,
729 return GNUNET_NO; /* plugin is blacklisted! */ 810 be))
811 return GNUNET_NO; /* plugin is blacklisted! */
730 } 812 }
731 return GNUNET_OK; 813 return GNUNET_OK;
732} 814}
@@ -739,6 +821,8 @@ test_blacklisted (void *cls,
739 * @param transport_name name of the transport to test, never NULL 821 * @param transport_name name of the transport to test, never NULL
740 * @param cont function to call with result 822 * @param cont function to call with result
741 * @param cont_cls closure for @a cont 823 * @param cont_cls closure for @a cont
824 * @param address address to pass back to @a cont, can be NULL
825 * @param session session to pass back to @a cont, can be NULL
742 * @return handle to the blacklist check, NULL if the decision 826 * @return handle to the blacklist check, NULL if the decision
743 * was made instantly and @a cont was already called 827 * was made instantly and @a cont was already called
744 */ 828 */
@@ -746,7 +830,9 @@ struct GST_BlacklistCheck *
746GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, 830GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
747 const char *transport_name, 831 const char *transport_name,
748 GST_BlacklistTestContinuation cont, 832 GST_BlacklistTestContinuation cont,
749 void *cont_cls) 833 void *cont_cls,
834 const struct GNUNET_HELLO_Address *address,
835 struct Session *session)
750{ 836{
751 struct GST_BlacklistCheck *bc; 837 struct GST_BlacklistCheck *bc;
752 838
@@ -767,21 +853,30 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
767 /* Disallowed by config, disapprove instantly */ 853 /* Disallowed by config, disapprove instantly */
768 GNUNET_STATISTICS_update (GST_stats, 854 GNUNET_STATISTICS_update (GST_stats,
769 gettext_noop ("# disconnects due to blacklist"), 855 gettext_noop ("# disconnects due to blacklist"),
770 1, GNUNET_NO); 856 1,
857 GNUNET_NO);
771 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 858 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
772 _("Disallowing connection to peer `%s' on transport %s\n"), 859 _("Disallowing connection to peer `%s' on transport %s\n"),
773 GNUNET_i2s (peer), 860 GNUNET_i2s (peer),
774 (NULL != transport_name) ? transport_name : "unspecified"); 861 (NULL != transport_name) ? transport_name : "unspecified");
775 if (cont != NULL) 862 if (NULL != cont)
776 cont (cont_cls, peer, GNUNET_NO); 863 cont (cont_cls,
864 peer,
865 address,
866 session,
867 GNUNET_NO);
777 return NULL; 868 return NULL;
778 } 869 }
779 870
780 if (NULL == bl_head) 871 if (NULL == bl_head)
781 { 872 {
782 /* no blacklist clients, approve instantly */ 873 /* no blacklist clients, approve instantly */
783 if (cont != NULL) 874 if (NULL != cont)
784 cont (cont_cls, peer, GNUNET_OK); 875 cont (cont_cls,
876 peer,
877 address,
878 session,
879 GNUNET_OK);
785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
786 "Allowing connection to peer `%s' %s\n", 881 "Allowing connection to peer `%s' %s\n",
787 GNUNET_i2s (peer), 882 GNUNET_i2s (peer),
@@ -791,8 +886,12 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
791 886
792 /* need to query blacklist clients */ 887 /* need to query blacklist clients */
793 bc = GNUNET_new (struct GST_BlacklistCheck); 888 bc = GNUNET_new (struct GST_BlacklistCheck);
794 GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); 889 GNUNET_CONTAINER_DLL_insert (bc_head,
890 bc_tail,
891 bc);
795 bc->peer = *peer; 892 bc->peer = *peer;
893 bc->address = GNUNET_HELLO_address_copy (address);
894 bc->session = session;
796 bc->cont = cont; 895 bc->cont = cont;
797 bc->cont_cls = cont_cls; 896 bc->cont_cls = cont_cls;
798 bc->bl_pos = bl_head; 897 bc->bl_pos = bl_head;
@@ -830,6 +929,7 @@ GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc)
830 GNUNET_SERVER_notify_transmit_ready_cancel (bc->th); 929 GNUNET_SERVER_notify_transmit_ready_cancel (bc->th);
831 bc->th = NULL; 930 bc->th = NULL;
832 } 931 }
932 GNUNET_free_non_null (bc->address);
833 GNUNET_free (bc); 933 GNUNET_free (bc);
834} 934}
835 935
diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h
index 068556778..1a8bdebf4 100644
--- a/src/transport/gnunet-service-transport_blacklist.h
+++ b/src/transport/gnunet-service-transport_blacklist.h
@@ -27,6 +27,7 @@
27#define GNUNET_SERVICE_TRANSPORT_BLACKLIST_H 27#define GNUNET_SERVICE_TRANSPORT_BLACKLIST_H
28 28
29#include "gnunet_statistics_service.h" 29#include "gnunet_statistics_service.h"
30#include "gnunet_ats_service.h"
30#include "gnunet_util_lib.h" 31#include "gnunet_util_lib.h"
31 32
32/** 33/**
@@ -99,12 +100,17 @@ struct GST_BlacklistCheck;
99 * 100 *
100 * @param cls closure 101 * @param cls closure
101 * @param peer identity of peer that was tested 102 * @param peer identity of peer that was tested
103 * @param address address associated with the request
104 * @param session session associated with the request
102 * @param result #GNUNET_OK if the connection is allowed, 105 * @param result #GNUNET_OK if the connection is allowed,
103 * #GNUNET_NO if not 106 * #GNUNET_NO if not,
107 * #GNUNET_SYSERR if operation was aborted
104 */ 108 */
105typedef void 109typedef void
106(*GST_BlacklistTestContinuation) (void *cls, 110(*GST_BlacklistTestContinuation) (void *cls,
107 const struct GNUNET_PeerIdentity *peer, 111 const struct GNUNET_PeerIdentity *peer,
112 const struct GNUNET_HELLO_Address *address,
113 struct Session *session,
108 int result); 114 int result);
109 115
110 116
@@ -115,13 +121,30 @@ typedef void
115 * @param transport_name name of the transport to test, never NULL 121 * @param transport_name name of the transport to test, never NULL
116 * @param cont function to call with result 122 * @param cont function to call with result
117 * @param cont_cls closure for @a cont 123 * @param cont_cls closure for @a cont
124 * @param address address to pass back to @a cont, can be NULL
125 * @param session session to pass back to @a cont, can be NULL
118 * @return handle to the blacklist check, NULL if the decision 126 * @return handle to the blacklist check, NULL if the decision
119 * was made instantly and @a cont was already called 127 * was made instantly and @a cont was already called
120 */ 128 */
121struct GST_BlacklistCheck * 129struct GST_BlacklistCheck *
122GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, 130GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer,
123 const char *transport_name, 131 const char *transport_name,
124 GST_BlacklistTestContinuation cont, void *cont_cls); 132 GST_BlacklistTestContinuation cont,
133 void *cont_cls,
134 const struct GNUNET_HELLO_Address *address,
135 struct Session *session);
136
137
138/**
139 * Abort blacklist if @a address and @a session match.
140 *
141 * @param address address used to abort matching checks
142 * @param session session used to abort matching checks
143 */
144void
145GST_blacklist_abort_matching (const struct GNUNET_HELLO_Address *address,
146 struct Session *session);
147
125 148
126 149
127/** 150/**
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 404dadb80..7c596fbae 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -2142,16 +2142,6 @@ struct BlacklistCheckSwitchContext
2142 struct GST_BlacklistCheck *blc; 2142 struct GST_BlacklistCheck *blc;
2143 2143
2144 /** 2144 /**
2145 * Address we are asking the blacklist subsystem about.
2146 */
2147 struct GNUNET_HELLO_Address *address;
2148
2149 /**
2150 * Session we should use in conjunction with @e address, can be NULL.
2151 */
2152 struct Session *session;
2153
2154 /**
2155 * Inbound bandwidth that was assigned to @e address. 2145 * Inbound bandwidth that was assigned to @e address.
2156 */ 2146 */
2157 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in; 2147 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in;
@@ -2169,11 +2159,17 @@ struct BlacklistCheckSwitchContext
2169 * 2159 *
2170 * @param cls blc_ctx bl context 2160 * @param cls blc_ctx bl context
2171 * @param peer the peer 2161 * @param peer the peer
2172 * @param result the result 2162 * @param address address associated with the request
2163 * @param session session associated with the request
2164 * @param result #GNUNET_OK if the connection is allowed,
2165 * #GNUNET_NO if not,
2166 * #GNUNET_SYSERR if operation was aborted
2173 */ 2167 */
2174static void 2168static void
2175try_connect_bl_check_cont (void *cls, 2169try_connect_bl_check_cont (void *cls,
2176 const struct GNUNET_PeerIdentity *peer, 2170 const struct GNUNET_PeerIdentity *peer,
2171 const struct GNUNET_HELLO_Address *address,
2172 struct Session *session,
2177 int result) 2173 int result)
2178{ 2174{
2179 struct BlacklistCheckSwitchContext *blc_ctx = cls; 2175 struct BlacklistCheckSwitchContext *blc_ctx = cls;
@@ -2281,7 +2277,9 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
2281 (blc = GST_blacklist_test_allowed (target, 2277 (blc = GST_blacklist_test_allowed (target,
2282 NULL, 2278 NULL,
2283 &try_connect_bl_check_cont, 2279 &try_connect_bl_check_cont,
2284 blc_ctx))) 2280 blc_ctx,
2281 NULL,
2282 NULL)))
2285 { 2283 {
2286 blc_ctx->blc = blc; 2284 blc_ctx->blc = blc;
2287 } 2285 }
@@ -2475,54 +2473,66 @@ try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
2475 * @param cls the `struct BlacklistCheckSwitchContext` with 2473 * @param cls the `struct BlacklistCheckSwitchContext` with
2476 * the information about the future address 2474 * the information about the future address
2477 * @param peer the peer we may switch addresses on 2475 * @param peer the peer we may switch addresses on
2478 * @param result #GNUNET_NO if we are not allowed to use the new 2476 * @param address address associated with the request
2479 * address 2477 * @param session session associated with the request
2478 * @param result #GNUNET_OK if the connection is allowed,
2479 * #GNUNET_NO if not,
2480 * #GNUNET_SYSERR if operation was aborted
2480 */ 2481 */
2481static void 2482static void
2482switch_address_bl_check_cont (void *cls, 2483switch_address_bl_check_cont (void *cls,
2483 const struct GNUNET_PeerIdentity *peer, 2484 const struct GNUNET_PeerIdentity *peer,
2485 const struct GNUNET_HELLO_Address *address,
2486 struct Session *session,
2484 int result) 2487 int result)
2485{ 2488{
2486 struct BlacklistCheckSwitchContext *blc_ctx = cls; 2489 struct BlacklistCheckSwitchContext *blc_ctx = cls;
2487 struct GNUNET_TRANSPORT_PluginFunctions *papi; 2490 struct GNUNET_TRANSPORT_PluginFunctions *papi;
2488 struct NeighbourMapEntry *n; 2491 struct NeighbourMapEntry *n;
2489 2492
2490 if (result == GNUNET_NO) 2493 if (GNUNET_SYSERR == result)
2494 goto cleanup;
2495
2496 papi = GST_plugins_find (address->transport_name);
2497 GNUNET_assert (NULL != papi);
2498
2499 if (GNUNET_NO == result)
2491 { 2500 {
2492 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2501 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2493 "Blacklist denied to switch to suggested address `%s' session %p for peer `%s'\n", 2502 "Blacklist denied to switch to suggested address `%s' session %p for peer `%s'\n",
2494 GST_plugins_a2s (blc_ctx->address), 2503 GST_plugins_a2s (address),
2495 blc_ctx->session, 2504 session,
2496 GNUNET_i2s (&blc_ctx->address->peer)); 2505 GNUNET_i2s (peer));
2497 GNUNET_STATISTICS_update (GST_stats, 2506 GNUNET_STATISTICS_update (GST_stats,
2498 "# ATS suggestions ignored (blacklist denied)", 2507 "# ATS suggestions ignored (blacklist denied)",
2499 1, 2508 1,
2500 GNUNET_NO); 2509 GNUNET_NO);
2501 /* FIXME: tell plugin to force killing session here and now 2510 papi->disconnect_session (papi->cls,
2502 (note: _proper_ plugin API for this does not yet exist) */ 2511 session);
2503 GST_ats_block_address (blc_ctx->address, 2512 if (GNUNET_YES !=
2504 blc_ctx->session); 2513 GNUNET_HELLO_address_check_option (address,
2514 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
2515 GST_ats_block_address (address,
2516 NULL);
2505 goto cleanup; 2517 goto cleanup;
2506 } 2518 }
2507 2519
2508 papi = GST_plugins_find (blc_ctx->address->transport_name);
2509 GNUNET_assert (NULL != papi);
2510 2520
2511 if (NULL == blc_ctx->session) 2521 if (NULL == session)
2512 { 2522 {
2513 /* need to create a session, ATS only gave us an address */ 2523 /* need to create a session, ATS only gave us an address */
2514 blc_ctx->session = papi->get_session (papi->cls, 2524 session = papi->get_session (papi->cls,
2515 blc_ctx->address); 2525 address);
2516 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2526 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2517 "Obtained new session for peer `%s' and address '%s': %p\n", 2527 "Obtained new session for peer `%s' and address '%s': %p\n",
2518 GNUNET_i2s (&blc_ctx->address->peer), 2528 GNUNET_i2s (&address->peer),
2519 GST_plugins_a2s (blc_ctx->address), 2529 GST_plugins_a2s (address),
2520 blc_ctx->session); 2530 session);
2521 if (NULL != blc_ctx->session) 2531 if (NULL != session)
2522 GST_ats_new_session (blc_ctx->address, 2532 GST_ats_new_session (address,
2523 blc_ctx->session); 2533 session);
2524 } 2534 }
2525 if (NULL == blc_ctx->session) 2535 if (NULL == session)
2526 { 2536 {
2527 /* session creation failed, bad!, fail! */ 2537 /* session creation failed, bad!, fail! */
2528 GNUNET_STATISTICS_update (GST_stats, 2538 GNUNET_STATISTICS_update (GST_stats,
@@ -2532,10 +2542,10 @@ switch_address_bl_check_cont (void *cls,
2532 /* No session could be obtained, remove blacklist check and clean up */ 2542 /* No session could be obtained, remove blacklist check and clean up */
2533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2543 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2534 "Failed to obtain new session for peer `%s' and address '%s'\n", 2544 "Failed to obtain new session for peer `%s' and address '%s'\n",
2535 GNUNET_i2s (&blc_ctx->address->peer), 2545 GNUNET_i2s (&address->peer),
2536 GST_plugins_a2s (blc_ctx->address)); 2546 GST_plugins_a2s (address));
2537 GST_ats_block_address (blc_ctx->address, 2547 GST_ats_block_address (address,
2538 blc_ctx->session); 2548 session);
2539 goto cleanup; 2549 goto cleanup;
2540 } 2550 }
2541 2551
@@ -2543,8 +2553,8 @@ switch_address_bl_check_cont (void *cls,
2543 it is theoretically possible that the situation changed in 2553 it is theoretically possible that the situation changed in
2544 the meantime, hence we check again here */ 2554 the meantime, hence we check again here */
2545 if (GNUNET_OK == 2555 if (GNUNET_OK ==
2546 try_run_fast_ats_update (blc_ctx->address, 2556 try_run_fast_ats_update (address,
2547 blc_ctx->session, 2557 session,
2548 blc_ctx->bandwidth_in, 2558 blc_ctx->bandwidth_in,
2549 blc_ctx->bandwidth_out)) 2559 blc_ctx->bandwidth_out))
2550 goto cleanup; /* was just a minor update, we're done */ 2560 goto cleanup; /* was just a minor update, we're done */
@@ -2558,23 +2568,23 @@ switch_address_bl_check_cont (void *cls,
2558 2568
2559 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2569 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
2560 "Peer `%s' switches to address `%s'\n", 2570 "Peer `%s' switches to address `%s'\n",
2561 GNUNET_i2s (&blc_ctx->address->peer), 2571 GNUNET_i2s (&address->peer),
2562 GST_plugins_a2s (blc_ctx->address)); 2572 GST_plugins_a2s (address));
2563 2573
2564 switch (n->state) 2574 switch (n->state)
2565 { 2575 {
2566 case GNUNET_TRANSPORT_PS_NOT_CONNECTED: 2576 case GNUNET_TRANSPORT_PS_NOT_CONNECTED:
2567 GNUNET_break (0); 2577 GNUNET_break (0);
2568 GST_ats_block_address (blc_ctx->address, 2578 GST_ats_block_address (address,
2569 blc_ctx->session); 2579 session);
2570 free_neighbour (n); 2580 free_neighbour (n);
2571 return; 2581 return;
2572 case GNUNET_TRANSPORT_PS_INIT_ATS: 2582 case GNUNET_TRANSPORT_PS_INIT_ATS:
2573 /* We requested an address and ATS suggests one: 2583 /* We requested an address and ATS suggests one:
2574 * set primary address and send SYN message*/ 2584 * set primary address and send SYN message*/
2575 set_primary_address (n, 2585 set_primary_address (n,
2576 blc_ctx->address, 2586 address,
2577 blc_ctx->session, 2587 session,
2578 blc_ctx->bandwidth_in, 2588 blc_ctx->bandwidth_in,
2579 blc_ctx->bandwidth_out); 2589 blc_ctx->bandwidth_out);
2580 if (ACK_SEND_SYN_ACK == n->ack_state) 2590 if (ACK_SEND_SYN_ACK == n->ack_state)
@@ -2594,8 +2604,8 @@ switch_address_bl_check_cont (void *cls,
2594 * Switch and send new SYN */ 2604 * Switch and send new SYN */
2595 /* ATS suggests a different address, switch again */ 2605 /* ATS suggests a different address, switch again */
2596 set_primary_address (n, 2606 set_primary_address (n,
2597 blc_ctx->address, 2607 address,
2598 blc_ctx->session, 2608 session,
2599 blc_ctx->bandwidth_in, 2609 blc_ctx->bandwidth_in,
2600 blc_ctx->bandwidth_out); 2610 blc_ctx->bandwidth_out);
2601 if (ACK_SEND_SYN_ACK == n->ack_state) 2611 if (ACK_SEND_SYN_ACK == n->ack_state)
@@ -2614,8 +2624,8 @@ switch_address_bl_check_cont (void *cls,
2614 /* We requested an address and ATS suggests one: 2624 /* We requested an address and ATS suggests one:
2615 * set primary address and send SYN_ACK message*/ 2625 * set primary address and send SYN_ACK message*/
2616 set_primary_address (n, 2626 set_primary_address (n,
2617 blc_ctx->address, 2627 address,
2618 blc_ctx->session, 2628 session,
2619 blc_ctx->bandwidth_in, 2629 blc_ctx->bandwidth_in,
2620 blc_ctx->bandwidth_out); 2630 blc_ctx->bandwidth_out);
2621 /* Send an ACK message as a response to the SYN msg */ 2631 /* Send an ACK message as a response to the SYN msg */
@@ -2638,8 +2648,8 @@ switch_address_bl_check_cont (void *cls,
2638 n->connect_ack_timestamp); 2648 n->connect_ack_timestamp);
2639 } 2649 }
2640 set_primary_address (n, 2650 set_primary_address (n,
2641 blc_ctx->address, 2651 address,
2642 blc_ctx->session, 2652 session,
2643 blc_ctx->bandwidth_in, 2653 blc_ctx->bandwidth_in,
2644 blc_ctx->bandwidth_out); 2654 blc_ctx->bandwidth_out);
2645 set_state_and_timeout (n, 2655 set_state_and_timeout (n,
@@ -2649,12 +2659,12 @@ switch_address_bl_check_cont (void *cls,
2649 case GNUNET_TRANSPORT_PS_CONNECTED: 2659 case GNUNET_TRANSPORT_PS_CONNECTED:
2650 GNUNET_assert (NULL != n->primary_address.address); 2660 GNUNET_assert (NULL != n->primary_address.address);
2651 GNUNET_assert (NULL != n->primary_address.session); 2661 GNUNET_assert (NULL != n->primary_address.session);
2652 GNUNET_break (n->primary_address.session != blc_ctx->session); 2662 GNUNET_break (n->primary_address.session != session);
2653 /* ATS asks us to switch a life connection; see if we can get 2663 /* ATS asks us to switch a life connection; see if we can get
2654 a SYN_ACK on it before we actually do this! */ 2664 a SYN_ACK on it before we actually do this! */
2655 set_alternative_address (n, 2665 set_alternative_address (n,
2656 blc_ctx->address, 2666 address,
2657 blc_ctx->session, 2667 session,
2658 blc_ctx->bandwidth_in, 2668 blc_ctx->bandwidth_in,
2659 blc_ctx->bandwidth_out); 2669 blc_ctx->bandwidth_out);
2660 set_state_and_timeout (n, 2670 set_state_and_timeout (n,
@@ -2668,8 +2678,8 @@ switch_address_bl_check_cont (void *cls,
2668 break; 2678 break;
2669 case GNUNET_TRANSPORT_PS_RECONNECT_ATS: 2679 case GNUNET_TRANSPORT_PS_RECONNECT_ATS:
2670 set_primary_address (n, 2680 set_primary_address (n,
2671 blc_ctx->address, 2681 address,
2672 blc_ctx->session, 2682 session,
2673 blc_ctx->bandwidth_in, 2683 blc_ctx->bandwidth_in,
2674 blc_ctx->bandwidth_out); 2684 blc_ctx->bandwidth_out);
2675 if (ACK_SEND_SYN_ACK == n->ack_state) 2685 if (ACK_SEND_SYN_ACK == n->ack_state)
@@ -2688,8 +2698,8 @@ switch_address_bl_check_cont (void *cls,
2688 /* ATS asks us to switch while we were trying to reconnect; switch to new 2698 /* ATS asks us to switch while we were trying to reconnect; switch to new
2689 address and send SYN again */ 2699 address and send SYN again */
2690 set_primary_address (n, 2700 set_primary_address (n,
2691 blc_ctx->address, 2701 address,
2692 blc_ctx->session, 2702 session,
2693 blc_ctx->bandwidth_in, 2703 blc_ctx->bandwidth_in,
2694 blc_ctx->bandwidth_out); 2704 blc_ctx->bandwidth_out);
2695 set_state_and_timeout (n, 2705 set_state_and_timeout (n,
@@ -2699,8 +2709,8 @@ switch_address_bl_check_cont (void *cls,
2699 break; 2709 break;
2700 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT: 2710 case GNUNET_TRANSPORT_PS_SWITCH_SYN_SENT:
2701 if ( (0 == GNUNET_HELLO_address_cmp (n->primary_address.address, 2711 if ( (0 == GNUNET_HELLO_address_cmp (n->primary_address.address,
2702 blc_ctx->address)) && 2712 address)) &&
2703 (n->primary_address.session == blc_ctx->session) ) 2713 (n->primary_address.session == session) )
2704 { 2714 {
2705 /* ATS switches back to still-active session */ 2715 /* ATS switches back to still-active session */
2706 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2713,8 +2723,8 @@ switch_address_bl_check_cont (void *cls,
2713 } 2723 }
2714 /* ATS asks us to switch a life connection, send */ 2724 /* ATS asks us to switch a life connection, send */
2715 set_alternative_address (n, 2725 set_alternative_address (n,
2716 blc_ctx->address, 2726 address,
2717 blc_ctx->session, 2727 session,
2718 blc_ctx->bandwidth_in, 2728 blc_ctx->bandwidth_in,
2719 blc_ctx->bandwidth_out); 2729 blc_ctx->bandwidth_out);
2720 set_state_and_timeout (n, 2730 set_state_and_timeout (n,
@@ -2743,7 +2753,6 @@ switch_address_bl_check_cont (void *cls,
2743 GNUNET_CONTAINER_DLL_remove (pending_bc_head, 2753 GNUNET_CONTAINER_DLL_remove (pending_bc_head,
2744 pending_bc_tail, 2754 pending_bc_tail,
2745 blc_ctx); 2755 blc_ctx);
2746 GNUNET_HELLO_address_free (blc_ctx->address);
2747 GNUNET_free (blc_ctx); 2756 GNUNET_free (blc_ctx);
2748} 2757}
2749 2758
@@ -2811,8 +2820,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2811 2820
2812 /* Perform blacklist check */ 2821 /* Perform blacklist check */
2813 blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext); 2822 blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext);
2814 blc_ctx->address = GNUNET_HELLO_address_copy (address);
2815 blc_ctx->session = session;
2816 blc_ctx->bandwidth_in = bandwidth_in; 2823 blc_ctx->bandwidth_in = bandwidth_in;
2817 blc_ctx->bandwidth_out = bandwidth_out; 2824 blc_ctx->bandwidth_out = bandwidth_out;
2818 GNUNET_CONTAINER_DLL_insert (pending_bc_head, 2825 GNUNET_CONTAINER_DLL_insert (pending_bc_head,
@@ -2821,7 +2828,9 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2821 if (NULL != (blc = GST_blacklist_test_allowed (&address->peer, 2828 if (NULL != (blc = GST_blacklist_test_allowed (&address->peer,
2822 address->transport_name, 2829 address->transport_name,
2823 &switch_address_bl_check_cont, 2830 &switch_address_bl_check_cont,
2824 blc_ctx))) 2831 blc_ctx,
2832 address,
2833 session)))
2825 { 2834 {
2826 blc_ctx->blc = blc; 2835 blc_ctx->blc = blc;
2827 } 2836 }
@@ -3835,8 +3844,6 @@ GST_neighbours_stop ()
3835 GST_blacklist_test_cancel (cur->blc); 3844 GST_blacklist_test_cancel (cur->blc);
3836 cur->blc = NULL; 3845 cur->blc = NULL;
3837 } 3846 }
3838 if (NULL != cur->address)
3839 GNUNET_HELLO_address_free (cur->address);
3840 GNUNET_free (cur); 3847 GNUNET_free (cur);
3841 } 3848 }
3842} 3849}
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index 2022a8c47..de6edc90a 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -505,11 +505,17 @@ timeout_hello_validation (void *cls,
505 * 505 *
506 * @param cls our `struct ValidationEntry` 506 * @param cls our `struct ValidationEntry`
507 * @param pid identity of the other peer 507 * @param pid identity of the other peer
508 * @param result #GNUNET_OK if the connection is allowed, #GNUNET_NO if not 508 * @param address_null address associated with the request, always NULL
509 * @param session_null session associated with the request, always NULL
510 * @param result #GNUNET_OK if the connection is allowed,
511 * #GNUNET_NO if not,
512 * #GNUNET_SYSERR if operation was aborted
509 */ 513 */
510static void 514static void
511transmit_ping_if_allowed (void *cls, 515transmit_ping_if_allowed (void *cls,
512 const struct GNUNET_PeerIdentity *pid, 516 const struct GNUNET_PeerIdentity *pid,
517 const struct GNUNET_HELLO_Address *address_null,
518 struct Session *session_null,
513 int result) 519 int result)
514{ 520{
515 struct ValidationEntry *ve = cls; 521 struct ValidationEntry *ve = cls;
@@ -524,7 +530,7 @@ transmit_ping_if_allowed (void *cls,
524 struct Session *session; 530 struct Session *session;
525 531
526 ve->bc = NULL; 532 ve->bc = NULL;
527 if (GNUNET_NO == result) 533 if (GNUNET_OK != result)
528 { 534 {
529 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 535 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
530 "Blacklist denies sending PING to `%s' `%s' `%s'\n", 536 "Blacklist denies sending PING to `%s' `%s' `%s'\n",
@@ -743,7 +749,10 @@ revalidate_address (void *cls,
743 GNUNET_NO); 749 GNUNET_NO);
744 bc = GST_blacklist_test_allowed (&ve->address->peer, 750 bc = GST_blacklist_test_allowed (&ve->address->peer,
745 ve->address->transport_name, 751 ve->address->transport_name,
746 &transmit_ping_if_allowed, ve); 752 &transmit_ping_if_allowed,
753 ve,
754 NULL,
755 NULL);
747 if (NULL != bc) 756 if (NULL != bc)
748 ve->bc = bc; /* only set 'bc' if 'transmit_ping_if_allowed' was not already 757 ve->bc = bc; /* only set 'bc' if 'transmit_ping_if_allowed' was not already
749 * called... */ 758 * called... */
diff --git a/src/transport/test_transport_api_blacklisting.c b/src/transport/test_transport_api_blacklisting.c
index 7338dabe7..601ab27f1 100644
--- a/src/transport/test_transport_api_blacklisting.c
+++ b/src/transport/test_transport_api_blacklisting.c
@@ -367,7 +367,8 @@ blacklist_cb (void *cls,
367 return res; 367 return res;
368} 368}
369 369
370void 370
371static void
371start_cb (struct PeerContext *p, void *cls) 372start_cb (struct PeerContext *p, void *cls)
372{ 373{
373 static int started; 374 static int started;
@@ -392,6 +393,7 @@ start_cb (struct PeerContext *p, void *cls)
392 393
393} 394}
394 395
396
395static void 397static void
396run (void *cls, char *const *args, const char *cfgfile, 398run (void *cls, char *const *args, const char *cfgfile,
397 const struct GNUNET_CONFIGURATION_Handle *cfg) 399 const struct GNUNET_CONFIGURATION_Handle *cfg)
diff --git a/src/transport/test_transport_api_data.conf b/src/transport/test_transport_api_data.conf
index 164a38f69..58b8e17b0 100644
--- a/src/transport/test_transport_api_data.conf
+++ b/src/transport/test_transport_api_data.conf
@@ -7,5 +7,3 @@ PORT = 2094
7[transport-udp] 7[transport-udp]
8PORT = 2094 8PORT = 2094
9 9
10
11
diff --git a/src/transport/test_transport_api_tcp_peer1.conf b/src/transport/test_transport_api_tcp_peer1.conf
index 72b8006b1..4bfe9b6ca 100644
--- a/src/transport/test_transport_api_tcp_peer1.conf
+++ b/src/transport/test_transport_api_tcp_peer1.conf
@@ -5,3 +5,5 @@ GNUNET_TEST_HOME = /tmp/test-transport/api-tcp-p1/
5[transport] 5[transport]
6PLUGINS = tcp 6PLUGINS = tcp
7 7
8#[transport]
9#PREFIX = valgrind
diff --git a/src/transport/test_transport_api_tcp_peer2.conf b/src/transport/test_transport_api_tcp_peer2.conf
index afb412cd0..e68cdbee4 100644
--- a/src/transport/test_transport_api_tcp_peer2.conf
+++ b/src/transport/test_transport_api_tcp_peer2.conf
@@ -5,3 +5,5 @@ GNUNET_TEST_HOME = /tmp/test-transport/api-tcp-p2/
5[transport] 5[transport]
6PLUGINS = tcp 6PLUGINS = tcp
7 7
8#[transport]
9#PREFIX = valgrind