diff options
Diffstat (limited to 'src/transport')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 96 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 8 | ||||
-rw-r--r-- | src/transport/plugin_transport_tcp.c | 12 |
3 files changed, 101 insertions, 15 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 | ||
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index 1273700a2..f113dc870 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -877,7 +877,8 @@ set_address (struct NeighbourAddress *na, | |||
877 | * #GNUNET_YES to keep all sessions | 877 | * #GNUNET_YES to keep all sessions |
878 | */ | 878 | */ |
879 | static void | 879 | static void |
880 | free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) | 880 | free_neighbour (struct NeighbourMapEntry *n, |
881 | int keep_sessions) | ||
881 | { | 882 | { |
882 | struct MessageQueue *mq; | 883 | struct MessageQueue *mq; |
883 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | 884 | struct GNUNET_TRANSPORT_PluginFunctions *papi; |
@@ -3090,7 +3091,10 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, | |||
3090 | ("# SESSION_ACK messages received"), | 3091 | ("# SESSION_ACK messages received"), |
3091 | 1, GNUNET_NO); | 3092 | 1, GNUNET_NO); |
3092 | if (NULL == (n = lookup_neighbour (peer))) | 3093 | if (NULL == (n = lookup_neighbour (peer))) |
3094 | { | ||
3095 | GNUNET_break_op (0); | ||
3093 | return GNUNET_SYSERR; | 3096 | return GNUNET_SYSERR; |
3097 | } | ||
3094 | /* check if we are in a plausible state for having sent | 3098 | /* check if we are in a plausible state for having sent |
3095 | a CONNECT_ACK. If not, return, otherwise break */ | 3099 | a CONNECT_ACK. If not, return, otherwise break */ |
3096 | if ( ( (S_CONNECT_RECV_ACK != n->state) && | 3100 | if ( ( (S_CONNECT_RECV_ACK != n->state) && |
@@ -3105,7 +3109,7 @@ GST_neighbours_handle_session_ack (const struct GNUNET_MessageHeader *message, | |||
3105 | GNUNET_STATISTICS_update (GST_stats, | 3109 | GNUNET_STATISTICS_update (GST_stats, |
3106 | gettext_noop ("# unexpected SESSION_ACK messages"), 1, | 3110 | gettext_noop ("# unexpected SESSION_ACK messages"), 1, |
3107 | GNUNET_NO); | 3111 | GNUNET_NO); |
3108 | return GNUNET_SYSERR; | 3112 | return GNUNET_OK; |
3109 | } | 3113 | } |
3110 | n->state = S_CONNECTED; | 3114 | n->state = S_CONNECTED; |
3111 | n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 3115 | n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c index 9e78e47d9..e0572d5d0 100644 --- a/src/transport/plugin_transport_tcp.c +++ b/src/transport/plugin_transport_tcp.c | |||
@@ -2297,13 +2297,11 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, | |||
2297 | (GNUNET_YES == session->inbound) ? NULL : session->addr, | 2297 | (GNUNET_YES == session->inbound) ? NULL : session->addr, |
2298 | (GNUNET_YES == session->inbound) ? 0 : session->addrlen); | 2298 | (GNUNET_YES == session->inbound) ? 0 : session->addrlen); |
2299 | plugin->env->update_address_metrics (plugin->env->cls, | 2299 | plugin->env->update_address_metrics (plugin->env->cls, |
2300 | &session->target, | 2300 | &session->target, |
2301 | (GNUNET_YES == session->inbound) ? NULL : session->addr, | 2301 | (GNUNET_YES == session->inbound) ? NULL : session->addr, |
2302 | (GNUNET_YES == session->inbound) ? 0 : session->addrlen, | 2302 | (GNUNET_YES == session->inbound) ? 0 : session->addrlen, |
2303 | session, &distance, 1); | 2303 | session, &distance, 1); |
2304 | |||
2305 | reschedule_session_timeout (session); | 2304 | reschedule_session_timeout (session); |
2306 | |||
2307 | if (0 == delay.rel_value_us) | 2305 | if (0 == delay.rel_value_us) |
2308 | { | 2306 | { |
2309 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 2307 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
@@ -2316,7 +2314,7 @@ handle_tcp_data (void *cls, struct GNUNET_SERVER_Client *client, | |||
2316 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); | 2314 | GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES)); |
2317 | GNUNET_SERVER_disable_receive_done_warning (client); | 2315 | GNUNET_SERVER_disable_receive_done_warning (client); |
2318 | session->receive_delay_task = | 2316 | session->receive_delay_task = |
2319 | GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session); | 2317 | GNUNET_SCHEDULER_add_delayed (delay, &delayed_done, session); |
2320 | } | 2318 | } |
2321 | } | 2319 | } |
2322 | 2320 | ||