X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Ftransport%2Fgnunet-service-transport_validation.c;h=86172fab3aca26bbdb229a99183ab0a423d8ae0f;hb=395052f780eed32332f6b7ceada109b8a800eb07;hp=98a73b3da561745227cf34802d8e8dbff7cb8b07;hpb=89963b943638799819321934761a31aaa442f384;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index 98a73b3da..86172fab3 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2010,2011 Christian Grothoff (and other contributing authors) + (C) 2010-2014 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -24,10 +24,12 @@ * @author Christian Grothoff */ #include "platform.h" +#include "gnunet-service-transport_clients.h" #include "gnunet-service-transport_validation.h" #include "gnunet-service-transport_plugins.h" #include "gnunet-service-transport_hello.h" #include "gnunet-service-transport_blacklist.h" +#include "gnunet-service-transport_neighbours.h" #include "gnunet-service-transport.h" #include "gnunet_hello_lib.h" #include "gnunet_ats_service.h" @@ -148,7 +150,7 @@ struct TransportPongMessage /** * Signature. */ - struct GNUNET_CRYPTO_EccSignature signature; + struct GNUNET_CRYPTO_EddsaSignature signature; /** * GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN to confirm that this is a @@ -189,7 +191,7 @@ struct ValidationEntry /** * Public key of the peer. */ - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded public_key; + struct GNUNET_CRYPTO_EddsaPublicKey public_key; /** * The identity of the peer. FIXME: duplicated (also in 'address') @@ -199,7 +201,7 @@ struct ValidationEntry /** * Cached PONG signature */ - struct GNUNET_CRYPTO_EccSignature pong_sig_cache; + struct GNUNET_CRYPTO_EddsaSignature pong_sig_cache; /** * ID of task that will clean up this entry if nothing happens. @@ -216,6 +218,11 @@ struct ValidationEntry */ struct GNUNET_TIME_Absolute send_time; + /** + * At what time do we send the next validation request (PING)? + */ + struct GNUNET_TIME_Absolute next_validation; + /** * Until when is this address valid? * ZERO if it is not currently considered valid. @@ -242,6 +249,10 @@ struct ValidationEntry */ struct GNUNET_TIME_Relative latency; + /** + * Current state of this validation entry + */ + enum GNUNET_TRANSPORT_ValidationState state; /** * Challenge number we used. */ @@ -263,10 +274,6 @@ struct ValidationEntry */ int expecting_pong; - /* FIXME: DEBUGGING */ - int last_line_set_to_no; - int last_line_set_to_yes; - enum GNUNET_ATS_Network_Type network; }; @@ -311,14 +318,13 @@ static struct CheckHelloValidatedContext *chvc_tail; * of the given peer that we are currently validating, have validated * or are blocked from re-validation for a while). */ -static struct GNUNET_CONTAINER_MultiHashMap *validation_map; +static struct GNUNET_CONTAINER_MultiPeerMap *validation_map; /** * Context for peerinfo iteration. */ static struct GNUNET_PEERINFO_NotifyContext *pnc; - /** * Minimum delay between to validations */ @@ -339,6 +345,7 @@ static unsigned int validations_fast_start_threshold; */ static struct GNUNET_TIME_Absolute validation_next; + /** * Context for the validation entry match function. */ @@ -360,14 +367,16 @@ struct ValidationEntryMatchContext /** * Iterate over validation entries until a matching one is found. * - * @param cls the 'struct ValidationEntryMatchContext' + * @param cls the `struct ValidationEntryMatchContext *` * @param key peer identity (unused) - * @param value a 'struct ValidationEntry' to match - * @return GNUNET_YES if the entry does not match, - * GNUNET_NO if the entry does match + * @param value a `struct ValidationEntry *` to match + * @return #GNUNET_YES if the entry does not match, + * #GNUNET_NO if the entry does match */ static int -validation_entry_match (void *cls, const struct GNUNET_HashCode * key, void *value) +validation_entry_match (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) { struct ValidationEntryMatchContext *vemc = cls; struct ValidationEntry *ve = value; @@ -381,27 +390,56 @@ validation_entry_match (void *cls, const struct GNUNET_HashCode * key, void *val } +/** + * A validation entry changed. Update the state and notify + * monitors. + * + * @param ve validation entry that changed + * @param state new state + */ +static void +validation_entry_changed (struct ValidationEntry *ve, + enum GNUNET_TRANSPORT_ValidationState state) +{ + ve->state = state; + GST_clients_broadcast_validation_notification (&ve->pid, + ve->address, + ve->send_time, + ve->valid_until, + ve->next_validation, + state); +} + + /** * Iterate over validation entries and free them. * * @param cls (unused) * @param key peer identity (unused) - * @param value a 'struct ValidationEntry' to clean up - * @return GNUNET_YES (continue to iterate) + * @param value a `struct ValidationEntry *` to clean up + * @return #GNUNET_YES (continue to iterate) */ static int -cleanup_validation_entry (void *cls, const struct GNUNET_HashCode * key, void *value) +cleanup_validation_entry (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) { struct ValidationEntry *ve = value; + ve->next_validation = GNUNET_TIME_absolute_get_zero_(); + ve->valid_until = GNUNET_TIME_UNIT_ZERO_ABS; + + /* Notify about deleted entry */ + validation_entry_changed (ve, GNUNET_TRANSPORT_VS_REMOVE); + if (NULL != ve->bc) { GST_blacklist_test_cancel (ve->bc); ve->bc = NULL; } GNUNET_break (GNUNET_OK == - GNUNET_CONTAINER_multihashmap_remove (validation_map, - &ve->pid.hashPubKey, ve)); + GNUNET_CONTAINER_multipeermap_remove (validation_map, + &ve->pid, ve)); GNUNET_HELLO_address_free (ve->address); if (GNUNET_SCHEDULER_NO_TASK != ve->timeout_task) { @@ -444,7 +482,7 @@ timeout_hello_validation (void *cls, ve->timeout_task = GNUNET_SCHEDULER_NO_TASK; max = GNUNET_TIME_absolute_max (ve->valid_until, ve->revalidation_block); left = GNUNET_TIME_absolute_get_remaining (max); - if (left.rel_value > 0) + if (left.rel_value_us > 0) { /* should wait a bit longer */ ve->timeout_task = @@ -454,7 +492,7 @@ timeout_hello_validation (void *cls, GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# address records discarded"), 1, GNUNET_NO); - cleanup_validation_entry (NULL, &ve->pid.hashPubKey, ve); + cleanup_validation_entry (NULL, &ve->pid, ve); } @@ -464,10 +502,11 @@ timeout_hello_validation (void *cls, * * @param cls our 'struct ValidationEntry' * @param pid identity of the other peer - * @param result GNUNET_OK if the connection is allowed, GNUNET_NO if not + * @param result #GNUNET_OK if the connection is allowed, #GNUNET_NO if not */ static void -transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, +transmit_ping_if_allowed (void *cls, + const struct GNUNET_PeerIdentity *pid, int result) { struct ValidationEntry *ve = cls; @@ -482,20 +521,26 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, uint16_t hsize; ve->bc = NULL; - if (GNUNET_NO == result) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Blacklist denies to send PING to `%s' %s %s\n", - GNUNET_i2s (pid), GST_plugins_a2s (ve->address), ve->address->transport_name); - return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Blacklist denies to send PING to `%s' `%s' `%s'\n", + GNUNET_i2s (pid), + GST_plugins_a2s (ve->address), + ve->address->transport_name); + return; } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting plain PING to `%s' %s %s\n", - GNUNET_i2s (pid), GST_plugins_a2s (ve->address), ve->address->transport_name); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Transmitting plain PING to `%s' `%s' `%s'\n", + GNUNET_i2s (pid), + GST_plugins_a2s (ve->address), + ve->address->transport_name); - next = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), validation_delay); - if (next.abs_value > validation_next.abs_value) - validation_next = next; /* We're going to send a PING so delay next validation */ + next = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get(), + validation_delay); + if (next.abs_value_us > validation_next.abs_value_us) + validation_next = next; /* We're going to send a PING so delay next validation */ slen = strlen (ve->address->transport_name) + 1; hello = GST_hello_get (); @@ -539,8 +584,8 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, ret = -1; else { - GNUNET_assert (papi->send != NULL); - GNUNET_assert (papi->get_session != NULL); + GNUNET_assert (NULL != papi->send); + GNUNET_assert (NULL != papi->get_session); struct Session * session = papi->get_session(papi->cls, ve->address); if (session != NULL) @@ -549,20 +594,24 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, message_buf, tsize, PING_PRIORITY, ACCEPTABLE_PING_DELAY, NULL, NULL); - network = papi->get_network (ve->address, session); + network = papi->get_network (papi->cls, session); if (GNUNET_ATS_NET_UNSPECIFIED == network) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Could not obtain a valid network for `%s' %s\n", - GNUNET_i2s (pid), GST_plugins_a2s (ve->address)); - GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Could not obtain a valid network for `%s' `%s'\n", + GNUNET_i2s (pid), + GST_plugins_a2s (ve->address)); + GNUNET_break(0); } + GST_neighbours_notify_data_sent (pid, ve->address, session, tsize); } else { /* Could not get a valid session */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not get a valid session for `%s' %s\n", - GNUNET_i2s (pid), GST_plugins_a2s (ve->address)); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Could not get a valid session for `%s' `%s'\n", + GNUNET_i2s (pid), + GST_plugins_a2s (ve->address)); ret = -1; } } @@ -577,10 +626,12 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, ve->network = network; ve->expecting_pong = GNUNET_YES; - validations_running ++; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Validation started, %u validation processes running\n", - validations_running); + validations_running++; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Validation started, %u validation processes running\n", + validations_running); + /* Notify about PING sent */ + validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE); } } @@ -592,7 +643,8 @@ transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid, * @param tc scheduler context (unused) */ static void -revalidate_address (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +revalidate_address (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { struct ValidationEntry *ve = cls; struct GNUNET_TIME_Relative canonical_delay; @@ -607,28 +659,40 @@ revalidate_address (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) canonical_delay = (ve->in_use == GNUNET_YES) ? CONNECTED_PING_FREQUENCY - : ((GNUNET_TIME_absolute_get_remaining (ve->valid_until).rel_value > + : ((GNUNET_TIME_absolute_get_remaining (ve->valid_until).rel_value_us > 0) ? VALIDATED_PING_FREQUENCY : UNVALIDATED_PING_KEEPALIVE); - if (delay.rel_value > canonical_delay.rel_value * 2) + if (delay.rel_value_us > canonical_delay.rel_value_us * 2) { /* situation changed, recalculate delay */ delay = canonical_delay; ve->revalidation_block = GNUNET_TIME_relative_to_absolute (delay); } - if (delay.rel_value > 0) + if (delay.rel_value_us > 0) { /* should wait a bit longer */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Waiting for %s longer before validating address `%s'\n", + GNUNET_STRINGS_relative_time_to_string (delay, + GNUNET_YES), + GST_plugins_a2s (ve->address)); ve->revalidation_task = GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve); + ve->next_validation = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), delay); return; } blocked_for = GNUNET_TIME_absolute_get_remaining(validation_next); if ((validations_running > validations_fast_start_threshold) && - (blocked_for.rel_value > 0)) + (blocked_for.rel_value_us > 0)) { /* Validations are blocked, have to wait for blocked_for time */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Validations blocked for another %s, delaying validating address `%s'\n", + GNUNET_STRINGS_relative_time_to_string (blocked_for, + GNUNET_YES), + GST_plugins_a2s (ve->address)); ve->revalidation_task = GNUNET_SCHEDULER_add_delayed (blocked_for, &revalidate_address, ve); + ve->next_validation = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), blocked_for); return; } ve->revalidation_block = GNUNET_TIME_relative_to_absolute (canonical_delay); @@ -636,28 +700,30 @@ revalidate_address (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) /* schedule next PINGing with some extra random delay to avoid synchronous re-validations */ rdelay = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, - canonical_delay.rel_value); + canonical_delay.rel_value_us); - /* Debug code for mantis 0002726*/ - if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value == - GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, rdelay).rel_value) + /* Debug code for mantis 0002726 */ + if (GNUNET_TIME_UNIT_FOREVER_REL.rel_value_us == + GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MICROSECONDS, rdelay).rel_value_us) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Revalidation interval for peer `%s' for is FOREVER (debug: rdelay: %llu, canonical delay %llu)\n", - GNUNET_i2s (&ve->pid), - (unsigned long long) delay.rel_value, - (unsigned long long) canonical_delay.rel_value); + GNUNET_break (0); delay = canonical_delay; } else { - delay = GNUNET_TIME_relative_add (canonical_delay, - GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_MILLISECONDS, rdelay)); + delay = GNUNET_TIME_relative_add (canonical_delay, + GNUNET_TIME_relative_multiply + (GNUNET_TIME_UNIT_MICROSECONDS, rdelay)); } /* End debug code for mantis 0002726*/ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Validating now, next scheduled for %s, now validating address `%s'\n", + GNUNET_STRINGS_relative_time_to_string (blocked_for, + GNUNET_YES), + GST_plugins_a2s (ve->address)); ve->revalidation_task = GNUNET_SCHEDULER_add_delayed (delay, &revalidate_address, ve); + ve->next_validation = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), delay); /* start PINGing by checking blacklist */ GNUNET_STATISTICS_update (GST_stats, @@ -682,39 +748,38 @@ revalidate_address (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) * if we don't have an existing entry and no public key was given */ static struct ValidationEntry * -find_validation_entry (const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded - *public_key, const struct GNUNET_HELLO_Address *address) +find_validation_entry (const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, + const struct GNUNET_HELLO_Address *address) { struct ValidationEntryMatchContext vemc; struct ValidationEntry *ve; vemc.ve = NULL; vemc.address = address; - GNUNET_CONTAINER_multihashmap_get_multiple (validation_map, - &address->peer.hashPubKey, + GNUNET_CONTAINER_multipeermap_get_multiple (validation_map, + &address->peer, &validation_entry_match, &vemc); if (NULL != (ve = vemc.ve)) return ve; if (public_key == NULL) return NULL; - ve = GNUNET_malloc (sizeof (struct ValidationEntry)); + ve = GNUNET_new (struct ValidationEntry); ve->in_use = GNUNET_SYSERR; /* not defined */ - ve->last_line_set_to_no = 0; - ve->last_line_set_to_yes = 0; ve->address = GNUNET_HELLO_address_copy (address); ve->public_key = *public_key; ve->pid = address->peer; ve->pong_sig_valid_until = GNUNET_TIME_absolute_get_zero_(); - memset (&ve->pong_sig_cache, '\0', sizeof (struct GNUNET_CRYPTO_EccSignature)); + memset (&ve->pong_sig_cache, '\0', sizeof (struct GNUNET_CRYPTO_EddsaSignature)); ve->latency = GNUNET_TIME_UNIT_FOREVER_REL; ve->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); ve->timeout_task = GNUNET_SCHEDULER_add_delayed (UNVALIDATED_PING_KEEPALIVE, &timeout_hello_validation, ve); - GNUNET_CONTAINER_multihashmap_put (validation_map, &address->peer.hashPubKey, + GNUNET_CONTAINER_multipeermap_put (validation_map, &address->peer, ve, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); + validation_entry_changed (ve, GNUNET_TRANSPORT_VS_NEW); ve->expecting_pong = GNUNET_NO; return ve; } @@ -727,19 +792,20 @@ find_validation_entry (const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded * @param cls original HELLO message * @param address the address * @param expiration expiration time - * @return GNUNET_OK (keep the address) + * @return #GNUNET_OK (keep the address) */ static int -add_valid_address (void *cls, const struct GNUNET_HELLO_Address *address, +add_valid_address (void *cls, + const struct GNUNET_HELLO_Address *address, struct GNUNET_TIME_Absolute expiration) { const struct GNUNET_HELLO_Message *hello = cls; struct ValidationEntry *ve; struct GNUNET_PeerIdentity pid; struct GNUNET_ATS_Information ats; - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded public_key; + struct GNUNET_CRYPTO_EddsaPublicKey public_key; - if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) + if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) return GNUNET_OK; /* expired */ if ((GNUNET_OK != GNUNET_HELLO_get_id (hello, &pid)) || (GNUNET_OK != GNUNET_HELLO_get_key (hello, &public_key))) @@ -747,7 +813,9 @@ add_valid_address (void *cls, const struct GNUNET_HELLO_Address *address, GNUNET_break (0); return GNUNET_OK; /* invalid HELLO !? */ } - if (0 == memcmp (&GST_my_identity, &pid, sizeof (struct GNUNET_PeerIdentity))) + if (0 == memcmp (&GST_my_identity, + &pid, + sizeof (struct GNUNET_PeerIdentity))) { /* Peerinfo returned own identity, skip validation */ return GNUNET_OK; @@ -757,7 +825,14 @@ add_valid_address (void *cls, const struct GNUNET_HELLO_Address *address, ve->valid_until = GNUNET_TIME_absolute_max (ve->valid_until, expiration); if (GNUNET_SCHEDULER_NO_TASK == ve->revalidation_task) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Starting revalidations for valid address `%s'\n", + GST_plugins_a2s (ve->address)); + ve->next_validation = GNUNET_TIME_absolute_get(); ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); + } + validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE); ats.type = htonl (GNUNET_ATS_NETWORK_TYPE); ats.value = htonl (ve->network); @@ -783,6 +858,9 @@ process_peerinfo_hello (void *cls, const struct GNUNET_PeerIdentity *peer, GNUNET_assert (NULL != peer); if (NULL == hello) return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Handling HELLO for peer `%s'\n", + GNUNET_i2s (peer)); GNUNET_assert (NULL == GNUNET_HELLO_iterate_addresses (hello, GNUNET_NO, &add_valid_address, @@ -798,27 +876,31 @@ process_peerinfo_hello (void *cls, const struct GNUNET_PeerIdentity *peer, void GST_validation_start (unsigned int max_fds) { - /** - * Initialization for validation throttling - * - * We have a maximum number max_fds of connections we can use for validation - * We monitor the number of validations in parallel and start to throttle it - * when doing to many validations in parallel: - * if (running validations < (max_fds / 2)) - * - "fast start": run validation immediately - * - have delay of (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value) / (max_fds / 2) - * (300 sec / ~150 == ~2 sec.) between two validations - */ - - validation_next = GNUNET_TIME_absolute_get(); - validation_delay.rel_value = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value) / (max_fds / 2); - validations_fast_start_threshold = (max_fds / 2); - validations_running = 0; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Validation uses a fast start threshold of %u connections and a delay between of %u ms\n ", - validations_fast_start_threshold, validation_delay.rel_value); - validation_map = GNUNET_CONTAINER_multihashmap_create (VALIDATION_MAP_SIZE, + /** + * Initialization for validation throttling + * + * We have a maximum number max_fds of connections we can use for validation + * We monitor the number of validations in parallel and start to throttle it + * when doing to many validations in parallel: + * if (running validations < (max_fds / 2)) + * - "fast start": run validation immediately + * - have delay of (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us) / (max_fds / 2) + * (300 sec / ~150 == ~2 sec.) between two validations + */ + + validation_next = GNUNET_TIME_absolute_get(); + validation_delay.rel_value_us = (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value_us) / (max_fds / 2); + validations_fast_start_threshold = (max_fds / 2); + validations_running = 0; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Validation uses a fast start threshold of %u connections and a delay between of %s\n ", + validations_fast_start_threshold, + GNUNET_STRINGS_relative_time_to_string (validation_delay, + GNUNET_YES)); + validation_map = GNUNET_CONTAINER_multipeermap_create (VALIDATION_MAP_SIZE, GNUNET_NO); - pnc = GNUNET_PEERINFO_notify (GST_cfg, GNUNET_YES, &process_peerinfo_hello, NULL); + pnc = GNUNET_PEERINFO_notify (GST_cfg, GNUNET_YES, + &process_peerinfo_hello, NULL); } @@ -830,9 +912,9 @@ GST_validation_stop () { struct CheckHelloValidatedContext *chvc; - GNUNET_CONTAINER_multihashmap_iterate (validation_map, + GNUNET_CONTAINER_multipeermap_iterate (validation_map, &cleanup_validation_entry, NULL); - GNUNET_CONTAINER_multihashmap_destroy (validation_map); + GNUNET_CONTAINER_multipeermap_destroy (validation_map); validation_map = NULL; while (NULL != (chvc = chvc_head)) { @@ -857,32 +939,38 @@ GST_validation_stop () */ static void multicast_pong (void *cls, - const struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded - *public_key, struct GNUNET_TIME_Absolute valid_until, + const struct GNUNET_CRYPTO_EddsaPublicKey *public_key, + struct GNUNET_TIME_Absolute valid_until, struct GNUNET_TIME_Absolute validation_block, const struct GNUNET_HELLO_Address *address) { struct TransportPongMessage *pong = cls; struct GNUNET_TRANSPORT_PluginFunctions *papi; + struct Session *session; papi = GST_plugins_find (address->transport_name); - if (papi == NULL) + if (NULL == papi) return; - GNUNET_assert (papi->send != NULL); - GNUNET_assert (papi->get_session != NULL); - - struct Session * session = papi->get_session(papi->cls, address); - if (session == NULL) + GNUNET_assert (NULL != papi->send); + GNUNET_assert (NULL != papi->get_session); + session = papi->get_session(papi->cls, address); + if (NULL == session) { GNUNET_break (0); return; } - papi->send (papi->cls, session, - (const char *) pong, ntohs (pong->header.size), - PONG_PRIORITY, ACCEPTABLE_PING_DELAY, + (const char *) pong, + ntohs (pong->header.size), + PONG_PRIORITY, + ACCEPTABLE_PING_DELAY, NULL, NULL); + GST_neighbours_notify_data_sent (&address->peer, + address, + session, + pong->header.size); + } @@ -893,8 +981,9 @@ multicast_pong (void *cls, * @param hdr the PING * @param sender_address the sender address as we got it * @param session session we got the PING from + * @return #GNUNET_OK if the message was fine, #GNUNET_SYSERR on serious error */ -void +int GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *hdr, const struct GNUNET_HELLO_Address *sender_address, @@ -903,8 +992,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, const struct TransportPingMessage *ping; struct TransportPongMessage *pong; struct GNUNET_TRANSPORT_PluginFunctions *papi; - struct GNUNET_TRANSPORT_PluginFunctions *server_papi; - struct GNUNET_CRYPTO_EccSignature *sig_cache; + struct GNUNET_CRYPTO_EddsaSignature *sig_cache; struct GNUNET_TIME_Absolute *sig_cache_exp; const char *addr; const char *addrend; @@ -919,7 +1007,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, if (ntohs (hdr->size) < sizeof (struct TransportPingMessage)) { GNUNET_break_op (0); - return; + return GNUNET_SYSERR; } ping = (const struct TransportPingMessage *) hdr; if (0 != @@ -930,7 +1018,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, gettext_noop ("# PING message for different peer received"), 1, GNUNET_NO); - return; + return GNUNET_SYSERR; } GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# PING messages received"), 1, @@ -942,18 +1030,19 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, sig_cache = NULL; sig_cache_exp = NULL; - + papi = NULL; if (alen > 0) { addrend = memchr (addr, '\0', alen); if (NULL == addrend) { GNUNET_break_op (0); - return; + return GNUNET_SYSERR; } addrend++; slen = strlen (addr) + 1; alen -= slen; + address.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE; address.address = addrend; address.address_length = alen; address.transport_name = addr; @@ -961,47 +1050,60 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, if (NULL == address.transport_name) { - GNUNET_break (0); + GNUNET_break (0); } if (0 != strstr (address.transport_name, "_client")) - { - plugin_name = GNUNET_strdup (address.transport_name); - pos = strstr (plugin_name, "_client"); - GNUNET_assert (NULL != pos); - GNUNET_snprintf (pos, strlen ("_server") + 1, "%s", "_server"); - } + { + plugin_name = GNUNET_strdup (address.transport_name); + pos = strstr (plugin_name, "_client"); + GNUNET_assert (NULL != pos); + GNUNET_snprintf (pos, strlen ("_server") + 1, "%s", "_server"); + } else - plugin_name = GNUNET_strdup (address.transport_name); + plugin_name = GNUNET_strdup (address.transport_name); if (NULL == (papi = GST_plugins_find (plugin_name))) { /* we don't have the plugin for this address */ - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Plugin `%s' not available, cannot confirm having this address \n", - plugin_name); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Plugin `%s' not available, cannot confirm having this address\n"), + plugin_name); GNUNET_free (plugin_name); - return; + return GNUNET_SYSERR; } GNUNET_free (plugin_name); if (GNUNET_OK != papi->check_address (papi->cls, addrend, alen)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Address `%s' is not one of my addresses, not confirming PING\n", - GST_plugins_a2s (&address)); - return; - } + { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# failed address checks during validation"), 1, + GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Address `%s' is not one of my addresses, not confirming PING\n"), + GST_plugins_a2s (&address)); + return GNUNET_SYSERR; + } else - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Address `%s' is one of my addresses, confirming PING\n", - GST_plugins_a2s (&address)); /* DEBUGGING*/ + { + GNUNET_STATISTICS_update (GST_stats, + gettext_noop + ("# successful address checks during validation"), 1, + GNUNET_NO); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Address `%s' is one of my addresses, confirming PING\n", + GST_plugins_a2s (&address)); + } if (GNUNET_YES != GST_hello_test_address (&address, &sig_cache, &sig_cache_exp)) { if (GNUNET_NO == buggy) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Not confirming PING from peer `%s' with address `%s' since I cannot confirm having this address.\n", + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Not confirming PING from peer `%s' with address `%s' since I cannot confirm having this address.\n"), GNUNET_i2s (sender), GST_plugins_a2s (&address)); - return; + return GNUNET_SYSERR; } else { @@ -1015,7 +1117,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, { addrend = NULL; /* make gcc happy */ slen = 0; - static struct GNUNET_CRYPTO_EccSignature no_address_signature; + static struct GNUNET_CRYPTO_EddsaSignature no_address_signature; static struct GNUNET_TIME_Absolute no_address_signature_expiration; sig_cache = &no_address_signature; @@ -1024,7 +1126,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "I am `%s', sending PONG to peer `%s'\n", - GNUNET_h2s (&GST_my_identity.hashPubKey), + GNUNET_i2s_full (&GST_my_identity), GNUNET_i2s (sender)); /* message with structure: @@ -1047,24 +1149,28 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, GNUNET_assert (NULL != addrend); memcpy (&((char *) &pong[1])[slen], addrend, alen); } - if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value < - PONG_SIGNATURE_LIFETIME.rel_value / 4) + if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value_us < + PONG_SIGNATURE_LIFETIME.rel_value_us / 4) { /* create / update cached sig */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating PONG signature to indicate ownership.\n"); *sig_cache_exp = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); - GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_ecc_sign (GST_my_private_key, &pong->purpose, - sig_cache)); + if (GNUNET_OK != + GNUNET_CRYPTO_eddsa_sign (GST_my_private_key, &pong->purpose, + sig_cache)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + _("Failed to create PONG signature for peer `%s'\n"), GNUNET_i2s (sender)); + } } else { pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); } pong->signature = *sig_cache; - + GNUNET_assert (sender_address != NULL); /* first see if the session we got this PING from can be used to transmit @@ -1091,9 +1197,13 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, (const char *) pong, ntohs (pong->header.size), PONG_PRIORITY, ACCEPTABLE_PING_DELAY, NULL, NULL); + if (-1 != ret) + GST_neighbours_notify_data_sent (sender, + sender_address, session, + pong->header.size); } } - if (ret != -1) + if (-1 != ret) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitted PONG to `%s' via reliable mechanism\n", @@ -1104,7 +1214,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, ("# PONGs unicast via reliable transport"), 1, GNUNET_NO); GNUNET_free (pong); - return; + return GNUNET_OK; } /* no reliable method found, try transmission via all known addresses */ @@ -1112,13 +1222,15 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, gettext_noop ("# PONGs multicast to all available addresses"), 1, GNUNET_NO); - GST_validation_get_addresses (sender, &multicast_pong, pong); + GST_validation_get_addresses (sender, + &multicast_pong, pong); GNUNET_free (pong); + return GNUNET_OK; } /** - * Context for the 'validate_address' function + * Context for the #validate_address_iterator() function */ struct ValidateAddressContext { @@ -1130,7 +1242,8 @@ struct ValidateAddressContext /** * Public key of the peer whose address is being validated. */ - struct GNUNET_CRYPTO_EccPublicKeyBinaryEncoded public_key; + struct GNUNET_CRYPTO_EddsaPublicKey public_key; + }; @@ -1138,10 +1251,10 @@ struct ValidateAddressContext * 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 cls pointer to a `struct ValidateAddressContext *` * @param address the address * @param expiration expiration time - * @return GNUNET_OK (keep the address) + * @return #GNUNET_OK (keep the address) */ static int validate_address_iterator (void *cls, @@ -1151,11 +1264,20 @@ validate_address_iterator (void *cls, const struct ValidateAddressContext *vac = cls; struct ValidationEntry *ve; - if (GNUNET_TIME_absolute_get_remaining (expiration).rel_value == 0) + if (0 == GNUNET_TIME_absolute_get_remaining (expiration).rel_value_us) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Skipping expired address from HELLO\n"); return GNUNET_OK; /* expired */ + } ve = find_validation_entry (&vac->public_key, address); if (GNUNET_SCHEDULER_NO_TASK == ve->revalidation_task) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Validation process started for fresh address `%s'\n", + GST_plugins_a2s (ve->address)); ve->revalidation_task = GNUNET_SCHEDULER_add_now (&revalidate_address, ve); + } return GNUNET_OK; } @@ -1163,19 +1285,21 @@ validate_address_iterator (void *cls, /** * Add the validated peer address to the HELLO. * - * @param cls the 'struct ValidationEntry' with the validated address - * @param max space in buf + * @param cls the `struct ValidationEntry *` with the validated address + * @param max space in @a buf * @param buf where to add the address - * @return number of bytes written, 0 to signal the + * @return number of bytes written, #GNUNET_SYSERR to signal the * end of the iteration. */ -static size_t -add_valid_peer_address (void *cls, size_t max, void *buf) +static ssize_t +add_valid_peer_address (void *cls, + size_t max, + void *buf) { struct ValidationEntry *ve = cls; if (GNUNET_YES == ve->copied) - return 0; /* terminate */ + return GNUNET_SYSERR; /* Done */ ve->copied = GNUNET_YES; return GNUNET_HELLO_add_address (ve->address, ve->valid_until, buf, max); } @@ -1187,8 +1311,9 @@ add_valid_peer_address (void *cls, size_t max, void *buf) * * @param sender peer sending the PONG * @param hdr the PONG + * @return #GNUNET_OK if the message was fine, #GNUNET_SYSERR on serious error */ -void +int GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, const struct GNUNET_MessageHeader *hdr) { @@ -1207,7 +1332,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, if (ntohs (hdr->size) < sizeof (struct TransportPongMessage)) { GNUNET_break_op (0); - return; + return GNUNET_SYSERR; } GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# PONG messages received"), 1, @@ -1223,7 +1348,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, if (NULL == addr) { GNUNET_break_op (0); - return; + return GNUNET_SYSERR; } addr++; slen = strlen (tname) + 1; @@ -1232,6 +1357,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, address.address = addr; address.address_length = addrlen; address.transport_name = tname; + address.local_info = GNUNET_HELLO_ADDRESS_INFO_NONE; ve = find_validation_entry (NULL, &address); if ((NULL == ve) || (GNUNET_NO == ve->expecting_pong)) { @@ -1239,61 +1365,70 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, gettext_noop ("# PONGs dropped, no matching pending validation"), 1, GNUNET_NO); - return; + return GNUNET_OK; } /* now check that PONG is well-formed */ if (0 != memcmp (&ve->pid, sender, sizeof (struct GNUNET_PeerIdentity))) { GNUNET_break_op (0); - return; + return GNUNET_SYSERR; } if (GNUNET_TIME_absolute_get_remaining - (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0) + (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value_us == 0) { GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# PONGs dropped, signature expired"), 1, GNUNET_NO); - return; + return GNUNET_SYSERR; } sig_res = GNUNET_SYSERR; do_verify = GNUNET_YES; - if (0 != GNUNET_TIME_absolute_get_remaining(ve->pong_sig_valid_until).rel_value) + if (0 != GNUNET_TIME_absolute_get_remaining (ve->pong_sig_valid_until).rel_value_us) { - /* We have a cached and valid signature for this peer, - * try to compare instead of verify */ - if (0 == memcmp (&ve->pong_sig_cache, &pong->signature, sizeof (struct GNUNET_CRYPTO_EccSignature))) - { - /* signatures are identical, we can skip verification */ - sig_res = GNUNET_OK; - do_verify = GNUNET_NO; - } - else - { - sig_res = GNUNET_SYSERR; - /* signatures do not match, we have to verify */ - } + /* We have a cached and valid signature for this peer, + * try to compare instead of verify */ + if (0 == memcmp (&ve->pong_sig_cache, &pong->signature, sizeof (struct GNUNET_CRYPTO_EddsaSignature))) + { + /* signatures are identical, we can skip verification */ + sig_res = GNUNET_OK; + do_verify = GNUNET_NO; + } + else + { + sig_res = GNUNET_SYSERR; + /* signatures do not match, we have to verify */ + } } if (GNUNET_YES == do_verify) { - /* Do expensive verification */ - sig_res = GNUNET_CRYPTO_ecc_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, - &pong->purpose, &pong->signature, - &ve->public_key); - if (sig_res == GNUNET_SYSERR) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Failed to verify: invalid signature on address %s:%s from peer `%s'\n", - tname, GST_plugins_a2s (ve->address),GNUNET_i2s (sender)); + /* Do expensive verification */ + sig_res = GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN, + &pong->purpose, &pong->signature, + &ve->public_key); + if (sig_res == GNUNET_SYSERR) + { + GNUNET_break_op (0); + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + "Failed to verify: invalid signature on address `%s':%s from peer `%s'\n", + tname, + GST_plugins_a2s (ve->address), + GNUNET_i2s (sender)); + } } - if (sig_res == GNUNET_SYSERR) - return; + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Address validated for peer `%s' with plugin `%s': `%s'\n", - GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address)); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Validation process successful for peer `%s' with plugin `%s' address `%s'\n", + GNUNET_i2s (sender), + tname, + GST_plugins_a2s (ve->address)); /* validity achieved, remember it! */ ve->expecting_pong = GNUNET_NO; ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); @@ -1302,27 +1437,36 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); { struct GNUNET_ATS_Information ats[2]; + ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY); - ats[0].value = htonl ((uint32_t) ve->latency.rel_value); + ats[0].value = htonl ((uint32_t) ve->latency.rel_value_us); ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE); ats[1].value = htonl ((uint32_t) ve->network); GNUNET_ATS_address_add (GST_ats, ve->address, NULL, ats, 2); } if (validations_running > 0) { - validations_running --; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Validation finished, %u validation processes running\n", - validations_running); + validations_running --; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Validation finished, %u validation processes running\n", + validations_running); } else - GNUNET_break (0); + { + GNUNET_break (0); + } + + /* Notify about new validity */ + validation_entry_changed (ve, GNUNET_TRANSPORT_VS_UPDATE); /* build HELLO to store in PEERINFO */ ve->copied = GNUNET_NO; - hello = GNUNET_HELLO_create (&ve->public_key, &add_valid_peer_address, ve, GNUNET_NO); + hello = GNUNET_HELLO_create (&ve->public_key, + &add_valid_peer_address, ve, + GNUNET_NO); GNUNET_PEERINFO_add_peer (GST_peerinfo, hello, NULL, NULL); GNUNET_free (hello); + return GNUNET_OK; } @@ -1331,8 +1475,9 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, * validation. * * @param hello the HELLO we received + * @return #GNUNET_OK if the message was fine, #GNUNET_SYSERR on serious error */ -void +int GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) { const struct GNUNET_HELLO_Message *hm = @@ -1342,19 +1487,25 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) int friend; friend = GNUNET_HELLO_is_friend_only (hm); - if (((GNUNET_YES != friend) && (GNUNET_NO != friend)) || - (GNUNET_OK != GNUNET_HELLO_get_id (hm, &vac.pid)) || - (GNUNET_OK != GNUNET_HELLO_get_key (hm, &vac.public_key))) + if ( ( (GNUNET_YES != friend) && + (GNUNET_NO != friend) ) || + (GNUNET_OK != GNUNET_HELLO_get_id (hm, &vac.pid)) || + (GNUNET_OK != GNUNET_HELLO_get_key (hm, &vac.public_key))) { /* malformed HELLO */ - GNUNET_break (0); - return; + GNUNET_break_op (0); + return GNUNET_SYSERR; } if (0 == memcmp (&GST_my_identity, &vac.pid, sizeof (struct GNUNET_PeerIdentity))) - return; + return GNUNET_OK; /* Add peer identity without addresses to peerinfo service */ h = GNUNET_HELLO_create (&vac.public_key, NULL, NULL, friend); + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Validation received new %s message for peer `%s' with size %u\n"), + "HELLO", + GNUNET_i2s (&vac.pid), + ntohs (hello->size)); GNUNET_PEERINFO_add_peer (GST_peerinfo, h, NULL, NULL); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, @@ -1366,11 +1517,12 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) GNUNET_HELLO_iterate_addresses (hm, GNUNET_NO, &validate_address_iterator, &vac)); + return GNUNET_OK; } /** - * Closure for 'iterate_addresses' + * Closure for #iterate_addresses(). */ struct IteratorContext { @@ -1380,7 +1532,7 @@ struct IteratorContext GST_ValidationAddressCallback cb; /** - * Closure for 'cb'. + * Closure for @e cb. */ void *cb_cls; @@ -1390,13 +1542,15 @@ struct IteratorContext /** * Call the callback in the closure for each validation entry. * - * @param cls the 'struct GST_ValidationIteratorContext' + * @param cls the `struct IteratorContext` * @param key the peer's identity - * @param value the 'struct ValidationEntry' - * @return GNUNET_OK (continue to iterate) + * @param value the `struct ValidationEntry` + * @return #GNUNET_OK (continue to iterate) */ static int -iterate_addresses (void *cls, const struct GNUNET_HashCode * key, void *value) +iterate_addresses (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) { struct IteratorContext *ic = cls; struct ValidationEntry *ve = value; @@ -1413,7 +1567,7 @@ iterate_addresses (void *cls, const struct GNUNET_HashCode * key, void *value) * * @param target peer information is requested for * @param cb function to call; will not be called after this function returns - * @param cb_cls closure for 'cb' + * @param cb_cls closure for @a cb */ void GST_validation_get_addresses (const struct GNUNET_PeerIdentity *target, @@ -1423,8 +1577,8 @@ GST_validation_get_addresses (const struct GNUNET_PeerIdentity *target, ic.cb = cb; ic.cb_cls = cb_cls; - GNUNET_CONTAINER_multihashmap_get_multiple (validation_map, - &target->hashPubKey, + GNUNET_CONTAINER_multipeermap_get_multiple (validation_map, + target, &iterate_addresses, &ic); } @@ -1436,15 +1590,13 @@ GST_validation_get_addresses (const struct GNUNET_PeerIdentity *target, * * @param address the address * @param session the session - * @param in_use GNUNET_YES if we are now using the address for a connection, - * GNUNET_NO if we are no longer using the address for a connection - * @param line line of caller just for DEBUGGING! + * @param in_use #GNUNET_YES if we are now using the address for a connection, + * #GNUNET_NO if we are no longer using the address for a connection */ void GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, struct Session *session, - int in_use, - int line) + int in_use) { struct ValidationEntry *ve; @@ -1463,28 +1615,17 @@ GST_validation_set_address_use (const struct GNUNET_HELLO_Address *address, if (GNUNET_YES == in_use) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error setting address in use for peer `%s' `%s' to USED: set last time by %i, called now by %i\n", - GNUNET_i2s (&address->peer), GST_plugins_a2s (address), - ve->last_line_set_to_yes, line); + "Error setting address in use for peer `%s' `%s' to USED\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); } if (GNUNET_NO == in_use) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error setting address in use for peer `%s' `%s' to NOT_USED: set last time by %i, called now by %i\n", - GNUNET_i2s (&address->peer), GST_plugins_a2s (address), - ve->last_line_set_to_no, line); + "Error setting address in use for peer `%s' `%s' to NOT_USED\n", + GNUNET_i2s (&address->peer), GST_plugins_a2s (address)); } } - if (GNUNET_YES == in_use) - { - ve->last_line_set_to_yes = line; - } - if (GNUNET_NO == in_use) - { - ve->last_line_set_to_no = line; - } - GNUNET_break (ve->in_use != in_use); /* should be different... */ ve->in_use = in_use; if (in_use == GNUNET_YES) @@ -1524,5 +1665,58 @@ GST_validation_get_address_latency (const struct GNUNET_PeerIdentity *sender, return ve->latency; } +/** + * Closure for the validation_entries_iterate function. + */ +struct ValidationIteratorContext +{ + /** + * Function to call on each validation entry + */ + GST_ValidationChangedCallback cb; + + /** + * Closure for @e cb. + */ + void *cb_cls; +}; + + +static int +validation_entries_iterate (void *cls, + const struct GNUNET_PeerIdentity *key, + void *value) +{ + struct ValidationIteratorContext *ic = cls; + struct ValidationEntry *ve = value; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Notifying about validation entry for peer `%s' address `%s' \n", + GNUNET_i2s (&ve->pid), GST_plugins_a2s (ve->address)); + ic->cb (ic->cb_cls, &ve->pid, ve->address, ve->send_time, + ve->valid_until, ve->next_validation, ve->state); + + return GNUNET_OK; +} + +/** + * Iterate over all iteration entries + * + * @param cb function to call + * @param cb_cls closure for cb + */ +void +GST_validation_iterate (GST_ValidationChangedCallback cb, + void *cb_cls) +{ + struct ValidationIteratorContext ic; + + if (NULL == validation_map) + return; /* can happen during shutdown */ + ic.cb = cb; + ic.cb_cls = cb_cls; + GNUNET_CONTAINER_multipeermap_iterate (validation_map, + &validation_entries_iterate, + &ic); +} /* end of file gnunet-service-transport_validation.c */