[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r21573 - gnunet/src/transport
From: |
gnunet |
Subject: |
[GNUnet-SVN] r21573 - gnunet/src/transport |
Date: |
Fri, 25 May 2012 11:34:49 +0200 |
Author: wachs
Date: 2012-05-25 11:34:49 +0200 (Fri, 25 May 2012)
New Revision: 21573
Modified:
gnunet/src/transport/plugin_transport_tcp.c
gnunet/src/transport/plugin_transport_udp.c
Log:
session timeout for udp and tcp
Modified: gnunet/src/transport/plugin_transport_tcp.c
===================================================================
--- gnunet/src/transport/plugin_transport_tcp.c 2012-05-25 08:25:18 UTC (rev
21572)
+++ gnunet/src/transport/plugin_transport_tcp.c 2012-05-25 09:34:49 UTC (rev
21573)
@@ -273,6 +273,11 @@
GNUNET_SCHEDULER_TaskIdentifier receive_delay_task;
/**
+ * Session timeout task
+ */
+ GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+ /**
* Address of the other peer (either based on our 'connect'
* call or on our 'accept' call).
*
@@ -395,6 +400,26 @@
};
+
+/**
+ * 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);
+
+
/* DEBUG CODE */
static const char *
tcp_address_to_string (void *cls, const void *addr, size_t addrlen);
@@ -740,6 +765,8 @@
gettext_noop ("# TCP sessions active"), 1,
GNUNET_NO);
}
+ start_session_timeout (ret);
+
return ret;
}
@@ -919,14 +946,16 @@
GNUNET_i2s (&session->target),
tcp_address_to_string(NULL, session->addr, session->addrlen));
- if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->sessionmap,
&session->target.hashPubKey, session))
- {
+ stop_session_timeout (session);
+
+ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove(plugin->sessionmap,
&session->target.hashPubKey, session))
+ {
GNUNET_STATISTICS_update (session->plugin->env->stats,
gettext_noop ("# TCP sessions active"), -1,
GNUNET_NO);
dec_sessions (plugin, session, __LINE__);
- }
- else GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove(plugin->nat_wait_conns,
&session->target.hashPubKey, session));
+ }
+ else GNUNET_assert (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_remove(plugin->nat_wait_conns,
&session->target.hashPubKey, session));
/* clean up state */
if (session->transmit_handle != NULL)
@@ -1037,6 +1066,8 @@
"Asked to transmit %u bytes to `%s', added message to list.\n",
msgbuf_size, GNUNET_i2s (&session->target));
+ reschedule_session_timeout (session);
+
if (GNUNET_YES ==
GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessionmap,
&session->target.hashPubKey, session))
{
GNUNET_assert (session->client != NULL);
@@ -1850,6 +1881,8 @@
session->plugin->env->receive (session->plugin->env->cls,
&session->target, NULL, &ats, 0, session,
NULL, 0);
+ reschedule_session_timeout (session);
+
if (delay.rel_value == 0)
GNUNET_SERVER_receive_done (session->client, GNUNET_OK);
else
@@ -1948,6 +1981,9 @@
1, session,
(GNUNET_YES == session->inbound) ? NULL :
session->addr,
(GNUNET_YES == session->inbound) ? 0 :
session->addrlen);
+
+ reschedule_session_timeout (session);
+
if (delay.rel_value == 0)
{
GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -2087,6 +2123,84 @@
/**
+ * 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 */
+ disconnect_session(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.
*
* @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
Modified: gnunet/src/transport/plugin_transport_udp.c
===================================================================
--- gnunet/src/transport/plugin_transport_udp.c 2012-05-25 08:25:18 UTC (rev
21572)
+++ gnunet/src/transport/plugin_transport_udp.c 2012-05-25 09:34:49 UTC (rev
21573)
@@ -111,6 +111,11 @@
struct GNUNET_TIME_Absolute flow_delay_from_other_peer;
/**
+ * Session timeout task
+ */
+ GNUNET_SCHEDULER_TaskIdentifier timeout_task;
+
+ /**
* expected delay for ACKs
*/
struct GNUNET_TIME_Relative last_expected_delay;
@@ -293,7 +298,12 @@
};
+/**
+ * Encapsulation of all of the state of the plugin.
+ */
+struct Plugin * plugin;
+
/**
* We have been notified that our readset has something to read. We don't
* know which socket needs to be read, so we have to check each one
@@ -317,6 +327,26 @@
udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext
*tc);
/**
+ * 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);
+
+
+
+/**
* Function called for a quick conversion of the binary address to
* a numeric address. Note that the caller must not free the
* address and that the next call to this function is allowed
@@ -649,18 +679,15 @@
/**
- * Destroy a session, plugin is being unloaded.
+ * Functions with this signature are called whenever we need
+ * to close a session due to a disconnect or failure to
+ * establish a connection.
*
- * @param cls unused
- * @param key hash of public key of target peer
- * @param value a 'struct PeerSession*' to clean up
- * @return GNUNET_OK (continue to iterate)
+ * @param session session to close down
*/
-static int
-disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
+static void
+disconnect_session (struct Session *s)
{
- struct Plugin *plugin = cls;
- struct Session *s = value;
struct UDPMessageWrapper *udpw;
struct UDPMessageWrapper *next;
@@ -670,6 +697,7 @@
s,
GNUNET_i2s (&s->target),
GNUNET_a2s (s->sock_addr, s->addrlen));
+ stop_session_timeout(s);
next = plugin->ipv4_queue_head;
while (NULL != (udpw = next))
{
@@ -718,6 +746,20 @@
s->in_destroy = GNUNET_YES;
else
free_session (s);
+}
+
+/**
+ * Destroy a session, plugin is being unloaded.
+ *
+ * @param cls unused
+ * @param key hash of public key of target peer
+ * @param value a 'struct PeerSession*' to clean up
+ * @return GNUNET_OK (continue to iterate)
+ */
+static int
+disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
+{
+ disconnect_session(value);
return GNUNET_OK;
}
@@ -804,6 +846,8 @@
s->flow_delay_from_other_peer = GNUNET_TIME_absolute_get_zero();
s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
+ start_session_timeout(s);
+
return s;
}
@@ -1129,6 +1173,7 @@
udp->reserved = htonl (0);
udp->sender = *plugin->env->my_identity;
+ reschedule_session_timeout(s);
if (mlen <= UDP_MTU)
{
udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + mlen);
@@ -1289,6 +1334,7 @@
si->arg,
si->args);
si->session->flow_delay_for_other_peer = delay;
+ reschedule_session_timeout(si->session);
return GNUNET_OK;
}
@@ -2141,8 +2187,84 @@
return sockets_created;
}
+/**
+ * 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 */
+ disconnect_session(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);
+ }
+}
+
+/**
* The exported method. Makes the core api available via a global and
* returns the udp transport API.
*
@@ -2154,7 +2276,7 @@
{
struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
struct GNUNET_TRANSPORT_PluginFunctions *api;
- struct Plugin *plugin;
+ struct Plugin *p;
unsigned long long port;
unsigned long long aport;
unsigned long long broadcast;
@@ -2263,21 +2385,23 @@
udp_max_bps = 1024 * 1024 * 50; /* 50 MB/s == infinity for practical
purposes */
}
- plugin = GNUNET_malloc (sizeof (struct Plugin));
+ p = GNUNET_malloc (sizeof (struct Plugin));
api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
- GNUNET_BANDWIDTH_tracker_init (&plugin->tracker,
+ GNUNET_BANDWIDTH_tracker_init (&p->tracker,
GNUNET_BANDWIDTH_value_init
((uint32_t)udp_max_bps), 30);
- plugin->sessions = GNUNET_CONTAINER_multihashmap_create (10);
- plugin->defrag_ctxs = GNUNET_CONTAINER_heap_create
(GNUNET_CONTAINER_HEAP_ORDER_MIN);
- plugin->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages,
plugin);
- plugin->port = port;
- plugin->aport = aport;
- plugin->broadcast_interval = interval;
- plugin->enable_ipv6 = enable_v6;
- plugin->env = env;
+ p->sessions = GNUNET_CONTAINER_multihashmap_create (10);
+ p->defrag_ctxs = GNUNET_CONTAINER_heap_create
(GNUNET_CONTAINER_HEAP_ORDER_MIN);
+ p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p);
+ p->port = port;
+ p->aport = aport;
+ p->broadcast_interval = interval;
+ p->enable_ipv6 = enable_v6;
+ p->env = env;
- api->cls = plugin;
+ plugin = p;
+
+ api->cls = p;
api->send = NULL;
api->disconnect = &udp_disconnect;
api->address_pretty_printer = &udp_plugin_address_pretty_printer;
@@ -2288,11 +2412,11 @@
api->send = &udp_plugin_send;
LOG (GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n");
- res = setup_sockets (plugin, &serverAddrv6, &serverAddrv4);
- if ((res == 0) || ((plugin->sockv4 == NULL) && (plugin->sockv6 == NULL)))
+ res = setup_sockets (p, &serverAddrv6, &serverAddrv4);
+ if ((res == 0) || ((p->sockv4 == NULL) && (p->sockv6 == NULL)))
{
LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create network sockets, plugin
failed\n");
- GNUNET_free (plugin);
+ GNUNET_free (p);
GNUNET_free (api);
return NULL;
}
@@ -2300,7 +2424,7 @@
if (broadcast == GNUNET_YES)
{
LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n");
- setup_broadcast (plugin, &serverAddrv6, &serverAddrv4);
+ setup_broadcast (p, &serverAddrv6, &serverAddrv4);
}
GNUNET_free_non_null (bind4_address);
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r21573 - gnunet/src/transport,
gnunet <=