aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-01-30 15:33:17 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-01-30 15:33:17 +0000
commit8fd5ba93eabe126d751662bdedc507f3270cd5c0 (patch)
treea155d1afa2eb2d930dd23c15a005125f9542bc58
parent89394682eb6f7a8d4735225a6128b94598a59184 (diff)
downloadgnunet-8fd5ba93eabe126d751662bdedc507f3270cd5c0.tar.gz
gnunet-8fd5ba93eabe126d751662bdedc507f3270cd5c0.zip
- sending and getting sessions
-rw-r--r--src/transport/plugin_transport_udp_new.c354
-rw-r--r--src/transport/plugin_transport_udp_new.h22
2 files changed, 328 insertions, 48 deletions
diff --git a/src/transport/plugin_transport_udp_new.c b/src/transport/plugin_transport_udp_new.c
index 1a706a680..02a2fac0e 100644
--- a/src/transport/plugin_transport_udp_new.c
+++ b/src/transport/plugin_transport_udp_new.c
@@ -77,6 +77,11 @@ struct Session
77 const struct sockaddr *sock_addr; 77 const struct sockaddr *sock_addr;
78 78
79 size_t addrlen; 79 size_t addrlen;
80
81 /**
82 * Desired delay for next sending we received from other peer
83 */
84 struct GNUNET_TIME_Absolute flow_delay_from_other_peer;
80}; 85};
81 86
82 87
@@ -87,6 +92,29 @@ struct SessionCompareContext
87}; 92};
88 93
89 94
95/**
96 * Closure for 'process_inbound_tokenized_messages'
97 */
98struct SourceInformation
99{
100 /**
101 * Sender identity.
102 */
103 struct GNUNET_PeerIdentity sender;
104
105 /**
106 * Source address.
107 */
108 const void *arg;
109
110 /**
111 * Number of bytes in source address.
112 */
113 size_t args;
114
115 struct Session *session;
116};
117
90 118
91/** 119/**
92 * Function called for a quick conversion of the binary address to 120 * Function called for a quick conversion of the binary address to
@@ -442,43 +470,44 @@ static int session_cmp_it (void *cls,
442 struct SessionCompareContext * cctx = cls; 470 struct SessionCompareContext * cctx = cls;
443 const struct GNUNET_HELLO_Address *address = cctx->addr; 471 const struct GNUNET_HELLO_Address *address = cctx->addr;
444 struct Session *s = value; 472 struct Session *s = value;
445 struct Session *r = cctx->res;
446 struct IPv4UdpAddress * u4 = NULL;
447 struct IPv6UdpAddress * u6 = NULL;
448 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "AAAAAAAAAAAAAAAAAAa\n");
449 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for existing session for address %s\n", udp_address_to_string (NULL, (void *) address->address, address->address_length));
450 473
451 if (s->addrlen == address->address_length) 474 socklen_t s_addrlen = s->addrlen;
475
476#if VERBOSE
477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Comparing address %s <-> %s\n",
478 udp_address_to_string (NULL, (void *) address->address, address->address_length),
479 GNUNET_a2s (s->sock_addr, s->addrlen));
480#endif
481
482 if ((address->address_length == sizeof (struct IPv4UdpAddress)) &&
483 (s_addrlen == sizeof (struct sockaddr_in)))
452 { 484 {
453 if (address->address_length == sizeof (struct IPv4UdpAddress)) 485 struct IPv4UdpAddress * u4 = NULL;
486 u4 = (struct IPv4UdpAddress *) address->address;
487 const struct sockaddr_in *s4 = (const struct sockaddr_in *) s->sock_addr;
488 if ((0 == memcmp ((const void *) &u4->ipv4_addr,(const void *) &s4->sin_addr, sizeof (struct in_addr))) &&
489 (u4->u4_port == s4->sin_port))
454 { 490 {
455 u4 = (struct IPv4UdpAddress * ) address->address; 491 cctx->res = s;
456 struct sockaddr_in *sai = (struct sockaddr_in *) s->sock_addr; 492 return GNUNET_NO;
457 if ((u4->ipv4_addr == sai->sin_addr.s_addr) &&
458 (u4->u4_port == sai->sin_port))
459 {
460 r = s;
461 return GNUNET_NO;
462 }
463 } 493 }
464 else if (address->address_length == sizeof (struct IPv6UdpAddress))
465 {
466 u6 = (struct IPv6UdpAddress * ) address->address;
467 struct sockaddr_in6 *sai = (struct sockaddr_in6 *) s->sock_addr;
468 494
469 if ((0 == memcmp (&u6->ipv6_addr, &sai->sin6_addr, sizeof (struct in6_addr))) && 495 }
470 (u6->u6_port == sai->sin6_port)) 496 if ((address->address_length == sizeof (struct IPv6UdpAddress)) &&
471 { 497 (s_addrlen == sizeof (struct sockaddr_in6)))
472 r = s; 498 {
473 return GNUNET_NO; 499 struct IPv6UdpAddress * u6 = NULL;
474 } 500 u6 = (struct IPv6UdpAddress *) address->address;
475 } 501 const struct sockaddr_in6 *s6 = (const struct sockaddr_in6 *) s->sock_addr;
476 else 502 if ((0 == memcmp (&u6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr))) &&
503 (u6->u6_port == s6->sin6_port))
477 { 504 {
478 GNUNET_break (0); 505 cctx->res = s;
479 return GNUNET_YES; 506 return GNUNET_NO;
480 } 507 }
481 } 508 }
509
510
482 return GNUNET_YES; 511 return GNUNET_YES;
483} 512}
484 513
@@ -510,33 +539,39 @@ udp_plugin_get_session (void *cls,
510 } 539 }
511 540
512 /* check if session already exists */ 541 /* check if session already exists */
513 if (NULL != NULL)
514 {
515 struct SessionCompareContext cctx; 542 struct SessionCompareContext cctx;
516 cctx.addr = address; 543 cctx.addr = address;
517 cctx.res = NULL; 544 cctx.res = NULL;
518#if DEBUG_UDP 545#if DEBUG_UDP
519 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Looking for existing session for peer `%s' `%s' \n", GNUNET_i2s (&address->peer), udp_address_to_string(NULL, address->address, address->address_length)); 546 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for existing session for peer `%s' `%s' \n", GNUNET_i2s (&address->peer), udp_address_to_string(NULL, address->address, address->address_length));
520#endif 547#endif
521 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessions, &address->peer.hashPubKey, session_cmp_it, &cctx); 548 GNUNET_CONTAINER_multihashmap_get_multiple(plugin->sessions, &address->peer.hashPubKey, session_cmp_it, &cctx);
522 if (cctx.res != NULL) 549 if (cctx.res != NULL)
523 { 550 {
524 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Found existing session\n"); 551#if DEBUG_UDP
552 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found existing session %p\n", cctx.res);
553#endif
525 return cctx.res; 554 return cctx.res;
526 } 555 }
527 } 556
528 /* otherwise create new */ 557 /* otherwise create new */
529 s = create_session (plugin, 558 s = create_session (plugin,
530 &address->peer, 559 &address->peer,
531 address->address, 560 address->address,
532 address->address_length, 561 address->address_length,
533 NULL, NULL); 562 NULL, NULL);
534 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Creating new session %p\n", s); 563#if DEBUG_UDP
564 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
565 "Creating new session %p for peer `%s' address `%s'\n",
566 s,
567 GNUNET_i2s(&address->peer),
568 udp_address_to_string(NULL,address->address,address->address_length));
569#endif
535 GNUNET_assert (GNUNET_OK == 570 GNUNET_assert (GNUNET_OK ==
536 GNUNET_CONTAINER_multihashmap_put (plugin->sessions, 571 GNUNET_CONTAINER_multihashmap_put (plugin->sessions,
537 &s->target.hashPubKey, 572 &s->target.hashPubKey,
538 s, 573 s,
539 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 574 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
540 575
541 return s; 576 return s;
542} 577}
@@ -571,15 +606,58 @@ udp_plugin_get_session (void *cls,
571 */ 606 */
572static ssize_t 607static ssize_t
573udp_plugin_send (void *cls, 608udp_plugin_send (void *cls,
574 struct Session *session, 609 struct Session *s,
575 const char *msgbuf, size_t msgbuf_size, 610 const char *msgbuf, size_t msgbuf_size,
576 unsigned int priority, 611 unsigned int priority,
577 struct GNUNET_TIME_Relative to, 612 struct GNUNET_TIME_Relative to,
578 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) 613 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
579{ 614{
615 struct Plugin *plugin = cls;
616 size_t mlen = msgbuf_size + sizeof (struct UDPMessage);;
617
618 struct GNUNET_TIME_Relative delta;
619 struct UDPMessageWrapper * udpw;
620 struct UDPMessage *udp;
621
622 GNUNET_assert (plugin != NULL);
623 GNUNET_assert (s != NULL);
624
625 if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
626 {
627 GNUNET_break (0);
628 return GNUNET_SYSERR;
629 }
630
631 LOG (GNUNET_ERROR_TYPE_DEBUG,
632 "UDP transmits %u-byte message to `%s' using address `%s'\n",
633 msgbuf_size,
634 GNUNET_i2s (&s->target),
635 GNUNET_a2s(s->sock_addr, s->addrlen));
636
637 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains_value(plugin->sessions, &s->target.hashPubKey, s))
638 {
639 GNUNET_break (0);
640 return GNUNET_SYSERR;
641 }
642
643 udpw = GNUNET_malloc (sizeof (struct UDPMessageWrapper) + sizeof (struct UDPMessage) + msgbuf_size);
644 udpw->session = s;
645 udp = (struct UDPMessage *) &udpw[1];
646 udpw->udp = udp;
647 udpw->msg_size = mlen;
648 udpw->cont = cont;
649 udpw->cont_cls = cont_cls;
580 650
581 return 0; 651 udp->header.size = htons (mlen);
652 udp->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE);
653 udp->reserved = htonl (0);
654 udp->sender = *plugin->env->my_identity;
655 memcpy (&udp[1], msgbuf, msgbuf_size);
582 656
657 GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, udpw);
658
659 delta = GNUNET_TIME_absolute_get_remaining (s->flow_delay_from_other_peer);
660 return mlen;
583} 661}
584 662
585static ssize_t udp_plugin_send_wrapper (void *cls, 663static ssize_t udp_plugin_send_wrapper (void *cls,
@@ -660,6 +738,114 @@ udp_nat_port_map_callback (void *cls, int add_remove,
660} 738}
661 739
662 740
741
742/**
743 * Message tokenizer has broken up an incomming message. Pass it on
744 * to the service.
745 *
746 * @param cls the 'struct Plugin'
747 * @param client the 'struct SourceInformation'
748 * @param hdr the actual message
749 */
750static void
751process_inbound_tokenized_messages (void *cls, void *client,
752 const struct GNUNET_MessageHeader *hdr)
753{
754 struct Plugin *plugin = cls;
755 struct SourceInformation *si = client;
756 struct GNUNET_ATS_Information ats[2];
757 struct GNUNET_TIME_Relative delay;
758
759 /* setup ATS */
760 ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
761 ats[0].value = htonl (1);
762 ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
763 ats[1].value = htonl (GNUNET_ATS_COST_WAN);
764 //GNUNET_break (ntohl(si->session->ats_address_network_type) != GNUNET_ATS_NET_UNSPECIFIED);
765 delay = plugin->env->receive (plugin->env->cls,
766 &si->sender,
767 hdr,
768 (const struct GNUNET_ATS_Information *) &ats, 2,
769 NULL,
770 si->arg,
771 si->args);
772 //si->session->flow_delay_for_other_peer = delay;
773}
774
775
776/**
777 * We've received a UDP Message. Process it (pass contents to main service).
778 *
779 * @param plugin plugin context
780 * @param msg the message
781 * @param sender_addr sender address
782 * @param sender_addr_len number of bytes in sender_addr
783 */
784static void
785process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg,
786 const struct sockaddr *sender_addr,
787 socklen_t sender_addr_len)
788{
789 struct SourceInformation si;
790 struct IPv4UdpAddress u4;
791 struct IPv6UdpAddress u6;
792 struct GNUNET_ATS_Information ats;
793 const void *arg;
794 size_t args;
795
796 if (0 != ntohl (msg->reserved))
797 {
798 GNUNET_break_op (0);
799 return;
800 }
801 if (ntohs (msg->header.size) <
802 sizeof (struct GNUNET_MessageHeader) + sizeof (struct UDPMessage))
803 {
804 GNUNET_break_op (0);
805 return;
806 }
807
808 ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
809 ats.value = htonl (GNUNET_ATS_NET_UNSPECIFIED);
810 /* convert address */
811 switch (sender_addr->sa_family)
812 {
813 case AF_INET:
814 GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in));
815 u4.ipv4_addr = ((struct sockaddr_in *) sender_addr)->sin_addr.s_addr;
816 u4.u4_port = ((struct sockaddr_in *) sender_addr)->sin_port;
817 arg = &u4;
818 args = sizeof (u4);
819 break;
820 case AF_INET6:
821 GNUNET_assert (sender_addr_len == sizeof (struct sockaddr_in6));
822 u6.ipv6_addr = ((struct sockaddr_in6 *) sender_addr)->sin6_addr;
823 u6.u6_port = ((struct sockaddr_in6 *) sender_addr)->sin6_port;
824 arg = &u6;
825 args = sizeof (u6);
826 break;
827 default:
828 GNUNET_break (0);
829 return;
830 }
831#if DEBUG_UDP
832 LOG (GNUNET_ERROR_TYPE_DEBUG,
833 "Received message with %u bytes from peer `%s' at `%s'\n",
834 (unsigned int) ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
835 GNUNET_a2s (sender_addr, sender_addr_len));
836#endif
837
838 /* iterate over all embedded messages */
839 si.sender = msg->sender;
840 si.arg = arg;
841 si.args = args;
842
843 GNUNET_SERVER_mst_receive (plugin->mst, &si, (const char *) &msg[1],
844 ntohs (msg->header.size) -
845 sizeof (struct UDPMessage), GNUNET_YES, GNUNET_NO);
846}
847
848
663/** 849/**
664 * Read and process a message from the given socket. 850 * Read and process a message from the given socket.
665 * 851 *
@@ -667,7 +853,7 @@ udp_nat_port_map_callback (void *cls, int add_remove,
667 * @param rsock socket to read from 853 * @param rsock socket to read from
668 */ 854 */
669static void 855static void
670udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) 856udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
671{ 857{
672 socklen_t fromlen; 858 socklen_t fromlen;
673 char addr[32]; 859 char addr[32];
@@ -717,10 +903,10 @@ udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
717 GNUNET_break_op (0); 903 GNUNET_break_op (0);
718 return; 904 return;
719 } 905 }
720 /* 906
721 process_udp_message (plugin, (const struct UDPMessage *) msg, 907 process_udp_message (plugin, (const struct UDPMessage *) msg,
722 (const struct sockaddr *) addr, fromlen); 908 (const struct sockaddr *) addr, fromlen);
723 */ 909
724 return; 910 return;
725 default: 911 default:
726 GNUNET_break_op (0); 912 GNUNET_break_op (0);
@@ -728,6 +914,59 @@ udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
728 } 914 }
729} 915}
730 916
917size_t
918udp_select_send (struct Plugin *plugin)
919{
920 ssize_t sent;
921 size_t slen;
922
923 struct UDPMessageWrapper *udpw = plugin->msg_head;
924 const struct sockaddr * sa = udpw->session->sock_addr;
925
926 switch (sa->sa_family)
927 {
928 case AF_INET:
929 if (NULL == plugin->sockv4)
930 return 0;
931 sent =
932 GNUNET_NETWORK_socket_sendto (plugin->sockv4, udpw->udp, udpw->msg_size,
933 sa, slen = sizeof (struct sockaddr_in));
934 break;
935 case AF_INET6:
936 if (NULL == plugin->sockv6)
937 return 0;
938 sent =
939 GNUNET_NETWORK_socket_sendto (plugin->sockv6, udpw->udp, udpw->msg_size,
940 sa, slen = sizeof (struct sockaddr_in6));
941 break;
942 default:
943 GNUNET_break (0);
944 return 0;
945 }
946 if (GNUNET_SYSERR == sent)
947 {
948 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
949 LOG (GNUNET_ERROR_TYPE_ERROR,
950 "UDP transmitted %u-byte message to %s (%d: %s)\n",
951 (unsigned int) ntohs (udpw->msg_size), GNUNET_a2s (sa, slen), (int) sent,
952 (sent < 0) ? STRERROR (errno) : "ok");
953 if (udpw->cont != NULL)
954 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR);
955 }
956 LOG (GNUNET_ERROR_TYPE_DEBUG,
957 "UDP transmitted %u-byte message to %s (%d: %s)\n",
958 (unsigned int) ntohs (udpw->msg_size), GNUNET_a2s (sa, slen), (int) sent,
959 (sent < 0) ? STRERROR (errno) : "ok");
960
961 if (udpw->cont != NULL)
962 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_OK);
963
964 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw);
965 GNUNET_free (udpw);
966
967 return sent;
968}
969
731/** 970/**
732 * We have been notified that our readset has something to read. We don't 971 * We have been notified that our readset has something to read. We don't
733 * know which socket needs to be read, so we have to check each one 972 * know which socket needs to be read, so we have to check each one
@@ -749,15 +988,16 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
749 { 988 {
750 if ((NULL != plugin->sockv4) && 989 if ((NULL != plugin->sockv4) &&
751 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4))) 990 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv4)))
752 udp_read (plugin, plugin->sockv4); 991 udp_select_read (plugin, plugin->sockv4);
753 if ((NULL != plugin->sockv6) && 992 if ((NULL != plugin->sockv6) &&
754 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6))) 993 (GNUNET_NETWORK_fdset_isset (tc->read_ready, plugin->sockv6)))
755 udp_read (plugin, plugin->sockv6); 994 udp_select_read (plugin, plugin->sockv6);
756 } 995 }
757 996
758 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) 997 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0)
759 { 998 {
760 /* TODO */ 999 if (plugin->msg_head != NULL)
1000 udp_select_send (plugin);
761 } 1001 }
762 1002
763 plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1003 plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
@@ -1033,6 +1273,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
1033 1273
1034 1274
1035 plugin->sessions = GNUNET_CONTAINER_multihashmap_create (10); 1275 plugin->sessions = GNUNET_CONTAINER_multihashmap_create (10);
1276 plugin->mst = GNUNET_SERVER_mst_create (&process_inbound_tokenized_messages, plugin);
1036 plugin->port = port; 1277 plugin->port = port;
1037 plugin->aport = aport; 1278 plugin->aport = aport;
1038 plugin->last_expected_delay = GNUNET_TIME_UNIT_SECONDS; 1279 plugin->last_expected_delay = GNUNET_TIME_UNIT_SECONDS;
@@ -1050,7 +1291,7 @@ libgnunet_plugin_transport_udp_init (void *cls)
1050 api->send = &udp_plugin_send_wrapper; 1291 api->send = &udp_plugin_send_wrapper;
1051 api->send_with_session = &udp_plugin_send; 1292 api->send_with_session = &udp_plugin_send;
1052 1293
1053 LOG (GNUNET_ERROR_TYPE_ERROR, "Setting up sockets\n"); 1294 LOG (GNUNET_ERROR_TYPE_DEBUG, "Setting up sockets\n");
1054 res = setup_sockets (plugin, &serverAddrv6, &serverAddrv4); 1295 res = setup_sockets (plugin, &serverAddrv6, &serverAddrv4);
1055 if ((res == 0) || ((plugin->sockv4 == NULL) && (plugin->sockv6 == NULL))) 1296 if ((res == 0) || ((plugin->sockv4 == NULL) && (plugin->sockv6 == NULL)))
1056 { 1297 {
@@ -1060,8 +1301,9 @@ libgnunet_plugin_transport_udp_init (void *cls)
1060 return NULL; 1301 return NULL;
1061 } 1302 }
1062 1303
1063 LOG (GNUNET_ERROR_TYPE_ERROR, "Starting broadcasting\n"); 1304 LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting broadcasting\n");
1064 setup_broadcast (plugin, &serverAddrv6, &serverAddrv4); 1305 if (broadcast == GNUNET_YES)
1306 setup_broadcast (plugin, &serverAddrv6, &serverAddrv4);
1065 1307
1066 1308
1067 GNUNET_free_non_null (bind4_address); 1309 GNUNET_free_non_null (bind4_address);
@@ -1105,6 +1347,24 @@ libgnunet_plugin_transport_udp_done (void *cls)
1105 GNUNET_NETWORK_fdset_destroy (plugin->ws); 1347 GNUNET_NETWORK_fdset_destroy (plugin->ws);
1106 GNUNET_NAT_unregister (plugin->nat); 1348 GNUNET_NAT_unregister (plugin->nat);
1107 1349
1350 if (plugin->mst != NULL)
1351 {
1352 GNUNET_SERVER_mst_destroy(plugin->mst);
1353 plugin->mst = NULL;
1354 }
1355
1356 /* Clean up leftover messages */
1357 struct UDPMessageWrapper *udpw = plugin->msg_head;
1358 while (udpw != NULL)
1359 {
1360 struct UDPMessageWrapper *tmp = udpw->next;
1361 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw);
1362 if (udpw->cont != NULL)
1363 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR);
1364 GNUNET_free (udpw);
1365 udpw = tmp;
1366 }
1367
1108 /* Clean up sessions */ 1368 /* Clean up sessions */
1109#if DEBUG_UDP 1369#if DEBUG_UDP
1110 LOG (GNUNET_ERROR_TYPE_DEBUG, 1370 LOG (GNUNET_ERROR_TYPE_DEBUG,
diff --git a/src/transport/plugin_transport_udp_new.h b/src/transport/plugin_transport_udp_new.h
index 062849e9d..b565f9cb6 100644
--- a/src/transport/plugin_transport_udp_new.h
+++ b/src/transport/plugin_transport_udp_new.h
@@ -41,7 +41,7 @@
41 41
42#define LOG(kind,...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__) 42#define LOG(kind,...) GNUNET_log_from (kind, "transport-udp", __VA_ARGS__)
43 43
44#define DEBUG_UDP GNUNET_YES 44#define DEBUG_UDP GNUNET_NO
45#define DEBUG_UDP_BROADCASTING GNUNET_NO 45#define DEBUG_UDP_BROADCASTING GNUNET_NO
46 46
47/** 47/**
@@ -110,6 +110,23 @@ struct UDPMessage
110 110
111}; 111};
112 112
113struct UDPMessageWrapper
114{
115 struct Session *session;
116 struct UDPMessageWrapper *prev;
117 struct UDPMessageWrapper *next;
118 struct UDPMessage *udp;
119 size_t msg_size;
120 /**
121 * Function to call upon completion of the transmission.
122 */
123 GNUNET_TRANSPORT_TransmitContinuation cont;
124
125 /**
126 * Closure for 'cont'.
127 */
128 void *cont_cls;
129};
113 130
114/** 131/**
115 * Encapsulation of all of the state of the plugin. 132 * Encapsulation of all of the state of the plugin.
@@ -257,6 +274,9 @@ struct Plugin
257 */ 274 */
258 uint16_t aport; 275 uint16_t aport;
259 276
277 struct UDPMessageWrapper *msg_head;
278 struct UDPMessageWrapper *msg_tail;
279
260}; 280};
261 281
262 282