aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_blacklist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_blacklist.c')
-rw-r--r--src/transport/gnunet-service-transport_blacklist.c128
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 */
42struct BlacklistCheck; 42struct 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 */
78struct BlacklistCheck 84struct 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 */
128static struct BlacklistCheck *bc_head; 134static 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 */
133static struct BlacklistCheck *bc_tail; 139static 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 */
485static void 492static void
486do_blacklist_check (void *cls, 493do_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 */
758void 773struct GST_BlacklistCheck *
759GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, 774GST_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 */
824void
825GST_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 */