diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-25 09:34:49 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-05-25 09:34:49 +0000 |
commit | 95a032ed3619880651eda8f0a5abc9d3520a6f8e (patch) | |
tree | c26673078f8180b79386b6a5ff49b1c1e065f0ac /src/transport/plugin_transport_tcp.c | |
parent | 1e46552077655aeb2f54e59cad77edcdffe3f1ce (diff) | |
download | gnunet-95a032ed3619880651eda8f0a5abc9d3520a6f8e.tar.gz gnunet-95a032ed3619880651eda8f0a5abc9d3520a6f8e.zip |
session timeout for udp and tcp
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 122 |
1 files changed, 118 insertions, 4 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 8e76398ea..18482b11e 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -273,6 +273,11 @@ struct Session | |||
273 | GNUNET_SCHEDULER_TaskIdentifier receive_delay_task; | 273 | GNUNET_SCHEDULER_TaskIdentifier receive_delay_task; |
274 | 274 | ||
275 | /** | 275 | /** |
276 | * Session timeout task | ||
277 | */ | ||
278 | GNUNET_SCHEDULER_TaskIdentifier timeout_task; | ||
279 | |||
280 | /** | ||
276 | * Address of the other peer (either based on our 'connect' | 281 | * Address of the other peer (either based on our 'connect' |
277 | * call or on our 'accept' call). | 282 | * call or on our 'accept' call). |
278 | * | 283 | * |
@@ -395,6 +400,26 @@ struct Plugin | |||
395 | 400 | ||
396 | }; | 401 | }; |
397 | 402 | ||
403 | |||
404 | /** | ||
405 | * Start session timeout | ||
406 | */ | ||
407 | static void | ||
408 | start_session_timeout (struct Session *s); | ||
409 | |||
410 | /** | ||
411 | * Increment session timeout due to activity | ||
412 | */ | ||
413 | static void | ||
414 | reschedule_session_timeout (struct Session *s); | ||
415 | |||
416 | /** | ||
417 | * Cancel timeout | ||
418 | */ | ||
419 | static void | ||
420 | stop_session_timeout (struct Session *s); | ||
421 | |||
422 | |||
398 | /* DEBUG CODE */ | 423 | /* DEBUG CODE */ |
399 | static const char * | 424 | static const char * |
400 | tcp_address_to_string (void *cls, const void *addr, size_t addrlen); | 425 | tcp_address_to_string (void *cls, const void *addr, size_t addrlen); |
@@ -740,6 +765,8 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | |||
740 | gettext_noop ("# TCP sessions active"), 1, | 765 | gettext_noop ("# TCP sessions active"), 1, |
741 | GNUNET_NO); | 766 | GNUNET_NO); |
742 | } | 767 | } |
768 | start_session_timeout (ret); | ||
769 | |||
743 | return ret; | 770 | return ret; |
744 | } | 771 | } |
745 | 772 | ||
@@ -919,14 +946,16 @@ disconnect_session (struct Session *session) | |||
919 | GNUNET_i2s (&session->target), | 946 | GNUNET_i2s (&session->target), |
920 | tcp_address_to_string(NULL, session->addr, session->addrlen)); | 947 | tcp_address_to_string(NULL, session->addr, session->addrlen)); |
921 | 948 | ||
922 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->sessionmap, &session->target.hashPubKey, session)) | 949 | stop_session_timeout (session); |
923 | { | 950 | |
951 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->sessionmap, &session->target.hashPubKey, session)) | ||
952 | { | ||
924 | GNUNET_STATISTICS_update (session->plugin->env->stats, | 953 | GNUNET_STATISTICS_update (session->plugin->env->stats, |
925 | gettext_noop ("# TCP sessions active"), -1, | 954 | gettext_noop ("# TCP sessions active"), -1, |
926 | GNUNET_NO); | 955 | GNUNET_NO); |
927 | dec_sessions (plugin, session, __LINE__); | 956 | dec_sessions (plugin, session, __LINE__); |
928 | } | 957 | } |
929 | else GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->nat_wait_conns, &session->target.hashPubKey, session)); | 958 | else GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->nat_wait_conns, &session->target.hashPubKey, session)); |
930 | 959 | ||
931 | /* clean up state */ | 960 | /* clean up state */ |
932 | if (session->transmit_handle != NULL) | 961 | if (session->transmit_handle != NULL) |
@@ -1037,6 +1066,8 @@ tcp_plugin_send (void *cls, | |||
1037 | "Asked to transmit %u bytes to `%s', added message to list.\n", | 1066 | "Asked to transmit %u bytes to `%s', added message to list.\n", |
1038 | msgbuf_size, GNUNET_i2s (&session->target)); | 1067 | msgbuf_size, GNUNET_i2s (&session->target)); |
1039 | 1068 | ||
1069 | reschedule_session_timeout (session); | ||
1070 | |||
1040 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessionmap, &session->target.hashPubKey, session)) | 1071 | if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessionmap, &session->target.hashPubKey, session)) |
1041 | { | 1072 | { |
1042 | GNUNET_assert (session->client != NULL); | 1073 | GNUNET_assert (session->client != NULL); |
@@ -1850,6 +1881,8 @@ delayed_done (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1850 | session->plugin->env->receive (session->plugin->env->cls, | 1881 | session->plugin->env->receive (session->plugin->env->cls, |
1851 | &session->target, NULL, &ats, 0, session, | 1882 | &session->target, NULL, &ats, 0, session, |
1852 | NULL, 0); | 1883 | NULL, 0); |
1884 | reschedule_session_timeout (session); | ||
1885 | |||
1853 | if (delay.rel_value == 0) | 1886 | if (delay.rel_value == 0) |
1854 | GNUNET_SERVER_receive_done (session->client, GNUNET_OK); | 1887 | GNUNET_SERVER_receive_done (session->client, GNUNET_OK); |
1855 | else | 1888 | else |
@@ -1948,6 +1981,9 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, | |||
1948 | 1, session, | 1981 | 1, session, |
1949 | (GNUNET_YES == session->inbound) ? NULL : session->addr, | 1982 | (GNUNET_YES == session->inbound) ? NULL : session->addr, |
1950 | (GNUNET_YES == session->inbound) ? 0 : session->addrlen); | 1983 | (GNUNET_YES == session->inbound) ? 0 : session->addrlen); |
1984 | |||
1985 | reschedule_session_timeout (session); | ||
1986 | |||
1951 | if (delay.rel_value == 0) | 1987 | if (delay.rel_value == 0) |
1952 | { | 1988 | { |
1953 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1989 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -2087,6 +2123,84 @@ try_connection_reversal (void *cls, const struct sockaddr *addr, | |||
2087 | 2123 | ||
2088 | 2124 | ||
2089 | /** | 2125 | /** |
2126 | * Session was idle, so disconnect it | ||
2127 | */ | ||
2128 | static void | ||
2129 | session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
2130 | { | ||
2131 | GNUNET_assert (NULL != cls); | ||
2132 | struct Session *s = cls; | ||
2133 | |||
2134 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
2135 | |||
2136 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n", | ||
2137 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
2138 | |||
2139 | /* call session destroy function */ | ||
2140 | disconnect_session(s); | ||
2141 | |||
2142 | } | ||
2143 | |||
2144 | /** | ||
2145 | * Start session timeout | ||
2146 | */ | ||
2147 | static void | ||
2148 | start_session_timeout (struct Session *s) | ||
2149 | { | ||
2150 | GNUNET_assert (NULL != s); | ||
2151 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); | ||
2152 | |||
2153 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2154 | &session_timeout, | ||
2155 | s); | ||
2156 | |||
2157 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n", | ||
2158 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
2159 | } | ||
2160 | |||
2161 | /** | ||
2162 | * Increment session timeout due to activity | ||
2163 | */ | ||
2164 | static void | ||
2165 | reschedule_session_timeout (struct Session *s) | ||
2166 | { | ||
2167 | GNUNET_assert (NULL != s); | ||
2168 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); | ||
2169 | |||
2170 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
2171 | s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, | ||
2172 | &session_timeout, | ||
2173 | s); | ||
2174 | |||
2175 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", | ||
2176 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
2177 | } | ||
2178 | |||
2179 | /** | ||
2180 | * Cancel timeout | ||
2181 | */ | ||
2182 | static void | ||
2183 | stop_session_timeout (struct Session *s) | ||
2184 | { | ||
2185 | GNUNET_assert (NULL != s); | ||
2186 | |||
2187 | if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) | ||
2188 | { | ||
2189 | GNUNET_SCHEDULER_cancel (s->timeout_task); | ||
2190 | s->timeout_task = GNUNET_SCHEDULER_NO_TASK; | ||
2191 | |||
2192 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n", | ||
2193 | s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); | ||
2194 | } | ||
2195 | else | ||
2196 | { | ||
2197 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n", | ||
2198 | s); | ||
2199 | } | ||
2200 | } | ||
2201 | |||
2202 | |||
2203 | /** | ||
2090 | * Entry point for the plugin. | 2204 | * Entry point for the plugin. |
2091 | * | 2205 | * |
2092 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' | 2206 | * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*' |