From 70b173c768c3a43fc392507562df0ede641edbbe Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Fri, 25 May 2012 14:04:41 +0000 Subject: - timeout for http/s --- src/transport/plugin_transport_http.c | 121 ++++++++++++++++++++++++++++++---- src/transport/plugin_transport_http.h | 10 +-- 2 files changed, 114 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/transport/plugin_transport_http.c b/src/transport/plugin_transport_http.c index de616173e..37f7f798d 100644 --- a/src/transport/plugin_transport_http.c +++ b/src/transport/plugin_transport_http.c @@ -106,7 +106,23 @@ struct PrettyPrinterContext */ struct Plugin; +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s); +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s); + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s); /** * Append our port and forward the result. @@ -320,6 +336,8 @@ http_plugin_receive (void *cls, const struct GNUNET_PeerIdentity *peer, atsi[1].value = session->ats_address_network_type; GNUNET_break (session->ats_address_network_type != ntohl (GNUNET_ATS_NET_UNSPECIFIED)); + reschedule_session_timeout (session); + delay = plugin->env->receive (plugin->env->cls, &s->target, message, (const struct GNUNET_ATS_Information *) &atsi, @@ -575,6 +593,8 @@ exist_session (struct Plugin *plugin, struct Session *s) void delete_session (struct Session *s) { + stop_session_timeout(s); + if (s->msg_tk != NULL) { GNUNET_SERVER_mst_destroy (s->msg_tk); @@ -588,8 +608,7 @@ delete_session (struct Session *s) struct Session * create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, - const void *addr, size_t addrlen, - GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) + const void *addr, size_t addrlen) { struct Session *s = NULL; @@ -604,9 +623,12 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, s->next = NULL; s->next_receive = GNUNET_TIME_absolute_get_zero (); s->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); + start_session_timeout(s); return s; } + + void notify_session_end (void *cls, const struct GNUNET_PeerIdentity *peer, struct Session *s) @@ -662,16 +684,7 @@ http_get_session (void *cls, GNUNET_assert ((addrlen == sizeof (struct IPv6HttpAddress)) || (addrlen == sizeof (struct IPv4HttpAddress))); - s = GNUNET_malloc (sizeof (struct Session)); - memcpy (&s->target, &address->peer, sizeof (struct GNUNET_PeerIdentity)); - s->plugin = plugin; - s->addr = GNUNET_malloc (address->address_length); - memcpy (s->addr, address->address, address->address_length); - s->addrlen = addrlen; - s->next = NULL; - s->next_receive = GNUNET_TIME_absolute_get_zero (); - s->inbound = GNUNET_NO; - s->ats_address_network_type = htonl (GNUNET_ATS_NET_UNSPECIFIED); + s = create_session (plugin, &address->peer, address->address, address->address_length); /* Get ATS type */ if (addrlen == sizeof (struct IPv4HttpAddress)) @@ -790,6 +803,8 @@ http_plugin_send (void *cls, msg->transmit_cont_cls = cont_cls; memcpy (msg->buf, msgbuf, msgbuf_size); + reschedule_session_timeout (session); + if (session->inbound == GNUNET_NO) { GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, plugin->name, @@ -1468,6 +1483,88 @@ fail: return res; } + +/** + * Session was idle, so disconnect it + */ +static void +session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_assert (NULL != cls); + struct Session *s = cls; + + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + + /* call session destroy function */ + if (s->inbound == GNUNET_NO) + GNUNET_assert (GNUNET_OK == client_disconnect (s)); + else + GNUNET_assert (GNUNET_OK == server_disconnect (s)); + +} + +/** + * Start session timeout + */ +static void +start_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task); + + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + +/** + * Increment session timeout due to activity + */ +static void +reschedule_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task); + + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, + &session_timeout, + s); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); +} + +/** + * Cancel timeout + */ +static void +stop_session_timeout (struct Session *s) +{ + GNUNET_assert (NULL != s); + + if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task) + { + GNUNET_SCHEDULER_cancel (s->timeout_task); + s->timeout_task = GNUNET_SCHEDULER_NO_TASK; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n", + s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n", + s); + } +} + + /** * Entry point for the plugin. */ diff --git a/src/transport/plugin_transport_http.h b/src/transport/plugin_transport_http.h index 89fb86dd9..b1a7fcaf3 100644 --- a/src/transport/plugin_transport_http.h +++ b/src/transport/plugin_transport_http.h @@ -399,6 +399,11 @@ struct Session */ GNUNET_SCHEDULER_TaskIdentifier recv_wakeup_task; + /** + * Session timeout task + */ + GNUNET_SCHEDULER_TaskIdentifier timeout_task; + /** * Is client send handle paused since there are no data to send? * GNUNET_YES/NO @@ -469,11 +474,6 @@ exist_session (struct Plugin *plugin, struct Session *s); void delete_session (struct Session *s); -struct Session * -create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, - const void *addr, size_t addrlen, - GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls); - int exist_session (struct Plugin *plugin, struct Session *s); -- cgit v1.2.3