From ce440f071e48bbc75ff797f8a37662996c4af57a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 14 Aug 2011 14:26:33 +0000 Subject: LRN: Fix deps in transport --- src/transport/Makefile.am | 7 ++ src/transport/gnunet-service-transport-new.c | 3 +- src/transport/gnunet-service-transport_blacklist.c | 128 ++++++++++++++------- src/transport/gnunet-service-transport_blacklist.h | 18 ++- src/transport/gnunet-service-transport_clients.c | 3 + .../gnunet-service-transport_validation.c | 110 +++++++++++------- 6 files changed, 186 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am index 4694ba2e5..2a217d4f3 100644 --- a/src/transport/Makefile.am +++ b/src/transport/Makefile.am @@ -71,6 +71,13 @@ lib_LTLIBRARIES = \ libgnunettransporttesting_la_SOURCES = \ transport-testing.c +libgnunettransporttesting_la_LIBADD = \ + $(top_builddir)/src/transport/libgnunettransport.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(GN_LIBINTL) +libgnunettransporttesting_la_DEPENDS = \ + libgnunettransport.la libgnunettransport_la_SOURCES = \ transport_api.c transport.h \ diff --git a/src/transport/gnunet-service-transport-new.c b/src/transport/gnunet-service-transport-new.c index da0bfa6d3..e8369b661 100644 --- a/src/transport/gnunet-service-transport-new.c +++ b/src/transport/gnunet-service-transport-new.c @@ -150,7 +150,8 @@ plugin_env_receive_callback (void *cls, uint16_t sender_address_len) { const char *plugin_name = cls; - + + if (NULL != message) GST_clients_broadcast (message, GNUNET_YES); GNUNET_ATS_address_update (GST_ats, 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 @@ /** * 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. @@ -172,7 +178,7 @@ client_disconnect_notification (void *cls, struct GNUNET_SERVER_Client *client) { struct Blacklisters *bl; - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; if (client == NULL) return; @@ -435,7 +441,7 @@ GST_blacklist_stop () /** * 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 @@ -445,7 +451,7 @@ 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; @@ -472,6 +478,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,14 +486,14 @@ 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) { - struct BlacklistCheck *bc = cls; + struct GST_BlacklistCheck *bc = cls; struct Blacklisters *bl; bc->task = GNUNET_SCHEDULER_NO_TASK; @@ -504,7 +511,8 @@ do_blacklist_check (void *cls, GNUNET_free (bc); return; } - if (bl->bc != NULL) + 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, @@ -572,9 +580,9 @@ test_connection_ok (void *cls, 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; @@ -647,7 +655,7 @@ GST_blacklist_handle_reply (void *cls, { const struct BlacklistMessage *msg = (const struct BlacklistMessage*) message; struct Blacklisters *bl; - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; bl = bl_head; while ( (bl != NULL) && @@ -665,36 +673,42 @@ GST_blacklist_handle_reply (void *cls, } 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"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "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 - { + bc->cont (bc->cont_cls, &bc->peer, GNUNET_NO); + GNUNET_CONTAINER_DLL_remove (bc_head, bc_tail, bc); + GNUNET_free (bc); + } + else + { #if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Blacklist check succeeded, continuing with checks\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "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->bl_pos = bc->bl_pos->next; + 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) - { - if ( (bc->bl_pos == bl) && - (GNUNET_SCHEDULER_NO_TASK == bc->task) ) + for (bc = bc_head; bc != NULL; bc = bc->next) + if ( (bc->bl_pos == bl) && + (GNUNET_SCHEDULER_NO_TASK == bc->task) ) + { bc->task = GNUNET_SCHEDULER_add_now (&do_blacklist_check, bc); - bc = bc->next; - } + break; + } } @@ -754,14 +768,15 @@ 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 */ -void +struct GST_BlacklistCheck * GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, const char *transport_name, GST_BlacklistTestContinuation cont, void *cont_cls) { - struct BlacklistCheck *bc; + struct GST_BlacklistCheck *bc; if ( (blacklist != NULL) && (GNUNET_SYSERR == @@ -789,7 +804,7 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, } /* 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; @@ -797,8 +812,39 @@ GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, bc->bl_pos = bl_head; 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 */ diff --git a/src/transport/gnunet-service-transport_blacklist.h b/src/transport/gnunet-service-transport_blacklist.h index 03f059d81..6721b6aa2 100644 --- a/src/transport/gnunet-service-transport_blacklist.h +++ b/src/transport/gnunet-service-transport_blacklist.h @@ -80,7 +80,13 @@ GST_blacklist_handle_reply (void *cls, void GST_blacklist_add_peer (const struct GNUNET_PeerIdentity *peer, const char *transport_name); - + + +/** + * Handle to an active blacklist check. + */ +struct GST_BlacklistCheck; + /** * Continuation called from a blacklist test. @@ -102,14 +108,22 @@ typedef void (*GST_BlacklistTestContinuation)(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 */ -void +struct GST_BlacklistCheck * GST_blacklist_test_allowed (const struct GNUNET_PeerIdentity *peer, const char *transport_name, GST_BlacklistTestContinuation cont, void *cont_cls); +/** + * Cancel a blacklist check. + * + * @param bc check to cancel + */ +void +GST_blacklist_test_cancel (struct GST_BlacklistCheck *bc); #endif /* end of file gnunet-service-transport_blacklist.h */ diff --git a/src/transport/gnunet-service-transport_clients.c b/src/transport/gnunet-service-transport_clients.c index f03c3a4d3..e73826daf 100644 --- a/src/transport/gnunet-service-transport_clients.c +++ b/src/transport/gnunet-service-transport_clients.c @@ -24,6 +24,7 @@ * @author Christian Grothoff */ #include "platform.h" +#include "gnunet-service-transport_blacklist.h" #include "gnunet-service-transport_clients.h" #include "gnunet-service-transport_hello.h" #include "gnunet-service-transport_neighbours.h" @@ -801,6 +802,8 @@ GST_clients_start (struct GNUNET_SERVER_Handle *server) { &clients_handle_address_lookup, NULL, 0}, { &clients_handle_peer_address_lookup, NULL, sizeof (struct PeerAddressLookupMessage)}, { &clients_handle_address_iterate, NULL, sizeof (struct GNUNET_MessageHeader)}, + { &GST_blacklist_handle_init, NULL, sizeof (struct GNUNET_MessageHeader)}, + { &GST_blacklist_handle_reply, NULL, sizeof (struct BlacklistMessage)}, {NULL, NULL, 0, 0} }; GNUNET_SERVER_add_handlers (server, handlers); diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index 50626eaa6..666892e6e 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -177,6 +177,11 @@ struct ValidationEntry */ const void *addr; + /** + * Handle to the blacklist check (if we're currently in it). + */ + struct GST_BlacklistCheck *bc; + /** * Public key of the peer. */ @@ -483,6 +488,15 @@ cleanup_validation_entry (void *cls, { struct ValidationEntry *ve = value; + if (NULL != ve->bc) + { + GST_blacklist_test_cancel (ve->bc); + ve->bc = NULL; + } + GNUNET_break (GNUNET_OK == + GNUNET_CONTAINER_multihashmap_remove (validation_map, + &va->pid.hashPubKey, + va)); GNUNET_free (ve->transport_name); if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) { @@ -528,19 +542,14 @@ static void timeout_hello_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct ValidationEntry *va = cls; + struct ValidationEntry *ve = cls; - va->timeout_task = GNUNET_SCHEDULER_NO_TASK; + ve->timeout_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# address records discarded"), 1, GNUNET_NO); - GNUNET_break (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_remove (validation_map, - &va->pid.hashPubKey, - va)); - GNUNET_free (va->transport_name); - GNUNET_free (va); + cleanup_validation_entry (NULL, &ve->pid.hashPubKey, ve); } @@ -772,26 +781,19 @@ struct ValidateAddressContext /** - * Iterator callback to go over all addresses and try to validate them - * (unless blocked or already validated). + * Function called with the result from blacklisting. + * Send a PING to the other peer if a communication is allowed. * - * @param cls pointer to a 'struct ValidateAddressContext' - * @param tname name of the transport - * @param expiration expiration time - * @param addr the address - * @param addrlen length of the address - * @return GNUNET_OK (keep the address) + * @param cls ou r'struct ValidationEntry' + * @param pid identity of the other peer + * @param result GNUNET_OK if the connection is allowed, GNUNET_NO if not */ -static int -validate_address (void *cls, - const char *tname, - struct GNUNET_TIME_Absolute expiration, - const void *addr, - uint16_t addrlen) +static void +transmit_ping_if_allowed (void *cls, + const struct GNUNET_PeerIdentity *pid, + int result) { - const struct ValidateAddressContext *vac = cls; - const struct GNUNET_PeerIdentity *pid = &vac->pid; - struct ValidationEntry *ve; + struct ValidationEntry *ve = cls; struct TransportPingMessage ping; struct GNUNET_TRANSPORT_PluginFunctions *papi; const struct GNUNET_MessageHeader *hello; @@ -800,20 +802,7 @@ validate_address (void *cls, size_t slen; uint16_t hsize; - if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) - return GNUNET_OK; /* expired */ - ve = find_validation_entry (&vac->public_key, pid, tname, addr, addrlen); - if (GNUNET_TIME_absolute_get_remaining (ve->validation_block).rel_value > 0) - return GNUNET_OK; /* blocked */ - if ( (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) && - (GNUNET_TIME_absolute_get_remaining (ve->valid_until).rel_value > 0) ) - return GNUNET_OK; /* revalidation task already scheduled & still valid */ - ve->validation_block = GNUNET_TIME_relative_to_absolute (HELLO_REVALIDATION_START_TIME); - if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) - GNUNET_SCHEDULER_cancel (ve->timeout_task); - ve->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_REVALIDATION_START_TIME, - &timeout_hello_validation, - ve); + ve->bc = NULL; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting plain PING to `%s'\n", GNUNET_i2s (pid)); @@ -872,6 +861,49 @@ validate_address (void *cls, 1, GNUNET_NO); } +} + + +/** + * Iterator callback to go over all addresses and try to validate them + * (unless blocked or already validated). + * + * @param cls pointer to a 'struct ValidateAddressContext' + * @param tname name of the transport + * @param expiration expiration time + * @param addr the address + * @param addrlen length of the address + * @return GNUNET_OK (keep the address) + */ +static int +validate_address (void *cls, + const char *tname, + struct GNUNET_TIME_Absolute expiration, + const void *addr, + uint16_t addrlen) +{ + const struct ValidateAddressContext *vac = cls; + const struct GNUNET_PeerIdentity *pid = &vac->pid; + struct ValidationEntry *ve; + + if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) + return GNUNET_OK; /* expired */ + ve = find_validation_entry (&vac->public_key, pid, tname, addr, addrlen); + if (GNUNET_TIME_absolute_get_remaining (ve->validation_block).rel_value > 0) + return GNUNET_OK; /* blocked */ + if ( (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) && + (GNUNET_TIME_absolute_get_remaining (ve->valid_until).rel_value > 0) ) + return GNUNET_OK; /* revalidation task already scheduled & still valid */ + ve->validation_block = GNUNET_TIME_relative_to_absolute (HELLO_REVALIDATION_START_TIME); + if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) + GNUNET_SCHEDULER_cancel (ve->timeout_task); + ve->timeout_task = GNUNET_SCHEDULER_add_delayed (HELLO_REVALIDATION_START_TIME, + &timeout_hello_validation, + ve); + ve->bc = GST_blacklist_test_allowed (pid, + tname, + &transmit_ping_if_allowed, + ve); return GNUNET_OK; } -- cgit v1.2.3