aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/transport/plugin_transport_udp.c144
-rw-r--r--src/transport/plugin_transport_udp.h6
2 files changed, 108 insertions, 42 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 78b58eae5..740ad38da 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -550,13 +550,28 @@ disconnect_and_free_it (void *cls, const GNUNET_HashCode * key, void *value)
550 s->frag_ctx = NULL; 550 s->frag_ctx = NULL;
551 } 551 }
552 552
553 udpw = plugin->msg_head; 553 udpw = plugin->ipv4_queue_head;
554 while (udpw != NULL) 554 while (udpw != NULL)
555 { 555 {
556 next = udpw->next; 556 next = udpw->next;
557 if (udpw->session == s) 557 if (udpw->session == s)
558 { 558 {
559 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw); 559 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw);
560
561 if (udpw->cont != NULL)
562 udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR);
563 GNUNET_free (udpw);
564 }
565 udpw = next;
566 }
567
568 udpw = plugin->ipv6_queue_head;
569 while (udpw != NULL)
570 {
571 next = udpw->next;
572 if (udpw->session == s)
573 {
574 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw);
560 575
561 if (udpw->cont != NULL) 576 if (udpw->cont != NULL)
562 udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR); 577 udpw->cont (udpw->cont_cls, &s->target, GNUNET_SYSERR);
@@ -776,6 +791,15 @@ udp_plugin_get_session (void *cls,
776 return s; 791 return s;
777} 792}
778 793
794static void enqueue (struct Plugin *plugin, struct UDPMessageWrapper * udpw)
795{
796
797 if (udpw->session->addrlen == sizeof (struct sockaddr_in))
798 GNUNET_CONTAINER_DLL_insert(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw);
799 if (udpw->session->addrlen == sizeof (struct sockaddr_in6))
800 GNUNET_CONTAINER_DLL_insert(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw);
801}
802
779/** 803/**
780 * Function that is called with messages created by the fragmentation 804 * Function that is called with messages created by the fragmentation
781 * module. In the case of the 'proc' callback of the 805 * module. In the case of the 'proc' callback of the
@@ -809,7 +833,8 @@ enqueue_fragment (void *cls, const struct GNUNET_MessageHeader *msg)
809 udpw->frag_ctx = frag_ctx; 833 udpw->frag_ctx = frag_ctx;
810 memcpy (udpw->udp, msg, msg_len); 834 memcpy (udpw->udp, msg, msg_len);
811 835
812 GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, udpw); 836 enqueue (plugin, udpw);
837
813} 838}
814 839
815 840
@@ -896,7 +921,7 @@ udp_plugin_send (void *cls,
896 memcpy (udpw->udp, udp, sizeof (struct UDPMessage)); 921 memcpy (udpw->udp, udp, sizeof (struct UDPMessage));
897 memcpy (&udpw->udp[sizeof (struct UDPMessage)], msgbuf, msgbuf_size); 922 memcpy (&udpw->udp[sizeof (struct UDPMessage)], msgbuf, msgbuf_size);
898 923
899 GNUNET_CONTAINER_DLL_insert(plugin->msg_head, plugin->msg_tail, udpw); 924 enqueue (plugin, udpw);
900 } 925 }
901 else 926 else
902 { 927 {
@@ -1218,7 +1243,7 @@ ack_proc (void *cls, uint32_t id, const struct GNUNET_MessageHeader *msg)
1218 udp_ack->sender = *rc->plugin->env->my_identity; 1243 udp_ack->sender = *rc->plugin->env->my_identity;
1219 memcpy (&udp_ack[1], msg, ntohs (msg->size)); 1244 memcpy (&udp_ack[1], msg, ntohs (msg->size));
1220 1245
1221 GNUNET_CONTAINER_DLL_insert(rc->plugin->msg_head, rc->plugin->msg_tail, udpw); 1246 enqueue (rc->plugin, udpw);
1222} 1247}
1223 1248
1224 1249
@@ -1301,15 +1326,32 @@ static void read_process_ack (struct Plugin *plugin,
1301#endif 1326#endif
1302 s->last_expected_delay = GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag); 1327 s->last_expected_delay = GNUNET_FRAGMENT_context_destroy (s->frag_ctx->frag);
1303 1328
1304 struct UDPMessageWrapper * udpw = plugin->msg_head; 1329 struct UDPMessageWrapper * udpw = NULL;
1305 while (udpw!= NULL) 1330 if (s->addrlen == sizeof (struct sockaddr_in6))
1306 { 1331 {
1307 if ((udpw->frag_ctx != NULL) && (udpw->frag_ctx == s->frag_ctx)) 1332 udpw = plugin->ipv6_queue_head;
1333 while (udpw!= NULL)
1308 { 1334 {
1309 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw); 1335 if ((udpw->frag_ctx != NULL) && (udpw->frag_ctx == s->frag_ctx))
1310 GNUNET_free (udpw); 1336 {
1337 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw);
1338 GNUNET_free (udpw);
1339 }
1340 udpw = udpw->next;
1341 }
1342 }
1343 if (s->addrlen == sizeof (struct sockaddr_in))
1344 {
1345 udpw = plugin->ipv4_queue_head;
1346 while (udpw!= NULL)
1347 {
1348 if ((udpw->frag_ctx != NULL) && (udpw->frag_ctx == s->frag_ctx))
1349 {
1350 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw);
1351 GNUNET_free (udpw);
1352 }
1353 udpw = udpw->next;
1311 } 1354 }
1312 udpw = udpw->next;
1313 } 1355 }
1314 1356
1315 if (s->frag_ctx->cont != NULL) 1357 if (s->frag_ctx->cont != NULL)
@@ -1458,15 +1500,28 @@ udp_select_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock)
1458} 1500}
1459 1501
1460size_t 1502size_t
1461udp_select_send (struct Plugin *plugin) 1503udp_select_send (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *sock)
1462{ 1504{
1463 ssize_t sent; 1505 ssize_t sent;
1464 size_t slen; 1506 size_t slen;
1465 struct GNUNET_TIME_Absolute max; 1507 struct GNUNET_TIME_Absolute max;
1466 struct GNUNET_TIME_Absolute ; 1508 struct GNUNET_TIME_Absolute ;
1467 1509
1468 struct UDPMessageWrapper *udpw = plugin->msg_head; 1510 struct UDPMessageWrapper *udpw = NULL;
1511
1512 if (sock == plugin->sockv4)
1513 {
1514 udpw = plugin->ipv4_queue_head;
1515 }
1516 else if (sock == plugin->sockv6)
1517 {
1518 udpw = plugin->ipv6_queue_head;
1519 }
1520 else
1521 GNUNET_break (0);
1522
1469 const struct sockaddr * sa = udpw->session->sock_addr; 1523 const struct sockaddr * sa = udpw->session->sock_addr;
1524 slen = udpw->session->addrlen;
1470 1525
1471 max = GNUNET_TIME_absolute_max(udpw->timeout, GNUNET_TIME_absolute_get()); 1526 max = GNUNET_TIME_absolute_max(udpw->timeout, GNUNET_TIME_absolute_get());
1472 1527
@@ -1496,9 +1551,13 @@ udp_select_send (struct Plugin *plugin)
1496#endif 1551#endif
1497 } 1552 }
1498 1553
1499 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw); 1554 if (sock == plugin->sockv4)
1555 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw);
1556 else if (sock == plugin->sockv6)
1557 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw);
1558
1500 GNUNET_free (udpw); 1559 GNUNET_free (udpw);
1501 udpw = plugin->msg_head; 1560 udpw = plugin->ipv4_queue_head;
1502 } 1561 }
1503 else 1562 else
1504 { 1563 {
@@ -1528,26 +1587,8 @@ udp_select_send (struct Plugin *plugin)
1528 return 0; 1587 return 0;
1529 } 1588 }
1530 1589
1531 switch (sa->sa_family) 1590 sent = GNUNET_NETWORK_socket_sendto (sock, udpw->udp, udpw->msg_size, sa, slen);
1532 { 1591
1533 case AF_INET:
1534 if (NULL == plugin->sockv4)
1535 return 0;
1536 sent =
1537 GNUNET_NETWORK_socket_sendto (plugin->sockv4, udpw->udp, udpw->msg_size,
1538 sa, slen = sizeof (struct sockaddr_in));
1539 break;
1540 case AF_INET6:
1541 if (NULL == plugin->sockv6)
1542 return 0;
1543 sent =
1544 GNUNET_NETWORK_socket_sendto (plugin->sockv6, udpw->udp, udpw->msg_size,
1545 sa, slen = sizeof (struct sockaddr_in6));
1546 break;
1547 default:
1548 GNUNET_break (0);
1549 return 0;
1550 }
1551 if (GNUNET_SYSERR == sent) 1592 if (GNUNET_SYSERR == sent)
1552 { 1593 {
1553 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto"); 1594 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "sendto");
@@ -1575,8 +1616,12 @@ udp_select_send (struct Plugin *plugin)
1575 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_OK); 1616 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_OK);
1576 } 1617 }
1577 1618
1578 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw); 1619 if (sock == plugin->sockv4)
1620 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw);
1621 else if (sock == plugin->sockv6)
1622 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw);
1579 GNUNET_free (udpw); 1623 GNUNET_free (udpw);
1624 udpw = NULL;
1580 1625
1581 return sent; 1626 return sent;
1582} 1627}
@@ -1610,8 +1655,16 @@ udp_plugin_select (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1610 1655
1611 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0) 1656 if ((tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY) != 0)
1612 { 1657 {
1613 if (plugin->msg_head != NULL) 1658 if ((NULL != plugin->sockv4) && (plugin->ipv4_queue_head != NULL) &&
1614 udp_select_send (plugin); 1659 (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv4)))
1660 {
1661 udp_select_send (plugin, plugin->sockv4);
1662 }
1663 if ((NULL != plugin->sockv6) && (plugin->ipv6_queue_head != NULL) &&
1664 (GNUNET_NETWORK_fdset_isset (tc->write_ready, plugin->sockv6)))
1665 {
1666 udp_select_send (plugin, plugin->sockv6);
1667 }
1615 } 1668 }
1616 1669
1617 plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1670 plugin->select_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
@@ -1990,11 +2043,22 @@ libgnunet_plugin_transport_udp_done (void *cls)
1990 } 2043 }
1991 2044
1992 /* Clean up leftover messages */ 2045 /* Clean up leftover messages */
1993 struct UDPMessageWrapper *udpw = plugin->msg_head; 2046 struct UDPMessageWrapper * updw;
2047 udpw = plugin->ipv4_queue_head;
2048 while (udpw != NULL)
2049 {
2050 struct UDPMessageWrapper *tmp = udpw->next;
2051 GNUNET_CONTAINER_DLL_remove(plugin->ipv4_queue_head, plugin->ipv4_queue_tail, udpw);
2052 if (udpw->cont != NULL)
2053 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR);
2054 GNUNET_free (udpw);
2055 udpw = tmp;
2056 }
2057 udpw = plugin->ipv6_queue_head;
1994 while (udpw != NULL) 2058 while (udpw != NULL)
1995 { 2059 {
1996 struct UDPMessageWrapper *tmp = udpw->next; 2060 struct UDPMessageWrapper *tmp = udpw->next;
1997 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, udpw); 2061 GNUNET_CONTAINER_DLL_remove(plugin->ipv6_queue_head, plugin->ipv6_queue_tail, udpw);
1998 if (udpw->cont != NULL) 2062 if (udpw->cont != NULL)
1999 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR); 2063 udpw->cont (udpw->cont_cls, &udpw->session->target, GNUNET_SYSERR);
2000 GNUNET_free (udpw); 2064 GNUNET_free (udpw);
diff --git a/src/transport/plugin_transport_udp.h b/src/transport/plugin_transport_udp.h
index d3eb192a1..6f78a4169 100644
--- a/src/transport/plugin_transport_udp.h
+++ b/src/transport/plugin_transport_udp.h
@@ -251,9 +251,11 @@ struct Plugin
251 */ 251 */
252 uint16_t aport; 252 uint16_t aport;
253 253
254 struct UDPMessageWrapper *msg_head; 254 struct UDPMessageWrapper *ipv4_queue_head;
255 struct UDPMessageWrapper *msg_tail; 255 struct UDPMessageWrapper *ipv4_queue_tail;
256 256
257 struct UDPMessageWrapper *ipv6_queue_head;
258 struct UDPMessageWrapper *ipv6_queue_tail;
257}; 259};
258 260
259 261