X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-service-transport_blacklist.c;h=7720e467fac2401f7a448418316dc3a6a4e26668;hb=502af2167f7c218366666ca4944bd7cc54b5b19a;hp=aa4644d105b033e26ae93f408b942896c1a88efd;hpb=ed4272a244d2770c42ffdb22c80cb4245fbcf538;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-service-transport_blacklist.c b/src/transport/gnunet-service-transport_blacklist.c index aa4644d10..7720e467f 100644 --- a/src/transport/gnunet-service-transport_blacklist.c +++ b/src/transport/gnunet-service-transport_blacklist.c @@ -39,7 +39,7 @@ /** * Context we use when performing a blacklist check. */ -struct BlacklistCheck; +struct GST_BlacklistCheck; /** @@ -64,9 +64,15 @@ struct Blacklisters struct GNUNET_SERVER_Client *client; /** - * Blacklist check that we're currently performing. + * Blacklist check that we're currently performing (or NULL + * if we're performing one that has been cancelled). */ - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; + + /** + * Set to GNUNET_YES if we're currently waiting for a reply. + */ + int waiting_for_reply; }; @@ -75,18 +81,18 @@ struct Blacklisters /** * Context we use when performing a blacklist check. */ -struct BlacklistCheck +struct GST_BlacklistCheck { /** * This is a linked list. */ - struct BlacklistCheck *next; + struct GST_BlacklistCheck *next; /** * This is a linked list. */ - struct BlacklistCheck *prev; + struct GST_BlacklistCheck *prev; /** * Peer being checked. @@ -125,12 +131,12 @@ struct BlacklistCheck /** * Head of DLL of active blacklisting queries. */ -static struct BlacklistCheck *bc_head; +static struct GST_BlacklistCheck *bc_head; /** * Tail of DLL of active blacklisting queries. */ -static struct BlacklistCheck *bc_tail; +static struct GST_BlacklistCheck *bc_tail; /** * Head of DLL of blacklisting clients. @@ -156,8 +162,7 @@ static struct GNUNET_CONTAINER_MultiHashMap *blacklist; * @param tc unused */ static void -do_blacklist_check (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); +do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); /** @@ -168,40 +173,36 @@ do_blacklist_check (void *cls, * @param client identification of the client */ static void -client_disconnect_notification (void *cls, - struct GNUNET_SERVER_Client *client) +client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) { struct Blacklisters *bl; - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; if (client == NULL) return; for (bl = bl_head; bl != NULL; bl = bl->next) + { + if (bl->client != client) + continue; + for (bc = bc_head; bc != NULL; bc = bc->next) { - if (bl->client != client) - continue; - for (bc = bc_head; bc != NULL; bc = bc->next) - { - if (bc->bl_pos != bl) - continue; - bc->bl_pos = bl->next; - if (bc->th != NULL) - { - GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); - bc->th = NULL; - } - if (bc->task == GNUNET_SCHEDULER_NO_TASK) - bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, - bc); - break; - } - GNUNET_CONTAINER_DLL_remove (bl_head, - bl_tail, - bl); - GNUNET_SERVER_client_drop (bl->client); - GNUNET_free (bl); + if (bc->bl_pos != bl) + continue; + bc->bl_pos = bl->next; + if (bc->th != NULL) + { + GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); + bc->th = NULL; + } + if (bc->task == GNUNET_SCHEDULER_NO_TASK) + bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); break; } + GNUNET_CONTAINER_DLL_remove (bl_head, bl_tail, bl); + GNUNET_SERVER_client_drop (bl->client); + GNUNET_free (bl); + break; + } } @@ -228,153 +229,152 @@ read_blacklist_file () if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (GST_cfg, "TRANSPORT", - "BLACKLIST_FILE", - &fn)) - { + "BLACKLIST_FILE", &fn)) + { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Option `%s' in section `%s' not specified!\n", - "BLACKLIST_FILE", - "TRANSPORT"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Option `%s' in section `%s' not specified!\n", + "BLACKLIST_FILE", "TRANSPORT"); #endif - return; - } + return; + } if (GNUNET_OK != GNUNET_DISK_file_test (fn)) - GNUNET_DISK_fn_write (fn, NULL, 0, - GNUNET_DISK_PERM_USER_READ | GNUNET_DISK_PERM_USER_WRITE); + GNUNET_DISK_fn_write (fn, NULL, 0, + GNUNET_DISK_PERM_USER_READ | + GNUNET_DISK_PERM_USER_WRITE); if (0 != STAT (fn, &frstat)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Could not read blacklist file `%s'\n"), - fn); - GNUNET_free (fn); - return; - } + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Could not read blacklist file `%s'\n"), fn); + GNUNET_free (fn); + return; + } if (frstat.st_size == 0) - { + { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Blacklist file `%s' is empty.\n"), - fn); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + _("Blacklist file `%s' is empty.\n"), fn); #endif - GNUNET_free (fn); - return; - } + GNUNET_free (fn); + return; + } /* FIXME: use mmap */ data = GNUNET_malloc_large (frstat.st_size); - GNUNET_assert(data != NULL); - if (frstat.st_size != - GNUNET_DISK_fn_read (fn, data, frstat.st_size)) + GNUNET_assert (data != NULL); + if (frstat.st_size != GNUNET_DISK_fn_read (fn, data, frstat.st_size)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to read blacklist from `%s'\n"), fn); + GNUNET_free (fn); + GNUNET_free (data); + return; + } + entries_found = 0; + pos = 0; + while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + pos++; + while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && + (pos <= + frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) + { + colon_pos = pos; + while ((colon_pos < frstat.st_size) && + (data[colon_pos] != ':') && + (!isspace ((unsigned char) data[colon_pos]))) + colon_pos++; + if (colon_pos >= frstat.st_size) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - _("Failed to read blacklist from `%s'\n"), - fn); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Syntax error in blacklist file at offset %llu, giving up!\n"), + (unsigned long long) colon_pos); GNUNET_free (fn); GNUNET_free (data); return; } - entries_found = 0; - pos = 0; - while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) - pos++; - while ((frstat.st_size >= sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)) && - (pos <= frstat.st_size - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded))) + + if (isspace ((unsigned char) data[colon_pos])) { - colon_pos = pos; - while ( (colon_pos < frstat.st_size) && - (data[colon_pos] != ':') && - (! isspace ( (unsigned char) data[colon_pos])) ) - colon_pos++; - if (colon_pos >= frstat.st_size) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error in blacklist file at offset %llu, giving up!\n"), - (unsigned long long) colon_pos); - GNUNET_free (fn); - GNUNET_free (data); - return; - } - - if (isspace( (unsigned char) data[colon_pos])) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), - (unsigned long long) colon_pos); - pos = colon_pos; - while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) - pos++; - continue; - } - tsize = colon_pos - pos; - if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) || (tsize == 0)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error in blacklist file at offset %llu, giving up!\n"), - (unsigned long long) colon_pos); - GNUNET_free (fn); - GNUNET_free (data); - return; - } - - if (tsize < 1) - continue; + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), + (unsigned long long) colon_pos); + pos = colon_pos; + while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + pos++; + continue; + } + tsize = colon_pos - pos; + if ((pos >= frstat.st_size) || (pos + tsize >= frstat.st_size) || + (tsize == 0)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Syntax error in blacklist file at offset %llu, giving up!\n"), + (unsigned long long) colon_pos); + GNUNET_free (fn); + GNUNET_free (data); + return; + } - transport_name = GNUNET_malloc(tsize + 1); - memcpy(transport_name, &data[pos], tsize); - pos = colon_pos + 1; + if (tsize < 1) + continue; + + transport_name = GNUNET_malloc (tsize + 1); + memcpy (transport_name, &data[pos], tsize); + pos = colon_pos + 1; #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Read transport name `%s' in blacklist file.\n", - transport_name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Read transport name `%s' in blacklist file.\n", + transport_name); #endif - memcpy (&enc, - &data[pos], - sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); - if (! isspace ( (unsigned char) enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), - (unsigned long long) pos); - pos++; - while ((pos < frstat.st_size) && (!isspace ( (unsigned char) data[pos]))) - pos++; - GNUNET_free_non_null(transport_name); - continue; - } - enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; - if (GNUNET_OK != GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey)) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n"), - (unsigned long long) pos, - &enc); - } - else - { - if (0 != memcmp (&pid, - &GST_my_identity, - sizeof (struct GNUNET_PeerIdentity))) - { - entries_found++; - GST_blacklist_add_peer (&pid, - transport_name); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - _("Found myself `%s' in blacklist (useless, ignored)\n"), - GNUNET_i2s (&pid)); - } - } - pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); - GNUNET_free_non_null(transport_name); - while ((pos < frstat.st_size) && isspace ( (unsigned char) data[pos])) + memcpy (&enc, &data[pos], sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded)); + if (!isspace + ((unsigned char) + enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1])) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Syntax error in blacklist file at offset %llu, skipping bytes.\n"), + (unsigned long long) pos); + pos++; + while ((pos < frstat.st_size) && (!isspace ((unsigned char) data[pos]))) pos++; + GNUNET_free_non_null (transport_name); + continue; } - GNUNET_STATISTICS_update (GST_stats, - "# Transport entries blacklisted", - entries_found, - GNUNET_NO); + enc.encoding[sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded) - 1] = '\0'; + if (GNUNET_OK != + GNUNET_CRYPTO_hash_from_string ((char *) &enc, &pid.hashPubKey)) + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _ + ("Syntax error in blacklist file at offset %llu, skipping bytes `%s'.\n"), + (unsigned long long) pos, &enc); + } + else + { + if (0 != memcmp (&pid, + &GST_my_identity, sizeof (struct GNUNET_PeerIdentity))) + { + entries_found++; + GST_blacklist_add_peer (&pid, transport_name); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Found myself `%s' in blacklist (useless, ignored)\n"), + GNUNET_i2s (&pid)); + } + } + pos = pos + sizeof (struct GNUNET_CRYPTO_HashAsciiEncoded); + GNUNET_free_non_null (transport_name); + while ((pos < frstat.st_size) && isspace ((unsigned char) data[pos])) + pos++; + } + GNUNET_STATISTICS_update (GST_stats, + "# Transport entries blacklisted", + entries_found, GNUNET_NO); GNUNET_free (data); GNUNET_free (fn); } @@ -390,8 +390,7 @@ GST_blacklist_start (struct GNUNET_SERVER_Handle *server) { read_blacklist_file (); GNUNET_SERVER_disconnect_notify (server, - &client_disconnect_notification, - NULL); + &client_disconnect_notification, NULL); } @@ -404,9 +403,7 @@ GST_blacklist_start (struct GNUNET_SERVER_Handle *server) * @return GNUNET_OK (continue to iterate) */ static int -free_blacklist_entry (void *cls, - const GNUNET_HashCode *key, - void *value) +free_blacklist_entry (void *cls, const GNUNET_HashCode * key, void *value) { char *be = value; @@ -422,48 +419,44 @@ void GST_blacklist_stop () { if (NULL != blacklist) - { - GNUNET_CONTAINER_multihashmap_iterate (blacklist, - &free_blacklist_entry, - NULL); - GNUNET_CONTAINER_multihashmap_destroy (blacklist); - blacklist = NULL; - } + { + GNUNET_CONTAINER_multihashmap_iterate (blacklist, + &free_blacklist_entry, NULL); + GNUNET_CONTAINER_multihashmap_destroy (blacklist); + blacklist = NULL; + } } /** * Transmit blacklist query to the client. * - * @param cls the 'struct BlacklistCheck' + * @param cls the 'struct GST_BlacklistCheck' * @param size number of bytes allowed * @param buf where to copy the message * @return number of bytes copied to buf */ static size_t -transmit_blacklist_message (void *cls, - size_t size, - void *buf) +transmit_blacklist_message (void *cls, size_t size, void *buf) { - struct BlacklistCheck *bc = cls; + struct GST_BlacklistCheck *bc = cls; struct Blacklisters *bl; struct BlacklistMessage bm; bc->th = NULL; if (size == 0) - { - GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK); - bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, - bc); - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to send blacklist test for peer `%s' to client\n", - GNUNET_i2s (&bc->peer)); - return 0; - } + { + GNUNET_assert (bc->task == GNUNET_SCHEDULER_NO_TASK); + bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to send blacklist test for peer `%s' to client\n", + GNUNET_i2s (&bc->peer)); + return 0; + } #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending blacklist test for peer `%s' to client\n", - GNUNET_i2s (&bc->peer)); + "Sending blacklist test for peer `%s' to client\n", + GNUNET_i2s (&bc->peer)); #endif bl = bc->bl_pos; bm.header.size = htons (sizeof (struct BlacklistMessage)); @@ -472,6 +465,7 @@ transmit_blacklist_message (void *cls, bm.peer = bc->peer; memcpy (buf, &bm, sizeof (bm)); GNUNET_SERVER_receive_done (bl->client, GNUNET_OK); + bl->waiting_for_reply = GNUNET_YES; return sizeof (bm); } @@ -479,39 +473,37 @@ transmit_blacklist_message (void *cls, /** * Perform next action in the blacklist check. * - * @param cls the 'struct BlacklistCheck*' + * @param cls the 'struct GST_BlacklistCheck*' * @param tc unused */ static void -do_blacklist_check (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +do_blacklist_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct BlacklistCheck *bc = cls; + struct GST_BlacklistCheck *bc = cls; struct Blacklisters *bl; bc->task = GNUNET_SCHEDULER_NO_TASK; bl = bc->bl_pos; if (bl == NULL) - { + { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No other blacklist clients active, will allow neighbour `%s'\n", - GNUNET_i2s (&bc->peer)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "No other blacklist clients active, will allow neighbour `%s'\n", + GNUNET_i2s (&bc->peer)); #endif - bc->cont (bc->cont_cls, - &bc->peer, - GNUNET_OK); - GNUNET_free (bc); - return; - } - if (bl->bc != NULL) - return; /* someone else busy with this client */ + bc->cont (bc->cont_cls, &bc->peer, GNUNET_OK); + GNUNET_free (bc); + return; + } + if ((bl->bc != NULL) || (bl->waiting_for_reply != GNUNET_NO)) + return; /* someone else busy with this client */ bl->bc = bc; bc->th = GNUNET_SERVER_notify_transmit_ready (bl->client, - sizeof (struct BlacklistMessage), - GNUNET_TIME_UNIT_FOREVER_REL, - &transmit_blacklist_message, - bc); + sizeof (struct + BlacklistMessage), + GNUNET_TIME_UNIT_FOREVER_REL, + &transmit_blacklist_message, + bc); } @@ -526,15 +518,13 @@ do_blacklist_check (void *cls, */ static void confirm_or_drop_neighbour (void *cls, - const struct GNUNET_PeerIdentity *peer, - int allowed) + const struct GNUNET_PeerIdentity *peer, int allowed) { if (GNUNET_OK == allowed) - return; /* we're done */ + return; /* we're done */ GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# disconnects due to blacklist"), - 1, - GNUNET_NO); + gettext_noop ("# disconnects due to blacklist"), + 1, GNUNET_NO); GST_neighbours_force_disconnect (peer); } @@ -546,7 +536,7 @@ struct TestConnectionContext { /** * Is this the first neighbour we're checking? - */ + */ int first; /** @@ -562,28 +552,31 @@ struct TestConnectionContext * * @param cls the 'struct TestConnectionContest' * @param pid neighbour's identity + * @param ats performance data + * @param ats_count number of entries in ats (excluding 0-termination) */ static void test_connection_ok (void *cls, - const struct GNUNET_PeerIdentity *neighbour) + const struct GNUNET_PeerIdentity *neighbour, + const struct GNUNET_TRANSPORT_ATS_Information *ats, + uint32_t ats_count) { struct TestConnectionContext *tcc = cls; - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; - bc = GNUNET_malloc (sizeof (struct BlacklistCheck)); + bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck)); GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); bc->peer = *neighbour; bc->cont = &confirm_or_drop_neighbour; bc->cont_cls = NULL; bc->bl_pos = tcc->bl; if (GNUNET_YES == tcc->first) - { - /* all would wait for the same client, no need to - create more than just the first task right now */ - bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, - bc); - tcc->first = GNUNET_NO; - } + { + /* all would wait for the same client, no need to + * create more than just the first task right now */ + bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); + tcc->first = GNUNET_NO; + } } @@ -599,23 +592,23 @@ test_connection_ok (void *cls, */ void GST_blacklist_handle_init (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) { struct Blacklisters *bl; struct TestConnectionContext tcc; bl = bl_head; while (bl != NULL) + { + if (bl->client == client) { - if (bl->client == client) - { - GNUNET_break (0); - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } - bl = bl->next; + GNUNET_break (0); + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; } + bl = bl->next; + } bl = GNUNET_malloc (sizeof (struct Blacklisters)); bl->client = client; GNUNET_SERVER_client_keep (client); @@ -624,8 +617,7 @@ GST_blacklist_handle_init (void *cls, /* confirm that all existing connections are OK! */ tcc.bl = bl; tcc.first = GNUNET_YES; - GST_neighbours_iterate (&test_connection_ok, - &tcc); + GST_neighbours_iterate (&test_connection_ok, &tcc); } @@ -638,58 +630,60 @@ GST_blacklist_handle_init (void *cls, */ void GST_blacklist_handle_reply (void *cls, - struct GNUNET_SERVER_Client *client, - const struct GNUNET_MessageHeader *message) + struct GNUNET_SERVER_Client *client, + const struct GNUNET_MessageHeader *message) { - const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; + const struct BlacklistMessage *msg = + (const struct BlacklistMessage *) message; struct Blacklisters *bl; - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; bl = bl_head; - while ( (bl != NULL) && - (bl->client != client) ) + while ((bl != NULL) && (bl->client != client)) bl = bl->next; if (bl == NULL) - { + { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklist client disconnected\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist client disconnected\n"); #endif - /* FIXME: other error handling here!? */ - GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); - return; - } + /* FIXME: other error handling here!? */ + GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); + return; + } bc = bl->bc; bl->bc = NULL; - if (ntohl (msg->is_allowed) == GNUNET_SYSERR) + bl->waiting_for_reply = GNUNET_NO; + if (NULL != bc) + { + /* only run this if the blacklist check has not been + * cancelled in the meantime... */ + if (ntohl (msg->is_allowed) == GNUNET_SYSERR) { #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklist check failed, peer not allowed\n"); + "Blacklist check failed, peer not allowed\n"); #endif bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); GNUNET_free (bc); } - else + else { #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklist check succeeded, continuing with checks\n"); + "Blacklist check succeeded, continuing with checks\n"); #endif bc->bl_pos = bc->bl_pos->next; - bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, - bc); + bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); } + } /* check if any other bc's are waiting for this blacklister */ bc = bc_head; - while (bc != NULL) + for (bc = bc_head; bc != NULL; bc = bc->next) + if ((bc->bl_pos == bl) && (GNUNET_SCHEDULER_NO_TASK == bc->task)) { - if ( (bc->bl_pos == bl) && - (GNUNET_SCHEDULER_NO_TASK == bc->task) ) - bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, - bc); - bc = bc->next; + bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); + break; } } @@ -702,20 +696,19 @@ GST_blacklist_handle_reply (void *cls, */ void GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, - const char *transport_name) + const char *transport_name) { #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Adding peer `%s' with plugin `%s' to blacklist\n", - GNUNET_i2s (peer), - transport_name); + "Adding peer `%s' with plugin `%s' to blacklist\n", + GNUNET_i2s (peer), transport_name); #endif if (blacklist == NULL) - blacklist = GNUNET_CONTAINER_multihashmap_create(TRANSPORT_BLACKLIST_HT_SIZE); - GNUNET_CONTAINER_multihashmap_put (blacklist, - &peer->hashPubKey, - GNUNET_strdup (transport_name), - GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + blacklist = + GNUNET_CONTAINER_multihashmap_create (TRANSPORT_BLACKLIST_HT_SIZE); + GNUNET_CONTAINER_multihashmap_put (blacklist, &peer->hashPubKey, + GNUNET_strdup (transport_name), + GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); } @@ -729,16 +722,13 @@ GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, * @return GNUNET_OK if the entry does not match, GNUNET_NO if it matches */ static int -test_blacklisted (void *cls, - const GNUNET_HashCode *key, - void *value) +test_blacklisted (void *cls, const GNUNET_HashCode * key, void *value) { const char *transport_name = cls; char *be = value; - if (0 == strcmp (transport_name, - be)) - return GNUNET_NO; /* abort iteration! */ + if (0 == strcmp (transport_name, be)) + return GNUNET_NO; /* abort iteration! */ return GNUNET_OK; } @@ -750,51 +740,81 @@ test_blacklisted (void *cls, * @param transport_name name of the transport to test, never NULL * @param cont function to call with result * @param cont_cls closure for 'cont' + * @return handle to the blacklist check, NULL if the decision + * was made instantly and 'cont' was already called */ -void +struct GST_BlacklistCheck * GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, - const char *transport_name, - GST_BlacklistTestContinuation cont, - void *cont_cls) + const char *transport_name, + GST_BlacklistTestContinuation cont, void *cont_cls) { - struct BlacklistCheck *bc; - - if ( (blacklist != NULL) && - (GNUNET_SYSERR == - GNUNET_CONTAINER_multihashmap_get_multiple (blacklist, - &peer->hashPubKey, - &test_blacklisted, - (void*) transport_name)) ) - { - /* disallowed by config, disapprove instantly */ - GNUNET_STATISTICS_update (GST_stats, - gettext_noop ("# disconnects due to blacklist"), - 1, - GNUNET_NO); - if (cont != NULL) - cont (cont_cls, peer, GNUNET_NO); - return; - } + struct GST_BlacklistCheck *bc; + + if ((blacklist != NULL) && + (GNUNET_SYSERR == + GNUNET_CONTAINER_multihashmap_get_multiple (blacklist, + &peer->hashPubKey, + &test_blacklisted, + (void *) transport_name))) + { + /* disallowed by config, disapprove instantly */ + GNUNET_STATISTICS_update (GST_stats, + gettext_noop ("# disconnects due to blacklist"), + 1, GNUNET_NO); + if (cont != NULL) + cont (cont_cls, peer, GNUNET_NO); + return NULL; + } if (bl_head == NULL) - { - /* no blacklist clients, approve instantly */ - if (cont != NULL) - cont (cont_cls, peer, GNUNET_OK); - return; - } + { + /* no blacklist clients, approve instantly */ + if (cont != NULL) + cont (cont_cls, peer, GNUNET_OK); + return NULL; + } /* need to query blacklist clients */ - bc = GNUNET_malloc (sizeof (struct BlacklistCheck)); + bc = GNUNET_malloc (sizeof (struct GST_BlacklistCheck)); GNUNET_CONTAINER_DLL_insert (bc_head, bc_tail, bc); bc->peer = *peer; bc->cont = cont; bc->cont_cls = cont_cls; bc->bl_pos = bl_head; - bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, - bc); + bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); + return bc; +} + + +/** + * Cancel a blacklist check. + * + * @param bc check to cancel + */ +void +GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc) +{ + GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); + if (bc->bl_pos != NULL) + { + if (bc->bl_pos->bc == bc) + { + /* we're at the head of the queue, remove us! */ + bc->bl_pos->bc = NULL; + } + } + if (GNUNET_SCHEDULER_NO_TASK != bc->task) + { + GNUNET_SCHEDULER_cancel (bc->task); + bc->task = GNUNET_SCHEDULER_NO_TASK; + } + if (NULL != bc->th) + { + GNUNET_CONNECTION_notify_transmit_ready_cancel (bc->th); + bc->th = NULL; + } + GNUNET_free (bc); } - /* end of file gnunet-service-transport_blacklist.c */