diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_blacklist.c')
-rw-r--r-- | src/transport/gnunet-service-transport_blacklist.c | 128 |
1 files changed, 87 insertions, 41 deletions
diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index 09aa43452..7250b6e45 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c | |||
@@ -39,7 +39,7 @@ | |||
39 | /** | 39 | /** |
40 | * Context we use when performing a blacklist check. | 40 | * Context we use when performing a blacklist check. |
41 | */ | 41 | */ |
42 | struct BlacklistCheck; | 42 | struct GST_BlacklistCheck; |
43 | 43 | ||
44 | 44 | ||
45 | /** | 45 | /** |
@@ -64,9 +64,15 @@ struct Blacklisters | |||
64 | struct GNUNET_SERVER_Client *client; | 64 | struct GNUNET_SERVER_Client *client; |
65 | 65 | ||
66 | /** | 66 | /** |
67 | * Blacklist check that we're currently performing. | 67 | * Blacklist check that we're currently performing (or NULL |
68 | * if we're performing one that has been cancelled). | ||
68 | */ | 69 | */ |
69 | struct BlacklistCheck *bc; | 70 | struct GST_BlacklistCheck *bc; |
71 | |||
72 | /** | ||
73 | * Set to GNUNET_YES if we're currently waiting for a reply. | ||
74 | */ | ||
75 | int waiting_for_reply; | ||
70 | 76 | ||
71 | }; | 77 | }; |
72 | 78 | ||
@@ -75,18 +81,18 @@ struct Blacklisters | |||
75 | /** | 81 | /** |
76 | * Context we use when performing a blacklist check. | 82 | * Context we use when performing a blacklist check. |
77 | */ | 83 | */ |
78 | struct BlacklistCheck | 84 | struct GST_BlacklistCheck |
79 | { | 85 | { |
80 | 86 | ||
81 | /** | 87 | /** |
82 | * This is a linked list. | 88 | * This is a linked list. |
83 | */ | 89 | */ |
84 | struct BlacklistCheck *next; | 90 | struct GST_BlacklistCheck *next; |
85 | 91 | ||
86 | /** | 92 | /** |
87 | * This is a linked list. | 93 | * This is a linked list. |
88 | */ | 94 | */ |
89 | struct BlacklistCheck *prev; | 95 | struct GST_BlacklistCheck *prev; |
90 | 96 | ||
91 | /** | 97 | /** |
92 | * Peer being checked. | 98 | * Peer being checked. |
@@ -125,12 +131,12 @@ struct BlacklistCheck | |||
125 | /** | 131 | /** |
126 | * Head of DLL of active blacklisting queries. | 132 | * Head of DLL of active blacklisting queries. |
127 | */ | 133 | */ |
128 | static struct BlacklistCheck *bc_head; | 134 | static struct GST_BlacklistCheck *bc_head; |
129 | 135 | ||
130 | /** | 136 | /** |
131 | * Tail of DLL of active blacklisting queries. | 137 | * Tail of DLL of active blacklisting queries. |
132 | */ | 138 | */ |
133 | static struct BlacklistCheck *bc_tail; | 139 | static struct GST_BlacklistCheck *bc_tail; |
134 | 140 | ||
135 | /** | 141 | /** |
136 | * Head of DLL of blacklisting clients. | 142 | * Head of DLL of blacklisting clients. |
@@ -172,7 +178,7 @@ client_disconnect_notification (void *cls, | |||
172 | struct GNUNET_SERVER_Client *client) | 178 | struct GNUNET_SERVER_Client *client) |
173 | { | 179 | { |
174 | struct Blacklisters *bl; | 180 | struct Blacklisters *bl; |
175 | struct BlacklistCheck *bc; | 181 | struct GST_BlacklistCheck *bc; |
176 | 182 | ||
177 | if (client == NULL) | 183 | if (client == NULL) |
178 | return; | 184 | return; |
@@ -435,7 +441,7 @@ GST_blacklist_stop () | |||
435 | /** | 441 | /** |
436 | * Transmit blacklist query to the client. | 442 | * Transmit blacklist query to the client. |
437 | * | 443 | * |
438 | * @param cls the 'struct BlacklistCheck' | 444 | * @param cls the 'struct GST_BlacklistCheck' |
439 | * @param size number of bytes allowed | 445 | * @param size number of bytes allowed |
440 | * @param buf where to copy the message | 446 | * @param buf where to copy the message |
441 | * @return number of bytes copied to buf | 447 | * @return number of bytes copied to buf |
@@ -445,7 +451,7 @@ transmit_blacklist_message (void *cls, | |||
445 | size_t size, | 451 | size_t size, |
446 | void *buf) | 452 | void *buf) |
447 | { | 453 | { |
448 | struct BlacklistCheck *bc = cls; | 454 | struct GST_BlacklistCheck *bc = cls; |
449 | struct Blacklisters *bl; | 455 | struct Blacklisters *bl; |
450 | struct BlacklistMessage bm; | 456 | struct BlacklistMessage bm; |
451 | 457 | ||
@@ -472,6 +478,7 @@ transmit_blacklist_message (void *cls, | |||
472 | bm.peer = bc->peer; | 478 | bm.peer = bc->peer; |
473 | memcpy (buf, &bm, sizeof (bm)); | 479 | memcpy (buf, &bm, sizeof (bm)); |
474 | GNUNET_SERVER_receive_done (bl->client, GNUNET_OK); | 480 | GNUNET_SERVER_receive_done (bl->client, GNUNET_OK); |
481 | bl->waiting_for_reply = GNUNET_YES; | ||
475 | return sizeof (bm); | 482 | return sizeof (bm); |
476 | } | 483 | } |
477 | 484 | ||
@@ -479,14 +486,14 @@ transmit_blacklist_message (void *cls, | |||
479 | /** | 486 | /** |
480 | * Perform next action in the blacklist check. | 487 | * Perform next action in the blacklist check. |
481 | * | 488 | * |
482 | * @param cls the 'struct BlacklistCheck*' | 489 | * @param cls the 'struct GST_BlacklistCheck*' |
483 | * @param tc unused | 490 | * @param tc unused |
484 | */ | 491 | */ |
485 | static void | 492 | static void |
486 | do_blacklist_check (void *cls, | 493 | do_blacklist_check (void *cls, |
487 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 494 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
488 | { | 495 | { |
489 | struct BlacklistCheck *bc = cls; | 496 | struct GST_BlacklistCheck *bc = cls; |
490 | struct Blacklisters *bl; | 497 | struct Blacklisters *bl; |
491 | 498 | ||
492 | bc->task = GNUNET_SCHEDULER_NO_TASK; | 499 | bc->task = GNUNET_SCHEDULER_NO_TASK; |
@@ -504,7 +511,8 @@ do_blacklist_check (void *cls, | |||
504 | GNUNET_free (bc); | 511 | GNUNET_free (bc); |
505 | return; | 512 | return; |
506 | } | 513 | } |
507 | if (bl->bc != NULL) | 514 | if ( (bl->bc != NULL) || |
515 | (bl->waiting_for_reply != GNUNET_NO) ) | ||
508 | return; /* someone else busy with this client */ | 516 | return; /* someone else busy with this client */ |
509 | bl->bc = bc; | 517 | bl->bc = bc; |
510 | bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client, | 518 | bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client, |
@@ -572,9 +580,9 @@ test_connection_ok (void *cls, | |||
572 | uint32_t ats_count) | 580 | uint32_t ats_count) |
573 | { | 581 | { |
574 | struct TestConnectionContext *tcc = cls; | 582 | struct TestConnectionContext *tcc = cls; |
575 | struct BlacklistCheck *bc; | 583 | struct GST_BlacklistCheck *bc; |
576 | 584 | ||
577 | bc = GNUNET_malloc (sizeof (struct BlacklistCheck)); | 585 | bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck)); |
578 | GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); | 586 | GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); |
579 | bc->peer = *neighbour; | 587 | bc->peer = *neighbour; |
580 | bc->cont = &confirm_or_drop_neighbour; | 588 | bc->cont = &confirm_or_drop_neighbour; |
@@ -647,7 +655,7 @@ GST_blacklist_handle_reply (void *cls, | |||
647 | { | 655 | { |
648 | const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; | 656 | const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; |
649 | struct Blacklisters *bl; | 657 | struct Blacklisters *bl; |
650 | struct BlacklistCheck *bc; | 658 | struct GST_BlacklistCheck *bc; |
651 | 659 | ||
652 | bl = bl_head; | 660 | bl = bl_head; |
653 | while ( (bl != NULL) && | 661 | while ( (bl != NULL) && |
@@ -665,36 +673,42 @@ GST_blacklist_handle_reply (void *cls, | |||
665 | } | 673 | } |
666 | bc = bl->bc; | 674 | bc = bl->bc; |
667 | bl->bc = NULL; | 675 | bl->bc = NULL; |
668 | if (ntohl (msg->is_allowed) == GNUNET_SYSERR) | 676 | bl->waiting_for_reply = GNUNET_NO; |
677 | if (NULL != bc) | ||
669 | { | 678 | { |
679 | /* only run this if the blacklist check has not been | ||
680 | cancelled in the meantime... */ | ||
681 | if (ntohl (msg->is_allowed) == GNUNET_SYSERR) | ||
682 | { | ||
670 | #if DEBUG_TRANSPORT | 683 | #if DEBUG_TRANSPORT |
671 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 684 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
672 | "Blacklist check failed, peer not allowed\n"); | 685 | "Blacklist check failed, peer not allowed\n"); |
673 | #endif | 686 | #endif |
674 | bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); | 687 | bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); |
675 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); | 688 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); |
676 | GNUNET_free (bc); | 689 | GNUNET_free (bc); |
677 | } | 690 | } |
678 | else | 691 | else |
679 | { | 692 | { |
680 | #if DEBUG_TRANSPORT | 693 | #if DEBUG_TRANSPORT |
681 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 694 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
682 | "Blacklist check succeeded, continuing with checks\n"); | 695 | "Blacklist check succeeded, continuing with checks\n"); |
683 | #endif | 696 | #endif |
684 | bc->bl_pos = bc->bl_pos->next; | 697 | bc->bl_pos = bc->bl_pos->next; |
685 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 698 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, |
686 | bc); | 699 | bc); |
700 | } | ||
687 | } | 701 | } |
688 | /* check if any other bc's are waiting for this blacklister */ | 702 | /* check if any other bc's are waiting for this blacklister */ |
689 | bc = bc_head; | 703 | bc = bc_head; |
690 | while (bc != NULL) | 704 | for (bc = bc_head; bc != NULL; bc = bc->next) |
691 | { | 705 | if ( (bc->bl_pos == bl) && |
692 | if ( (bc->bl_pos == bl) && | 706 | (GNUNET_SCHEDULER_NO_TASK == bc->task) ) |
693 | (GNUNET_SCHEDULER_NO_TASK == bc->task) ) | 707 | { |
694 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 708 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, |
695 | bc); | 709 | bc); |
696 | bc = bc->next; | 710 | break; |
697 | } | 711 | } |
698 | } | 712 | } |
699 | 713 | ||
700 | 714 | ||
@@ -754,14 +768,15 @@ test_blacklisted (void *cls, | |||
754 | * @param transport_name name of the transport to test, never NULL | 768 | * @param transport_name name of the transport to test, never NULL |
755 | * @param cont function to call with result | 769 | * @param cont function to call with result |
756 | * @param cont_cls closure for 'cont' | 770 | * @param cont_cls closure for 'cont' |
771 | * @return handle to the blacklist check | ||
757 | */ | 772 | */ |
758 | void | 773 | struct GST_BlacklistCheck * |
759 | GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, | 774 | GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, |
760 | const char *transport_name, | 775 | const char *transport_name, |
761 | GST_BlacklistTestContinuation cont, | 776 | GST_BlacklistTestContinuation cont, |
762 | void *cont_cls) | 777 | void *cont_cls) |
763 | { | 778 | { |
764 | struct BlacklistCheck *bc; | 779 | struct GST_BlacklistCheck *bc; |
765 | 780 | ||
766 | if ( (blacklist != NULL) && | 781 | if ( (blacklist != NULL) && |
767 | (GNUNET_SYSERR == | 782 | (GNUNET_SYSERR == |
@@ -789,7 +804,7 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, | |||
789 | } | 804 | } |
790 | 805 | ||
791 | /* need to query blacklist clients */ | 806 | /* need to query blacklist clients */ |
792 | bc = GNUNET_malloc (sizeof (struct BlacklistCheck)); | 807 | bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck)); |
793 | GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); | 808 | GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); |
794 | bc->peer = *peer; | 809 | bc->peer = *peer; |
795 | bc->cont = cont; | 810 | bc->cont = cont; |
@@ -797,8 +812,39 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, | |||
797 | bc->bl_pos = bl_head; | 812 | bc->bl_pos = bl_head; |
798 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, | 813 | bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, |
799 | bc); | 814 | bc); |
815 | return bc; | ||
800 | } | 816 | } |
801 | 817 | ||
818 | |||
819 | /** | ||
820 | * Cancel a blacklist check. | ||
821 | * | ||
822 | * @param bc check to cancel | ||
823 | */ | ||
824 | void | ||
825 | GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc) | ||
826 | { | ||
827 | GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); | ||
828 | if (bc->bl_pos != NULL) | ||
829 | { | ||
830 | if (bc->bl_pos->bc == bc) | ||
831 | { | ||
832 | /* we're at the head of the queue, remove us! */ | ||
833 | bc->bl_pos->bc = NULL; | ||
834 | } | ||
835 | } | ||
836 | if (GNUNET_SCHEDULER_NO_TASK != bc->task) | ||
837 | { | ||
838 | GNUNET_SCHEDULER_cancel (bc->task); | ||
839 | bc->task = GNUNET_SCHEDULER_NO_TASK; | ||
840 | } | ||
841 | if (NULL != bc->th) | ||
842 | { | ||
843 | GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); | ||
844 | bc->th = NULL; | ||
845 | } | ||
846 | GNUNET_free (bc); | ||
847 | } | ||
802 | 848 | ||
803 | 849 | ||
804 | /* end of file gnunet-service-transport_blacklist.c */ | 850 | /* end of file gnunet-service-transport_blacklist.c */ |