From 1f5249e010b9d850e8aa6b6b745e55902051ac2e Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Tue, 16 Mar 2010 14:11:54 +0000 Subject: [PATCH] stats --- src/transport/gnunet-service-transport.c | 624 ++++++++++++----------- src/transport/plugin_transport_tcp.c | 24 + 2 files changed, 346 insertions(+), 302 deletions(-) diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index 6899ef5fb..a8c3b99a9 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -23,6 +23,12 @@ * @brief low-level P2P messaging * @author Christian Grothoff * + * BUGS: + * - bi-directional nature of TCP is not exploited + * - re-validation is broken (triggered only on successful validation, + * does not consider expiration times + * + * * NOTE: * - This code uses 'GNUNET_a2s' for debug printing in many places, * which is technically wrong since it assumes we have IP+Port @@ -444,7 +450,9 @@ struct NeighbourList /** * ID of task scheduled to run when we should retry transmitting - * the head of the message queue. + * the head of the message queue. Actually triggered when the + * transmission is timing out (we trigger instantly when we have + * a chance of success). */ GNUNET_SCHEDULER_TaskIdentifier retry_task; @@ -1082,11 +1090,25 @@ transmit_send_continuation (void *cls, mq->specific_address->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); - mq->specific_address->connected = GNUNET_YES; + if (mq->specific_address->connected != GNUNET_YES) + { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connected addresses"), + 1, + GNUNET_NO); + mq->specific_address->connected = GNUNET_YES; + } } else { - mq->specific_address->connected = GNUNET_NO; + if (mq->specific_address->connected != GNUNET_NO) + { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connected addresses"), + -1, + GNUNET_NO); + mq->specific_address->connected = GNUNET_NO; + } } if (! mq->internal_msg) mq->specific_address->in_transmit = GNUNET_NO; @@ -1129,6 +1151,10 @@ find_ready_address(struct NeighbourList *neighbour) "Marking long-time inactive connection to `%4s' as down.\n", GNUNET_i2s (&neighbour->id)); #endif + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connected addresses"), + -1, + GNUNET_NO); addresses->connected = GNUNET_NO; } addresses = addresses->next; @@ -1150,14 +1176,21 @@ find_ready_address(struct NeighbourList *neighbour) } head = head->next; } -#if DEBUG_TRANSPORT if (best_address != NULL) { +#if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Best address found has latency of %llu ms.\n", best_address->latency.value); - } #endif + } + else + { + GNUNET_STATISTICS_update (stats, + gettext_noop ("# transmission attempts failed (no validated address)"), + 1, + GNUNET_NO); + } return best_address; } @@ -1225,6 +1258,10 @@ try_transmission_to_peer (struct NeighbourList *neighbour) GNUNET_free (mq); return; /* nobody ready */ } + GNUNET_STATISTICS_update (stats, + gettext_noop ("# message delivery deferred (no validated address)"), + 1, + GNUNET_NO); if (neighbour->retry_task != GNUNET_SCHEDULER_NO_TASK) GNUNET_SCHEDULER_cancel (sched, neighbour->retry_task); @@ -1784,184 +1821,91 @@ add_validated_address (void *cls, } -static void send_periodic_ping(void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc); + +/** + * Closure for 'check_address_exists'. + */ +struct CheckAddressExistsClosure +{ + /** + * Address to check for. + */ + const void *addr; + + /** + * Name of the transport. + */ + const char *tname; + + /** + * Length of addr. + */ + size_t addrlen; + + /** + * Set to GNUNET_YES if the address exists. + */ + int exists; +}; /** - * Iterator over hash map entries. Checks if the given validation - * entry is for the same challenge as what is given in the PONG. + * Iterator over hash map entries. Checks if the given + * validation entry is for the same address as what is given + * in the closure. * - * @param cls the 'struct TransportPongMessage*' - * @param key peer identity + * @param cls the 'struct CheckAddressExistsClosure*' + * @param key current key code (ignored) * @param value value in the hash map ('struct ValidationEntry') * @return GNUNET_YES if we should continue to * iterate (mismatch), GNUNET_NO if not (entry matched) */ static int -check_pending_validation (void *cls, - const GNUNET_HashCode * key, - void *value) +check_address_exists (void *cls, + const GNUNET_HashCode * key, + void *value) { - const struct TransportPongMessage *pong = cls; + struct CheckAddressExistsClosure *caec = cls; struct ValidationEntry *ve = value; - struct AddValidatedAddressContext avac; - unsigned int challenge = ntohl(pong->challenge); - struct GNUNET_HELLO_Message *hello; - struct GNUNET_PeerIdentity target; - struct NeighbourList *n; - struct ForeignAddressList *fal; - struct PeriodicValidationContext *periodic_validation_context; - - if (ve->challenge != challenge) - return GNUNET_YES; - -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", - GNUNET_h2s (key), - GNUNET_a2s ((const struct sockaddr *) ve->addr, - ve->addrlen), - ve->transport_name); -#endif - GNUNET_STATISTICS_update (stats, - gettext_noop ("# address validation successes"), - 1, - GNUNET_NO); - /* create the updated HELLO */ - GNUNET_CRYPTO_hash (&ve->publicKey, - sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &target.hashPubKey); - avac.done = GNUNET_NO; - avac.ve = ve; - hello = GNUNET_HELLO_create (&ve->publicKey, - &add_validated_address, - &avac); - GNUNET_PEERINFO_add_peer (cfg, sched, - &target, - hello); - GNUNET_free (hello); - n = find_neighbour (&target); - if (n != NULL) + if ( (0 == strcmp (caec->tname, + ve->transport_name)) && + (caec->addrlen == ve->addrlen) && + (0 == memcmp (caec->addr, + ve->addr, + caec->addrlen)) ) { - fal = add_peer_address (n, - ve->transport_name, - ve->addr, - ve->addrlen); - GNUNET_assert (fal != NULL); - fal->expires = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); - fal->validated = GNUNET_YES; - fal->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); - periodic_validation_context = GNUNET_malloc(sizeof(struct PeriodicValidationContext)); - periodic_validation_context->foreign_address = fal; - periodic_validation_context->transport = strdup(ve->transport_name); - memcpy(&periodic_validation_context->publicKey, - &ve->publicKey, - sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); - /* FIXME: this causes all of the revalidation PINGs for the same HELLO - to be transmitted in bulk, which is not nice; also, - triggering these HERE means that revalidations do NOT happen AT ALL - for HELLOs a previous instance of this process validated (since - there is no "initial" validation PING => no revalidation => BUG! */ - fal->revalidate_task = GNUNET_SCHEDULER_add_delayed(sched, - TRANSPORT_DEFAULT_REVALIDATION, - &send_periodic_ping, - periodic_validation_context); - if (n->latency.value == GNUNET_TIME_UNIT_FOREVER_REL.value) - n->latency = fal->latency; - else - n->latency.value = (fal->latency.value + n->latency.value) / 2; - n->distance = fal->distance; - if (GNUNET_NO == n->received_pong) - { - notify_clients_connect (&target, n->latency, n->distance); - n->received_pong = GNUNET_YES; - } - if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (sched, - n->retry_task); - n->retry_task = GNUNET_SCHEDULER_NO_TASK; - try_transmission_to_peer (n); - } + caec->exists = GNUNET_YES; + return GNUNET_NO; } - - /* clean up validation entry */ - GNUNET_assert (GNUNET_YES == - GNUNET_CONTAINER_multihashmap_remove (validation_map, - key, - ve)); - GNUNET_SCHEDULER_cancel (sched, - ve->timeout_task); - GNUNET_free (ve->transport_name); - GNUNET_free (ve); - return GNUNET_NO; + return GNUNET_YES; } /** - * Function that will be called if we receive a validation - * of an address challenge that we transmitted to another - * peer. Note that the validation should only be considered - * acceptable if the challenge matches AND if the sender - * address is at least a plausible address for this peer - * (otherwise we may be seeing a MiM attack). + * HELLO validation cleanup task (validation failed). * - * @param cls closure - * @param message the pong message - * @param peer who responded to our challenge - * @param sender_address string describing our sender address (as observed - * by the other peer in binary format) - * @param sender_address_len number of bytes in 'sender_address' + * @param cls the 'struct ValidationEntry' that failed + * @param tc scheduler context (unused) */ static void -handle_pong (void *cls, const struct GNUNET_MessageHeader *message, - const struct GNUNET_PeerIdentity *peer, - const char *sender_address, - size_t sender_address_len) +timeout_hello_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { -#if DEBUG_TRANSPORT > 1 - /* we get tons of these that just get discarded, only log - if we are quite verbose */ - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Receiving `%s' message from `%4s'.\n", "PONG", - GNUNET_i2s (peer)); -#endif + struct ValidationEntry *va = cls; + struct GNUNET_PeerIdentity pid; + GNUNET_STATISTICS_update (stats, - gettext_noop ("# PONG messages received"), + gettext_noop ("# address validation timeouts"), 1, GNUNET_NO); - if (GNUNET_SYSERR != - GNUNET_CONTAINER_multihashmap_get_multiple (validation_map, - &peer->hashPubKey, - &check_pending_validation, - (void*) message)) - { - /* This is *expected* to happen a lot since we send - PONGs to *all* known addresses of the sender of - the PING, so most likely we get multiple PONGs - per PING, and all but the first PONG will end up - here. So really we should not print anything here - unless we want to be very, very verbose... */ -#if DEBUG_TRANSPORT > 2 - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Received `%s' message from `%4s' but have no record of a matching `%s' message. Ignoring.\n", - "PONG", - GNUNET_i2s (peer), - "PING"); -#endif - return; - } - -#if 0 - /* FIXME: add given address to potential pool of our addresses - (for voting) */ - GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, - _("Another peer saw us using the address `%s' via `%s'.\n"), - GNUNET_a2s ((const struct sockaddr *) &pong[1], - ntohs(pong->addrlen)), - va->transport_name); -#endif + GNUNET_CRYPTO_hash (&va->publicKey, + sizeof (struct + GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &pid.hashPubKey); + GNUNET_CONTAINER_multihashmap_remove (validation_map, + &pid.hashPubKey, + va); + GNUNET_free (va->transport_name); + GNUNET_free (va); } @@ -2000,6 +1944,10 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer) struct ReadyList *rl; GNUNET_assert (our_hello != NULL); + GNUNET_STATISTICS_update (stats, + gettext_noop ("# active neighbours"), + 1, + GNUNET_NO); n = GNUNET_malloc (sizeof (struct NeighbourList)); n->next = neighbours; neighbours = n; @@ -2037,123 +1985,38 @@ setup_new_neighbour (const struct GNUNET_PeerIdentity *peer) /** - * Closure for 'check_address_exists'. + * Send periodic PING messages to a give foreign address. + * + * @param cls our 'struct PeriodicValidationContext*' + * @param tc task context */ -struct CheckAddressExistsClosure +static void +send_periodic_ping (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - /** - * Address to check for. - */ - const void *addr; + struct PeriodicValidationContext *pvc = cls; + struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded publicKey = pvc->publicKey; + char *tname = pvc->transport; + const void *addr = pvc->foreign_address->addr; + size_t addrlen = pvc->foreign_address->addrlen; + struct GNUNET_PeerIdentity id; + struct TransportPlugin *tp; + struct ValidationEntry *va; + struct NeighbourList *neighbour; + struct ForeignAddressList *peer_address; + struct TransportPingMessage ping; + struct CheckAddressExistsClosure caec; + char * message_buf; + uint16_t hello_size; + size_t tsize; - /** - * Name of the transport. - */ - const char *tname; - - /** - * Length of addr. - */ - size_t addrlen; - - /** - * Set to GNUNET_YES if the address exists. - */ - int exists; -}; - - -/** - * Iterator over hash map entries. Checks if the given - * validation entry is for the same address as what is given - * in the closure. - * - * @param cls the 'struct CheckAddressExistsClosure*' - * @param key current key code (ignored) - * @param value value in the hash map ('struct ValidationEntry') - * @return GNUNET_YES if we should continue to - * iterate (mismatch), GNUNET_NO if not (entry matched) - */ -static int -check_address_exists (void *cls, - const GNUNET_HashCode * key, - void *value) -{ - struct CheckAddressExistsClosure *caec = cls; - struct ValidationEntry *ve = value; - if ( (0 == strcmp (caec->tname, - ve->transport_name)) && - (caec->addrlen == ve->addrlen) && - (0 == memcmp (caec->addr, - ve->addr, - caec->addrlen)) ) + GNUNET_free (pvc); + if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) { - caec->exists = GNUNET_YES; - return GNUNET_NO; + /* We have been shutdown, don't do anything! */ + GNUNET_free (tname); + return; } - return GNUNET_YES; -} - - -/** - * HELLO validation cleanup task (validation failed). - * - * @param cls the 'struct ValidationEntry' that failed - * @param tc scheduler context (unused) - */ -static void -timeout_hello_validation (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct ValidationEntry *va = cls; - struct GNUNET_PeerIdentity pid; - - GNUNET_STATISTICS_update (stats, - gettext_noop ("# address validation timeouts"), - 1, - GNUNET_NO); - GNUNET_CRYPTO_hash (&va->publicKey, - sizeof (struct - GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), - &pid.hashPubKey); - GNUNET_CONTAINER_multihashmap_remove (validation_map, - &pid.hashPubKey, - va); - GNUNET_free (va->transport_name); - GNUNET_free (va); -} - - -/** - * Check if the given address is already being validated; if not, - * append the given address to the list of entries that are being be - * validated and initiate validation. - * - * @param cls closure ('struct PeriodicValidationContext *') - * @param tname name of the transport - * @param expiration expiration time - * @param addr the address - * @param addrlen length of the address - * @return GNUNET_OK (always) - */ -static int -rerun_validation (void *cls, - const char *tname, - struct GNUNET_TIME_Absolute expiration, - const void *addr, size_t addrlen) -{ - struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *publicKey = cls; - struct GNUNET_PeerIdentity id; - struct TransportPlugin *tp; - struct ValidationEntry *va; - struct NeighbourList *neighbour; - struct ForeignAddressList *peer_address; - struct TransportPingMessage ping; - /*struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pk;*/ - struct CheckAddressExistsClosure caec; - char * message_buf; - uint16_t hello_size; - size_t tsize; - tp = find_transport (tname); if (tp == NULL) { @@ -2162,10 +2025,11 @@ rerun_validation (void *cls, _ ("Transport `%s' not loaded, will not try to validate peer address using this transport.\n"), tname); - return GNUNET_OK; + GNUNET_free (tname); + return; } - GNUNET_CRYPTO_hash (publicKey, + GNUNET_CRYPTO_hash (&publicKey, sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), &id.hashPubKey); @@ -2189,17 +2053,18 @@ rerun_validation (void *cls, tname, GNUNET_i2s (&id)); #endif - return GNUNET_OK; + GNUNET_free (tname); + return; } va = GNUNET_malloc (sizeof (struct ValidationEntry) + addrlen); - va->transport_name = GNUNET_strdup (tname); + va->transport_name = tname; va->challenge = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, (unsigned int) -1); va->send_time = GNUNET_TIME_absolute_get(); va->addr = (const void*) &va[1]; memcpy (&va[1], addr, addrlen); va->addrlen = addrlen; - memcpy(&va->publicKey, publicKey, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + memcpy(&va->publicKey, &publicKey, sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); va->timeout_task = GNUNET_SCHEDULER_add_delayed (sched, HELLO_VERIFICATION_TIMEOUT, &timeout_hello_validation, @@ -2243,40 +2108,183 @@ rerun_validation (void *cls, message_buf, tsize, GNUNET_YES, neighbour); GNUNET_free(message_buf); - return GNUNET_OK; } /** - * Send periodic ping messages to a give foreign address. - * - * cls closure, can be safely cast to ForeignAddressList - * tc task context + * Iterator over hash map entries. Checks if the given validation + * entry is for the same challenge as what is given in the PONG. * - * FIXME: Since a _billion_ pongs are sent for every ping, - * maybe this should be a special message type or something - * that gets discarded on the other side instead of initiating - * a flood. + * @param cls the 'struct TransportPongMessage*' + * @param key peer identity + * @param value value in the hash map ('struct ValidationEntry') + * @return GNUNET_YES if we should continue to + * iterate (mismatch), GNUNET_NO if not (entry matched) */ -static void -send_periodic_ping (void *cls, - const struct GNUNET_SCHEDULER_TaskContext *tc) +static int +check_pending_validation (void *cls, + const GNUNET_HashCode * key, + void *value) { - struct PeriodicValidationContext *periodic_validation_context = cls; + const struct TransportPongMessage *pong = cls; + struct ValidationEntry *ve = value; + struct AddValidatedAddressContext avac; + unsigned int challenge = ntohl(pong->challenge); + struct GNUNET_HELLO_Message *hello; + struct GNUNET_PeerIdentity target; + struct NeighbourList *n; + struct ForeignAddressList *fal; + struct PeriodicValidationContext *periodic_validation_context; - if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) + if (ve->challenge != challenge) + return GNUNET_YES; + +#if DEBUG_TRANSPORT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Confirmed validity of address, peer `%4s' has address `%s' (%s).\n", + GNUNET_h2s (key), + GNUNET_a2s ((const struct sockaddr *) ve->addr, + ve->addrlen), + ve->transport_name); +#endif + GNUNET_STATISTICS_update (stats, + gettext_noop ("# address validation successes"), + 1, + GNUNET_NO); + /* create the updated HELLO */ + GNUNET_CRYPTO_hash (&ve->publicKey, + sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), + &target.hashPubKey); + avac.done = GNUNET_NO; + avac.ve = ve; + hello = GNUNET_HELLO_create (&ve->publicKey, + &add_validated_address, + &avac); + GNUNET_PEERINFO_add_peer (cfg, sched, + &target, + hello); + GNUNET_free (hello); + n = find_neighbour (&target); + if (n != NULL) { - GNUNET_free(periodic_validation_context->transport); - GNUNET_free(periodic_validation_context); - return; /* We have been shutdown, don't do anything! */ - } - rerun_validation(&periodic_validation_context->publicKey, - periodic_validation_context->transport, - periodic_validation_context->foreign_address->expires, - periodic_validation_context->foreign_address->addr, - periodic_validation_context->foreign_address->addrlen); - GNUNET_free(periodic_validation_context->transport); - GNUNET_free(periodic_validation_context); + fal = add_peer_address (n, + ve->transport_name, + ve->addr, + ve->addrlen); + GNUNET_assert (fal != NULL); + fal->expires = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); + fal->validated = GNUNET_YES; + fal->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); + periodic_validation_context = GNUNET_malloc(sizeof(struct PeriodicValidationContext)); + periodic_validation_context->foreign_address = fal; + periodic_validation_context->transport = strdup(ve->transport_name); + memcpy(&periodic_validation_context->publicKey, + &ve->publicKey, + sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded)); + /* FIXME: this causes all of the revalidation PINGs for the same HELLO + to be transmitted in bulk, which is not nice; also, + triggering these HERE means that revalidations do NOT happen AT ALL + for HELLOs a previous instance of this process validated (since + there is no "initial" validation PING => no revalidation => BUG! */ + fal->revalidate_task = GNUNET_SCHEDULER_add_delayed(sched, + TRANSPORT_DEFAULT_REVALIDATION, + &send_periodic_ping, + periodic_validation_context); + if (n->latency.value == GNUNET_TIME_UNIT_FOREVER_REL.value) + n->latency = fal->latency; + else + n->latency.value = (fal->latency.value + n->latency.value) / 2; + n->distance = fal->distance; + if (GNUNET_NO == n->received_pong) + { + notify_clients_connect (&target, n->latency, n->distance); + n->received_pong = GNUNET_YES; + } + if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (sched, + n->retry_task); + n->retry_task = GNUNET_SCHEDULER_NO_TASK; + try_transmission_to_peer (n); + } + } + + /* clean up validation entry */ + GNUNET_assert (GNUNET_YES == + GNUNET_CONTAINER_multihashmap_remove (validation_map, + key, + ve)); + GNUNET_SCHEDULER_cancel (sched, + ve->timeout_task); + GNUNET_free (ve->transport_name); + GNUNET_free (ve); + return GNUNET_NO; +} + + +/** + * Function that will be called if we receive a validation + * of an address challenge that we transmitted to another + * peer. Note that the validation should only be considered + * acceptable if the challenge matches AND if the sender + * address is at least a plausible address for this peer + * (otherwise we may be seeing a MiM attack). + * + * @param cls closure + * @param message the pong message + * @param peer who responded to our challenge + * @param sender_address string describing our sender address (as observed + * by the other peer in binary format) + * @param sender_address_len number of bytes in 'sender_address' + */ +static void +handle_pong (void *cls, const struct GNUNET_MessageHeader *message, + const struct GNUNET_PeerIdentity *peer, + const char *sender_address, + size_t sender_address_len) +{ +#if DEBUG_TRANSPORT > 1 + /* we get tons of these that just get discarded, only log + if we are quite verbose */ + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Receiving `%s' message from `%4s'.\n", "PONG", + GNUNET_i2s (peer)); +#endif + GNUNET_STATISTICS_update (stats, + gettext_noop ("# PONG messages received"), + 1, + GNUNET_NO); + if (GNUNET_SYSERR != + GNUNET_CONTAINER_multihashmap_get_multiple (validation_map, + &peer->hashPubKey, + &check_pending_validation, + (void*) message)) + { + /* This is *expected* to happen a lot since we send + PONGs to *all* known addresses of the sender of + the PING, so most likely we get multiple PONGs + per PING, and all but the first PONG will end up + here. So really we should not print anything here + unless we want to be very, very verbose... */ +#if DEBUG_TRANSPORT > 2 + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Received `%s' message from `%4s' but have no record of a matching `%s' message. Ignoring.\n", + "PONG", + GNUNET_i2s (peer), + "PING"); +#endif + return; + } + +#if 0 + /* FIXME: add given address to potential pool of our addresses + (for voting) */ + GNUNET_log (GNUNET_ERROR_TYPE_INFO | GNUNET_ERROR_TYPE_BULK, + _("Another peer saw us using the address `%s' via `%s'.\n"), + GNUNET_a2s ((const struct sockaddr *) &pong[1], + ntohs(pong->addrlen)), + va->transport_name); +#endif } @@ -2698,11 +2706,15 @@ disconnect_neighbour (struct NeighbourList *n, int check) { n->plugins = rpos->next; rpos->plugin->api->disconnect (rpos->plugin->api->cls, &n->id); - while (rpos->addresses != NULL) { peer_pos = rpos->addresses; rpos->addresses = peer_pos->next; + if (peer_pos->connected == GNUNET_YES) + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connected addresses"), + -1, + GNUNET_NO); GNUNET_free(peer_pos); } GNUNET_free (rpos); @@ -2738,6 +2750,10 @@ disconnect_neighbour (struct NeighbourList *n, int check) n->retry_task = GNUNET_SCHEDULER_NO_TASK; } /* finally, free n itself */ + GNUNET_STATISTICS_update (stats, + gettext_noop ("# active neighbours"), + -1, + GNUNET_NO); GNUNET_free (n); } @@ -2884,6 +2900,10 @@ plugin_env_receive (void *cls, const struct GNUNET_PeerIdentity *peer, { peer_address->connected = GNUNET_YES; peer_address->connect_attempts++; + GNUNET_STATISTICS_update (stats, + gettext_noop ("# connected addresses"), + 1, + GNUNET_NO); } peer_address->timeout = diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index a08d98625..e1bb0c7e9 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c @@ -308,6 +308,10 @@ create_session (struct Plugin *plugin, welcome.clientIdentity = *plugin->env->my_identity; memcpy (&pm[1], &welcome, sizeof (welcome)); pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS; + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + pm->message_size, + GNUNET_NO); GNUNET_CONTAINER_DLL_insert (ret->pending_messages_head, ret->pending_messages_tail, pm); @@ -370,6 +374,10 @@ do_transmit (void *cls, size_t size, void *buf) pm->message_size, GNUNET_i2s (&session->target)); #endif + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + -pm->message_size, + GNUNET_NO); GNUNET_STATISTICS_update (session->plugin->env->stats, gettext_noop ("# bytes discarded by TCP (timeout)"), pm->message_size, @@ -394,6 +402,10 @@ do_transmit (void *cls, size_t size, void *buf) GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, session->pending_messages_tail, pm); + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + -pm->message_size, + GNUNET_NO); if (pm->transmit_cont != NULL) pm->transmit_cont (pm->transmit_cont_cls, &session->target, GNUNET_OK); @@ -490,6 +502,14 @@ disconnect_session (struct Session *session) "Could not deliver message to `%4s', notifying.\n", GNUNET_i2s (&session->target)); #endif + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + -pm->message_size, + GNUNET_NO); + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes discarded by TCP (disconnect)"), + pm->message_size, + GNUNET_NO); GNUNET_CONTAINER_DLL_remove (session->pending_messages_head, session->pending_messages_tail, pm); @@ -673,6 +693,10 @@ tcp_plugin_send (void *cls, GNUNET_assert (session != NULL); GNUNET_assert (session->client != NULL); + GNUNET_STATISTICS_update (plugin->env->stats, + gettext_noop ("# bytes currently in TCP buffers"), + msgbuf_size, + GNUNET_NO); /* create new message entry */ pm = GNUNET_malloc (sizeof (struct PendingMessage) + msgbuf_size); pm->msg = (const char*) &pm[1]; -- 2.25.1