summaryrefslogtreecommitdiff
path: root/nuttx/net/tcp
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-02-10 06:54:10 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-02-10 06:54:10 -0600
commit9298ea5fcefcad303bdbb60081b0b2733e35173c (patch)
tree0f6036a492ae6013246f279983fdcc7e73eac263 /nuttx/net/tcp
parent87ce2109b5e49bd7f38d9108b0bf479dfdc418e1 (diff)
downloadpx4-nuttx-9298ea5fcefcad303bdbb60081b0b2733e35173c.tar.gz
px4-nuttx-9298ea5fcefcad303bdbb60081b0b2733e35173c.tar.bz2
px4-nuttx-9298ea5fcefcad303bdbb60081b0b2733e35173c.zip
Networking: Fix several build errors/warning with IPv4 + IPv6 + multiple networks are enabled.
Diffstat (limited to 'nuttx/net/tcp')
-rw-r--r--nuttx/net/tcp/tcp_conn.c67
1 files changed, 55 insertions, 12 deletions
diff --git a/nuttx/net/tcp/tcp_conn.c b/nuttx/net/tcp/tcp_conn.c
index d7a807067..6251cadcf 100644
--- a/nuttx/net/tcp/tcp_conn.c
+++ b/nuttx/net/tcp/tcp_conn.c
@@ -155,8 +155,8 @@ static inline FAR struct tcp_conn_s *tcp_ipv4_listener(in_addr_t ipaddr,
****************************************************************************/
#if defined(CONFIG_NET_IPv6) && defined(CONFIG_NETDEV_MULTINIC)
-static inline FAR struct tcp_conn_s *tcp_ipv6_ listener(net_ipv6addr_t ipaddr,
- uint16_t portno)
+static inline FAR struct tcp_conn_s *
+tcp_ipv6_listener(const net_ipv6addr_t ipaddr, uint16_t portno)
{
FAR struct tcp_conn_s *conn;
int i;
@@ -436,7 +436,7 @@ static inline FAR struct tcp_conn_s *
FAR struct tcp_conn_s *conn;
net_ipv6addr_t *srcipaddr;
#ifdef CONFIG_NETDEV_MULTINIC
- net_ipv6addr_t destipaddr;
+ net_ipv6addr_t *destipaddr;
#endif
conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head;
@@ -575,10 +575,16 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
/* Verify or select a local port */
#ifdef CONFIG_NETDEV_MULTINIC
+ /* The port number must be unique for this address binding */
+
port = tcp_selectport(PF_INET6,
- (FAR const union ip_addr_u ipaddr *)addr->sin6_addr.in6_u.u6_addr16,
+ (FAR const union ip_addr_u *)addr->sin6_addr.in6_u.u6_addr16,
ntohs(addr->sin6_port));
#else
+ /* There is only one network device; the port number can be globally
+ * unique.
+ */
+
port = tcp_selectport(ntohs(addr->sin6_port));
#endif
@@ -1099,19 +1105,56 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
*/
flags = net_lock();
+
#ifdef CONFIG_NETDEV_MULTINIC
-#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
- port = tcp_selectport(conn->domain, &conn->u, ntohs(conn->lport));
-#elif defined(CONFIG_NET_IPv4)
- port = tcp_selectport(PF_INET, &conn->u, ntohs(conn->lport));
-#else
- port = tcp_selectport(PF_INET6, &conn->u, ntohs(conn->lport));
+ /* If there are multiple network devices, then we need to pass the local,
+ * bound address. This is needed because port unique-ness is only for a
+ * given network.
+ *
+ * This is complicated by the fact that the local address may be either an
+ * IPv4 or an IPv6 address.
+ */
+
+#ifdef CONFIG_NET_IPv4
+#ifdef CONFIG_NET_IPv6
+ if (conn->domain == PF_INET)
#endif
-#else
- port = tcp_selectport(ntohs(conn->lport));
+ {
+ /* Select a port that is unique for this IPv4 local address */
+
+ port = tcp_selectport(PF_INET,
+ (FAR const union ip_addr_u *)&conn->u.ipv4.laddr,
+ ntohs(conn->lport));
+ }
+#endif /* CONFIG_NET_IPv4 */
+
+#ifdef CONFIG_NET_IPv6
+#ifdef CONFIG_NET_IPv4
+ else
#endif
+ {
+ /* Select a port that is unique for this IPv6 local address */
+
+ port = tcp_selectport(PF_INET6,
+ (FAR const union ip_addr_u *)conn->u.ipv6.laddr,
+ ntohs(conn->lport));
+ }
+#endif /* CONFIG_NET_IPv6 */
+
+#else /* CONFIG_NETDEV_MULTINIC */
+ /* Select the next available port number. This is only one network device
+ * so we do not have to bother with all of the IPv4/IPv6 local address
+ * silliness.
+ */
+
+ port = tcp_selectport(ntohs(conn->lport));
+
+#endif /* CONFIG_NETDEV_MULTINIC */
+
net_unlock(flags);
+ /* Did we have a port assignment? */
+
if (port < 0)
{
return port;