diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/plugin_transport_udp.c | 144 | ||||
-rw-r--r-- | src/transport/plugin_transport_udp.h | 6 |
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 | ||
794 | static 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 | ||
1460 | size_t | 1502 | size_t |
1461 | udp_select_send (struct Plugin *plugin) | 1503 | udp_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 | ||