aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/transport/plugin_transport_udp.c503
-rw-r--r--src/transport/plugin_transport_udp.h58
-rw-r--r--src/transport/plugin_transport_udp_broadcasting.c12
3 files changed, 285 insertions, 288 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 3702d99be..f6b1ac251 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -68,6 +68,29 @@
68 68
69 69
70/** 70/**
71 * UDP Message-Packet header (after defragmentation).
72 */
73struct UDPMessage
74{
75 /**
76 * Message header.
77 */
78 struct GNUNET_MessageHeader header;
79
80 /**
81 * Always zero for now.
82 */
83 uint32_t reserved;
84
85 /**
86 * What is the identity of the sender
87 */
88 struct GNUNET_PeerIdentity sender;
89
90};
91
92
93/**
71 * Closure for #append_port(). 94 * Closure for #append_port().
72 */ 95 */
73struct PrettyPrinterContext 96struct PrettyPrinterContext
@@ -213,32 +236,6 @@ struct Session
213}; 236};
214 237
215 238
216/**
217 * Closure for #find_receive_context().
218 */
219struct FindReceiveContext
220{
221 /**
222 * Where to store the result.
223 */
224 struct DefragContext *rc;
225
226 /**
227 * Session associated with this context.
228 */
229 struct Session *session;
230
231 /**
232 * Address to find.
233 */
234 const union UdpAddress *udp_addr;
235
236 /**
237 * Number of bytes in @e udp_addr.
238 */
239 size_t udp_addr_len;
240
241};
242 239
243/** 240/**
244 * Data structure to track defragmentation contexts based 241 * Data structure to track defragmentation contexts based
@@ -263,6 +260,12 @@ struct DefragContext
263 struct GNUNET_CONTAINER_HeapNode *hnode; 260 struct GNUNET_CONTAINER_HeapNode *hnode;
264 261
265 /** 262 /**
263 * Source address this receive context is for (allocated at the
264 * end of the struct).
265 */
266 const union UdpAddress *udp_addr;
267
268 /**
266 * Who's message(s) are we defragmenting here? 269 * Who's message(s) are we defragmenting here?
267 * Only initialized once we succeeded and 270 * Only initialized once we succeeded and
268 * @e have_sender is set. 271 * @e have_sender is set.
@@ -270,12 +273,6 @@ struct DefragContext
270 struct GNUNET_PeerIdentity sender; 273 struct GNUNET_PeerIdentity sender;
271 274
272 /** 275 /**
273 * Source address this receive context is for (allocated at the
274 * end of the struct).
275 */
276 const union UdpAddress *udp_addr;
277
278 /**
279 * Length of @e udp_addr. 276 * Length of @e udp_addr.
280 */ 277 */
281 size_t udp_addr_len; 278 size_t udp_addr_len;
@@ -313,7 +310,7 @@ struct UDP_FragmentationContext
313 struct Plugin *plugin; 310 struct Plugin *plugin;
314 311
315 /** 312 /**
316 * Handle for GNUNET_FRAGMENT context 313 * Handle for fragmentation.
317 */ 314 */
318 struct GNUNET_FRAGMENT_Context *frag; 315 struct GNUNET_FRAGMENT_Context *frag;
319 316
@@ -347,11 +344,6 @@ struct UDP_FragmentationContext
347 */ 344 */
348 size_t on_wire_size; 345 size_t on_wire_size;
349 346
350 /**
351 * FIXME.
352 */
353 unsigned int fragments_used;
354
355}; 347};
356 348
357 349
@@ -366,22 +358,26 @@ enum UDP_MessageType
366 UMT_UNDEFINED = 0, 358 UMT_UNDEFINED = 0,
367 359
368 /** 360 /**
369 * Fragment of a message. 361 * This queue entry represents a fragment of a message.
370 */ 362 */
371 UMT_MSG_FRAGMENTED = 1, 363 UMT_MSG_FRAGMENTED = 1,
372 364
373 /** 365 /**
374 * 366 * This queue entry does not include a message, but merely
367 * represents that we finished sending a fragmented message
368 * (all fragments confirmed, or timeout).
375 */ 369 */
376 UMT_MSG_FRAGMENTED_COMPLETE = 2, 370 UMT_MSG_FRAGMENTED_COMPLETE = 2,
377 371
378 /** 372 /**
379 * Unfragmented message. 373 * This queue entry represents a unfragmented message
374 * (was small enough to not require fragmentation).
380 */ 375 */
381 UMT_MSG_UNFRAGMENTED = 3, 376 UMT_MSG_UNFRAGMENTED = 3,
382 377
383 /** 378 /**
384 * Receipt confirmation. 379 * This queue entry represents the acknowledgement of us
380 * receiving a fragment.
385 */ 381 */
386 UMT_MSG_ACK = 4 382 UMT_MSG_ACK = 4
387 383
@@ -399,24 +395,22 @@ struct UDP_MessageWrapper
399 struct Session *session; 395 struct Session *session;
400 396
401 /** 397 /**
402 * DLL of messages 398 * DLL of messages, previous element
403 * previous element
404 */ 399 */
405 struct UDP_MessageWrapper *prev; 400 struct UDP_MessageWrapper *prev;
406 401
407 /** 402 /**
408 * DLL of messages 403 * DLL of messages, next element
409 * previous element
410 */ 404 */
411 struct UDP_MessageWrapper *next; 405 struct UDP_MessageWrapper *next;
412 406
413 /** 407 /**
414 * Message with size msg_size including UDP specific overhead 408 * Message with @e msg_size bytes including UDP-specific overhead.
415 */ 409 */
416 char *msg_buf; 410 char *msg_buf;
417 411
418 /** 412 /**
419 * Function to call upon completion of the transmission. 413 * Function to call upon completion of the transmission, can be NULL.
420 */ 414 */
421 GNUNET_TRANSPORT_TransmitContinuation cont; 415 GNUNET_TRANSPORT_TransmitContinuation cont;
422 416
@@ -426,29 +420,29 @@ struct UDP_MessageWrapper
426 void *cont_cls; 420 void *cont_cls;
427 421
428 /** 422 /**
429 * Fragmentation context 423 * Fragmentation context.
430 * frag_ctx == NULL if transport <= MTU 424 * frag_ctx == NULL if transport <= MTU
431 * frag_ctx != NULL if transport > MTU 425 * frag_ctx != NULL if transport > MTU
432 */ 426 */
433 struct UDP_FragmentationContext *frag_ctx; 427 struct UDP_FragmentationContext *frag_ctx;
434 428
435 /** 429 /**
436 * Message timeout 430 * Message timeout.
437 */ 431 */
438 struct GNUNET_TIME_Absolute timeout; 432 struct GNUNET_TIME_Absolute timeout;
439 433
440 /** 434 /**
441 * Size of UDP message to send including UDP specific overhead 435 * Size of UDP message to send, including UDP-specific overhead.
442 */ 436 */
443 size_t msg_size; 437 size_t msg_size;
444 438
445 /** 439 /**
446 * Payload size of original message 440 * Payload size of original message.
447 */ 441 */
448 size_t payload_size; 442 size_t payload_size;
449 443
450 /** 444 /**
451 * Message type 445 * Message type (what does this entry in the queue represent).
452 */ 446 */
453 enum UDP_MessageType msg_type; 447 enum UDP_MessageType msg_type;
454 448
@@ -466,7 +460,7 @@ struct UDP_ACK_Message
466 struct GNUNET_MessageHeader header; 460 struct GNUNET_MessageHeader header;
467 461
468 /** 462 /**
469 * Desired delay for flow control 463 * Desired delay for flow control, in us (in NBO).
470 */ 464 */
471 uint32_t delay; 465 uint32_t delay;
472 466
@@ -497,7 +491,9 @@ notify_session_monitor (struct Plugin *plugin,
497 return; 491 return;
498 if (GNUNET_YES == session->in_destroy) 492 if (GNUNET_YES == session->in_destroy)
499 return; /* already destroyed, just RC>0 left-over actions */ 493 return; /* already destroyed, just RC>0 left-over actions */
500 memset (&info, 0, sizeof (info)); 494 memset (&info,
495 0,
496 sizeof (info));
501 info.state = state; 497 info.state = state;
502 info.is_inbound = GNUNET_SYSERR; /* hard to say */ 498 info.is_inbound = GNUNET_SYSERR; /* hard to say */
503 info.num_msg_pending = session->msgs_in_queue; 499 info.num_msg_pending = session->msgs_in_queue;
@@ -522,8 +518,8 @@ notify_session_monitor (struct Plugin *plugin,
522 * @param tc the scheduling context (for rescheduling this function again) 518 * @param tc the scheduling context (for rescheduling this function again)
523 */ 519 */
524static void 520static void
525udp_plugin_select (void *cls, 521udp_plugin_select_v4 (void *cls,
526 const struct GNUNET_SCHEDULER_TaskContext *tc); 522 const struct GNUNET_SCHEDULER_TaskContext *tc);
527 523
528 524
529/** 525/**
@@ -540,55 +536,61 @@ udp_plugin_select_v6 (void *cls,
540 536
541 537
542/** 538/**
543 * (re)schedule select tasks for this plugin. 539 * (re)schedule IPv4-select tasks for this plugin.
544 * 540 *
545 * @param plugin plugin to reschedule 541 * @param plugin plugin to reschedule
546 */ 542 */
547static void 543static void
548schedule_select (struct Plugin *plugin) 544schedule_select_v4 (struct Plugin *plugin)
549{ 545{
550 struct GNUNET_TIME_Relative min_delay; 546 struct GNUNET_TIME_Relative min_delay;
551 struct UDP_MessageWrapper *udpw; 547 struct UDP_MessageWrapper *udpw;
552 548
553 if ((GNUNET_YES == plugin->enable_ipv4) && (NULL != plugin->sockv4)) 549 if ( (GNUNET_YES == plugin->enable_ipv4) &&
550 (NULL != plugin->sockv4) )
554 { 551 {
555 /* Find a message ready to send: 552 /* Find a message ready to send:
556 * Flow delay from other peer is expired or not set (0) */ 553 * Flow delay from other peer is expired or not set (0) */
557 min_delay = GNUNET_TIME_UNIT_FOREVER_REL; 554 min_delay = GNUNET_TIME_UNIT_FOREVER_REL;
558 for (udpw = plugin->ipv4_queue_head; NULL != udpw; udpw = udpw->next) 555 for (udpw = plugin->ipv4_queue_head; NULL != udpw; udpw = udpw->next)
559 min_delay = GNUNET_TIME_relative_min (min_delay, 556 min_delay = GNUNET_TIME_relative_min (min_delay,
560 GNUNET_TIME_absolute_get_remaining ( 557 GNUNET_TIME_absolute_get_remaining (udpw->session->flow_delay_from_other_peer));
561 udpw->session->flow_delay_from_other_peer)); 558 if (NULL != plugin->select_task_v4)
559 GNUNET_SCHEDULER_cancel (plugin->select_task_v4);
560 plugin->select_task_v4
561 = GNUNET_SCHEDULER_add_read_net (min_delay,
562 plugin->sockv4,
563 &udp_plugin_select_v4,
564 plugin);
565 }
566}
562 567
563 if (plugin->select_task != NULL )
564 GNUNET_SCHEDULER_cancel (plugin->select_task);
565 568
566 /* Schedule with: 569/**
567 * - write active set if message is ready 570 * (re)schedule IPv6-select tasks for this plugin.
568 * - timeout minimum delay */ 571 *
569 plugin->select_task = GNUNET_SCHEDULER_add_select ( 572 * @param plugin plugin to reschedule
570 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 573 */
571 (0 == min_delay.rel_value_us) ? 574static void
572 GNUNET_TIME_UNIT_FOREVER_REL : min_delay, plugin->rs_v4, 575schedule_select_v6 (struct Plugin *plugin)
573 (0 == min_delay.rel_value_us) ? plugin->ws_v4 : NULL, 576{
574 &udp_plugin_select, plugin); 577 struct GNUNET_TIME_Relative min_delay;
575 } 578 struct UDP_MessageWrapper *udpw;
576 if ((GNUNET_YES == plugin->enable_ipv6) && (NULL != plugin->sockv6)) 579
580 if ( (GNUNET_YES == plugin->enable_ipv6) &&
581 (NULL != plugin->sockv6) )
577 { 582 {
578 min_delay = GNUNET_TIME_UNIT_FOREVER_REL; 583 min_delay = GNUNET_TIME_UNIT_FOREVER_REL;
579 for (udpw = plugin->ipv6_queue_head; NULL != udpw; udpw = udpw->next) 584 for (udpw = plugin->ipv6_queue_head; NULL != udpw; udpw = udpw->next)
580 min_delay = GNUNET_TIME_relative_min (min_delay, 585 min_delay = GNUNET_TIME_relative_min (min_delay,
581 GNUNET_TIME_absolute_get_remaining ( 586 GNUNET_TIME_absolute_get_remaining (udpw->session->flow_delay_from_other_peer));
582 udpw->session->flow_delay_from_other_peer));
583
584 if (NULL != plugin->select_task_v6) 587 if (NULL != plugin->select_task_v6)
585 GNUNET_SCHEDULER_cancel (plugin->select_task_v6); 588 GNUNET_SCHEDULER_cancel (plugin->select_task_v6);
586 plugin->select_task_v6 = GNUNET_SCHEDULER_add_select ( 589 plugin->select_task_v6
587 GNUNET_SCHEDULER_PRIORITY_DEFAULT, 590 = GNUNET_SCHEDULER_add_read_net (min_delay,
588 (0 == min_delay.rel_value_us) ? 591 plugin->sockv6,
589 GNUNET_TIME_UNIT_FOREVER_REL : min_delay, plugin->rs_v6, 592 &udp_plugin_select_v6,
590 (0 == min_delay.rel_value_us) ? plugin->ws_v6 : NULL, 593 plugin);
591 &udp_plugin_select_v6, plugin);
592 } 594 }
593} 595}
594 596
@@ -1347,6 +1349,34 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
1347 1349
1348 1350
1349/** 1351/**
1352 * Closure for #find_receive_context().
1353 */
1354struct FindReceiveContext
1355{
1356 /**
1357 * Where to store the result.
1358 */
1359 struct DefragContext *rc;
1360
1361 /**
1362 * Session associated with this context.
1363 */
1364 struct Session *session;
1365
1366 /**
1367 * Address to find.
1368 */
1369 const union UdpAddress *udp_addr;
1370
1371 /**
1372 * Number of bytes in @e udp_addr.
1373 */
1374 size_t udp_addr_len;
1375
1376};
1377
1378
1379/**
1350 * Scan the heap for a receive context with the given address. 1380 * Scan the heap for a receive context with the given address.
1351 * 1381 *
1352 * @param cls the `struct FindReceiveContext` 1382 * @param cls the `struct FindReceiveContext`
@@ -1979,13 +2009,12 @@ enqueue_fragment (void *cls,
1979{ 2009{
1980 struct UDP_FragmentationContext *frag_ctx = cls; 2010 struct UDP_FragmentationContext *frag_ctx = cls;
1981 struct Plugin *plugin = frag_ctx->plugin; 2011 struct Plugin *plugin = frag_ctx->plugin;
1982 struct UDP_MessageWrapper * udpw; 2012 struct UDP_MessageWrapper *udpw;
1983 size_t msg_len = ntohs (msg->size); 2013 size_t msg_len = ntohs (msg->size);
1984 2014
1985 LOG (GNUNET_ERROR_TYPE_DEBUG, 2015 LOG (GNUNET_ERROR_TYPE_DEBUG,
1986 "Enqueuing fragment with %u bytes\n", 2016 "Enqueuing fragment with %u bytes\n",
1987 msg_len); 2017 msg_len);
1988 frag_ctx->fragments_used++;
1989 udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msg_len); 2018 udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msg_len);
1990 udpw->session = frag_ctx->session; 2019 udpw->session = frag_ctx->session;
1991 udpw->msg_buf = (char *) &udpw[1]; 2020 udpw->msg_buf = (char *) &udpw[1];
@@ -1997,8 +2026,12 @@ enqueue_fragment (void *cls,
1997 udpw->frag_ctx = frag_ctx; 2026 udpw->frag_ctx = frag_ctx;
1998 udpw->msg_type = UMT_MSG_FRAGMENTED; 2027 udpw->msg_type = UMT_MSG_FRAGMENTED;
1999 memcpy (udpw->msg_buf, msg, msg_len); 2028 memcpy (udpw->msg_buf, msg, msg_len);
2000 enqueue (plugin, udpw); 2029 enqueue (plugin,
2001 schedule_select (plugin); 2030 udpw);
2031 if (udpw->session->address->address_length == sizeof (struct IPv4UdpAddress))
2032 schedule_select_v4 (plugin);
2033 else
2034 schedule_select_v6 (plugin);
2002} 2035}
2003 2036
2004 2037
@@ -2151,7 +2184,10 @@ udp_plugin_send (void *cls,
2151 notify_session_monitor (s->plugin, 2184 notify_session_monitor (s->plugin,
2152 s, 2185 s,
2153 GNUNET_TRANSPORT_SS_UPDATE); 2186 GNUNET_TRANSPORT_SS_UPDATE);
2154 schedule_select (plugin); 2187 if (s->address->address_length == sizeof (struct IPv4UdpAddress))
2188 schedule_select_v4 (plugin);
2189 else
2190 schedule_select_v6 (plugin);
2155 return udpmlen; 2191 return udpmlen;
2156} 2192}
2157 2193
@@ -2334,7 +2370,7 @@ static void
2334fragment_msg_proc (void *cls, 2370fragment_msg_proc (void *cls,
2335 const struct GNUNET_MessageHeader *msg) 2371 const struct GNUNET_MessageHeader *msg)
2336{ 2372{
2337 struct DefragContext *rc = cls; 2373 struct DefragContext *dc = cls;
2338 const struct UDPMessage *um; 2374 const struct UDPMessage *um;
2339 2375
2340 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE) 2376 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE)
@@ -2348,13 +2384,13 @@ fragment_msg_proc (void *cls,
2348 return; 2384 return;
2349 } 2385 }
2350 um = (const struct UDPMessage *) msg; 2386 um = (const struct UDPMessage *) msg;
2351 rc->sender = um->sender; 2387 dc->sender = um->sender;
2352 rc->have_sender = GNUNET_YES; 2388 dc->have_sender = GNUNET_YES;
2353 process_udp_message (rc->plugin, 2389 process_udp_message (dc->plugin,
2354 um, 2390 um,
2355 rc->udp_addr, 2391 dc->udp_addr,
2356 rc->udp_addr_len, 2392 dc->udp_addr_len,
2357 rc->network_type); 2393 dc->network_type);
2358} 2394}
2359 2395
2360 2396
@@ -2373,7 +2409,7 @@ ack_proc (void *cls,
2373 struct DefragContext *rc = cls; 2409 struct DefragContext *rc = cls;
2374 size_t msize = sizeof(struct UDP_ACK_Message) + ntohs (msg->size); 2410 size_t msize = sizeof(struct UDP_ACK_Message) + ntohs (msg->size);
2375 struct UDP_ACK_Message *udp_ack; 2411 struct UDP_ACK_Message *udp_ack;
2376 uint32_t delay = 0; 2412 uint32_t delay;
2377 struct UDP_MessageWrapper *udpw; 2413 struct UDP_MessageWrapper *udpw;
2378 struct Session *s; 2414 struct Session *s;
2379 struct GNUNET_HELLO_Address *address; 2415 struct GNUNET_HELLO_Address *address;
@@ -2406,6 +2442,8 @@ ack_proc (void *cls,
2406 } 2442 }
2407 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) 2443 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX)
2408 delay = s->flow_delay_for_other_peer.rel_value_us; 2444 delay = s->flow_delay_for_other_peer.rel_value_us;
2445 else
2446 delay = UINT32_MAX;
2409 2447
2410 LOG (GNUNET_ERROR_TYPE_DEBUG, 2448 LOG (GNUNET_ERROR_TYPE_DEBUG,
2411 "Sending ACK to `%s' including delay of %s\n", 2449 "Sending ACK to `%s' including delay of %s\n",
@@ -2431,7 +2469,10 @@ ack_proc (void *cls,
2431 notify_session_monitor (s->plugin, 2469 notify_session_monitor (s->plugin,
2432 s, 2470 s,
2433 GNUNET_TRANSPORT_SS_UPDATE); 2471 GNUNET_TRANSPORT_SS_UPDATE);
2434 schedule_select (rc->plugin); 2472 if (s->address->address_length == sizeof (struct IPv4UdpAddress))
2473 schedule_select_v4 (rc->plugin);
2474 else
2475 schedule_select_v6 (rc->plugin);
2435} 2476}
2436 2477
2437 2478
@@ -2940,7 +2981,8 @@ remove_timeout_messages_and_select (struct Plugin *plugin,
2940static void 2981static void
2941analyze_send_error (struct Plugin *plugin, 2982analyze_send_error (struct Plugin *plugin,
2942 const struct sockaddr *sa, 2983 const struct sockaddr *sa,
2943 socklen_t slen, int error) 2984 socklen_t slen,
2985 int error)
2944{ 2986{
2945 enum GNUNET_ATS_Network_Type type; 2987 enum GNUNET_ATS_Network_Type type;
2946 2988
@@ -2989,9 +3031,8 @@ analyze_send_error (struct Plugin *plugin,
2989 * 3031 *
2990 * @param plugin the plugin 3032 * @param plugin the plugin
2991 * @param sock which socket (v4/v6) to send on 3033 * @param sock which socket (v4/v6) to send on
2992 * @return number of bytes transmitted, #GNUNET_SYSERR on failure
2993 */ 3034 */
2994static size_t 3035static void
2995udp_select_send (struct Plugin *plugin, 3036udp_select_send (struct Plugin *plugin,
2996 struct GNUNET_NETWORK_Handle *sock) 3037 struct GNUNET_NETWORK_Handle *sock)
2997{ 3038{
@@ -3004,103 +3045,102 @@ udp_select_send (struct Plugin *plugin,
3004 struct sockaddr_in6 a6; 3045 struct sockaddr_in6 a6;
3005 struct UDP_MessageWrapper *udpw; 3046 struct UDP_MessageWrapper *udpw;
3006 3047
3007 /* Find message to send */ 3048 /* Find message(s) to send */
3008 udpw = remove_timeout_messages_and_select (plugin, 3049 while (NULL != (udpw = remove_timeout_messages_and_select (plugin,
3009 sock); 3050 sock)))
3010 if (NULL == udpw)
3011 return 0; /* No message to send */
3012
3013 if (sizeof (struct IPv4UdpAddress) == udpw->session->address->address_length)
3014 { 3051 {
3015 u4 = udpw->session->address->address; 3052 if (sizeof (struct IPv4UdpAddress) == udpw->session->address->address_length)
3016 memset (&a4, 0, sizeof(a4)); 3053 {
3017 a4.sin_family = AF_INET; 3054 u4 = udpw->session->address->address;
3055 memset (&a4, 0, sizeof(a4));
3056 a4.sin_family = AF_INET;
3018#if HAVE_SOCKADDR_IN_SIN_LEN 3057#if HAVE_SOCKADDR_IN_SIN_LEN
3019 a4.sin_len = sizeof (a4); 3058 a4.sin_len = sizeof (a4);
3020#endif 3059#endif
3021 a4.sin_port = u4->u4_port; 3060 a4.sin_port = u4->u4_port;
3022 memcpy (&a4.sin_addr, 3061 memcpy (&a4.sin_addr,
3023 &u4->ipv4_addr, 3062 &u4->ipv4_addr,
3024 sizeof(struct in_addr)); 3063 sizeof(struct in_addr));
3025 a = (struct sockaddr *) &a4; 3064 a = (struct sockaddr *) &a4;
3026 slen = sizeof (a4); 3065 slen = sizeof (a4);
3027 } 3066 }
3028 else if (sizeof (struct IPv6UdpAddress) == udpw->session->address->address_length) 3067 else if (sizeof (struct IPv6UdpAddress) == udpw->session->address->address_length)
3029 { 3068 {
3030 u6 = udpw->session->address->address; 3069 u6 = udpw->session->address->address;
3031 memset (&a6, 0, sizeof(a6)); 3070 memset (&a6, 0, sizeof(a6));
3032 a6.sin6_family = AF_INET6; 3071 a6.sin6_family = AF_INET6;
3033#if HAVE_SOCKADDR_IN_SIN_LEN 3072#if HAVE_SOCKADDR_IN_SIN_LEN
3034 a6.sin6_len = sizeof (a6); 3073 a6.sin6_len = sizeof (a6);
3035#endif 3074#endif
3036 a6.sin6_port = u6->u6_port; 3075 a6.sin6_port = u6->u6_port;
3037 memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof(struct in6_addr)); 3076 memcpy (&a6.sin6_addr, &u6->ipv6_addr, sizeof(struct in6_addr));
3038 a = (struct sockaddr *) &a6; 3077 a = (struct sockaddr *) &a6;
3039 slen = sizeof (a6); 3078 slen = sizeof (a6);
3040 } 3079 }
3041 else 3080 else
3042 { 3081 {
3043 call_continuation (udpw, 3082 call_continuation (udpw,
3044 GNUNET_OK); 3083 GNUNET_OK);
3084 dequeue (plugin,
3085 udpw);
3086 notify_session_monitor (plugin,
3087 udpw->session,
3088 GNUNET_TRANSPORT_SS_UPDATE);
3089 GNUNET_free (udpw);
3090 continue;
3091 }
3092 sent = GNUNET_NETWORK_socket_sendto (sock,
3093 udpw->msg_buf,
3094 udpw->msg_size,
3095 a,
3096 slen);
3097 if (GNUNET_SYSERR == sent)
3098 {
3099 /* Failure */
3100 analyze_send_error (plugin,
3101 a,
3102 slen,
3103 errno);
3104 call_continuation (udpw,
3105 GNUNET_SYSERR);
3106 GNUNET_STATISTICS_update (plugin->env->stats,
3107 "# UDP, total, bytes, sent, failure",
3108 sent,
3109 GNUNET_NO);
3110 GNUNET_STATISTICS_update (plugin->env->stats,
3111 "# UDP, total, messages, sent, failure",
3112 1,
3113 GNUNET_NO);
3114 }
3115 else
3116 {
3117 /* Success */
3118 LOG (GNUNET_ERROR_TYPE_DEBUG,
3119 "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n",
3120 (unsigned int) (udpw->msg_size),
3121 GNUNET_i2s (&udpw->session->target),
3122 GNUNET_a2s (a, slen),
3123 (int ) sent,
3124 (sent < 0) ? STRERROR (errno) : "ok");
3125 GNUNET_STATISTICS_update (plugin->env->stats,
3126 "# UDP, total, bytes, sent, success",
3127 sent,
3128 GNUNET_NO);
3129 GNUNET_STATISTICS_update (plugin->env->stats,
3130 "# UDP, total, messages, sent, success",
3131 1,
3132 GNUNET_NO);
3133 if (NULL != udpw->frag_ctx)
3134 udpw->frag_ctx->on_wire_size += udpw->msg_size;
3135 call_continuation (udpw, GNUNET_OK);
3136 }
3045 dequeue (plugin, 3137 dequeue (plugin,
3046 udpw); 3138 udpw);
3047 notify_session_monitor (plugin, 3139 notify_session_monitor (plugin,
3048 udpw->session, 3140 udpw->session,
3049 GNUNET_TRANSPORT_SS_UPDATE); 3141 GNUNET_TRANSPORT_SS_UPDATE);
3050 GNUNET_free (udpw); 3142 GNUNET_free (udpw);
3051 return GNUNET_SYSERR;
3052 }
3053 sent = GNUNET_NETWORK_socket_sendto (sock,
3054 udpw->msg_buf,
3055 udpw->msg_size,
3056 a,
3057 slen);
3058 if (GNUNET_SYSERR == sent)
3059 {
3060 /* Failure */
3061 analyze_send_error (plugin,
3062 a,
3063 slen,
3064 errno);
3065 call_continuation (udpw,
3066 GNUNET_SYSERR);
3067 GNUNET_STATISTICS_update (plugin->env->stats,
3068 "# UDP, total, bytes, sent, failure",
3069 sent,
3070 GNUNET_NO);
3071 GNUNET_STATISTICS_update (plugin->env->stats,
3072 "# UDP, total, messages, sent, failure",
3073 1,
3074 GNUNET_NO);
3075 }
3076 else
3077 {
3078 /* Success */
3079 LOG (GNUNET_ERROR_TYPE_DEBUG,
3080 "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n",
3081 (unsigned int) (udpw->msg_size),
3082 GNUNET_i2s (&udpw->session->target),
3083 GNUNET_a2s (a, slen),
3084 (int ) sent,
3085 (sent < 0) ? STRERROR (errno) : "ok");
3086 GNUNET_STATISTICS_update (plugin->env->stats,
3087 "# UDP, total, bytes, sent, success",
3088 sent,
3089 GNUNET_NO);
3090 GNUNET_STATISTICS_update (plugin->env->stats,
3091 "# UDP, total, messages, sent, success",
3092 1,
3093 GNUNET_NO);
3094 if (NULL != udpw->frag_ctx)
3095 udpw->frag_ctx->on_wire_size += udpw->msg_size;
3096 call_continuation (udpw, GNUNET_OK);
3097 } 3143 }
3098 dequeue (plugin, udpw);
3099 notify_session_monitor (plugin,
3100 udpw->session,
3101 GNUNET_TRANSPORT_SS_UPDATE);
3102 GNUNET_free (udpw);
3103 return sent;
3104} 3144}
3105 3145
3106 3146
@@ -3110,26 +3150,26 @@ udp_select_send (struct Plugin *plugin,
3110 * Then reschedule this function to be called again once more is available. 3150 * Then reschedule this function to be called again once more is available.
3111 * 3151 *
3112 * @param cls the plugin handle 3152 * @param cls the plugin handle
3113 * @param tc the scheduling context (for rescheduling this function again) 3153 * @param tc the scheduling context
3114 */ 3154 */
3115static void 3155static void
3116udp_plugin_select (void *cls, 3156udp_plugin_select_v4 (void *cls,
3117 const struct GNUNET_SCHEDULER_TaskContext *tc) 3157 const struct GNUNET_SCHEDULER_TaskContext *tc)
3118{ 3158{
3119 struct Plugin *plugin = cls; 3159 struct Plugin *plugin = cls;
3120 3160
3121 plugin->select_task = NULL; 3161 plugin->select_task_v4 = NULL;
3122 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 3162 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
3123 return; 3163 return;
3124 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) 3164 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
3125 && (NULL != plugin->sockv4) 3165 (NULL != plugin->sockv4) &&
3126 && (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4))) 3166 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
3127 udp_select_read (plugin, plugin->sockv4); 3167 plugin->sockv4)))
3128 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) 3168 udp_select_read (plugin,
3129 && (NULL != plugin->sockv4) && (NULL != plugin->ipv4_queue_head) 3169 plugin->sockv4);
3130 && (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv4))) 3170 udp_select_send (plugin,
3131 udp_select_send (plugin, plugin->sockv4); 3171 plugin->sockv4);
3132 schedule_select (plugin); 3172 schedule_select_v4 (plugin);
3133} 3173}
3134 3174
3135 3175
@@ -3139,7 +3179,7 @@ udp_plugin_select (void *cls,
3139 * Then reschedule this function to be called again once more is available. 3179 * Then reschedule this function to be called again once more is available.
3140 * 3180 *
3141 * @param cls the plugin handle 3181 * @param cls the plugin handle
3142 * @param tc the scheduling context (for rescheduling this function again) 3182 * @param tc the scheduling context
3143 */ 3183 */
3144static void 3184static void
3145udp_plugin_select_v6 (void *cls, 3185udp_plugin_select_v6 (void *cls,
@@ -3150,14 +3190,15 @@ udp_plugin_select_v6 (void *cls,
3150 plugin->select_task_v6 = NULL; 3190 plugin->select_task_v6 = NULL;
3151 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 3191 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
3152 return; 3192 return;
3153 if (((tc->reason & GNUNET_SCHEDULER_REASON_READ_READY) != 0) 3193 if ( (0 != (tc->reason & GNUNET_SCHEDULER_REASON_READ_READY)) &&
3154 && (NULL != plugin->sockv6) 3194 (NULL != plugin->sockv6) &&
3155 && (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6))) 3195 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
3156 udp_select_read (plugin, plugin->sockv6); 3196 plugin->sockv6)) )
3157 if ((0 != (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY)) 3197 udp_select_read (plugin,
3158 && (NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL )&& 3198 plugin->sockv6);
3159 (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6)) )udp_select_send (plugin, plugin->sockv6); 3199 udp_select_send (plugin,
3160 schedule_select (plugin); 3200 plugin->sockv6);
3201 schedule_select_v6 (plugin);
3161} 3202}
3162 3203
3163 3204
@@ -3365,35 +3406,8 @@ setup_sockets (struct Plugin *plugin,
3365 _("Failed to open UDP sockets\n")); 3406 _("Failed to open UDP sockets\n"));
3366 return 0; /* No sockets created, return */ 3407 return 0; /* No sockets created, return */
3367 } 3408 }
3368 3409 schedule_select_v4 (plugin);
3369 /* Create file descriptors */ 3410 schedule_select_v6 (plugin);
3370 if (plugin->enable_ipv4 == GNUNET_YES)
3371 {
3372 plugin->rs_v4 = GNUNET_NETWORK_fdset_create ();
3373 plugin->ws_v4 = GNUNET_NETWORK_fdset_create ();
3374 GNUNET_NETWORK_fdset_zero (plugin->rs_v4);
3375 GNUNET_NETWORK_fdset_zero (plugin->ws_v4);
3376 if (NULL != plugin->sockv4)
3377 {
3378 GNUNET_NETWORK_fdset_set (plugin->rs_v4, plugin->sockv4);
3379 GNUNET_NETWORK_fdset_set (plugin->ws_v4, plugin->sockv4);
3380 }
3381 }
3382
3383 if (plugin->enable_ipv6 == GNUNET_YES)
3384 {
3385 plugin->rs_v6 = GNUNET_NETWORK_fdset_create ();
3386 plugin->ws_v6 = GNUNET_NETWORK_fdset_create ();
3387 GNUNET_NETWORK_fdset_zero (plugin->rs_v6);
3388 GNUNET_NETWORK_fdset_zero (plugin->ws_v6);
3389 if (NULL != plugin->sockv6)
3390 {
3391 GNUNET_NETWORK_fdset_set (plugin->rs_v6, plugin->sockv6);
3392 GNUNET_NETWORK_fdset_set (plugin->ws_v6, plugin->sockv6);
3393 }
3394 }
3395
3396 schedule_select (plugin);
3397 plugin->nat = GNUNET_NAT_register (plugin->env->cfg, 3411 plugin->nat = GNUNET_NAT_register (plugin->env->cfg,
3398 GNUNET_NO, 3412 GNUNET_NO,
3399 plugin->port, 3413 plugin->port,
@@ -3719,12 +3733,12 @@ libgnunet_plugin_transport_udp_done (void *cls)
3719 return NULL; 3733 return NULL;
3720 } 3734 }
3721 stop_broadcast (plugin); 3735 stop_broadcast (plugin);
3722 if (plugin->select_task != NULL) 3736 if (NULL != plugin->select_task_v4)
3723 { 3737 {
3724 GNUNET_SCHEDULER_cancel (plugin->select_task); 3738 GNUNET_SCHEDULER_cancel (plugin->select_task_v4);
3725 plugin->select_task = NULL; 3739 plugin->select_task_v4 = NULL;
3726 } 3740 }
3727 if (plugin->select_task_v6 != NULL) 3741 if (NULL != plugin->select_task_v6)
3728 { 3742 {
3729 GNUNET_SCHEDULER_cancel (plugin->select_task_v6); 3743 GNUNET_SCHEDULER_cancel (plugin->select_task_v6);
3730 plugin->select_task_v6 = NULL; 3744 plugin->select_task_v6 = NULL;
@@ -3739,8 +3753,6 @@ libgnunet_plugin_transport_udp_done (void *cls)
3739 GNUNET_NETWORK_socket_close (plugin->sockv4)); 3753 GNUNET_NETWORK_socket_close (plugin->sockv4));
3740 plugin->sockv4 = NULL; 3754 plugin->sockv4 = NULL;
3741 } 3755 }
3742 GNUNET_NETWORK_fdset_destroy (plugin->rs_v4);
3743 GNUNET_NETWORK_fdset_destroy (plugin->ws_v4);
3744 } 3756 }
3745 if (GNUNET_YES == plugin->enable_ipv6) 3757 if (GNUNET_YES == plugin->enable_ipv6)
3746 { 3758 {
@@ -3749,9 +3761,6 @@ libgnunet_plugin_transport_udp_done (void *cls)
3749 GNUNET_break (GNUNET_OK == 3761 GNUNET_break (GNUNET_OK ==
3750 GNUNET_NETWORK_socket_close (plugin->sockv6)); 3762 GNUNET_NETWORK_socket_close (plugin->sockv6));
3751 plugin->sockv6 = NULL; 3763 plugin->sockv6 = NULL;
3752
3753 GNUNET_NETWORK_fdset_destroy (plugin->rs_v6);
3754 GNUNET_NETWORK_fdset_destroy (plugin->ws_v6);
3755 } 3764 }
3756 } 3765 }
3757 if (NULL != plugin->nat) 3766 if (NULL != plugin->nat)
diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h
index e1ff5e9cf..e6cb5b450 100644
--- a/src/transport/plugin_transport_udp.h
+++ b/src/transport/plugin_transport_udp.h
@@ -121,29 +121,14 @@ union UdpAddress
121 121
122 122
123/** 123/**
124 * UDP Message-Packet header (after defragmentation). 124 * Information we track for each message in the queue.
125 */ 125 */
126struct UDPMessage
127{
128 /**
129 * Message header.
130 */
131 struct GNUNET_MessageHeader header;
132
133 /**
134 * Always zero for now.
135 */
136 uint32_t reserved;
137
138 /**
139 * What is the identity of the sender
140 */
141 struct GNUNET_PeerIdentity sender;
142
143};
144
145struct UDP_MessageWrapper; 126struct UDP_MessageWrapper;
146 127
128
129/**
130 * Closure for #append_port().
131 */
147struct PrettyPrinterContext; 132struct PrettyPrinterContext;
148 133
149 134
@@ -172,7 +157,7 @@ struct Plugin
172 /** 157 /**
173 * ID of select task for IPv4 158 * ID of select task for IPv4
174 */ 159 */
175 struct GNUNET_SCHEDULER_Task *select_task; 160 struct GNUNET_SCHEDULER_Task *select_task_v4;
176 161
177 /** 162 /**
178 * ID of select task for IPv6 163 * ID of select task for IPv6
@@ -205,31 +190,11 @@ struct Plugin
205 struct GNUNET_NAT_Handle *nat; 190 struct GNUNET_NAT_Handle *nat;
206 191
207 /** 192 /**
208 * FD Read set
209 */
210 struct GNUNET_NETWORK_FDSet *rs_v4;
211
212 /**
213 * FD Write set
214 */
215 struct GNUNET_NETWORK_FDSet *ws_v4;
216
217 /**
218 * The read socket for IPv4 193 * The read socket for IPv4
219 */ 194 */
220 struct GNUNET_NETWORK_Handle *sockv4; 195 struct GNUNET_NETWORK_Handle *sockv4;
221 196
222 /** 197 /**
223 * FD Read set
224 */
225 struct GNUNET_NETWORK_FDSet *rs_v6;
226
227 /**
228 * FD Write set
229 */
230 struct GNUNET_NETWORK_FDSet *ws_v6;
231
232 /**
233 * The read socket for IPv6 198 * The read socket for IPv6
234 */ 199 */
235 struct GNUNET_NETWORK_Handle *sockv6; 200 struct GNUNET_NETWORK_Handle *sockv6;
@@ -347,6 +312,17 @@ struct Plugin
347}; 312};
348 313
349 314
315/**
316 * Function called for a quick conversion of the binary address to
317 * a numeric address. Note that the caller must not free the
318 * address and that the next call to this function is allowed
319 * to override the address again.
320 *
321 * @param cls closure
322 * @param addr binary address (a `union UdpAddress`)
323 * @param addrlen length of the @a addr
324 * @return string representing the same address
325 */
350const char * 326const char *
351udp_address_to_string (void *cls, 327udp_address_to_string (void *cls,
352 const void *addr, 328 const void *addr,
diff --git a/src/transport/plugin_transport_udp_broadcasting.c b/src/transport/plugin_transport_udp_broadcasting.c
index e7b7cdc23..ea8797f29 100644
--- a/src/transport/plugin_transport_udp_broadcasting.c
+++ b/src/transport/plugin_transport_udp_broadcasting.c
@@ -527,6 +527,13 @@ iface_proc (void *cls,
527} 527}
528 528
529 529
530/**
531 * Setup broadcasting subsystem.
532 *
533 * @param plugin
534 * @param server_addrv6
535 * @param server_addrv4
536 */
530void 537void
531setup_broadcast (struct Plugin *plugin, 538setup_broadcast (struct Plugin *plugin,
532 struct sockaddr_in6 *server_addrv6, 539 struct sockaddr_in6 *server_addrv6,
@@ -577,6 +584,11 @@ setup_broadcast (struct Plugin *plugin,
577} 584}
578 585
579 586
587/**
588 * Stop broadcasting subsystem.
589 *
590 * @param plugin
591 */
580void 592void
581stop_broadcast (struct Plugin *plugin) 593stop_broadcast (struct Plugin *plugin)
582{ 594{