aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-12-13 13:25:31 +0000
committerChristian Grothoff <christian@grothoff.org>2013-12-13 13:25:31 +0000
commitcdeef5dacc29fd2192b2df784a717812d4c80ec2 (patch)
tree907dd14832f7c473bf4a0a6b5bd848f678b09658 /src/transport/gnunet-service-transport.c
parentf588c2993d8034a5c893dacc770a367c7cb69c55 (diff)
downloadgnunet-cdeef5dacc29fd2192b2df784a717812d4c80ec2.tar.gz
gnunet-cdeef5dacc29fd2192b2df784a717812d4c80ec2.zip
-fix 3208 by making kills async
Diffstat (limited to 'src/transport/gnunet-service-transport.c')
-rw-r--r--src/transport/gnunet-service-transport.c96
1 files changed, 90 insertions, 6 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 5b09647ec..a4290a19a 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -40,6 +40,39 @@
40#include "gnunet-service-transport_manipulation.h" 40#include "gnunet-service-transport_manipulation.h"
41#include "transport.h" 41#include "transport.h"
42 42
43
44/**
45 * Information we need for an asynchronous session kill.
46 */
47struct SessionKiller
48{
49 /**
50 * Kept in a DLL.
51 */
52 struct SessionKiller *next;
53
54 /**
55 * Kept in a DLL.
56 */
57 struct SessionKiller *prev;
58
59 /**
60 * Session to kill.
61 */
62 struct Session *session;
63
64 /**
65 * Plugin for the session.
66 */
67 struct GNUNET_TRANSPORT_PluginFunctions *plugin;
68
69 /**
70 * The kill task.
71 */
72 GNUNET_SCHEDULER_TaskIdentifier task;
73};
74
75
43/* globals */ 76/* globals */
44 77
45/** 78/**
@@ -78,14 +111,24 @@ struct GNUNET_CRYPTO_EddsaPrivateKey *GST_my_private_key;
78struct GNUNET_ATS_SchedulingHandle *GST_ats; 111struct GNUNET_ATS_SchedulingHandle *GST_ats;
79 112
80/** 113/**
114 * Hello address expiration
115 */
116struct GNUNET_TIME_Relative hello_expiration;
117
118/**
81 * DEBUGGING connection counter 119 * DEBUGGING connection counter
82 */ 120 */
83static int connections; 121static int connections;
84 122
85/** 123/**
86 * Hello address expiration 124 * Head of DLL of asynchronous tasks to kill sessions.
87 */ 125 */
88struct GNUNET_TIME_Relative hello_expiration; 126static struct SessionKiller *sk_head;
127
128/**
129 * Tail of DLL of asynchronous tasks to kill sessions.
130 */
131static struct SessionKiller *sk_tail;
89 132
90 133
91/** 134/**
@@ -177,6 +220,26 @@ process_payload (const struct GNUNET_PeerIdentity *peer,
177 220
178 221
179/** 222/**
223 * Task to asynchronously terminate a session.
224 *
225 * @param cls the `struct SessionKiller` with the information for the kill
226 * @param tc scheduler context
227 */
228static void
229kill_session_task (void *cls,
230 const struct GNUNET_SCHEDULER_TaskContext *tc)
231{
232 struct SessionKiller *sk = cls;
233
234 sk->task = GNUNET_SCHEDULER_NO_TASK;
235 GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk);
236 sk->plugin->disconnect_session (sk->plugin->cls,
237 sk->session);
238 GNUNET_free (sk);
239}
240
241
242/**
180 * Force plugin to terminate session due to communication 243 * Force plugin to terminate session due to communication
181 * issue. 244 * issue.
182 * 245 *
@@ -188,15 +251,24 @@ kill_session (const char *plugin_name,
188 struct Session *session) 251 struct Session *session)
189{ 252{
190 struct GNUNET_TRANSPORT_PluginFunctions *plugin; 253 struct GNUNET_TRANSPORT_PluginFunctions *plugin;
254 struct SessionKiller *sk;
191 255
256 for (sk = sk_head; NULL != sk; sk = sk->next)
257 if (sk->session == session)
258 return;
192 plugin = GST_plugins_find (plugin_name); 259 plugin = GST_plugins_find (plugin_name);
193 if (NULL == plugin) 260 if (NULL == plugin)
194 { 261 {
195 GNUNET_break (0); 262 GNUNET_break (0);
196 return; 263 return;
197 } 264 }
198 plugin->disconnect_session (plugin->cls, 265 /* need to issue disconnect asynchronously */
199 session); 266 sk = GNUNET_new (struct SessionKiller);
267 sk->session = session;
268 sk->plugin = plugin;
269 sk->task = GNUNET_SCHEDULER_add_now (&kill_session_task,
270 sk);
271 GNUNET_CONTAINER_DLL_insert (sk_head, sk_tail, sk);
200} 272}
201 273
202 274
@@ -383,10 +455,13 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer,
383{ 455{
384 const char *transport_name = cls; 456 const char *transport_name = cls;
385 struct GNUNET_HELLO_Address address; 457 struct GNUNET_HELLO_Address address;
458 struct SessionKiller *sk;
386 459
387 GNUNET_assert (strlen (transport_name) > 0); 460 GNUNET_assert (strlen (transport_name) > 0);
388 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p to peer `%s' ended \n", 461 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
389 session, GNUNET_i2s (peer)); 462 "Session %p to peer `%s' ended \n",
463 session,
464 GNUNET_i2s (peer));
390 if (NULL != session) 465 if (NULL != session)
391 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK, 466 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
392 "transport-ats", 467 "transport-ats",
@@ -400,6 +475,15 @@ plugin_env_session_end (void *cls, const struct GNUNET_PeerIdentity *peer,
400 475
401 /* Tell ATS that session has ended */ 476 /* Tell ATS that session has ended */
402 GNUNET_ATS_address_destroyed (GST_ats, &address, session); 477 GNUNET_ATS_address_destroyed (GST_ats, &address, session);
478 for (sk = sk_head; NULL != sk; sk = sk->next)
479 {
480 if (sk->session == session)
481 {
482 GNUNET_CONTAINER_DLL_remove (sk_head, sk_tail, sk);
483 GNUNET_SCHEDULER_cancel (sk->task);
484 GNUNET_free (sk);
485 }
486 }
403} 487}
404 488
405 489