From: Matthias Wachs Date: Fri, 30 Mar 2012 15:36:28 +0000 (+0000) Subject: - throtteled fast reconnect X-Git-Tag: initial-import-from-subversion-38251~14053 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=f22fec7930cdbcc1c25d262d7ed164b818a22d00;p=oweals%2Fgnunet.git - throtteled fast reconnect --- diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index cd9bb5c65..c8cceb4ba 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c @@ -462,6 +462,10 @@ neighbours_connect_notification (void *cls, struct ConnectInfoMessage *connect_msg = (struct ConnectInfoMessage *) buf; struct GNUNET_ATS_Information *ap; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "We are now connected to peer `%s'\n", + GNUNET_i2s (peer)); + connect_msg->header.size = htons (sizeof (buf)); connect_msg->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_CONNECT); connect_msg->ats_count = htonl (ats_count); @@ -485,6 +489,10 @@ neighbours_disconnect_notification (void *cls, { struct DisconnectInfoMessage disconnect_msg; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Peer `%s' disconnected\n", + GNUNET_i2s (peer)); + disconnect_msg.header.size = htons (sizeof (struct DisconnectInfoMessage)); disconnect_msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_DISCONNECT); disconnect_msg.reserved = htonl (0); diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index eea5d80a1..3b25f5bbe 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -59,6 +59,8 @@ #define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) +#define FAST_RECONNECT_RATE GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 100) + #define FAST_RECONNECT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) #define SETUP_CONNECTION_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15) @@ -264,6 +266,12 @@ struct NeighbourMapEntry */ struct GNUNET_HELLO_Address *address; + /** + * Address we currently use. + */ + struct GNUNET_HELLO_Address *fast_reconnect_address; + + /** * Identity of this neighbour. */ @@ -322,6 +330,11 @@ struct NeighbourMapEntry */ GNUNET_SCHEDULER_TaskIdentifier ats_suggest; + /** + * Delay for ATS request + */ + GNUNET_SCHEDULER_TaskIdentifier ats_request; + /** * Task the resets the peer state after due to an pending * unsuccessful connection setup @@ -347,7 +360,16 @@ struct NeighbourMapEntry * Did we sent an KEEP_ALIVE message and are we expecting a response? */ int expect_latency_response; + + /** + * Was the address used successfully + */ int address_state; + + /** + * Fast reconnect attempts for identical address + */ + unsigned int fast_reconnect_attempts; }; @@ -981,6 +1003,12 @@ disconnect_neighbour (struct NeighbourMapEntry *n) GNUNET_SCHEDULER_cancel (n->ats_suggest); n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; } + if (n->ats_request != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (n->ats_request); + n->ats_request = GNUNET_SCHEDULER_NO_TASK; + } + if (GNUNET_SCHEDULER_NO_TASK != n->timeout_task) { GNUNET_SCHEDULER_cancel (n->timeout_task); @@ -991,6 +1019,11 @@ disconnect_neighbour (struct NeighbourMapEntry *n) GNUNET_SCHEDULER_cancel (n->transmission_task); n->transmission_task = GNUNET_SCHEDULER_NO_TASK; } + if (NULL != n->fast_reconnect_address) + { + GNUNET_HELLO_address_free (n->fast_reconnect_address); + n->fast_reconnect_address = NULL; + } if (NULL != n->address) { GNUNET_HELLO_address_free (n->address); @@ -1016,6 +1049,8 @@ neighbour_timeout_task (void *cls, struct NeighbourMapEntry *n = cls; n->timeout_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer`%4s' disconnected due to timeout\n", + GNUNET_i2s (&n->id)); GNUNET_STATISTICS_update (GST_stats, gettext_noop @@ -1099,7 +1134,7 @@ ats_suggest_cancel (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ATS did not suggested address to connect to peer `%s'\n", GNUNET_i2s (&n->id)); @@ -1212,6 +1247,18 @@ send_connect_continuation (void *cls, const struct GNUNET_PeerIdentity *target, } +static void +ats_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + struct NeighbourMapEntry *n = cls; + n->ats_request = GNUNET_SCHEDULER_NO_TASK; + + n->ats_suggest = + GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, + n); +} + + /** * We tried to switch addresses with an peer already connected. If it failed, * we should tell ATS to not use this address anymore (until it is re-validated). @@ -1246,20 +1293,42 @@ send_switch_address_continuation (void *cls, GNUNET_assert ((n->state == S_CONNECTED) || (n->state == S_FAST_RECONNECT)); if (GNUNET_YES != success) { -#if DEBUG_TRANSPORT + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Failed to switch connected peer `%s' to address '%s' session %X, asking ATS for new address \n", - GNUNET_i2s (&n->id), GST_plugins_a2s (cc->address), cc->session); -#endif + "Failed to switch connected peer `%s' in state %s to address '%s' session %X, asking ATS for new address \n", + GNUNET_i2s (&n->id), print_state(n->state), GST_plugins_a2s (cc->address), cc->session); + GNUNET_assert (strlen (cc->address->transport_name) > 0); GNUNET_ATS_address_destroyed (GST_ats, cc->address, cc->session); if (n->ats_suggest != GNUNET_SCHEDULER_NO_TASK) + { GNUNET_SCHEDULER_cancel (n->ats_suggest); - n->ats_suggest = + n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; + } + + if (n->state == S_FAST_RECONNECT) + { + if (GNUNET_SCHEDULER_NO_TASK == n->ats_request) + { + /* Throtteled ATS request for fast reconnect */ + struct GNUNET_TIME_Relative delay = GNUNET_TIME_relative_multiply(FAST_RECONNECT_RATE, n->fast_reconnect_attempts); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Fast reconnect attempt %u failed, delay ATS request for %llu ms\n", n->fast_reconnect_attempts, delay.rel_value); + n->ats_request = + GNUNET_SCHEDULER_add_delayed (delay, + ats_request, + n); + } + } + else + { + /* Immediate ATS request for connected peers */ + n->ats_suggest = GNUNET_SCHEDULER_add_delayed (ATS_RESPONSE_TIMEOUT, ats_suggest_cancel, n); - GNUNET_ATS_suggest_address (GST_ats, &n->id); + GNUNET_ATS_suggest_address (GST_ats, &n->id); + } GNUNET_HELLO_address_free (cc->address); GNUNET_free (cc); return; @@ -1443,18 +1512,32 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, GNUNET_SCHEDULER_cancel (n->ats_suggest); n->ats_suggest = GNUNET_SCHEDULER_NO_TASK; } - /* do not switch addresses just update quotas */ -/* + + if (n->state == S_FAST_RECONNECT) { - if (0 == GNUNET_HELLO_address_cmp(address, n->address)) + /* Throtteled fast reconnect */ + + if (NULL == n->fast_reconnect_address) { + n->fast_reconnect_address = GNUNET_HELLO_address_copy (address); + + } + else if (0 == GNUNET_HELLO_address_cmp(address, n->fast_reconnect_address)) + { + n->fast_reconnect_attempts ++; + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "FAST RECONNECT to peer `%s' and address '%s' with identical ADDRESS\n", - GNUNET_i2s (&n->id), GST_plugins_a2s (n->address)); + "FAST RECONNECT to peer `%s' and address '%s' with identical address attempt %u\n", + GNUNET_i2s (&n->id), GST_plugins_a2s (address), n->fast_reconnect_attempts); } } -*/ + else + { + n->fast_reconnect_attempts = 0; + } + + /* do not switch addresses just update quotas */ if ((n->state == S_CONNECTED) && (NULL != n->address) && (0 == GNUNET_HELLO_address_cmp (address, n->address)) && (n->session == session)) @@ -1805,6 +1888,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, GST_validation_set_address_use (n->address, n->session, GNUNET_NO, __LINE__); GNUNET_ATS_address_in_use (GST_ats, n->address, n->session, GNUNET_NO); n->address_state = UNUSED; + } }