aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r--src/transport/plugin_transport_udp.c176
1 files changed, 150 insertions, 26 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 60814327c..5b133951b 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -111,6 +111,11 @@ struct Session
111 struct GNUNET_TIME_Absolute flow_delay_from_other_peer; 111 struct GNUNET_TIME_Absolute flow_delay_from_other_peer;
112 112
113 /** 113 /**
114 * Session timeout task
115 */
116 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
117
118 /**
114 * expected delay for ACKs 119 * expected delay for ACKs
115 */ 120 */
116 struct GNUNET_TIME_Relative last_expected_delay; 121 struct GNUNET_TIME_Relative last_expected_delay;
@@ -293,6 +298,11 @@ struct UDP_ACK_Message
293 298
294}; 299};
295 300
301/**
302 * Encapsulation of all of the state of the plugin.
303 */
304struct Plugin * plugin;
305
296 306
297/** 307/**
298 * We have been notified that our readset has something to read. We don't 308 * We have been notified that our readset has something to read. We don't
@@ -317,6 +327,26 @@ static void
317udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 327udp_plugin_select_v6 (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
318 328
319/** 329/**
330 * Start session timeout
331 */
332static void
333start_session_timeout (struct Session *s);
334
335/**
336 * Increment session timeout due to activity
337 */
338static void
339reschedule_session_timeout (struct Session *s);
340
341/**
342 * Cancel timeout
343 */
344static void
345stop_session_timeout (struct Session *s);
346
347
348
349/**
320 * Function called for a quick conversion of the binary address to 350 * Function called for a quick conversion of the binary address to
321 * a numeric address. Note that the caller must not free the 351 * a numeric address. Note that the caller must not free the
322 * address and that the next call to this function is allowed 352 * address and that the next call to this function is allowed
@@ -649,18 +679,15 @@ free_session (struct Session *s)
649 679
650 680
651/** 681/**
652 * Destroy a session, plugin is being unloaded. 682 * Functions with this signature are called whenever we need
683 * to close a session due to a disconnect or failure to
684 * establish a connection.
653 * 685 *
654 * @param cls unused 686 * @param session session to close down
655 * @param key hash of public key of target peer
656 * @param value a 'struct PeerSession*' to clean up
657 * @return GNUNET_OK (continue to iterate)
658 */ 687 */
659static int 688static void
660disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value) 689disconnect_session (struct Session *s)
661{ 690{
662 struct Plugin *plugin = cls;
663 struct Session *s = value;
664 struct UDPMessageWrapper *udpw; 691 struct UDPMessageWrapper *udpw;
665 struct UDPMessageWrapper *next; 692 struct UDPMessageWrapper *next;
666 693
@@ -670,6 +697,7 @@ disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
670 s, 697 s,
671 GNUNET_i2s (&s->target), 698 GNUNET_i2s (&s->target),
672 GNUNET_a2s (s->sock_addr, s->addrlen)); 699 GNUNET_a2s (s->sock_addr, s->addrlen));
700 stop_session_timeout(s);
673 next = plugin->ipv4_queue_head; 701 next = plugin->ipv4_queue_head;
674 while (NULL != (udpw = next)) 702 while (NULL != (udpw = next))
675 { 703 {
@@ -718,6 +746,20 @@ disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
718 s->in_destroy = GNUNET_YES; 746 s->in_destroy = GNUNET_YES;
719 else 747 else
720 free_session (s); 748 free_session (s);
749}
750
751/**
752 * Destroy a session, plugin is being unloaded.
753 *
754 * @param cls unused
755 * @param key hash of public key of target peer
756 * @param value a 'struct PeerSession*' to clean up
757 * @return GNUNET_OK (continue to iterate)
758 */
759static int
760disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
761{
762 disconnect_session(value);
721 return GNUNET_OK; 763 return GNUNET_OK;
722} 764}
723 765
@@ -804,6 +846,8 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target,
804 s->flow_delay_from_other_peer = GNUNET_TIME_absolute_get_zero(); 846 s->flow_delay_from_other_peer = GNUNET_TIME_absolute_get_zero();
805 s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS; 847 s->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
806 848
849 start_session_timeout(s);
850
807 return s; 851 return s;
808} 852}
809 853
@@ -1129,6 +1173,7 @@ udp_plugin_send (void *cls,
1129 udp->reserved = htonl (0); 1173 udp->reserved = htonl (0);
1130 udp->sender = *plugin->env->my_identity; 1174 udp->sender = *plugin->env->my_identity;
1131 1175
1176 reschedule_session_timeout(s);
1132 if (mlen <= UDP_MTU) 1177 if (mlen <= UDP_MTU)
1133 { 1178 {
1134 udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + mlen); 1179 udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + mlen);
@@ -1289,6 +1334,7 @@ process_inbound_tokenized_messages (void *cls, void *client,
1289 si->arg, 1334 si->arg,
1290 si->args); 1335 si->args);
1291 si->session->flow_delay_for_other_peer = delay; 1336 si->session->flow_delay_for_other_peer = delay;
1337 reschedule_session_timeout(si->session);
1292 return GNUNET_OK; 1338 return GNUNET_OK;
1293} 1339}
1294 1340
@@ -2141,6 +2187,82 @@ setup_sockets (struct Plugin *plugin, struct sockaddr_in6 *serverAddrv6, struct
2141 return sockets_created; 2187 return sockets_created;
2142} 2188}
2143 2189
2190/**
2191 * Session was idle, so disconnect it
2192 */
2193static void
2194session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2195{
2196 GNUNET_assert (NULL != cls);
2197 struct Session *s = cls;
2198
2199 s->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2200
2201 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Session %p was idle for %llu, disconnecting\n",
2202 s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value);
2203
2204 /* call session destroy function */
2205 disconnect_session(s);
2206
2207}
2208
2209/**
2210 * Start session timeout
2211 */
2212static void
2213start_session_timeout (struct Session *s)
2214{
2215 GNUNET_assert (NULL != s);
2216 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == s->timeout_task);
2217
2218 s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2219 &session_timeout,
2220 s);
2221
2222 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p set to %llu\n",
2223 s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value);
2224}
2225
2226/**
2227 * Increment session timeout due to activity
2228 */
2229static void
2230reschedule_session_timeout (struct Session *s)
2231{
2232 GNUNET_assert (NULL != s);
2233 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != s->timeout_task);
2234
2235 GNUNET_SCHEDULER_cancel (s->timeout_task);
2236 s->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
2237 &session_timeout,
2238 s);
2239
2240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p set to %llu\n",
2241 s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value);
2242}
2243
2244/**
2245 * Cancel timeout
2246 */
2247static void
2248stop_session_timeout (struct Session *s)
2249{
2250 GNUNET_assert (NULL != s);
2251
2252 if (GNUNET_SCHEDULER_NO_TASK != s->timeout_task)
2253 {
2254 GNUNET_SCHEDULER_cancel (s->timeout_task);
2255 s->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2256
2257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout rescheduled for session %p canceled\n",
2258 s, GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT.rel_value);
2259 }
2260 else
2261 {
2262 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Timeout for session %p was not active\n",
2263 s);
2264 }
2265}
2144 2266
2145/** 2267/**
2146 * The exported method. Makes the core api available via a global and 2268 * The exported method. Makes the core api available via a global and
@@ -2154,7 +2276,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
2154{ 2276{
2155 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; 2277 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2156 struct GNUNET_TRANSPORT_PluginFunctions *api; 2278 struct GNUNET_TRANSPORT_PluginFunctions *api;
2157 struct Plugin *plugin; 2279 struct Plugin *p;
2158 unsigned long long port; 2280 unsigned long long port;
2159 unsigned long long aport; 2281 unsigned long long aport;
2160 unsigned long long broadcast; 2282 unsigned long long broadcast;
@@ -2263,21 +2385,23 @@ libgnunet_plugin_transport_udp_init (void *cls)
2263 udp_max_bps = 1024 * 1024 * 50; /* 50 MB/s == infinity for practical purposes */ 2385 udp_max_bps = 1024 * 1024 * 50; /* 50 MB/s == infinity for practical purposes */
2264 } 2386 }
2265 2387
2266 plugin = GNUNET_malloc (sizeof (struct Plugin)); 2388 p = GNUNET_malloc (sizeof (struct Plugin));
2267 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions)); 2389 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2268 2390
2269 GNUNET_BANDWIDTH_tracker_init (&plugin->tracker, 2391 GNUNET_BANDWIDTH_tracker_init (&p->tracker,
2270 GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30); 2392 GNUNET_BANDWIDTH_value_init ((uint32_t)udp_max_bps), 30);
2271 plugin->sessions = GNUNET_CONTAINER_multihashmap_create (10); 2393 p->sessions = GNUNET_CONTAINER_multihashmap_create (10);
2272 plugin->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 2394 p->defrag_ctxs = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
2273 plugin->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, plugin); 2395 p->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, p);
2274 plugin->port = port; 2396 p->port = port;
2275 plugin->aport = aport; 2397 p->aport = aport;
2276 plugin->broadcast_interval = interval; 2398 p->broadcast_interval = interval;
2277 plugin->enable_ipv6 = enable_v6; 2399 p->enable_ipv6 = enable_v6;
2278 plugin->env = env; 2400 p->env = env;
2279 2401
2280 api->cls = plugin; 2402 plugin = p;
2403
2404 api->cls = p;
2281 api->send = NULL; 2405 api->send = NULL;
2282 api->disconnect = &udp_disconnect; 2406 api->disconnect = &udp_disconnect;
2283 api->address_pretty_printer = &udp_plugin_address_pretty_printer; 2407 api->address_pretty_printer = &udp_plugin_address_pretty_printer;
@@ -2288,11 +2412,11 @@ libgnunet_plugin_transport_udp_init (void *cls)
2288 api->send = &udp_plugin_send; 2412 api->send = &udp_plugin_send;
2289 2413
2290 LOG (GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n"); 2414 LOG (GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n");
2291 res = setup_sockets (plugin, &serverAddrv6, &serverAddrv4); 2415 res = setup_sockets (p, &serverAddrv6, &serverAddrv4);
2292 if ((res == 0) || ((plugin->sockv4 == NULL) && (plugin->sockv6 == NULL))) 2416 if ((res == 0) || ((p->sockv4 == NULL) && (p->sockv6 == NULL)))
2293 { 2417 {
2294 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create network sockets, plugin failed\n"); 2418 LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to create network sockets, plugin failed\n");
2295 GNUNET_free (plugin); 2419 GNUNET_free (p);
2296 GNUNET_free (api); 2420 GNUNET_free (api);
2297 return NULL; 2421 return NULL;
2298 } 2422 }
@@ -2300,7 +2424,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
2300 if (broadcast == GNUNET_YES) 2424 if (broadcast == GNUNET_YES)
2301 { 2425 {
2302 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n"); 2426 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n");
2303 setup_broadcast (plugin, &serverAddrv6, &serverAddrv4); 2427 setup_broadcast (p, &serverAddrv6, &serverAddrv4);
2304 } 2428 }
2305 2429
2306 GNUNET_free_non_null (bind4_address); 2430 GNUNET_free_non_null (bind4_address);