aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/gnunet-service-transport.c96
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c8
-rw-r--r--src/transport/plugin_transport_tcp.c12
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 */
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
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 */
879static void 879static void
880free_neighbour (struct NeighbourMapEntry *n, int keep_sessions) 880free_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