From 4dca0c9b28d2115a936b05582618f2285022089a Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 7 Aug 2011 14:19:27 +0000 Subject: [PATCH] stuff --- .../gnunet-service-transport_neighbours.c | 185 +++++------------ .../gnunet-service-transport_neighbours.h | 23 --- .../gnunet-service-transport_validation.c | 190 ++++++------------ 3 files changed, 105 insertions(+), 293 deletions(-) diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index ab82153dd..6be718d91 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -216,6 +216,12 @@ struct NeighbourMapEntry */ int in_disconnect; + /** + * Do we currently consider this neighbour connected? (as far as + * the connect/disconnect callbacks are concerned)? + */ + int is_connected; + }; @@ -264,11 +270,9 @@ lookup_neighbour (const struct GNUNET_PeerIdentity *pid) static void try_transmission_to_peer (struct NeighbourMapEntry *n) { - struct ReadyList *rl; struct MessageQueue *mq; struct GNUNET_TIME_Relative timeout; ssize_t ret; - int force_address; if (n->messages_head == NULL) { @@ -279,115 +283,21 @@ try_transmission_to_peer (struct NeighbourMapEntry *n) #endif return; /* nothing to do */ } - rl = NULL; mq = n->messages_head; - force_address = GNUNET_YES; - if (mq->specific_address == NULL) - { - /* TODO: ADD ATS */ - mq->specific_address = get_preferred_ats_address(n); - GNUNET_STATISTICS_update (stats, - gettext_noop ("# transport selected peer address freely"), - 1, - GNUNET_NO); - force_address = GNUNET_NO; - } - if (mq->specific_address == NULL) - { - GNUNET_STATISTICS_update (stats, - gettext_noop ("# transport failed to selected peer address"), - 1, - GNUNET_NO); - timeout = GNUNET_TIME_absolute_get_remaining (mq->timeout); - if (timeout.rel_value == 0) - { -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No destination address available to transmit message of size %u to peer `%4s'\n", - mq->message_buf_size, - GNUNET_i2s (&mq->neighbour_id)); -#endif - GNUNET_STATISTICS_update (stats, - gettext_noop ("# bytes in message queue for other peers"), - - (int64_t) mq->message_buf_size, - GNUNET_NO); - GNUNET_STATISTICS_update (stats, - gettext_noop ("# bytes discarded (no destination address available)"), - mq->message_buf_size, - GNUNET_NO); - if (mq->client != NULL) - transmit_send_ok (mq->client, n, &n->id, GNUNET_NO); - GNUNET_CONTAINER_DLL_remove (n->messages_head, - n->messages_tail, - mq); - GNUNET_free (mq); - return; /* nobody ready */ - } - GNUNET_STATISTICS_update (stats, - gettext_noop ("# message delivery deferred (no address)"), - 1, - GNUNET_NO); - if (n->retry_task != GNUNET_SCHEDULER_NO_TASK) - GNUNET_SCHEDULER_cancel (n->retry_task); - n->retry_task = GNUNET_SCHEDULER_add_delayed (timeout, - &retry_transmission_task, - n); -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "No validated destination address available to transmit message of size %u to peer `%4s', will wait %llums to find an address.\n", - mq->message_buf_size, - GNUNET_i2s (&mq->neighbour_id), - timeout.rel_value); -#endif - /* FIXME: might want to trigger peerinfo lookup here - (unless that's already pending...) */ - return; - } GNUNET_CONTAINER_DLL_remove (n->messages_head, n->messages_tail, mq); - if (mq->specific_address->connected == GNUNET_NO) - mq->specific_address->connect_attempts++; - rl = mq->specific_address->ready_list; - mq->plugin = rl->plugin; - if (!mq->internal_msg) - mq->specific_address->in_transmit = GNUNET_YES; -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending message of size %u for `%4s' to `%s' via plugin `%s'\n", - mq->message_buf_size, - GNUNET_i2s (&n->id), - (mq->specific_address->addr != NULL) - ? a2s (mq->plugin->short_name, - mq->specific_address->addr, - mq->specific_address->addrlen) - : "", - rl->plugin->short_name); -#endif - GNUNET_STATISTICS_update (stats, - gettext_noop ("# bytes in message queue for other peers"), - - (int64_t) mq->message_buf_size, - GNUNET_NO); - GNUNET_STATISTICS_update (stats, - gettext_noop ("# bytes pending with plugins"), - mq->message_buf_size, - GNUNET_NO); - - GNUNET_CONTAINER_DLL_insert (n->cont_head, - n->cont_tail, - mq); - - ret = rl->plugin->api->send (rl->plugin->api->cls, - &mq->neighbour_id, - mq->message_buf, - mq->message_buf_size, - mq->priority, - GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, - mq->specific_address->session, - mq->specific_address->addr, - mq->specific_address->addrlen, - force_address, - &transmit_send_continuation, mq); + ret = papi->send (papi->cls, + &n->pid, + mq->message_buf, + mq->message_buf_size, + mq->priority, + GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + n->session, + n->addr, + n->addrlen, + GNUNET_YES /*?*/, + &transmit_send_continuation, mq); if (ret == -1) { /* failure, but 'send' would not call continuation in this case, @@ -776,32 +686,6 @@ GST_neighbours_iterate (GST_NeighbourIterator cb, } -/** - * We have received a PONG. Update lifeness of the neighbour. - * - * @param sender peer sending the PONG - * @param hdr the PONG message (presumably) - * @param plugin_name name of transport that delivered the PONG - * @param sender_address address of the other peer, NULL if other peer - * connected to us - * @param sender_address_len number of bytes in sender_address - * @param ats performance data - * @param ats_count number of entries in ats (excluding 0-termination) - * @return GNUNET_OK if the message was well-formed, GNUNET_SYSERR if not - */ -int -GST_neighbours_handle_pong (const struct GNUNET_PeerIdentity *sender, - const struct GNUNET_MessageHeader *hdr, - const char *plugin_name, - const void *sender_address, - size_t sender_address_len, - const struct GNUNET_TRANSPORT_ATS_Information *ats, - uint32_t ats_count) -{ - return GNUNET_SYSERR; -} - - /** * We have received a CONNECT. Set the peer to connected. * @@ -836,10 +720,14 @@ GST_neighbours_handle_connect (const struct GNUNET_PeerIdentity *sender, } n = lookup_neighbour (sender); if ( (NULL != n) || - (GNUNET_TIME_absolute_get_remaining (n->peer_timeout).rel_value > 0) ) + (n->is_connected == GNUNET_YES) ) { /* already connected */ - // FIXME: switch session!? + if (session != NULL) + { + // FIXME: ATS: switch session!? + // FIXME: merge/update ats? + } return GNUNET_OK; } if (n == NULL) @@ -858,9 +746,32 @@ GST_neighbours_handle_connect (const struct GNUNET_PeerIdentity *sender, &n->id.hashPubKey, n, GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); + if (NULL == ats) + { + GNUNET_array_grow (n->ats, + n->ats_count, + 1); + } + else + { + GNUNET_array_grow (n->ats, + n->ats_count, + ats_count); + memcpy (n->ats, + ats, + sizeof (struct GNUNET_TRANSPORT_ATS_Information) * ats_count); + } } - // FIXME: mark connected, etc? - + if (session != NULL) + { + // FIXME: ATS: switch session!? + // n->session = session; + } + n->is_connected = GNUNET_YES; + connect_notify_cb (callback_cls, + sender, + n->ats, + n->ats_count); return GNUNET_OK; } diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h index 1b0a98a2b..8ccf3cb67 100644 --- a/src/transport/gnunet-service-transport_neighbours.h +++ b/src/transport/gnunet-service-transport_neighbours.h @@ -146,29 +146,6 @@ GST_neighbours_iterate (GST_NeighbourIterator cb, void *cb_cls); -/** - * We have received a PONG. Update lifeness of the neighbour. - * - * @param sender peer sending the PONG - * @param hdr the PONG message (presumably) - * @param plugin_name name of transport that delivered the PONG - * @param sender_address address of the other peer, NULL if other peer - * connected to us - * @param sender_address_len number of bytes in sender_address - * @param ats performance data - * @param ats_count number of entries in ats (excluding 0-termination) - * @return GNUNET_OK if the message was well-formed, GNUNET_SYSERR if not - */ -int -GST_neighbours_handle_pong (const struct GNUNET_PeerIdentity *sender, - const struct GNUNET_MessageHeader *hdr, - const char *plugin_name, - const void *sender_address, - size_t sender_address_len, - const struct GNUNET_TRANSPORT_ATS_Information *ats, - uint32_t ats_count); - - /** * We have received a CONNECT. Set the peer to connected. * diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index c77fe7a44..db6f03dc5 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c @@ -612,7 +612,8 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, const struct TransportPingMessage *ping; struct TransportPongMessage *pong; struct GNUNET_TRANSPORT_PluginFunctions *papi; - struct SessionHeader *session_header; + struct GNUNET_CRYPTO_RsaSignature *sig_cache; + struct GNUNET_TIME_Absolute *sig_cache_exp; const char *addr; const char *addrend; size_t alen; @@ -629,17 +630,7 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, &GST_my_identity, sizeof (struct GNUNET_PeerIdentity))) { -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - _("Received `%s' message from `%s' destined for `%s' which is not me!\n"), - "PING", - (sender_address != NULL) - ? GST_plugin_a2s (plugin_name, - sender_address, - sender_address_len) - : "", - GNUNET_i2s (&ping->target)); -#endif + GNUNET_break_op (0); return; } #if DEBUG_TRANSPORT @@ -658,133 +649,67 @@ GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender, GNUNET_NO); addr = (const char*) &ping[1]; alen = ntohs (hdr->size) - sizeof (struct TransportPingMessage); - if (alen == 0) + /* peer wants to confirm that this is one of our addresses, this is what is + used for address validation */ + + addrend = memchr (addr, '\0', alen); + if (NULL == addrend) { - /* peer wants to confirm that we have an outbound connection to him; - we handle this case here even though it has nothing to do with - address validation (!) */ - if ( (sender_address == NULL) || (session == NULL) ) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Refusing to create PONG since I do initiate the session with `%s'.\n"), - GNUNET_i2s (sender)); - return; - } - session_header = (struct SessionHeader *)session; + GNUNET_break_op (0); + return; + } + addrend++; + slen = strlen(addr); + alen -= slen; + + if (GNUNET_YES != + GST_hello_test_address (addr, + addrend, + alen, + &sig_cache, + &sig_cache_exp)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"), + GST_plugins_a2s (addr, + addrend, + alen)); + return; + } + + pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen); + pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen); + pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); + pong->purpose.size = + htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + + sizeof (uint32_t) + + sizeof (struct GNUNET_TIME_AbsoluteNBO) + + sizeof (struct GNUNET_PeerIdentity) + alen + slen); + pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN); + pong->challenge = ping->challenge; + pong->addrlen = htonl(alen + slen); + pong->pid = GST_my_identity; + memcpy (&pong[1], addr, slen); + memcpy (&((char*)&pong[1])[slen], addrend, alen); + if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4) + { + /* create / update cached sig */ #if DEBUG_TRANSPORT GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating PONG indicating that we initiated a connection to peer `%s' using address `%s' \n", - GNUNET_i2s (peer), - GST_plugin_a2s (plugin_name, - sender_address, - sender_address_len)); -#endif - slen = strlen (plugin_name) + 1; - pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + sender_address_len + slen); - pong->header.size = htons (sizeof (struct TransportPongMessage) + sender_address_len + slen); - pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); - pong->purpose.size = - htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + - sizeof (uint32_t) + - sizeof (struct GNUNET_TIME_AbsoluteNBO) + - sizeof (struct GNUNET_PeerIdentity) + sender_address_len + slen); - pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_USING); - pong->challenge = ping->challenge; - pong->addrlen = htonl(sender_address_len + slen); - pong->pid = *sender; - memcpy (&pong[1], - plugin_name, - slen); - memcpy (&((char*)&pong[1])[slen], - sender_address, - sender_address_len); - if (GNUNET_TIME_absolute_get_remaining (session_header->pong_sig_expires).rel_value < - PONG_SIGNATURE_LIFETIME.rel_value / 4) - { - /* create / update cached sig */ -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating PONG signature to indicate active connection.\n"); + "Creating PONG signature to indicate ownership.\n"); #endif - session_header->pong_sig_expires = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME); - pong->expiration = GNUNET_TIME_absolute_hton (session_header->pong_sig_expires); - GNUNET_assert (GNUNET_OK == - GNUNET_CRYPTO_rsa_sign (GST_my_private_key, - &pong->purpose, - &session_header->pong_signature)); - } - else - { - pong->expiration = GNUNET_TIME_absolute_hton (session_header->pong_sig_expires); - } - pong->signature = session_header->pong_signature; + *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_rsa_sign (GST_my_private_key, + &pong->purpose, + sig_cache)); } else { - /* peer wants to confirm that this is one of our addresses, this is what is - used for address validation */ - struct GNUNET_CRYPTO_RsaSignature *sig_cache; - struct GNUNET_TIME_Absolute *sig_cache_exp; - - addrend = memchr (addr, '\0', alen); - if (NULL == addrend) - { - GNUNET_break_op (0); - return; - } - addrend++; - slen = strlen(addr); - alen -= slen; - - if (GNUNET_YES != - GST_hello_test_address (addr, - addrend, - alen, - &sig_cache, - &sig_cache_exp)) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - _("Not confirming PING with address `%s' since I cannot confirm having this address.\n"), - GST_plugins_a2s (addr, - addrend, - alen)); - return; - } - - pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen); - pong->header.size = htons (sizeof (struct TransportPongMessage) + alen + slen); - pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG); - pong->purpose.size = - htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + - sizeof (uint32_t) + - sizeof (struct GNUNET_TIME_AbsoluteNBO) + - sizeof (struct GNUNET_PeerIdentity) + alen + slen); - pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN); - pong->challenge = ping->challenge; - pong->addrlen = htonl(alen + slen); - pong->pid = GST_my_identity; - memcpy (&pong[1], addr, slen); - memcpy (&((char*)&pong[1])[slen], addrend, alen); - if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value < PONG_SIGNATURE_LIFETIME.rel_value / 4) - { - /* create / update cached sig */ -#if DEBUG_TRANSPORT - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Creating PONG signature to indicate ownership.\n"); -#endif - *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_rsa_sign (GST_my_private_key, - &pong->purpose, - sig_cache)); - } - else - { - pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); - } - pong->signature = *sig_cache; + pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp); } + pong->signature = *sig_cache; /* first see if the session we got this PING from can be used to transmit a response reliably */ @@ -1039,8 +964,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender, sender, sizeof (struct GNUNET_PeerIdentity))) { - /* PONG is validating inbound session, not an address, not the case - used for address validation, ignore here! */ + GNUNET_break_op (0); return; } #if DEBUG_TRANSPORT -- 2.25.1