aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_udp.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/plugin_transport_udp.c')
-rw-r--r--src/transport/plugin_transport_udp.c732
1 files changed, 372 insertions, 360 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c
index 0589a24bd..dba8de2cb 100644
--- a/src/transport/plugin_transport_udp.c
+++ b/src/transport/plugin_transport_udp.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet 2 This file is part of GNUnet
3 (C) 2010-2014 Christian Grothoff (and other contributing authors) 3 (C) 2010-2015 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -102,10 +102,10 @@ struct PrettyPrinterContext
102 /** 102 /**
103 * Timeout task 103 * Timeout task
104 */ 104 */
105 struct GNUNET_SCHEDULER_Task * timeout_task; 105 struct GNUNET_SCHEDULER_Task *timeout_task;
106 106
107 /** 107 /**
108 * IPv6 address 108 * Is this an IPv6 address?
109 */ 109 */
110 int ipv6; 110 int ipv6;
111 111
@@ -155,7 +155,7 @@ struct Session
155 /** 155 /**
156 * Session timeout task 156 * Session timeout task
157 */ 157 */
158 struct GNUNET_SCHEDULER_Task * timeout_task; 158 struct GNUNET_SCHEDULER_Task *timeout_task;
159 159
160 /** 160 /**
161 * When does this session time out? 161 * When does this session time out?
@@ -222,20 +222,10 @@ struct SourceInformation
222 struct GNUNET_PeerIdentity sender; 222 struct GNUNET_PeerIdentity sender;
223 223
224 /** 224 /**
225 * Source address.
226 */
227 const void *arg;
228
229 /**
230 * Associated session. 225 * Associated session.
231 */ 226 */
232 struct Session *session; 227 struct Session *session;
233 228
234 /**
235 * Number of bytes in source address.
236 */
237 size_t args;
238
239}; 229};
240 230
241/** 231/**
@@ -249,19 +239,19 @@ struct FindReceiveContext
249 struct DefragContext *rc; 239 struct DefragContext *rc;
250 240
251 /** 241 /**
252 * Address to find. 242 * Session associated with this context.
253 */ 243 */
254 const struct sockaddr *addr; 244 struct Session *session;
255 245
256 /** 246 /**
257 * 247 * Address to find.
258 */ 248 */
259 struct Session *session; 249 const union UdpAddress *udp_addr;
260 250
261 /** 251 /**
262 * Number of bytes in @e addr. 252 * Number of bytes in @e udp_addr.
263 */ 253 */
264 socklen_t addr_len; 254 size_t udp_addr_len;
265 255
266}; 256};
267 257
@@ -278,25 +268,42 @@ struct DefragContext
278 struct GNUNET_DEFRAGMENT_Context *defrag; 268 struct GNUNET_DEFRAGMENT_Context *defrag;
279 269
280 /** 270 /**
271 * Reference to master plugin struct.
272 */
273 struct Plugin *plugin;
274
275 /**
276 * Node in the defrag heap.
277 */
278 struct GNUNET_CONTAINER_HeapNode *hnode;
279
280 /**
281 * Who's message(s) are we defragmenting here?
282 * Only initialized once we succeeded and
283 * @e have_sender is set.
284 */
285 struct GNUNET_PeerIdentity sender;
286
287 /**
281 * Source address this receive context is for (allocated at the 288 * Source address this receive context is for (allocated at the
282 * end of the struct). 289 * end of the struct).
283 */ 290 */
284 const struct sockaddr *src_addr; 291 const union UdpAddress *udp_addr;
285 292
286 /** 293 /**
287 * Reference to master plugin struct. 294 * Length of @e udp_addr.
288 */ 295 */
289 struct Plugin *plugin; 296 size_t udp_addr_len;
290 297
291 /** 298 /**
292 * Node in the defrag heap. 299 * Network type the address belongs to.
293 */ 300 */
294 struct GNUNET_CONTAINER_HeapNode *hnode; 301 enum GNUNET_ATS_Network_Type network_type;
295 302
296 /** 303 /**
297 * Length of @e src_addr. 304 * Has the @e sender field been initialized yet?
298 */ 305 */
299 size_t addr_len; 306 int have_sender;
300}; 307};
301 308
302 309
@@ -464,7 +471,7 @@ struct UDP_MessageWrapper
464 471
465 472
466/** 473/**
467 * UDP ACK Message-Packet header (after defragmentation). 474 * UDP ACK Message-Packet header.
468 */ 475 */
469struct UDP_ACK_Message 476struct UDP_ACK_Message
470{ 477{
@@ -606,8 +613,8 @@ schedule_select (struct Plugin *plugin)
606 * to override the address again. 613 * to override the address again.
607 * 614 *
608 * @param cls closure 615 * @param cls closure
609 * @param addr binary address 616 * @param addr binary address (a `union UdpAddress`)
610 * @param addrlen length of the address 617 * @param addrlen length of the @a addr
611 * @return string representing the same address 618 * @return string representing the same address
612 */ 619 */
613const char * 620const char *
@@ -651,8 +658,13 @@ udp_address_to_string (void *cls,
651 inet_ntop (af, sb, buf, INET6_ADDRSTRLEN); 658 inet_ntop (af, sb, buf, INET6_ADDRSTRLEN);
652 659
653 GNUNET_snprintf (rbuf, sizeof(rbuf), 660 GNUNET_snprintf (rbuf, sizeof(rbuf),
654 (af == AF_INET6) ? "%s.%u.[%s]:%u" : "%s.%u.%s:%u", PLUGIN_NAME, options, 661 (af == AF_INET6)
655 buf, port); 662 ? "%s.%u.[%s]:%u"
663 : "%s.%u.%s:%u",
664 PLUGIN_NAME,
665 options,
666 buf,
667 port);
656 return rbuf; 668 return rbuf;
657} 669}
658 670
@@ -661,7 +673,7 @@ udp_address_to_string (void *cls,
661 * Function called to convert a string address to 673 * Function called to convert a string address to
662 * a binary address. 674 * a binary address.
663 * 675 *
664 * @param cls closure ('struct Plugin*') 676 * @param cls closure (`struct Plugin *`)
665 * @param addr string address 677 * @param addr string address
666 * @param addrlen length of the address 678 * @param addrlen length of the address
667 * @param buf location to store the buffer 679 * @param buf location to store the buffer
@@ -822,7 +834,8 @@ append_port (void *cls,
822 * @param cls closure with the `struct Plugin *` 834 * @param cls closure with the `struct Plugin *`
823 * @param type name of the transport that generated the address 835 * @param type name of the transport that generated the address
824 * @param addr one of the addresses of the host, NULL for the last address 836 * @param addr one of the addresses of the host, NULL for the last address
825 * the specific address format depends on the transport 837 * the specific address format depends on the transport;
838 * a `union UdpAddress`
826 * @param addrlen length of the address 839 * @param addrlen length of the address
827 * @param numeric should (IP) addresses be displayed in numeric form? 840 * @param numeric should (IP) addresses be displayed in numeric form?
828 * @param timeout after how long should we give up? 841 * @param timeout after how long should we give up?
@@ -1095,7 +1108,7 @@ check_port (struct Plugin *plugin,
1095 * traffic. 1108 * traffic.
1096 * 1109 *
1097 * @param cls closure, should be our handle to the Plugin 1110 * @param cls closure, should be our handle to the Plugin
1098 * @param addr pointer to the address 1111 * @param addr pointer to a `union UdpAddress`
1099 * @param addrlen length of @a addr 1112 * @param addrlen length of @a addr
1100 * @return #GNUNET_OK if this is a plausible address for this peer 1113 * @return #GNUNET_OK if this is a plausible address for this peer
1101 * and transport, #GNUNET_SYSERR if not 1114 * and transport, #GNUNET_SYSERR if not
@@ -1285,7 +1298,7 @@ fragmented_message_done (struct UDP_FragmentationContext *fc,
1285 * 1298 *
1286 * @param cls the `struct FindReceiveContext` 1299 * @param cls the `struct FindReceiveContext`
1287 * @param node internal node of the heap 1300 * @param node internal node of the heap
1288 * @param element value stored at the node (a 'struct ReceiveContext') 1301 * @param element value stored at the node (a `struct ReceiveContext`)
1289 * @param cost cost associated with the node 1302 * @param cost cost associated with the node
1290 * @return #GNUNET_YES if we should continue to iterate, 1303 * @return #GNUNET_YES if we should continue to iterate,
1291 * #GNUNET_NO if not. 1304 * #GNUNET_NO if not.
@@ -1299,8 +1312,10 @@ find_receive_context (void *cls,
1299 struct FindReceiveContext *frc = cls; 1312 struct FindReceiveContext *frc = cls;
1300 struct DefragContext *e = element; 1313 struct DefragContext *e = element;
1301 1314
1302 if ((frc->addr_len == e->addr_len) 1315 if ( (frc->udp_addr_len == e->udp_addr_len) &&
1303 && (0 == memcmp (frc->addr, e->src_addr, frc->addr_len))) 1316 (0 == memcmp (frc->udp_addr,
1317 e->udp_addr,
1318 frc->udp_addr_len)) )
1304 { 1319 {
1305 frc->rc = e; 1320 frc->rc = e;
1306 return GNUNET_NO; 1321 return GNUNET_NO;
@@ -1328,12 +1343,12 @@ udp_disconnect_session (void *cls,
1328 struct FindReceiveContext frc; 1343 struct FindReceiveContext frc;
1329 1344
1330 GNUNET_assert (GNUNET_YES != s->in_destroy); 1345 GNUNET_assert (GNUNET_YES != s->in_destroy);
1331 LOG(GNUNET_ERROR_TYPE_DEBUG, 1346 LOG (GNUNET_ERROR_TYPE_DEBUG,
1332 "Session %p to peer `%s' address ended\n", s, 1347 "Session %p to peer `%s' address ended\n", s,
1333 GNUNET_i2s (&s->target), 1348 GNUNET_i2s (&s->target),
1334 udp_address_to_string (NULL, 1349 udp_address_to_string (NULL,
1335 s->address->address, 1350 s->address->address,
1336 s->address->address_length)); 1351 s->address->address_length));
1337 /* stop timeout task */ 1352 /* stop timeout task */
1338 if (NULL != s->timeout_task) 1353 if (NULL != s->timeout_task)
1339 { 1354 {
@@ -1343,12 +1358,13 @@ udp_disconnect_session (void *cls,
1343 if (NULL != s->frag_ctx) 1358 if (NULL != s->frag_ctx)
1344 { 1359 {
1345 /* Remove fragmented message due to disconnect */ 1360 /* Remove fragmented message due to disconnect */
1346 fragmented_message_done (s->frag_ctx, GNUNET_SYSERR); 1361 fragmented_message_done (s->frag_ctx,
1362 GNUNET_SYSERR);
1347 } 1363 }
1348 1364
1349 frc.rc = NULL; 1365 frc.rc = NULL;
1350 frc.addr = s->address->address; 1366 frc.udp_addr = s->address->address;
1351 frc.addr_len = s->address->address_length; 1367 frc.udp_addr_len = s->address->address_length;
1352 /* Lookup existing receive context for this address */ 1368 /* Lookup existing receive context for this address */
1353 if (NULL != plugin->defrag_ctxs) 1369 if (NULL != plugin->defrag_ctxs)
1354 { 1370 {
@@ -1555,8 +1571,8 @@ create_session (struct Plugin *plugin,
1555 s->plugin = plugin; 1571 s->plugin = plugin;
1556 s->address = GNUNET_HELLO_address_copy (address); 1572 s->address = GNUNET_HELLO_address_copy (address);
1557 s->target = address->peer; 1573 s->target = address->peer;
1558 s->last_expected_ack_delay = GNUNET_TIME_relative_multiply ( 1574 s->last_expected_ack_delay = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
1559 GNUNET_TIME_UNIT_MILLISECONDS, 250); 1575 250);
1560 s->last_expected_msg_delay = GNUNET_TIME_UNIT_MILLISECONDS; 1576 s->last_expected_msg_delay = GNUNET_TIME_UNIT_MILLISECONDS;
1561 s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS; 1577 s->flow_delay_from_other_peer = GNUNET_TIME_UNIT_ZERO_ABS;
1562 s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO; 1578 s->flow_delay_for_other_peer = GNUNET_TIME_UNIT_ZERO;
@@ -1634,20 +1650,21 @@ session_cmp_it (void *cls,
1634 1650
1635 1651
1636/** 1652/**
1637 * Creates a new outbound session the transport service will use to 1653 * Locate an existing session the transport service is using to
1638 * send data to the peer 1654 * send data to another peer. Performs some basic sanity checks
1655 * on the address and then tries to locate a matching session.
1639 * 1656 *
1640 * @param cls the plugin 1657 * @param cls the plugin
1641 * @param address the address 1658 * @param address the address we should locate the session by
1642 * @return the session or NULL of max connections exceeded 1659 * @return the session if it exists, or NULL if it is not found
1643 */ 1660 */
1644static struct Session * 1661static struct Session *
1645udp_plugin_lookup_session (void *cls, 1662udp_plugin_lookup_session (void *cls,
1646 const struct GNUNET_HELLO_Address *address) 1663 const struct GNUNET_HELLO_Address *address)
1647{ 1664{
1648 struct Plugin * plugin = cls; 1665 struct Plugin *plugin = cls;
1649 struct IPv6UdpAddress *udp_a6; 1666 const struct IPv6UdpAddress *udp_a6;
1650 struct IPv4UdpAddress *udp_a4; 1667 const struct IPv4UdpAddress *udp_a4;
1651 struct SessionCompareContext cctx; 1668 struct SessionCompareContext cctx;
1652 1669
1653 if ( (NULL == address->address) || 1670 if ( (NULL == address->address) ||
@@ -1655,7 +1672,7 @@ udp_plugin_lookup_session (void *cls,
1655 (address->address_length != sizeof (struct IPv6UdpAddress)))) 1672 (address->address_length != sizeof (struct IPv6UdpAddress))))
1656 { 1673 {
1657 LOG (GNUNET_ERROR_TYPE_WARNING, 1674 LOG (GNUNET_ERROR_TYPE_WARNING,
1658 _("Trying to create session for address of unexpected length %u (should be %u or %u)\n"), 1675 _("Trying to locate session for address of unexpected length %u (should be %u or %u)\n"),
1659 address->address_length, 1676 address->address_length,
1660 sizeof (struct IPv4UdpAddress), 1677 sizeof (struct IPv4UdpAddress),
1661 sizeof (struct IPv6UdpAddress)); 1678 sizeof (struct IPv6UdpAddress));
@@ -1664,19 +1681,19 @@ udp_plugin_lookup_session (void *cls,
1664 1681
1665 if (address->address_length == sizeof(struct IPv4UdpAddress)) 1682 if (address->address_length == sizeof(struct IPv4UdpAddress))
1666 { 1683 {
1667 if (plugin->sockv4 == NULL) 1684 if (NULL == plugin->sockv4)
1668 return NULL; 1685 return NULL;
1669 udp_a4 = (struct IPv4UdpAddress *) address->address; 1686 udp_a4 = (const struct IPv4UdpAddress *) address->address;
1670 if (udp_a4->u4_port == 0) 1687 if (0 == udp_a4->u4_port)
1671 return NULL; 1688 return NULL;
1672 } 1689 }
1673 1690
1674 if (address->address_length == sizeof(struct IPv6UdpAddress)) 1691 if (address->address_length == sizeof(struct IPv6UdpAddress))
1675 { 1692 {
1676 if (plugin->sockv6 == NULL) 1693 if (NULL == plugin->sockv6)
1677 return NULL; 1694 return NULL;
1678 udp_a6 = (struct IPv6UdpAddress *) address->address; 1695 udp_a6 = (const struct IPv6UdpAddress *) address->address;
1679 if (udp_a6->u6_port == 0) 1696 if (0 == udp_a6->u6_port)
1680 return NULL; 1697 return NULL;
1681 } 1698 }
1682 1699
@@ -1689,7 +1706,7 @@ udp_plugin_lookup_session (void *cls,
1689 udp_address_to_string(NULL, address->address, address->address_length)); 1706 udp_address_to_string(NULL, address->address, address->address_length));
1690 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions, 1707 GNUNET_CONTAINER_multipeermap_get_multiple (plugin->sessions,
1691 &address->peer, 1708 &address->peer,
1692 session_cmp_it, 1709 &session_cmp_it,
1693 &cctx); 1710 &cctx);
1694 if (NULL != cctx.res) 1711 if (NULL != cctx.res)
1695 { 1712 {
@@ -1703,144 +1720,37 @@ udp_plugin_lookup_session (void *cls,
1703 1720
1704 1721
1705/** 1722/**
1706 * Context to lookup a session based on a IP address 1723 * Allocate a new session for the given endpoint address.
1707 */ 1724 * Note that this function does not inform the service
1708struct LookupContext 1725 * of the new session, this is the responsibility of the
1709{ 1726 * caller (if needed).
1710 /**
1711 * The result
1712 */
1713 struct Session *res;
1714
1715 /**
1716 * The socket address
1717 */
1718 const struct sockaddr *address;
1719
1720 /**
1721 * The socket address length
1722 */
1723 size_t addr_len;
1724
1725 /**
1726 * Is a fragmentation context required for the session
1727 */
1728 int must_have_frag_ctx;
1729};
1730
1731
1732/**
1733 * Find a session with a matching address.
1734 * FIXME: very similar code to #udp_plugin_lookup_session() above.
1735 * Unify?
1736 * 1727 *
1737 * @param cls the `struct LookupContext *` 1728 * @param cls the `struct Plugin`
1738 * @param key peer identity (unused) 1729 * @param address address of the other peer to use
1739 * @param value the `struct Session *` 1730 * @param network_type network type the address belongs to
1740 * @return #GNUNET_NO if we found the session, #GNUNET_OK if not 1731 * @return NULL on error, otherwise session handle
1741 */ 1732 */
1742static int
1743lookup_session_by_sockaddr_it (void *cls,
1744 const struct GNUNET_PeerIdentity *key,
1745 void *value)
1746{
1747 struct LookupContext *l_ctx = cls;
1748 struct Session *s = value;
1749 struct IPv4UdpAddress u4;
1750 struct IPv6UdpAddress u6;
1751 void *arg;
1752 size_t args;
1753
1754 /* convert address */
1755 switch (l_ctx->address->sa_family)
1756 {
1757 case AF_INET:
1758 GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in));
1759 memset (&u4, 0, sizeof(u4));
1760 u6.options = htonl (0);
1761 u4.ipv4_addr = ((struct sockaddr_in *) l_ctx->address)->sin_addr.s_addr;
1762 u4.u4_port = ((struct sockaddr_in *) l_ctx->address)->sin_port;
1763 arg = &u4;
1764 args = sizeof(u4);
1765 break;
1766 case AF_INET6:
1767 GNUNET_assert(l_ctx->addr_len == sizeof(struct sockaddr_in6));
1768 memset (&u6, 0, sizeof(u6));
1769 u6.options = htonl (0);
1770 u6.ipv6_addr = ((struct sockaddr_in6 *) l_ctx->address)->sin6_addr;
1771 u6.u6_port = ((struct sockaddr_in6 *) l_ctx->address)->sin6_port;
1772 arg = &u6;
1773 args = sizeof(u6);
1774 break;
1775 default:
1776 GNUNET_break(0);
1777 return GNUNET_YES;
1778 }
1779 if ( (GNUNET_YES == l_ctx->must_have_frag_ctx) &&
1780 (NULL == s->frag_ctx))
1781 return GNUNET_YES;
1782
1783 /* Does not compare peer identities but addresses */
1784 if ((args == s->address->address_length) &&
1785 (0 == memcmp (arg, s->address->address, args)))
1786 {
1787 l_ctx->res = s;
1788 return GNUNET_NO;
1789 }
1790 return GNUNET_YES;
1791}
1792
1793
1794static struct Session * 1733static struct Session *
1795udp_plugin_create_session (void *cls, 1734udp_plugin_create_session (void *cls,
1796 const struct GNUNET_HELLO_Address *address) 1735 const struct GNUNET_HELLO_Address *address,
1736 enum GNUNET_ATS_Network_Type network_type)
1797{ 1737{
1798 struct Plugin *plugin = cls; 1738 struct Plugin *plugin = cls;
1799 struct Session *s; 1739 struct Session *s;
1800 struct IPv4UdpAddress *udp_v4;
1801 struct IPv6UdpAddress *udp_v6;
1802 1740
1803 s = create_session (plugin, address); 1741 s = create_session (plugin, address);
1804 if (sizeof (struct IPv4UdpAddress) == address->address_length) 1742 s->ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1805 { 1743 s->ats.value = htonl (network_type);
1806 struct sockaddr_in v4;
1807
1808 udp_v4 = (struct IPv4UdpAddress *) address->address;
1809 memset (&v4, '\0', sizeof (v4));
1810 v4.sin_family = AF_INET;
1811#if HAVE_SOCKADDR_IN_SIN_LEN
1812 v4.sin_len = sizeof (struct sockaddr_in);
1813#endif
1814 v4.sin_port = udp_v4->u4_port;
1815 v4.sin_addr.s_addr = udp_v4->ipv4_addr;
1816 s->ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1817 s->ats.value = htonl (plugin->env->get_address_type (plugin->env->cls,
1818 (const struct sockaddr *) &v4,
1819 sizeof (v4)));
1820 }
1821 else if (sizeof (struct IPv6UdpAddress) == address->address_length)
1822 {
1823 struct sockaddr_in6 v6;
1824 udp_v6 = (struct IPv6UdpAddress *) address->address;
1825 memset (&v6, '\0', sizeof (v6));
1826 v6.sin6_family = AF_INET6;
1827#if HAVE_SOCKADDR_IN_SIN_LEN
1828 v6.sin6_len = sizeof (struct sockaddr_in6);
1829#endif
1830 v6.sin6_port = udp_v6->u6_port;
1831 v6.sin6_addr = udp_v6->ipv6_addr;
1832 s->ats.type = htonl (GNUNET_ATS_NETWORK_TYPE);
1833 s->ats.value = htonl (plugin->env->get_address_type (plugin->env->cls,
1834 (const struct sockaddr *) &v6,
1835 sizeof (v6)));
1836 }
1837 1744
1838 if (NULL == s) 1745 if (NULL == s)
1839 return NULL; /* protocol not supported or address invalid */ 1746 return NULL; /* protocol not supported or address invalid */
1840 LOG(GNUNET_ERROR_TYPE_DEBUG, 1747 LOG (GNUNET_ERROR_TYPE_DEBUG,
1841 "Creating new session %p for peer `%s' address `%s'\n", 1748 "Creating new session %p for peer `%s' address `%s'\n",
1842 s, GNUNET_i2s (&address->peer), 1749 s,
1843 udp_address_to_string( NULL,address->address,address->address_length)); 1750 GNUNET_i2s (&address->peer),
1751 udp_address_to_string (plugin,
1752 address->address,
1753 address->address_length));
1844 GNUNET_assert(GNUNET_OK == 1754 GNUNET_assert(GNUNET_OK ==
1845 GNUNET_CONTAINER_multipeermap_put (plugin->sessions, 1755 GNUNET_CONTAINER_multipeermap_put (plugin->sessions,
1846 &s->target, 1756 &s->target,
@@ -1884,8 +1794,8 @@ udp_plugin_update_session_timeout (void *cls,
1884 1794
1885 1795
1886/** 1796/**
1887 * Creates a new outbound session the transport service will use to send data to the 1797 * Creates a new outbound session the transport service will use to
1888 * peer 1798 * send data to the peer.
1889 * 1799 *
1890 * @param cls the plugin 1800 * @param cls the plugin
1891 * @param address the address 1801 * @param address the address
@@ -1895,7 +1805,11 @@ static struct Session *
1895udp_plugin_get_session (void *cls, 1805udp_plugin_get_session (void *cls,
1896 const struct GNUNET_HELLO_Address *address) 1806 const struct GNUNET_HELLO_Address *address)
1897{ 1807{
1808 struct Plugin *plugin = cls;
1898 struct Session *s; 1809 struct Session *s;
1810 enum GNUNET_ATS_Network_Type network_type;
1811 struct IPv4UdpAddress *udp_v4;
1812 struct IPv6UdpAddress *udp_v6;
1899 1813
1900 if (NULL == address) 1814 if (NULL == address)
1901 { 1815 {
@@ -1905,11 +1819,45 @@ udp_plugin_get_session (void *cls,
1905 if ( (address->address_length != sizeof(struct IPv4UdpAddress)) && 1819 if ( (address->address_length != sizeof(struct IPv4UdpAddress)) &&
1906 (address->address_length != sizeof(struct IPv6UdpAddress)) ) 1820 (address->address_length != sizeof(struct IPv6UdpAddress)) )
1907 return NULL; 1821 return NULL;
1822 if (NULL != (s = udp_plugin_lookup_session (cls,
1823 address)))
1824 return s;
1825
1826 if (sizeof (struct IPv4UdpAddress) == address->address_length)
1827 {
1828 struct sockaddr_in v4;
1829
1830 udp_v4 = (struct IPv4UdpAddress *) address->address;
1831 memset (&v4, '\0', sizeof (v4));
1832 v4.sin_family = AF_INET;
1833#if HAVE_SOCKADDR_IN_SIN_LEN
1834 v4.sin_len = sizeof (struct sockaddr_in);
1835#endif
1836 v4.sin_port = udp_v4->u4_port;
1837 v4.sin_addr.s_addr = udp_v4->ipv4_addr;
1838 network_type = plugin->env->get_address_type (plugin->env->cls,
1839 (const struct sockaddr *) &v4,
1840 sizeof (v4));
1841 }
1842 else if (sizeof (struct IPv6UdpAddress) == address->address_length)
1843 {
1844 struct sockaddr_in6 v6;
1845
1846 udp_v6 = (struct IPv6UdpAddress *) address->address;
1847 memset (&v6, '\0', sizeof (v6));
1848 v6.sin6_family = AF_INET6;
1849#if HAVE_SOCKADDR_IN_SIN_LEN
1850 v6.sin6_len = sizeof (struct sockaddr_in6);
1851#endif
1852 v6.sin6_port = udp_v6->u6_port;
1853 v6.sin6_addr = udp_v6->ipv6_addr;
1854 network_type = plugin->env->get_address_type (plugin->env->cls,
1855 (const struct sockaddr *) &v6,
1856 sizeof (v6));
1857 }
1908 1858
1909 /* otherwise create new */ 1859 /* otherwise create new */
1910 if (NULL != (s = udp_plugin_lookup_session (cls, address))) 1860 return udp_plugin_create_session (cls, address, network_type);
1911 return s;
1912 return udp_plugin_create_session (cls, address);
1913} 1861}
1914 1862
1915 1863
@@ -2258,7 +2206,7 @@ process_inbound_tokenized_messages (void *cls,
2258 struct SourceInformation *si = client; 2206 struct SourceInformation *si = client;
2259 struct GNUNET_TIME_Relative delay; 2207 struct GNUNET_TIME_Relative delay;
2260 2208
2261 GNUNET_assert(si->session != NULL); 2209 GNUNET_assert (NULL != si->session);
2262 if (GNUNET_YES == si->session->in_destroy) 2210 if (GNUNET_YES == si->session->in_destroy)
2263 return GNUNET_OK; 2211 return GNUNET_OK;
2264 /* setup ATS */ 2212 /* setup ATS */
@@ -2282,22 +2230,20 @@ process_inbound_tokenized_messages (void *cls,
2282 * 2230 *
2283 * @param plugin plugin context 2231 * @param plugin plugin context
2284 * @param msg the message 2232 * @param msg the message
2285 * @param sender_addr sender address 2233 * @param udp_addr sender address
2286 * @param sender_addr_len number of bytes in @a sender_addr 2234 * @param udp_addr_len number of bytes in @a udp_addr
2235 * @param network_type network type the address belongs to
2287 */ 2236 */
2288static void 2237static void
2289process_udp_message (struct Plugin *plugin, 2238process_udp_message (struct Plugin *plugin,
2290 const struct UDPMessage *msg, 2239 const struct UDPMessage *msg,
2291 const struct sockaddr *sender_addr, 2240 const union UdpAddress *udp_addr,
2292 socklen_t sender_addr_len) 2241 size_t udp_addr_len,
2242 enum GNUNET_ATS_Network_Type network_type)
2293{ 2243{
2294 struct SourceInformation si; 2244 struct SourceInformation si;
2295 struct Session * s; 2245 struct Session *s;
2296 struct GNUNET_HELLO_Address *address; 2246 struct GNUNET_HELLO_Address *address;
2297 struct IPv4UdpAddress u4;
2298 struct IPv6UdpAddress u6;
2299 const void *arg;
2300 size_t args;
2301 2247
2302 if (0 != ntohl (msg->reserved)) 2248 if (0 != ntohl (msg->reserved))
2303 { 2249 {
@@ -2311,42 +2257,16 @@ process_udp_message (struct Plugin *plugin,
2311 return; 2257 return;
2312 } 2258 }
2313 2259
2314 /* convert address */ 2260 address = GNUNET_HELLO_address_allocate (&msg->sender,
2315 switch (sender_addr->sa_family) 2261 PLUGIN_NAME,
2316 { 2262 udp_addr,
2317 case AF_INET: 2263 udp_addr_len,
2318 GNUNET_assert(sender_addr_len == sizeof(struct sockaddr_in));
2319 memset (&u4, 0, sizeof(u4));
2320 u6.options = htonl (0);
2321 u4.ipv4_addr = ((struct sockaddr_in *) sender_addr)->sin_addr.s_addr;
2322 u4.u4_port = ((struct sockaddr_in *) sender_addr)->sin_port;
2323 arg = &u4;
2324 args = sizeof(u4);
2325 break;
2326 case AF_INET6:
2327 GNUNET_assert(sender_addr_len == sizeof(struct sockaddr_in6));
2328 memset (&u6, 0, sizeof(u6));
2329 u6.options = htonl (0);
2330 u6.ipv6_addr = ((struct sockaddr_in6 *) sender_addr)->sin6_addr;
2331 u6.u6_port = ((struct sockaddr_in6 *) sender_addr)->sin6_port;
2332 arg = &u6;
2333 args = sizeof(u6);
2334 break;
2335 default:
2336 GNUNET_break(0);
2337 return;
2338 }
2339 LOG (GNUNET_ERROR_TYPE_DEBUG,
2340 "Received message with %u bytes from peer `%s' at `%s'\n",
2341 (unsigned int ) ntohs (msg->header.size), GNUNET_i2s (&msg->sender),
2342 GNUNET_a2s (sender_addr, sender_addr_len));
2343
2344 address = GNUNET_HELLO_address_allocate (&msg->sender, PLUGIN_NAME,
2345 arg, args,
2346 GNUNET_HELLO_ADDRESS_INFO_NONE); 2264 GNUNET_HELLO_ADDRESS_INFO_NONE);
2347 if (NULL == (s = udp_plugin_lookup_session (plugin, address))) 2265 if (NULL == (s = udp_plugin_lookup_session (plugin, address)))
2348 { 2266 {
2349 s = udp_plugin_create_session (plugin, address); 2267 s = udp_plugin_create_session (plugin,
2268 address,
2269 network_type);
2350 plugin->env->session_start (plugin->env->cls, 2270 plugin->env->session_start (plugin->env->cls,
2351 address, s, NULL, 0); 2271 address, s, NULL, 0);
2352 notify_session_monitor (s->plugin, 2272 notify_session_monitor (s->plugin,
@@ -2361,8 +2281,6 @@ process_udp_message (struct Plugin *plugin,
2361 /* iterate over all embedded messages */ 2281 /* iterate over all embedded messages */
2362 si.session = s; 2282 si.session = s;
2363 si.sender = msg->sender; 2283 si.sender = msg->sender;
2364 si.arg = arg;
2365 si.args = args;
2366 s->rc++; 2284 s->rc++;
2367 GNUNET_SERVER_mst_receive (plugin->mst, 2285 GNUNET_SERVER_mst_receive (plugin->mst,
2368 &si, 2286 &si,
@@ -2387,6 +2305,7 @@ fragment_msg_proc (void *cls,
2387 const struct GNUNET_MessageHeader *msg) 2305 const struct GNUNET_MessageHeader *msg)
2388{ 2306{
2389 struct DefragContext *rc = cls; 2307 struct DefragContext *rc = cls;
2308 const struct UDPMessage *um;
2390 2309
2391 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE) 2310 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE)
2392 { 2311 {
@@ -2398,10 +2317,14 @@ fragment_msg_proc (void *cls,
2398 GNUNET_break(0); 2317 GNUNET_break(0);
2399 return; 2318 return;
2400 } 2319 }
2320 um = (const struct UDPMessage *) msg;
2321 rc->sender = um->sender;
2322 rc->have_sender = GNUNET_YES;
2401 process_udp_message (rc->plugin, 2323 process_udp_message (rc->plugin,
2402 (const struct UDPMessage *) msg, 2324 um,
2403 rc->src_addr, 2325 rc->udp_addr,
2404 rc->addr_len); 2326 rc->udp_addr_len,
2327 rc->network_type);
2405} 2328}
2406 2329
2407 2330
@@ -2423,26 +2346,32 @@ ack_proc (void *cls,
2423 uint32_t delay = 0; 2346 uint32_t delay = 0;
2424 struct UDP_MessageWrapper *udpw; 2347 struct UDP_MessageWrapper *udpw;
2425 struct Session *s; 2348 struct Session *s;
2426 struct LookupContext l_ctx; 2349 struct GNUNET_HELLO_Address *address;
2427 2350
2428 l_ctx.address = rc->src_addr; 2351 if (GNUNET_NO == rc->have_sender)
2429 l_ctx.addr_len = rc->addr_len; 2352 {
2430 l_ctx.must_have_frag_ctx = GNUNET_NO; 2353 /* tried to defragment but never succeeded, hence will not ACK */
2431 l_ctx.res = NULL; 2354 GNUNET_break_op (0);
2432 GNUNET_CONTAINER_multipeermap_iterate (rc->plugin->sessions, 2355 return;
2433 &lookup_session_by_sockaddr_it, 2356 }
2434 &l_ctx); 2357 address = GNUNET_HELLO_address_allocate (&rc->sender,
2435 s = l_ctx.res; 2358 PLUGIN_NAME,
2359 rc->udp_addr,
2360 rc->udp_addr_len,
2361 GNUNET_HELLO_ADDRESS_INFO_NONE);
2362 s = udp_plugin_lookup_session (rc->plugin,
2363 address);
2364 GNUNET_HELLO_address_free (address);
2436 if (NULL == s) 2365 if (NULL == s)
2437 { 2366 {
2438 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2367 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2439 "Trying to transmit ACK to peer `%s' but not session found!\n", 2368 "Trying to transmit ACK to peer `%s' but no session found!\n",
2440 GNUNET_a2s(rc->src_addr, rc->addr_len)); 2369 udp_address_to_string (rc->plugin,
2441 2370 rc->udp_addr,
2371 rc->udp_addr_len));
2442 GNUNET_CONTAINER_heap_remove_node (rc->hnode); 2372 GNUNET_CONTAINER_heap_remove_node (rc->hnode);
2443 GNUNET_DEFRAGMENT_context_destroy (rc->defrag); 2373 GNUNET_DEFRAGMENT_context_destroy (rc->defrag);
2444 GNUNET_free (rc); 2374 GNUNET_free (rc);
2445
2446 return; 2375 return;
2447 } 2376 }
2448 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX) 2377 if (s->flow_delay_for_other_peer.rel_value_us <= UINT32_MAX)
@@ -2450,7 +2379,9 @@ ack_proc (void *cls,
2450 2379
2451 LOG (GNUNET_ERROR_TYPE_DEBUG, 2380 LOG (GNUNET_ERROR_TYPE_DEBUG,
2452 "Sending ACK to `%s' including delay of %s\n", 2381 "Sending ACK to `%s' including delay of %s\n",
2453 GNUNET_a2s (rc->src_addr, (rc->src_addr->sa_family == AF_INET) ? sizeof (struct sockaddr_in) : sizeof (struct sockaddr_in6)), 2382 udp_address_to_string (rc->plugin,
2383 rc->udp_addr,
2384 rc->udp_addr_len),
2454 GNUNET_STRINGS_relative_time_to_string (s->flow_delay_for_other_peer, 2385 GNUNET_STRINGS_relative_time_to_string (s->flow_delay_for_other_peer,
2455 GNUNET_YES)); 2386 GNUNET_YES));
2456 udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msize); 2387 udpw = GNUNET_malloc (sizeof (struct UDP_MessageWrapper) + msize);
@@ -2475,38 +2406,22 @@ ack_proc (void *cls,
2475 2406
2476 2407
2477/** 2408/**
2478 * FIXME. 2409 * Handle an ACK message.
2479 */ 2410 *
2480static void 2411 * @param plugin the UDP plugin
2481read_process_msg (struct Plugin *plugin, 2412 * @param msg the (presumed) UDP ACK message
2482 const struct GNUNET_MessageHeader *msg, 2413 * @param udp_addr sender address
2483 const struct sockaddr *addr, 2414 * @param udp_addr_len number of bytes in @a udp_addr
2484 socklen_t fromlen)
2485{
2486 if (ntohs (msg->size) < sizeof(struct UDPMessage))
2487 {
2488 GNUNET_break_op(0);
2489 return;
2490 }
2491 process_udp_message (plugin,
2492 (const struct UDPMessage *) msg,
2493 addr,
2494 fromlen);
2495}
2496
2497
2498/**
2499 * FIXME.
2500 */ 2415 */
2501static void 2416static void
2502read_process_ack (struct Plugin *plugin, 2417read_process_ack (struct Plugin *plugin,
2503 const struct GNUNET_MessageHeader *msg, 2418 const struct GNUNET_MessageHeader *msg,
2504 const struct sockaddr *addr, 2419 const union UdpAddress *udp_addr,
2505 socklen_t fromlen) 2420 socklen_t udp_addr_len)
2506{ 2421{
2507 const struct GNUNET_MessageHeader *ack; 2422 const struct GNUNET_MessageHeader *ack;
2508 const struct UDP_ACK_Message *udp_ack; 2423 const struct UDP_ACK_Message *udp_ack;
2509 struct LookupContext l_ctx; 2424 struct GNUNET_HELLO_Address *address;
2510 struct Session *s; 2425 struct Session *s;
2511 struct GNUNET_TIME_Relative flow_delay; 2426 struct GNUNET_TIME_Relative flow_delay;
2512 2427
@@ -2517,23 +2432,27 @@ read_process_ack (struct Plugin *plugin,
2517 return; 2432 return;
2518 } 2433 }
2519 udp_ack = (const struct UDP_ACK_Message *) msg; 2434 udp_ack = (const struct UDP_ACK_Message *) msg;
2520 2435 address = GNUNET_HELLO_address_allocate (&udp_ack->sender,
2521 /* Lookup session based on sockaddr */ 2436 PLUGIN_NAME,
2522 l_ctx.address = addr; 2437 udp_addr,
2523 l_ctx.addr_len = fromlen; 2438 udp_addr_len,
2524 l_ctx.res = NULL; 2439 GNUNET_HELLO_ADDRESS_INFO_NONE);
2525 l_ctx.must_have_frag_ctx = GNUNET_YES; 2440 s = udp_plugin_lookup_session (plugin,
2526 GNUNET_CONTAINER_multipeermap_iterate (plugin->sessions, 2441 address);
2527 &lookup_session_by_sockaddr_it, &l_ctx); 2442 GNUNET_HELLO_address_free (address);
2528 s = l_ctx.res; 2443 if ( (NULL == s) ||
2529 if ((NULL == s) || (NULL == s->frag_ctx)) 2444 (NULL == s->frag_ctx) )
2530 { 2445 {
2446 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
2447 "UDP session for ACK not found\n");
2531 return; 2448 return;
2532 } 2449 }
2533 2450
2534 flow_delay.rel_value_us = (uint64_t) ntohl (udp_ack->delay); 2451 flow_delay.rel_value_us = (uint64_t) ntohl (udp_ack->delay);
2535 LOG(GNUNET_ERROR_TYPE_DEBUG, "We received a sending delay of %s\n", 2452 LOG (GNUNET_ERROR_TYPE_DEBUG,
2536 GNUNET_STRINGS_relative_time_to_string (flow_delay, GNUNET_YES)); 2453 "We received a sending delay of %s\n",
2454 GNUNET_STRINGS_relative_time_to_string (flow_delay,
2455 GNUNET_YES));
2537 s->flow_delay_from_other_peer = GNUNET_TIME_relative_to_absolute (flow_delay); 2456 s->flow_delay_from_other_peer = GNUNET_TIME_relative_to_absolute (flow_delay);
2538 2457
2539 ack = (const struct GNUNET_MessageHeader *) &udp_ack[1]; 2458 ack = (const struct GNUNET_MessageHeader *) &udp_ack[1];
@@ -2543,92 +2462,120 @@ read_process_ack (struct Plugin *plugin,
2543 return; 2462 return;
2544 } 2463 }
2545 2464
2546 if (0 2465 if (GNUNET_OK !=
2547 != memcmp (&l_ctx.res->target, &udp_ack->sender, 2466 GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag,
2548 sizeof(struct GNUNET_PeerIdentity))) 2467 ack))
2549 GNUNET_break(0);
2550 if (GNUNET_OK != GNUNET_FRAGMENT_process_ack (s->frag_ctx->frag, ack))
2551 { 2468 {
2552 LOG(GNUNET_ERROR_TYPE_DEBUG, 2469 LOG(GNUNET_ERROR_TYPE_DEBUG,
2553 "UDP processes %u-byte acknowledgement from `%s' at `%s'\n", 2470 "UDP processes %u-byte acknowledgement from `%s' at `%s'\n",
2554 (unsigned int ) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), 2471 (unsigned int ) ntohs (msg->size),
2555 GNUNET_a2s (addr, fromlen)); 2472 GNUNET_i2s (&udp_ack->sender),
2473 udp_address_to_string (plugin,
2474 udp_addr,
2475 udp_addr_len));
2556 /* Expect more ACKs to arrive */ 2476 /* Expect more ACKs to arrive */
2557 return; 2477 return;
2558 } 2478 }
2559 2479
2560 LOG(GNUNET_ERROR_TYPE_DEBUG, "Message full ACK'ed\n", 2480 LOG (GNUNET_ERROR_TYPE_DEBUG,
2561 (unsigned int ) ntohs (msg->size), GNUNET_i2s (&udp_ack->sender), 2481 "Message full ACK'ed\n",
2562 GNUNET_a2s (addr, fromlen)); 2482 (unsigned int ) ntohs (msg->size),
2483 GNUNET_i2s (&udp_ack->sender),
2484 udp_address_to_string (plugin,
2485 udp_addr,
2486 udp_addr_len));
2487
2563 2488
2564 /* Remove fragmented message after successful sending */ 2489 /* Remove fragmented message after successful sending */
2565 fragmented_message_done (s->frag_ctx, GNUNET_OK); 2490 fragmented_message_done (s->frag_ctx,
2491 GNUNET_OK);
2566} 2492}
2567 2493
2568 2494
2569/** 2495/**
2570 * FIXME. 2496 * We received a fragment, process it.
2497 *
2498 * @param plugin our plugin
2499 * @param msg a message of type #GNUNET_MESSAGE_TYPE_FRAGMENT
2500 * @param udp_addr sender address
2501 * @param udp_addr_len number of bytes in @a udp_addr
2502 * @param network_type network type the address belongs to
2571 */ 2503 */
2572static void 2504static void
2573read_process_fragment (struct Plugin *plugin, 2505read_process_fragment (struct Plugin *plugin,
2574 const struct GNUNET_MessageHeader *msg, 2506 const struct GNUNET_MessageHeader *msg,
2575 const struct sockaddr *addr, 2507 const union UdpAddress *udp_addr,
2576 socklen_t fromlen) 2508 size_t udp_addr_len,
2509 enum GNUNET_ATS_Network_Type network_type)
2577{ 2510{
2578 struct DefragContext *d_ctx; 2511 struct DefragContext *d_ctx;
2579 struct GNUNET_TIME_Absolute now; 2512 struct GNUNET_TIME_Absolute now;
2580 struct FindReceiveContext frc; 2513 struct FindReceiveContext frc;
2581 2514
2582 frc.rc = NULL; 2515 frc.rc = NULL;
2583 frc.addr = addr; 2516 frc.udp_addr = udp_addr;
2584 frc.addr_len = fromlen; 2517 frc.udp_addr_len = udp_addr_len;
2585 2518
2586 LOG(GNUNET_ERROR_TYPE_DEBUG, "UDP processes %u-byte fragment from `%s'\n",
2587 (unsigned int ) ntohs (msg->size), GNUNET_a2s (addr, fromlen));
2588 /* Lookup existing receive context for this address */ 2519 /* Lookup existing receive context for this address */
2589 GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs, 2520 GNUNET_CONTAINER_heap_iterate (plugin->defrag_ctxs,
2590 &find_receive_context, &frc); 2521 &find_receive_context,
2522 &frc);
2591 now = GNUNET_TIME_absolute_get (); 2523 now = GNUNET_TIME_absolute_get ();
2592 d_ctx = frc.rc; 2524 d_ctx = frc.rc;
2593 2525
2594 if (d_ctx == NULL ) 2526 if (NULL == d_ctx)
2595 { 2527 {
2596 /* Create a new defragmentation context */ 2528 /* Create a new defragmentation context */
2597 d_ctx = GNUNET_malloc (sizeof (struct DefragContext) + fromlen); 2529 d_ctx = GNUNET_malloc (sizeof (struct DefragContext) + udp_addr_len);
2598 memcpy (&d_ctx[1], addr, fromlen); 2530 memcpy (&d_ctx[1],
2599 d_ctx->src_addr = (const struct sockaddr *) &d_ctx[1]; 2531 udp_addr,
2600 d_ctx->addr_len = fromlen; 2532 udp_addr_len);
2533 d_ctx->udp_addr = (const union UdpAddress *) &d_ctx[1];
2534 d_ctx->udp_addr_len = udp_addr_len;
2535 d_ctx->network_type = network_type;
2601 d_ctx->plugin = plugin; 2536 d_ctx->plugin = plugin;
2602 d_ctx->defrag = GNUNET_DEFRAGMENT_context_create (plugin->env->stats, 2537 d_ctx->defrag = GNUNET_DEFRAGMENT_context_create (plugin->env->stats,
2603 UDP_MTU, UDP_MAX_MESSAGES_IN_DEFRAG, d_ctx, &fragment_msg_proc, 2538 UDP_MTU,
2604 &ack_proc); 2539 UDP_MAX_MESSAGES_IN_DEFRAG,
2605 d_ctx->hnode = GNUNET_CONTAINER_heap_insert (plugin->defrag_ctxs, d_ctx, 2540 d_ctx,
2541 &fragment_msg_proc,
2542 &ack_proc);
2543 d_ctx->hnode = GNUNET_CONTAINER_heap_insert (plugin->defrag_ctxs,
2544 d_ctx,
2606 (GNUNET_CONTAINER_HeapCostType) now.abs_value_us); 2545 (GNUNET_CONTAINER_HeapCostType) now.abs_value_us);
2607 LOG(GNUNET_ERROR_TYPE_DEBUG, 2546 LOG (GNUNET_ERROR_TYPE_DEBUG,
2608 "Created new defragmentation context for %u-byte fragment from `%s'\n", 2547 "Created new defragmentation context for %u-byte fragment from `%s'\n",
2609 (unsigned int ) ntohs (msg->size), GNUNET_a2s (addr, fromlen)); 2548 (unsigned int ) ntohs (msg->size),
2549 udp_address_to_string (plugin,
2550 udp_addr,
2551 udp_addr_len));
2610 } 2552 }
2611 else 2553 else
2612 { 2554 {
2613 LOG(GNUNET_ERROR_TYPE_DEBUG, 2555 LOG (GNUNET_ERROR_TYPE_DEBUG,
2614 "Found existing defragmentation context for %u-byte fragment from `%s'\n", 2556 "Found existing defragmentation context for %u-byte fragment from `%s'\n",
2615 (unsigned int ) ntohs (msg->size), GNUNET_a2s (addr, fromlen)); 2557 (unsigned int ) ntohs (msg->size),
2558 udp_address_to_string (plugin,
2559 udp_addr,
2560 udp_addr_len));
2616 } 2561 }
2617 2562
2618 if (GNUNET_OK == GNUNET_DEFRAGMENT_process_fragment (d_ctx->defrag, msg)) 2563 if (GNUNET_OK ==
2564 GNUNET_DEFRAGMENT_process_fragment (d_ctx->defrag, msg))
2619 { 2565 {
2620 /* keep this 'rc' from expiring */ 2566 /* keep this 'rc' from expiring */
2621 GNUNET_CONTAINER_heap_update_cost (plugin->defrag_ctxs, d_ctx->hnode, 2567 GNUNET_CONTAINER_heap_update_cost (plugin->defrag_ctxs,
2568 d_ctx->hnode,
2622 (GNUNET_CONTAINER_HeapCostType) now.abs_value_us); 2569 (GNUNET_CONTAINER_HeapCostType) now.abs_value_us);
2623 } 2570 }
2624 if (GNUNET_CONTAINER_heap_get_size (plugin->defrag_ctxs) > 2571 if (GNUNET_CONTAINER_heap_get_size (plugin->defrag_ctxs) >
2625 UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG) 2572 UDP_MAX_SENDER_ADDRESSES_WITH_DEFRAG)
2626 { 2573 {
2627 /* remove 'rc' that was inactive the longest */ 2574 /* remove 'rc' that was inactive the longest */
2628 d_ctx = GNUNET_CONTAINER_heap_remove_root (plugin->defrag_ctxs); 2575 d_ctx = GNUNET_CONTAINER_heap_remove_root (plugin->defrag_ctxs);
2629 GNUNET_assert(NULL != d_ctx); 2576 GNUNET_assert (NULL != d_ctx);
2630 GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag); 2577 GNUNET_DEFRAGMENT_context_destroy (d_ctx->defrag);
2631 GNUNET_free(d_ctx); 2578 GNUNET_free (d_ctx);
2632 } 2579 }
2633} 2580}
2634 2581
@@ -2648,11 +2595,20 @@ udp_select_read (struct Plugin *plugin,
2648 char buf[65536] GNUNET_ALIGN; 2595 char buf[65536] GNUNET_ALIGN;
2649 ssize_t size; 2596 ssize_t size;
2650 const struct GNUNET_MessageHeader *msg; 2597 const struct GNUNET_MessageHeader *msg;
2598 struct IPv4UdpAddress v4;
2599 struct IPv6UdpAddress v6;
2600 const struct sockaddr *sa;
2601 const struct sockaddr_in *sa4;
2602 const struct sockaddr_in6 *sa6;
2603 const union UdpAddress *int_addr;
2604 size_t int_addr_len;
2605 enum GNUNET_ATS_Network_Type network_type;
2651 2606
2652 fromlen = sizeof(addr); 2607 fromlen = sizeof(addr);
2653 memset (&addr, 0, sizeof(addr)); 2608 memset (&addr, 0, sizeof(addr));
2654 size = GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof(buf), 2609 size = GNUNET_NETWORK_socket_recvfrom (rsock, buf, sizeof(buf),
2655 (struct sockaddr *) &addr, &fromlen); 2610 (struct sockaddr *) &addr, &fromlen);
2611 sa = (const struct sockaddr *) &addr;
2656#if MINGW 2612#if MINGW
2657 /* On SOCK_DGRAM UDP sockets recvfrom might fail with a 2613 /* On SOCK_DGRAM UDP sockets recvfrom might fail with a
2658 * WSAECONNRESET error to indicate that previous sendto() (yes, sendto!) 2614 * WSAECONNRESET error to indicate that previous sendto() (yes, sendto!)
@@ -2680,50 +2636,94 @@ udp_select_read (struct Plugin *plugin,
2680 LOG (GNUNET_ERROR_TYPE_WARNING, 2636 LOG (GNUNET_ERROR_TYPE_WARNING,
2681 "UDP got %u bytes from %s, which is not enough for a GNUnet message header\n", 2637 "UDP got %u bytes from %s, which is not enough for a GNUnet message header\n",
2682 (unsigned int ) size, 2638 (unsigned int ) size,
2683 GNUNET_a2s ((const struct sockaddr *) &addr, fromlen)); 2639 GNUNET_a2s (sa, fromlen));
2684 /* _MAY_ be a connection failure (got partial message) */ 2640 /* _MAY_ be a connection failure (got partial message) */
2685 /* But it _MAY_ also be that the other side uses non-GNUnet protocol. */ 2641 /* But it _MAY_ also be that the other side uses non-GNUnet protocol. */
2686 GNUNET_break_op(0); 2642 GNUNET_break_op(0);
2687 return; 2643 return;
2688 } 2644 }
2689 msg = (const struct GNUNET_MessageHeader *) buf; 2645 msg = (const struct GNUNET_MessageHeader *) buf;
2690
2691 LOG (GNUNET_ERROR_TYPE_DEBUG, 2646 LOG (GNUNET_ERROR_TYPE_DEBUG,
2692 "UDP received %u-byte message from `%s' type %u\n", 2647 "UDP received %u-byte message from `%s' type %u\n",
2693 (unsigned int) size, 2648 (unsigned int) size,
2694 GNUNET_a2s ((const struct sockaddr *) &addr, fromlen), 2649 GNUNET_a2s (sa,
2650 fromlen),
2695 ntohs (msg->type)); 2651 ntohs (msg->type));
2696
2697 if (size != ntohs (msg->size)) 2652 if (size != ntohs (msg->size))
2698 { 2653 {
2699 LOG (GNUNET_ERROR_TYPE_WARNING, 2654 LOG (GNUNET_ERROR_TYPE_WARNING,
2700 "UDP malformed message header from %s\n", 2655 "UDP malformed message header from %s\n",
2701 (unsigned int ) size, 2656 (unsigned int) size,
2702 GNUNET_a2s ((const struct sockaddr *) &addr, fromlen)); 2657 GNUNET_a2s (sa,
2703 GNUNET_break_op(0); 2658 fromlen));
2659 GNUNET_break_op (0);
2704 return; 2660 return;
2705 } 2661 }
2706 GNUNET_STATISTICS_update (plugin->env->stats, 2662 GNUNET_STATISTICS_update (plugin->env->stats,
2707 "# UDP, total, bytes, received", 2663 "# UDP, total, bytes, received",
2708 size, 2664 size,
2709 GNUNET_NO); 2665 GNUNET_NO);
2666 network_type = plugin->env->get_address_type (plugin->env->cls,
2667 sa,
2668 fromlen);
2669 switch (sa->sa_family)
2670 {
2671 case AF_INET:
2672 sa4 = (const struct sockaddr_in *) &addr;
2673 v4.options = 0;
2674 v4.ipv4_addr = sa4->sin_addr.s_addr;
2675 v4.u4_port = sa4->sin_port;
2676 int_addr = (union UdpAddress *) &v4;
2677 int_addr_len = sizeof (v4);
2678 break;
2679 case AF_INET6:
2680 sa6 = (const struct sockaddr_in6 *) &addr;
2681 v6.options = 0;
2682 v6.ipv6_addr = sa6->sin6_addr;
2683 v6.u6_port = sa6->sin6_port;
2684 int_addr = (union UdpAddress *) &v6;
2685 int_addr_len = sizeof (v6);
2686 break;
2687 default:
2688 GNUNET_break (0);
2689 return;
2690 }
2710 2691
2711 switch (ntohs (msg->type)) 2692 switch (ntohs (msg->type))
2712 { 2693 {
2713 case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON: 2694 case GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON:
2714 if (GNUNET_YES == plugin->enable_broadcasting_receiving) 2695 if (GNUNET_YES == plugin->enable_broadcasting_receiving)
2715 udp_broadcast_receive (plugin, buf, size, (const struct sockaddr *) &addr, 2696 udp_broadcast_receive (plugin,
2716 fromlen); 2697 buf,
2698 size,
2699 int_addr,
2700 int_addr_len,
2701 network_type);
2717 return; 2702 return;
2718 case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE: 2703 case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_MESSAGE:
2719 read_process_msg (plugin, msg, (const struct sockaddr *) &addr, fromlen); 2704 if (ntohs (msg->size) < sizeof(struct UDPMessage))
2705 {
2706 GNUNET_break_op(0);
2707 return;
2708 }
2709 process_udp_message (plugin,
2710 (const struct UDPMessage *) msg,
2711 int_addr,
2712 int_addr_len,
2713 network_type);
2720 return; 2714 return;
2721 case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK: 2715 case GNUNET_MESSAGE_TYPE_TRANSPORT_UDP_ACK:
2722 read_process_ack (plugin, msg, (const struct sockaddr *) &addr, fromlen); 2716 read_process_ack (plugin,
2717 msg,
2718 int_addr,
2719 int_addr_len);
2723 return; 2720 return;
2724 case GNUNET_MESSAGE_TYPE_FRAGMENT: 2721 case GNUNET_MESSAGE_TYPE_FRAGMENT:
2725 read_process_fragment (plugin, msg, (const struct sockaddr *) &addr, 2722 read_process_fragment (plugin,
2726 fromlen); 2723 msg,
2724 int_addr,
2725 int_addr_len,
2726 network_type);
2727 return; 2727 return;
2728 default: 2728 default:
2729 GNUNET_break_op(0); 2729 GNUNET_break_op(0);
@@ -3008,15 +3008,21 @@ udp_select_send (struct Plugin *plugin,
3008 else 3008 else
3009 { 3009 {
3010 /* Success */ 3010 /* Success */
3011 LOG(GNUNET_ERROR_TYPE_DEBUG, 3011 LOG (GNUNET_ERROR_TYPE_DEBUG,
3012 "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n", 3012 "UDP transmitted %u-byte message to `%s' `%s' (%d: %s)\n",
3013 (unsigned int ) (udpw->msg_size), GNUNET_i2s (&udpw->session->target), 3013 (unsigned int) (udpw->msg_size),
3014 GNUNET_a2s (a, slen), (int ) sent, 3014 GNUNET_i2s (&udpw->session->target),
3015 (sent < 0) ? STRERROR (errno) : "ok"); 3015 GNUNET_a2s (a, slen),
3016 (int ) sent,
3017 (sent < 0) ? STRERROR (errno) : "ok");
3016 GNUNET_STATISTICS_update (plugin->env->stats, 3018 GNUNET_STATISTICS_update (plugin->env->stats,
3017 "# UDP, total, bytes, sent, success", sent, GNUNET_NO); 3019 "# UDP, total, bytes, sent, success",
3020 sent,
3021 GNUNET_NO);
3018 GNUNET_STATISTICS_update (plugin->env->stats, 3022 GNUNET_STATISTICS_update (plugin->env->stats,
3019 "# UDP, total, messages, sent, success", 1, GNUNET_NO); 3023 "# UDP, total, messages, sent, success",
3024 1,
3025 GNUNET_NO);
3020 if (NULL != udpw->frag_ctx) 3026 if (NULL != udpw->frag_ctx)
3021 udpw->frag_ctx->on_wire_size += udpw->msg_size; 3027 udpw->frag_ctx->on_wire_size += udpw->msg_size;
3022 call_continuation (udpw, GNUNET_OK); 3028 call_continuation (udpw, GNUNET_OK);
@@ -3233,8 +3239,10 @@ setup_sockets (struct Plugin *plugin,
3233 GNUNET_a2s (server_addr, addrlen)); 3239 GNUNET_a2s (server_addr, addrlen));
3234 3240
3235 /* binding */ 3241 /* binding */
3236 if (GNUNET_OK 3242 if (GNUNET_OK ==
3237 == GNUNET_NETWORK_socket_bind (plugin->sockv4, server_addr, addrlen)) 3243 GNUNET_NETWORK_socket_bind (plugin->sockv4,
3244 server_addr,
3245 addrlen))
3238 break; 3246 break;
3239 eno = errno; 3247 eno = errno;
3240 if (0 != plugin->port) 3248 if (0 != plugin->port)
@@ -3259,8 +3267,9 @@ setup_sockets (struct Plugin *plugin,
3259 3267
3260 if (NULL != plugin->sockv4) 3268 if (NULL != plugin->sockv4)
3261 { 3269 {
3262 LOG(GNUNET_ERROR_TYPE_DEBUG, "IPv4 socket created on port %s\n", 3270 LOG (GNUNET_ERROR_TYPE_DEBUG,
3263 GNUNET_a2s (server_addr, addrlen)); 3271 "IPv4 socket created on port %s\n",
3272 GNUNET_a2s (server_addr, addrlen));
3264 addrs[sockets_created] = (struct sockaddr *) &server_addrv4; 3273 addrs[sockets_created] = (struct sockaddr *) &server_addrv4;
3265 addrlens[sockets_created] = sizeof(struct sockaddr_in); 3274 addrlens[sockets_created] = sizeof(struct sockaddr_in);
3266 sockets_created++; 3275 sockets_created++;
@@ -3276,7 +3285,8 @@ setup_sockets (struct Plugin *plugin,
3276 3285
3277 if (0 == sockets_created) 3286 if (0 == sockets_created)
3278 { 3287 {
3279 LOG(GNUNET_ERROR_TYPE_WARNING, _("Failed to open UDP sockets\n")); 3288 LOG (GNUNET_ERROR_TYPE_WARNING,
3289 _("Failed to open UDP sockets\n"));
3280 return 0; /* No sockets created, return */ 3290 return 0; /* No sockets created, return */
3281 } 3291 }
3282 3292
@@ -3425,11 +3435,13 @@ libgnunet_plugin_transport_udp_init (void *cls)
3425 /* Get port number: port == 0 : autodetect a port, 3435 /* Get port number: port == 0 : autodetect a port,
3426 * > 0 : use this port, not given : 2086 default */ 3436 * > 0 : use this port, not given : 2086 default */
3427 if (GNUNET_OK != 3437 if (GNUNET_OK !=
3428 GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", 3438 GNUNET_CONFIGURATION_get_value_number (env->cfg,
3439 "transport-udp",
3429 "PORT", &port)) 3440 "PORT", &port))
3430 port = 2086; 3441 port = 2086;
3431 if (GNUNET_OK != 3442 if (GNUNET_OK !=
3432 GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-udp", 3443 GNUNET_CONFIGURATION_get_value_number (env->cfg,
3444 "transport-udp",
3433 "ADVERTISED_PORT", &aport)) 3445 "ADVERTISED_PORT", &aport))
3434 aport = port; 3446 aport = port;
3435 if (port > 65535) 3447 if (port > 65535)