X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Ftransport%2Fgnunet-service-transport_neighbours.c;h=47e2713870609e97b384ba20ac990aae32df1f7f;hb=dc994999f6702effb64e5bfc3eb727ee0f3723ef;hp=c1138fbb844186c1bcadcb325d6cb16a15a6d1db;hpb=3230837d6c96247600030266a569f432b8ebbd68;p=oweals%2Fgnunet.git diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index c1138fbb8..47e271387 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c @@ -60,11 +60,11 @@ /** * How often do we send KEEPALIVE messages to each of our neighbours and measure * the latency with this neighbour? - * (idle timeout is 5 minutes or 300 seconds, so with 30s interval we - * send 10 keepalives in each interval, so 10 messages would need to be + * (idle timeout is 5 minutes or 300 seconds, so with 100s interval we + * send 3 keepalives in each interval, so 3 messages would need to be * lost in a row for a disconnect). */ -#define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30) +#define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100) /** * How long are we willing to wait for a response from ATS before timing out? @@ -847,9 +847,11 @@ set_address (struct NeighbourAddress *na, * Free a neighbour map entry. * * @param n entry to free + * @param keep_sessions GNUNET_NO to tell plugin to terminate sessions, + * GNUNET_YES to keep all sessions */ static void -free_neighbour (struct NeighbourMapEntry *n) +free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) { struct MessageQueue *mq; struct GNUNET_TRANSPORT_PluginFunctions *papi; @@ -884,8 +886,9 @@ free_neighbour (struct NeighbourMapEntry *n) API gives us not even the means to selectively kill only one of them! Killing all sessions like this seems to be very, very wrong. */ - if ( (NULL != n->primary_address.address) && - (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name))) ) + if ((GNUNET_NO == keep_sessions) && + (NULL != n->primary_address.address) && + (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name)))) papi->disconnect (papi->cls, &n->id); n->state = S_DISCONNECT_FINISHED; @@ -983,7 +986,8 @@ send_disconnect_cont (void *cls, const struct GNUNET_PeerIdentity *target, if (S_DISCONNECT != n->state) return; /* have created a fresh entry since */ n->state = S_DISCONNECT; - GNUNET_SCHEDULER_cancel (n->task); + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } @@ -1047,7 +1051,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n) case S_INIT_BLACKLIST: /* other peer is completely unaware of us, no need to send DISCONNECT */ n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_CONNECT_SENT: send_disconnect (n); @@ -1057,7 +1061,7 @@ disconnect_neighbour (struct NeighbourMapEntry *n) case S_CONNECT_RECV_BLACKLIST: /* we never ACK'ed the other peer's request, no need to send DISCONNECT */ n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_CONNECT_RECV_ACK: /* we DID ACK the other peer's request, must send DISCONNECT */ @@ -1123,19 +1127,15 @@ transmit_send_continuation (void *cls, struct MessageQueue *mq = cls; struct NeighbourMapEntry *n; - n = lookup_neighbour (receiver); - if (NULL == n) - { - GNUNET_break (0); - return; - } - + if (NULL == (n = lookup_neighbour (receiver))) + return; /* disconnect or other error while transmitting, can happen */ if (n->is_active == mq) { /* this is still "our" neighbour, remove us from its queue and allow it to send the next message now */ n->is_active = NULL; - GNUNET_SCHEDULER_cancel (n->task); + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } GNUNET_assert (bytes_in_send_queue >= mq->message_buf_size); @@ -1489,7 +1489,8 @@ GST_neighbours_send (const struct GNUNET_PeerIdentity *target, const void *msg, if ( (NULL != n->is_active) || ( (NULL == n->primary_address.session) && (NULL == n->primary_address.address)) ) return; - GNUNET_SCHEDULER_cancel (n->task); + if (GNUNET_SCHEDULER_NO_TASK != n->task) + GNUNET_SCHEDULER_cancel (n->task); n->task = GNUNET_SCHEDULER_add_now (&master_task, n); } @@ -1659,7 +1660,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) case S_NOT_CONNECTED: /* this should not be possible */ GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); break; case S_INIT_ATS: case S_INIT_BLACKLIST: @@ -1683,7 +1684,7 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) return; /* already connected */ case S_DISCONNECT: /* get rid of remains, ready to re-try immediately */ - free_neighbour (n); + free_neighbour (n, GNUNET_NO); break; case S_DISCONNECT_FINISHED: /* should not be possible */ @@ -1691,13 +1692,15 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target) default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); break; } } n = setup_neighbour (target); n->state = S_INIT_ATS; n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + + GNUNET_ATS_reset_backoff (GST_ats, target); GNUNET_ATS_suggest_address (GST_ats, target); } @@ -1737,7 +1740,7 @@ handle_test_blacklist_cont (void *cls, case S_NOT_CONNECTED: /* this should not be possible */ GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); break; case S_INIT_ATS: /* still waiting on ATS suggestion */ @@ -1807,6 +1810,7 @@ handle_test_blacklist_cont (void *cls, n->state = S_INIT_ATS; n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); // FIXME: do we need to ask ATS again for suggestions? + GNUNET_ATS_reset_backoff (GST_ats, peer); GNUNET_ATS_suggest_address (GST_ats, &n->id); } break; @@ -1904,7 +1908,7 @@ handle_test_blacklist_cont (void *cls, default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); break; } cleanup: @@ -2007,6 +2011,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, case S_NOT_CONNECTED: n->state = S_CONNECT_RECV_ATS; n->timeout = GNUNET_TIME_relative_to_absolute (ATS_RESPONSE_TIMEOUT); + GNUNET_ATS_reset_backoff (GST_ats, peer); GNUNET_ATS_suggest_address (GST_ats, peer); check_blacklist (peer, ts, address, session, ats, ats_count); break; @@ -2051,12 +2056,12 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, check_blacklist (peer, ts, address, session, ats, ats_count); break; case S_DISCONNECT: - /* get rid of remains, ready to re-try */ - free_neighbour (n); + /* get rid of remains without terminating sessions, ready to re-try */ + free_neighbour (n, GNUNET_YES); n = setup_neighbour (peer); n->state = S_CONNECT_RECV_ATS; + GNUNET_ATS_reset_backoff (GST_ats, peer); GNUNET_ATS_suggest_address (GST_ats, peer); - check_blacklist (peer, ts, address, session, ats, ats_count); break; case S_DISCONNECT_FINISHED: /* should not be possible */ @@ -2065,7 +2070,7 @@ GST_neighbours_handle_connect (const struct GNUNET_MessageHeader *message, default: GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unhandled state `%s' \n",print_state (n->state)); GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); break; } } @@ -2134,7 +2139,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, { case S_NOT_CONNECTED: GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_INIT_ATS: set_address (&n->primary_address, @@ -2173,8 +2178,8 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, n->connect_ack_timestamp, address, session, ats, ats_count); break; - case S_CONNECT_RECV_ACK: case S_CONNECT_RECV_BLACKLIST: + case S_CONNECT_RECV_ACK: /* ATS asks us to switch while we were trying to connect; switch to new address and check blacklist again */ set_address (&n->primary_address, @@ -2197,7 +2202,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, /* ATS asks us to switch a life connection; see if we can get a CONNECT_ACK on it before we actually do this! */ set_address (&n->alternative_address, - address, session, bandwidth_in, bandwidth_out, GNUNET_YES); + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); n->state = S_CONNECTED_SWITCHING_BLACKLIST; check_blacklist (&n->id, GNUNET_TIME_absolute_get (), @@ -2243,7 +2248,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, } /* ATS asks us to switch a life connection, update blacklist check */ set_address (&n->alternative_address, - address, session, bandwidth_in, bandwidth_out, GNUNET_YES); + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); check_blacklist (&n->id, GNUNET_TIME_absolute_get (), address, session, ats, ats_count); @@ -2258,7 +2263,7 @@ GST_neighbours_switch_to_address (const struct GNUNET_PeerIdentity *peer, } /* ATS asks us to switch a life connection, update blacklist check */ set_address (&n->alternative_address, - address, session, bandwidth_in, bandwidth_out, GNUNET_YES); + address, session, bandwidth_in, bandwidth_out, GNUNET_NO); n->state = S_CONNECTED_SWITCHING_BLACKLIST; check_blacklist (&n->id, GNUNET_TIME_absolute_get (), @@ -2301,7 +2306,7 @@ master_task (void *cls, /* invalid state for master task, clean up */ GNUNET_break (0); n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_INIT_ATS: if (0 == delay.rel_value) @@ -2310,7 +2315,7 @@ master_task (void *cls, "Connection to `%s' timed out waiting for ATS to provide address\n", GNUNET_i2s (&n->id)); n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; } break; @@ -2321,7 +2326,7 @@ master_task (void *cls, "Connection to `%s' timed out waiting for BLACKLIST to approve address\n", GNUNET_i2s (&n->id)); n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; } break; @@ -2342,7 +2347,7 @@ master_task (void *cls, "Connection to `%s' timed out waiting ATS to provide address to use for CONNECT_ACK\n", GNUNET_i2s (&n->id)); n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; } break; @@ -2353,7 +2358,7 @@ master_task (void *cls, "Connection to `%s' timed out waiting BLACKLIST to approve address to use for CONNECT_ACK\n", GNUNET_i2s (&n->id)); n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; } break; @@ -2438,7 +2443,7 @@ master_task (void *cls, "Cleaning up connection to `%s' after sending DISCONNECT\n", GNUNET_i2s (&n->id)); n->state = S_DISCONNECT_FINISHED; - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_DISCONNECT_FINISHED: /* how did we get here!? */ @@ -2451,10 +2456,10 @@ master_task (void *cls, } delay = GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time), delay); - GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == n->task); - n->task = GNUNET_SCHEDULER_add_delayed (delay, - &master_task, - n); + if (GNUNET_SCHEDULER_NO_TASK == n->task) + n->task = GNUNET_SCHEDULER_add_delayed (delay, + &master_task, + n); } @@ -2525,7 +2530,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, { case S_NOT_CONNECTED: GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_INIT_ATS: case S_INIT_BLACKLIST: @@ -2586,7 +2591,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message, /* new address worked; adopt it and go back to connected! */ n->state = S_CONNECTED; n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); - GNUNET_assert (GNUNET_NO == n->alternative_address.ats_active); + GNUNET_break (GNUNET_NO == n->alternative_address.ats_active); set_address (&n->primary_address, n->alternative_address.address, n->alternative_address.session, @@ -2665,11 +2670,11 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, { case S_NOT_CONNECTED: GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_INIT_ATS: GNUNET_break (0); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_INIT_BLACKLIST: case S_CONNECT_SENT: @@ -2684,7 +2689,7 @@ GST_neighbours_session_terminated (const struct GNUNET_PeerIdentity *peer, case S_CONNECT_RECV_ACK: /* error on inbound session; free neighbour entirely */ free_address (&n->primary_address); - free_neighbour (n); + free_neighbour (n, GNUNET_NO); return; case S_CONNECTED: free_address (&n->primary_address); @@ -3093,7 +3098,8 @@ disconnect_all_neighbours (void *cls, const GNUNET_HashCode * key, void *value) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting peer `%4s', %s\n", GNUNET_i2s (&n->id), "SHUTDOWN_TASK"); - free_neighbour (n); + n->state = S_DISCONNECT_FINISHED; + free_neighbour (n, GNUNET_NO); return GNUNET_OK; }