diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-12-13 13:25:31 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-12-13 13:25:31 +0000 |
commit | cdeef5dacc29fd2192b2df784a717812d4c80ec2 (patch) | |
tree | 907dd14832f7c473bf4a0a6b5bd848f678b09658 /src/transport/gnunet-service-transport.c | |
parent | f588c2993d8034a5c893dacc770a367c7cb69c55 (diff) | |
download | gnunet-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.c | 96 |
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 | */ | ||
47 | struct 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; | |||
78 | struct GNUNET_ATS_SchedulingHandle *GST_ats; | 111 | struct GNUNET_ATS_SchedulingHandle *GST_ats; |
79 | 112 | ||
80 | /** | 113 | /** |
114 | * Hello address expiration | ||
115 | */ | ||
116 | struct GNUNET_TIME_Relative hello_expiration; | ||
117 | |||
118 | /** | ||
81 | * DEBUGGING connection counter | 119 | * DEBUGGING connection counter |
82 | */ | 120 | */ |
83 | static int connections; | 121 | static int connections; |
84 | 122 | ||
85 | /** | 123 | /** |
86 | * Hello address expiration | 124 | * Head of DLL of asynchronous tasks to kill sessions. |
87 | */ | 125 | */ |
88 | struct GNUNET_TIME_Relative hello_expiration; | 126 | static struct SessionKiller *sk_head; |
127 | |||
128 | /** | ||
129 | * Tail of DLL of asynchronous tasks to kill sessions. | ||
130 | */ | ||
131 | static 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 | */ | ||
228 | static void | ||
229 | kill_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 | ||