aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_tcp.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2013-06-27 09:20:00 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2013-06-27 09:20:00 +0000
commitb5f7f58e273a0e270586a378cb81ede568ff71b1 (patch)
tree8c39f3929841da6eae033f57c366d676167489b5 /src/transport/plugin_transport_tcp.c
parent596878227cf1c326cba9273c0bedd6a00e142552 (diff)
downloadgnunet-b5f7f58e273a0e270586a378cb81ede568ff71b1.tar.gz
gnunet-b5f7f58e273a0e270586a378cb81ede568ff71b1.zip
added option field in tcp plugin
+ fixed bug in port map callback: stack allocated variables not zeroed out -> addresses not comparable!
Diffstat (limited to 'src/transport/plugin_transport_tcp.c')
-rw-r--r--src/transport/plugin_transport_tcp.c111
1 files changed, 100 insertions, 11 deletions
diff --git a/src/transport/plugin_transport_tcp.c b/src/transport/plugin_transport_tcp.c
index b2cb18916..df7e833a0 100644
--- a/src/transport/plugin_transport_tcp.c
+++ b/src/transport/plugin_transport_tcp.c
@@ -41,6 +41,8 @@
41 41
42#define LOG(kind,...) GNUNET_log_from (kind, "transport-tcp",__VA_ARGS__) 42#define LOG(kind,...) GNUNET_log_from (kind, "transport-tcp",__VA_ARGS__)
43 43
44#define PLUGIN_NAME "tcp"
45
44/** 46/**
45 * How long until we give up on establishing an NAT connection? 47 * How long until we give up on establishing an NAT connection?
46 * Must be > 4 RTT 48 * Must be > 4 RTT
@@ -51,6 +53,11 @@
51GNUNET_NETWORK_STRUCT_BEGIN 53GNUNET_NETWORK_STRUCT_BEGIN
52 54
53/** 55/**
56 * Address options
57 */
58static uint32_t myoptions;
59
60/**
54 * Initial handshake message for a session. 61 * Initial handshake message for a session.
55 */ 62 */
56struct WelcomeMessage 63struct WelcomeMessage
@@ -132,6 +139,11 @@ GNUNET_NETWORK_STRUCT_BEGIN
132 */ 139 */
133struct IPv4TcpAddress 140struct IPv4TcpAddress
134{ 141{
142 /**
143 * Optional options and flags for this address
144 */
145 uint32_t options;
146
135 /** 147 /**
136 * IPv4 address, in network byte order. 148 * IPv4 address, in network byte order.
137 */ 149 */
@@ -150,6 +162,11 @@ struct IPv4TcpAddress
150 */ 162 */
151struct IPv6TcpAddress 163struct IPv6TcpAddress
152{ 164{
165 /**
166 * Optional flags for this address
167 */
168 uint32_t options;
169
153 /** 170 /**
154 * IPv6 address. 171 * IPv6 address.
155 */ 172 */
@@ -529,6 +546,8 @@ tcp_nat_port_map_callback (void *cls, int add_remove,
529 { 546 {
530 case AF_INET: 547 case AF_INET:
531 GNUNET_assert (addrlen == sizeof (struct sockaddr_in)); 548 GNUNET_assert (addrlen == sizeof (struct sockaddr_in));
549 memset (&t4,0, sizeof (t4));
550 t4.options = htonl (myoptions);
532 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr; 551 t4.ipv4_addr = ((struct sockaddr_in *) addr)->sin_addr.s_addr;
533 t4.t4_port = ((struct sockaddr_in *) addr)->sin_port; 552 t4.t4_port = ((struct sockaddr_in *) addr)->sin_port;
534 arg = &t4; 553 arg = &t4;
@@ -536,8 +555,10 @@ tcp_nat_port_map_callback (void *cls, int add_remove,
536 break; 555 break;
537 case AF_INET6: 556 case AF_INET6:
538 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6)); 557 GNUNET_assert (addrlen == sizeof (struct sockaddr_in6));
558 memset (&t6, 0, sizeof (t6));
539 memcpy (&t6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr, 559 memcpy (&t6.ipv6_addr, &((struct sockaddr_in6 *) addr)->sin6_addr,
540 sizeof (struct in6_addr)); 560 sizeof (struct in6_addr));
561 t6.options = htonl (myoptions);
541 t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port; 562 t6.t6_port = ((struct sockaddr_in6 *) addr)->sin6_port;
542 arg = &t6; 563 arg = &t6;
543 args = sizeof (t6); 564 args = sizeof (t6);
@@ -574,13 +595,16 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
574 const struct IPv6TcpAddress *t6; 595 const struct IPv6TcpAddress *t6;
575 int af; 596 int af;
576 uint16_t port; 597 uint16_t port;
598 uint32_t options;
577 599
600 options = 0;
578 switch (addrlen) 601 switch (addrlen)
579 { 602 {
580 case sizeof (struct IPv6TcpAddress): 603 case sizeof (struct IPv6TcpAddress):
581 t6 = addr; 604 t6 = addr;
582 af = AF_INET6; 605 af = AF_INET6;
583 port = ntohs (t6->t6_port); 606 port = ntohs (t6->t6_port);
607 options = ntohl (t6->options);
584 memcpy (&a6, &t6->ipv6_addr, sizeof (a6)); 608 memcpy (&a6, &t6->ipv6_addr, sizeof (a6));
585 sb = &a6; 609 sb = &a6;
586 break; 610 break;
@@ -588,6 +612,7 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
588 t4 = addr; 612 t4 = addr;
589 af = AF_INET; 613 af = AF_INET;
590 port = ntohs (t4->t4_port); 614 port = ntohs (t4->t4_port);
615 options = ntohl (t4->options);
591 memcpy (&a4, &t4->ipv4_addr, sizeof (a4)); 616 memcpy (&a4, &t4->ipv4_addr, sizeof (a4));
592 sb = &a4; 617 sb = &a4;
593 break; 618 break;
@@ -603,8 +628,8 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
603 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop"); 628 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "inet_ntop");
604 return NULL; 629 return NULL;
605 } 630 }
606 GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "[%s]:%u" : "%s:%u", 631 GNUNET_snprintf (rbuf, sizeof (rbuf), (af == AF_INET6) ? "%s.%u.[%s]:%u" : "%s.%u.%s:%u",
607 buf, port); 632 PLUGIN_NAME, options, buf, port);
608 return rbuf; 633 return rbuf;
609} 634}
610 635
@@ -614,7 +639,7 @@ tcp_address_to_string (void *cls, const void *addr, size_t addrlen)
614 * a binary address. 639 * a binary address.
615 * 640 *
616 * @param cls closure ('struct Plugin*') 641 * @param cls closure ('struct Plugin*')
617 * @param addr string address 642 * @param address string address
618 * @param addrlen length of the address 643 * @param addrlen length of the address
619 * @param buf location to store the buffer 644 * @param buf location to store the buffer
620 * @param added location to store the number of bytes in the buffer. 645 * @param added location to store the number of bytes in the buffer.
@@ -626,7 +651,16 @@ tcp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
626 void **buf, size_t *added) 651 void **buf, size_t *added)
627{ 652{
628 struct sockaddr_storage socket_address; 653 struct sockaddr_storage socket_address;
629 654 char *address;
655 char *plugin;
656 char *optionstr;
657 uint32_t options;
658
659 /* Format tcp.options.address:port */
660 address = NULL;
661 plugin = NULL;
662 optionstr = NULL;
663 options = 0;
630 if ((NULL == addr) || (addrlen == 0)) 664 if ((NULL == addr) || (addrlen == 0))
631 { 665 {
632 GNUNET_break (0); 666 GNUNET_break (0);
@@ -642,21 +676,44 @@ tcp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
642 GNUNET_break (0); 676 GNUNET_break (0);
643 return GNUNET_SYSERR; 677 return GNUNET_SYSERR;
644 } 678 }
679 plugin = GNUNET_strdup (addr);
680 optionstr = strchr (plugin, '.');
681 if (NULL == optionstr)
682 {
683 GNUNET_break (0);
684 GNUNET_free (plugin);
685 return GNUNET_SYSERR;
686 }
687 optionstr[0] = '\0';
688 optionstr ++;
689 options = atol (optionstr);
690 address = strchr (optionstr, '.');
691 if (NULL == address)
692 {
693 GNUNET_break (0);
694 GNUNET_free (plugin);
695 return GNUNET_SYSERR;
696 }
697 address[0] = '\0';
698 address ++;
699
645 if (GNUNET_OK != 700 if (GNUNET_OK !=
646 GNUNET_STRINGS_to_address_ip (addr, strlen (addr), 701 GNUNET_STRINGS_to_address_ip (address, strlen (address),
647 &socket_address)) 702 &socket_address))
648 { 703 {
649 GNUNET_break (0); 704 GNUNET_break (0);
650 return GNUNET_SYSERR; 705 return GNUNET_SYSERR;
651 } 706 }
707
708 GNUNET_free (plugin);
652 switch (socket_address.ss_family) 709 switch (socket_address.ss_family)
653 { 710 {
654 case AF_INET: 711 case AF_INET:
655 { 712 {
656 struct IPv4TcpAddress *t4; 713 struct IPv4TcpAddress *t4;
657 struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address; 714 struct sockaddr_in *in4 = (struct sockaddr_in *) &socket_address;
658
659 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 715 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
716 t4->options = htonl (options);
660 t4->ipv4_addr = in4->sin_addr.s_addr; 717 t4->ipv4_addr = in4->sin_addr.s_addr;
661 t4->t4_port = in4->sin_port; 718 t4->t4_port = in4->sin_port;
662 *buf = t4; 719 *buf = t4;
@@ -668,6 +725,7 @@ tcp_string_to_address (void *cls, const char *addr, uint16_t addrlen,
668 struct IPv6TcpAddress *t6; 725 struct IPv6TcpAddress *t6;
669 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address; 726 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) &socket_address;
670 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 727 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
728 t6->options = htonl (options);
671 t6->ipv6_addr = in6->sin6_addr; 729 t6->ipv6_addr = in6->sin6_addr;
672 t6->t6_port = in6->sin6_port; 730 t6->t6_port = in6->sin6_port;
673 *buf = t6; 731 *buf = t6;
@@ -1346,9 +1404,9 @@ tcp_plugin_get_session (void *cls,
1346 } 1404 }
1347 else 1405 else
1348 { 1406 {
1349 LOG (GNUNET_ERROR_TYPE_ERROR, 1407 LOG (GNUNET_ERROR_TYPE_WARNING,
1350 _("Address of unexpected length: %u\n"), addrlen); 1408 _("%s:%u: Address of unexpected length %u (should be %u or %u)\n"),
1351 GNUNET_break (0); 1409 addrlen, sizeof (struct IPv4TcpAddress), sizeof (struct IPv6TcpAddress));
1352 return NULL; 1410 return NULL;
1353 } 1411 }
1354 1412
@@ -1520,6 +1578,11 @@ struct PrettyPrinterContext
1520 uint16_t port; 1578 uint16_t port;
1521 1579
1522 int ipv6; 1580 int ipv6;
1581
1582 /**
1583 * Options
1584 */
1585 uint32_t options;
1523}; 1586};
1524 1587
1525 1588
@@ -1542,9 +1605,9 @@ append_port (void *cls, const char *hostname)
1542 return; 1605 return;
1543 } 1606 }
1544 if (GNUNET_YES == ppc->ipv6) 1607 if (GNUNET_YES == ppc->ipv6)
1545 GNUNET_asprintf (&ret, "[%s]:%d", hostname, ppc->port); 1608 GNUNET_asprintf (&ret, "%s.%u.[%s]:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port);
1546 else 1609 else
1547 GNUNET_asprintf (&ret, "%s:%d", hostname, ppc->port); 1610 GNUNET_asprintf (&ret, "%s.%u.%s:%d", PLUGIN_NAME, ppc->options, hostname, ppc->port);
1548 ppc->asc (ppc->asc_cls, ret); 1611 ppc->asc (ppc->asc_cls, ret);
1549 GNUNET_free (ret); 1612 GNUNET_free (ret);
1550} 1613}
@@ -1580,7 +1643,10 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type,
1580 const struct IPv4TcpAddress *t4; 1643 const struct IPv4TcpAddress *t4;
1581 const struct IPv6TcpAddress *t6; 1644 const struct IPv6TcpAddress *t6;
1582 uint16_t port; 1645 uint16_t port;
1646 uint32_t options;
1647
1583 1648
1649 options = 0;
1584 if (addrlen == sizeof (struct IPv6TcpAddress)) 1650 if (addrlen == sizeof (struct IPv6TcpAddress))
1585 { 1651 {
1586 t6 = addr; 1652 t6 = addr;
@@ -1589,6 +1655,7 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type,
1589 a6.sin6_port = t6->t6_port; 1655 a6.sin6_port = t6->t6_port;
1590 memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof (struct in6_addr)); 1656 memcpy (&a6.sin6_addr, &t6->ipv6_addr, sizeof (struct in6_addr));
1591 port = ntohs (t6->t6_port); 1657 port = ntohs (t6->t6_port);
1658 options = ntohl (t6->options);
1592 sb = &a6; 1659 sb = &a6;
1593 sbs = sizeof (a6); 1660 sbs = sizeof (a6);
1594 } 1661 }
@@ -1600,6 +1667,7 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type,
1600 a4.sin_port = t4->t4_port; 1667 a4.sin_port = t4->t4_port;
1601 a4.sin_addr.s_addr = t4->ipv4_addr; 1668 a4.sin_addr.s_addr = t4->ipv4_addr;
1602 port = ntohs (t4->t4_port); 1669 port = ntohs (t4->t4_port);
1670 options = ntohl (t4->options);
1603 sb = &a4; 1671 sb = &a4;
1604 sbs = sizeof (a4); 1672 sbs = sizeof (a4);
1605 } 1673 }
@@ -1624,6 +1692,7 @@ tcp_plugin_address_pretty_printer (void *cls, const char *type,
1624 ppc->asc = asc; 1692 ppc->asc = asc;
1625 ppc->asc_cls = asc_cls; 1693 ppc->asc_cls = asc_cls;
1626 ppc->port = port; 1694 ppc->port = port;
1695 ppc->options = options;
1627 GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc); 1696 GNUNET_RESOLVER_hostname_get (sb, sbs, !numeric, timeout, &append_port, ppc);
1628} 1697}
1629 1698
@@ -1675,9 +1744,16 @@ tcp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1675 GNUNET_break_op (0); 1744 GNUNET_break_op (0);
1676 return GNUNET_SYSERR; 1745 return GNUNET_SYSERR;
1677 } 1746 }
1747
1748
1678 if (addrlen == sizeof (struct IPv4TcpAddress)) 1749 if (addrlen == sizeof (struct IPv4TcpAddress))
1679 { 1750 {
1680 v4 = (struct IPv4TcpAddress *) addr; 1751 v4 = (struct IPv4TcpAddress *) addr;
1752 if (0 != memcmp (&v4->options, &myoptions, sizeof (myoptions)))
1753 {
1754 GNUNET_break (0);
1755 return GNUNET_SYSERR;
1756 }
1681 if (GNUNET_OK != check_port (plugin, ntohs (v4->t4_port))) 1757 if (GNUNET_OK != check_port (plugin, ntohs (v4->t4_port)))
1682 return GNUNET_SYSERR; 1758 return GNUNET_SYSERR;
1683 if (GNUNET_OK != 1759 if (GNUNET_OK !=
@@ -1693,6 +1769,11 @@ tcp_plugin_check_address (void *cls, const void *addr, size_t addrlen)
1693 GNUNET_break_op (0); 1769 GNUNET_break_op (0);
1694 return GNUNET_SYSERR; 1770 return GNUNET_SYSERR;
1695 } 1771 }
1772 if (0 != memcmp (&v6->options, &myoptions, sizeof (myoptions)))
1773 {
1774 GNUNET_break (0);
1775 return GNUNET_SYSERR;
1776 }
1696 if (GNUNET_OK != check_port (plugin, ntohs (v6->t6_port))) 1777 if (GNUNET_OK != check_port (plugin, ntohs (v6->t6_port)))
1697 return GNUNET_SYSERR; 1778 return GNUNET_SYSERR;
1698 if (GNUNET_OK != 1779 if (GNUNET_OK !=
@@ -1796,6 +1877,7 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client,
1796 case AF_INET: 1877 case AF_INET:
1797 s4 = vaddr; 1878 s4 = vaddr;
1798 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 1879 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
1880 t4->options = 0;
1799 t4->t4_port = s4->sin_port; 1881 t4->t4_port = s4->sin_port;
1800 t4->ipv4_addr = s4->sin_addr.s_addr; 1882 t4->ipv4_addr = s4->sin_addr.s_addr;
1801 session->addr = t4; 1883 session->addr = t4;
@@ -1804,6 +1886,7 @@ handle_tcp_nat_probe (void *cls, struct GNUNET_SERVER_Client *client,
1804 case AF_INET6: 1886 case AF_INET6:
1805 s6 = vaddr; 1887 s6 = vaddr;
1806 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 1888 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
1889 t6->options = 0;
1807 t6->t6_port = s6->sin6_port; 1890 t6->t6_port = s6->sin6_port;
1808 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr)); 1891 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
1809 session->addr = t6; 1892 session->addr = t6;
@@ -1895,6 +1978,7 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client,
1895 { 1978 {
1896 s4 = vaddr; 1979 s4 = vaddr;
1897 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress)); 1980 t4 = GNUNET_malloc (sizeof (struct IPv4TcpAddress));
1981 t4->options = htonl (0);
1898 t4->t4_port = s4->sin_port; 1982 t4->t4_port = s4->sin_port;
1899 t4->ipv4_addr = s4->sin_addr.s_addr; 1983 t4->ipv4_addr = s4->sin_addr.s_addr;
1900 session->addr = t4; 1984 session->addr = t4;
@@ -1904,6 +1988,7 @@ handle_tcp_welcome (void *cls, struct GNUNET_SERVER_Client *client,
1904 { 1988 {
1905 s6 = vaddr; 1989 s6 = vaddr;
1906 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress)); 1990 t6 = GNUNET_malloc (sizeof (struct IPv6TcpAddress));
1991 t6->options = htonl (0);
1907 t6->t6_port = s6->sin6_port; 1992 t6->t6_port = s6->sin6_port;
1908 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr)); 1993 memcpy (&t6->ipv6_addr, &s6->sin6_addr, sizeof (struct in6_addr));
1909 session->addr = t6; 1994 session->addr = t6;
@@ -2312,6 +2397,7 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2312 struct sockaddr **addrs; 2397 struct sockaddr **addrs;
2313 socklen_t *addrlens; 2398 socklen_t *addrlens;
2314 2399
2400
2315 if (NULL == env->receive) 2401 if (NULL == env->receive)
2316 { 2402 {
2317 /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully 2403 /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully
@@ -2363,6 +2449,9 @@ libgnunet_plugin_transport_tcp_init (void *cls)
2363 else 2449 else
2364 service = NULL; 2450 service = NULL;
2365 2451
2452 /* Initialize my flags */
2453 myoptions = 0;
2454
2366 plugin = GNUNET_malloc (sizeof (struct Plugin)); 2455 plugin = GNUNET_malloc (sizeof (struct Plugin));
2367 plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create (max_connections, GNUNET_YES); 2456 plugin->sessionmap = GNUNET_CONTAINER_multihashmap_create (max_connections, GNUNET_YES);
2368 plugin->max_connections = max_connections; 2457 plugin->max_connections = max_connections;