From f73aebe9714ca9ede07a4b5a234b6c5f85490b4c Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 17 Jan 2015 17:07:54 -0600 Subject: Networking: Straighten up use if IPv6/IPv4 in TCP connection logic --- nuttx/include/net/if.h | 10 +- nuttx/net/socket/bind.c | 10 +- nuttx/net/tcp/tcp.h | 10 +- nuttx/net/tcp/tcp_conn.c | 593 +++++++++++++++++++++++++++++++++++++---------- 4 files changed, 474 insertions(+), 149 deletions(-) (limited to 'nuttx') diff --git a/nuttx/include/net/if.h b/nuttx/include/net/if.h index 56e778048..cd44f495b 100644 --- a/nuttx/include/net/if.h +++ b/nuttx/include/net/if.h @@ -74,11 +74,11 @@ #define IFF_CLR_IPv6(f) do { (f) &= ~IFF_IPv6; } while (0) #define IFF_CLR_NOARP(f) do { (f) &= ~IFF_NOARP; } while (0) -#define IFF_IS_DOWN(f) ((f) & IFF_DOWN) != 0) -#define IFF_IS_UP(f) ((f) & IFF_UP) != 0) -#define IFF_IS_RUNNING(f) ((f) & IFF_RUNNING) != 0) -#define IFF_IS_IPv6(f) ((f) & IFF_IPv6) != 0) -#define IFF_IS_NOARP(f) ((f) & IFF_NOARP) != 0) +#define IFF_IS_DOWN(f) (((f) & IFF_DOWN) != 0) +#define IFF_IS_UP(f) (((f) & IFF_UP) != 0) +#define IFF_IS_RUNNING(f) (((f) & IFF_RUNNING) != 0) +#define IFF_IS_IPv6(f) (((f) & IFF_IPv6) != 0) +#define IFF_IS_NOARP(f) (((f) & IFF_NOARP) != 0) #define IFF_SET_IPv4(f) IFF_CLR_IPv6(f) #define IFF_CLR_IPv4(f) IFF_SET_IPv6(f) diff --git a/nuttx/net/socket/bind.c b/nuttx/net/socket/bind.c index 489a8a228..2cde978f9 100644 --- a/nuttx/net/socket/bind.c +++ b/nuttx/net/socket/bind.c @@ -146,14 +146,6 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr, #ifdef CONFIG_NET_PKT FAR const struct sockaddr_ll *lladdr = (const struct sockaddr_ll *)addr; #endif -#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_UDP) -#ifdef CONFIG_NET_IPv6 - FAR const struct sockaddr_in6 *inaddr = (const struct sockaddr_in6 *)addr; -#else - FAR const struct sockaddr_in *inaddr = (const struct sockaddr_in *)addr; -#endif -#endif - int err; int ret = OK; @@ -204,7 +196,7 @@ int psock_bind(FAR struct socket *psock, const struct sockaddr *addr, #ifdef CONFIG_NET_TCP case SOCK_STREAM: - ret = tcp_bind(psock->s_conn, inaddr); + ret = tcp_bind(psock->s_conn, addr); psock->s_flags |= _SF_BOUND; break; #endif diff --git a/nuttx/net/tcp/tcp.h b/nuttx/net/tcp/tcp.h index 53c7f7257..16a5bbce8 100644 --- a/nuttx/net/tcp/tcp.h +++ b/nuttx/net/tcp/tcp.h @@ -269,7 +269,7 @@ extern "C" /* Defined in tcp_conn.c ****************************************************/ -struct sockaddr; /* Forward reference */ +struct sockaddr; /* Forward reference */ struct tcp_iphdr_s; /* Forward reference */ /**************************************************************************** @@ -366,13 +366,7 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_IPv6 -int tcp_bind(FAR struct tcp_conn_s *conn, - FAR const struct sockaddr_in6 *addr); -#else -int tcp_bind(FAR struct tcp_conn_s *conn, - FAR const struct sockaddr_in *addr); -#endif +int tcp_bind(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr); /**************************************************************************** * Name: tcp_connect diff --git a/nuttx/net/tcp/tcp_conn.c b/nuttx/net/tcp/tcp_conn.c index a8283278b..b364e74ee 100644 --- a/nuttx/net/tcp/tcp_conn.c +++ b/nuttx/net/tcp/tcp_conn.c @@ -64,8 +64,8 @@ * Pre-processor Definitions ****************************************************************************/ -#define IPv4 ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) -#define IPv6 ((struct net_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) +#define IPv4BUF ((struct net_iphdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) +#define IPv6BUF ((struct net_ipv6hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)]) /**************************************************************************** * Private Data @@ -92,7 +92,7 @@ static uint16_t g_last_tcp_port; ****************************************************************************/ /**************************************************************************** - * Name: tcp_listener + * Name: tcp_ipv4_listener * * Description: * Given a local port number (in network byte order), find the TCP @@ -103,11 +103,9 @@ static uint16_t g_last_tcp_port; * ****************************************************************************/ -#ifdef CONFIG_NETDEV_MULTINIC -static FAR struct tcp_conn_s *tcp_listener(in_addr_t ipaddr, uint16_t portno) -#else -static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) -#endif +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NETDEV_MULTINIC) +static inline FAR struct tcp_conn_s *tcp_ipv4_listener(inaddr_t ipaddr, + uint16_t portno) { FAR struct tcp_conn_s *conn; int i; @@ -124,7 +122,6 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) if (conn->tcpstateflags != TCP_CLOSED && conn->lport == portno) { -#ifdef CONFIG_NETDEV_MULTINIC /* If there are multiple interface devices, then the local IP * address of the connection must also match. INADDR_ANY is a * special case: There can only be instance of a port number @@ -132,12 +129,7 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) */ if (net_ipv4addr_cmp(conn->u.ipv4.laddr, ipaddr) || -#ifdef CONFIG_NET_IPv6 - net_ipv4addr_cmp(conn->u.ipv4.laddr, g_ipv4_allzeroaddr)) -#else net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_ANY)) -#endif -#endif { /* The port number is in use, return the connection */ @@ -148,6 +140,123 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) return NULL; } +#endif /* CONFIG_NET_IPv4 && CONFIG_NETDEV_MULTINIC */ + +/**************************************************************************** + * Name: tcp_ipv6_listener + * + * Description: + * Given a local port number (in network byte order), find the TCP + * connection that listens on this this port. + * + * Primary uses: (1) to determine if a port number is available, (2) to + * To identify the socket that will accept new connections on a local port. + * + ****************************************************************************/ + +#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) +{ + FAR struct tcp_conn_s *conn; + int i; + + /* Check if this port number is in use by any active UIP TCP connection */ + + for (i = 0; i < CONFIG_NET_TCP_CONNS; i++) + { + conn = &g_tcp_connections[i]; + + /* Check if this connection is open and the local port assignment + * matches the requested port number. + */ + + if (conn->tcpstateflags != TCP_CLOSED && conn->lport == portno) + { + /* If there are multiple interface devices, then the local IP + * address of the connection must also match. INADDR_ANY is a + * special case: There can only be instance of a port number + * with INADDR_ANY. + */ + + if (net_ipv6addr_cmp(conn->u.ipv6.laddr, ipaddr) || + net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr)) + { + /* The port number is in use, return the connection */ + + return conn; + } + } + } + + return NULL; +} +#endif /* CONFIG_NET_IPv6 && CONFIG_NETDEV_MULTINIC */ + +/**************************************************************************** + * Name: tcp_listener + * + * Description: + * Given a local port number (in network byte order), find the TCP + * connection that listens on this this port. + * + * Primary uses: (1) to determine if a port number is available, (2) to + * To identify the socket that will accept new connections on a local port. + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_MULTINIC +static FAR struct tcp_conn_s * + tcp_listener(uint8_t domain, FAR const union ip_binding_u *ipaddr, + uint16_t portno) +{ +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + if (domain == PF_INET) +#endif + { + return tcp_ipv4_listener(ipaddr->ipv4, portno); + } +#endif /* CONFIG_NET_IPv4 */ + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else +#endif + { + return tcp_ipv6_listener(ipaddr->ipv6, portno); + } +#endif /* CONFIG_NET_IPv6 */ +} + +#else /* CONFIG_NETDEV_MULTINIC */ + +static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) +{ + FAR struct tcp_conn_s *conn; + int i; + + /* Check if this port number is in use by any active UIP TCP connection */ + + for (i = 0; i < CONFIG_NET_TCP_CONNS; i++) + { + conn = &g_tcp_connections[i]; + + /* Check if this connection is open and the local port assignment + * matches the requested port number. + */ + + if (conn->tcpstateflags != TCP_CLOSED && conn->lport == portno) + { + /* The port number is in use, return the connection */ + + return conn; + } + } + + return NULL; +} +#endif /* CONFIG_NETDEV_MULTINIC */ /**************************************************************************** * Name: tcp_selectport @@ -175,7 +284,8 @@ static FAR struct tcp_conn_s *tcp_listener(uint16_t portno) ****************************************************************************/ #ifdef CONFIG_NETDEV_MULTINIC -static int tcp_selectport(in_addr_t ipaddr, uint16_t portno) +static int tcp_selectport(uint8_t domain, FAR const union ip_addr_u *ipaddr, + uint16_t portno) #else static int tcp_selectport(uint16_t portno) #endif @@ -203,7 +313,7 @@ static int tcp_selectport(uint16_t portno) } } #ifdef CONFIG_NETDEV_MULTINIC - while (tcp_listener(ipaddr, htons(g_last_tcp_port))); + while (tcp_listener(domain, ipaddr, htons(g_last_tcp_port))); #else while (tcp_listener(htons(g_last_tcp_port))); #endif @@ -215,7 +325,7 @@ static int tcp_selectport(uint16_t portno) */ #ifdef CONFIG_NETDEV_MULTINIC - if (tcp_listener(ipaddr, portno)) + if (tcp_listener(domain, ipaddr, portno)) #else if (tcp_listener(portno)) #endif @@ -231,6 +341,266 @@ static int tcp_selectport(uint16_t portno) return portno; } +/**************************************************************************** + * Name: tcp_ipv4_active + * + * Description: + * Find a connection structure that is the appropriate + * connection to be used with the provided TCP/IP header + * + * Assumptions: + * This function is called from UIP logic at interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +static inline FAR struct tcp_conn_s * + tcp_ipv4_active(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp) +{ + FAR struct net_iphdr_s *ip = IPv4BUF; + FAR struct tcp_conn_s *conn; + in_addr_t srcipaddr; +#ifdef CONFIG_NETDEV_MULTINIC + in_addr_t destipaddr; +#endif + + conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head; + srcipaddr = net_ip4addr_conv32(ip->srcipaddr); +#ifdef CONFIG_NETDEV_MULTINIC + destipaddr = net_ip4addr_conv32(ip->destipaddr); +#endif + + while (conn) + { + /* Find an open connection matching the TCP input. The following + * checks are performed: + * + * - The local port number is checked against the destination port + * number in the received packet. + * - The remote port number is checked if the connection is bound + * to a remote port. + * - If multiple network interfaces are supported, then the local + * IP address is available and we will insist that the + * destination IP matches the bound address. If a socket is + * bound to INADDRY_ANY, then it should receive all packets + * directed to the port. + * - Finally, if the connection is bound to a remote IP address, + * the source IP address of the packet is checked. + * + * If all of the above are true then the newly received TCP packet + * is destined for this TCP connection. + */ + + if (conn->tcpstateflags != TCP_CLOSED && + tcp->destport == conn->lport && + tcp->srcport == conn->rport && +#ifdef CONFIG_NETDEV_MULTINIC + (net_ipv4addr_cmp(conn->u.ipv4.laddr, g_ipv4_allzeroaddr) || + net_ipv4addr_cmp(destipaddr, conn->u.ipv4.laddr)) && +#endif + net_ipv4addr_cmp(srcipaddr, conn->u.ipv4.raddr)) + { + /* Matching connection found.. break out of the loop and return a + * reference to it. + */ + + break; + } + + /* Look at the next active connection */ + + conn = (FAR struct tcp_conn_s *)conn->node.flink; + } + + return conn; +} +#endif /* CONFIG_NET_IPv4 */ + +/**************************************************************************** + * Name: tcp_ipv6_active + * + * Description: + * Find a connection structure that is the appropriate + * connection to be used with the provided TCP/IP header + * + * Assumptions: + * This function is called from UIP logic at interrupt level + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +static inline FAR struct tcp_conn_s * + tcp_ipv6_active(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp) +{ + FAR struct net_ipv6hdr_s *ip = IPv6BUF; + FAR struct tcp_conn_s *conn; + net_ipv6addr_t *srcipaddr; +#ifdef CONFIG_NETDEV_MULTINIC + net_ipv6addr_t destipaddr; +#endif + + conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head; + srcipaddr = (net_ipv6addr_t *)ip->srcipaddr; +#ifdef CONFIG_NETDEV_MULTINIC + destipaddr = (net_ipv6addr_t *)ip->destipaddr; +#endif + + while (conn) + { + /* Find an open connection matching the TCP input. The following + * checks are performed: + * + * - The local port number is checked against the destination port + * number in the received packet. + * - The remote port number is checked if the connection is bound + * to a remote port. + * - If multiple network interfaces are supported, then the local + * IP address is available and we will insist that the + * destination IP matches the bound address. If a socket is + * bound to INADDRY_ANY, then it should receive all packets + * directed to the port. + * - Finally, if the connection is bound to a remote IP address, + * the source IP address of the packet is checked. + * + * If all of the above are true then the newly received TCP packet + * is destined for this TCP connection. + */ + + if (conn->tcpstateflags != TCP_CLOSED && + tcp->destport == conn->lport && + tcp->srcport == conn->rport && +#ifdef CONFIG_NETDEV_MULTINIC + (net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr) || + net_ipv6addr_cmp(*destipaddr, conn->u.ipv6.laddr)) && +#endif + net_ipv6addr_cmp(*srcipaddr, conn->u.ipv6.raddr)) + { + /* Matching connection found.. break out of the loop and return a + * reference to it. + */ + + break; + } + + /* Look at the next active connection */ + + conn = (FAR struct tcp_conn_s *)conn->node.flink; + } + + return conn; +} +#endif /* CONFIG_NET_IPv6 */ + +/**************************************************************************** + * Name: tcp_ipv4_bind + * + * Description: + * This function implements the lower level parts of the standard TCP + * bind() operation. + * + * Return: + * 0 on success or -EADDRINUSE on failure + * + * Assumptions: + * This function is called from normal user level code. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv4 +static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn, + FAR const struct sockaddr_in *addr) +{ + net_lock_t flags; + int port; + + /* Verify or select a local port and address */ + + flags = net_lock(); + + /* Verify or select a local port */ + +#ifdef CONFIG_NETDEV_MULTINIC + port = tcp_selectport(PF_INET, + (FAR const union ip_addr_u ipaddr *)&addr->sin_addr.s_addr, + ntohs(addr->sin_port)); +#else + port = tcp_selectport(ntohs(addr->sin_port)); +#endif + + net_unlock(flags); + + if (port < 0) + { + return port; + } + + /* Save the local address in the connection structure. */ + + conn->lport = addr->sin_port; + +#ifdef CONFIG_NETDEV_MULTINIC + net_ipv4addr_copy(conn->u.ipv4.laddr, ipaddr); +#endif + + return OK; +} +#endif /* CONFIG_NET_IPv4 */ + +/**************************************************************************** + * Name: tcp_ipv6_bind + * + * Description: + * This function implements the lower level parts of the standard TCP + * bind() operation. + * + * Return: + * 0 on success or -EADDRINUSE on failure + * + * Assumptions: + * This function is called from normal user level code. + * + ****************************************************************************/ + +#ifdef CONFIG_NET_IPv6 +static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn, + FAR const struct sockaddr_in6 *addr) +{ + net_lock_t flags; + int port; + + /* Verify or select a local port and address */ + + flags = net_lock(); + + /* Verify or select a local port */ + +#ifdef CONFIG_NETDEV_MULTINIC + port = tcp_selectport(PF_INET6, + (FAR const union ip_addr_u ipaddr *)addr->sin6_addr.in6_u.u6_addr16, + ntohs(addr->sin_port)); +#else + port = tcp_selectport(ntohs(addr->sin_port)); +#endif + + net_unlock(flags); + + if (port < 0) + { + return port; + } + + /* Save the local address in the connection structure. */ + + conn->lport = addr->sin_port; + +#ifdef CONFIG_NETDEV_MULTINIC + net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16); +#endif + + return OK; +} +#endif /* CONFIG_NET_IPv6 */ + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -489,62 +859,23 @@ void tcp_free(FAR struct tcp_conn_s *conn) FAR struct tcp_conn_s *tcp_active(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp) { - FAR struct net_iphdr_s *ip = IPv4; - FAR struct tcp_conn_s *conn; - in_addr_t srcipaddr; -#ifdef CONFIG_NETDEV_MULTINIC - in_addr_t destipaddr; -#endif - - conn = (FAR struct tcp_conn_s *)g_active_tcp_connections.head; - srcipaddr = net_ip4addr_conv32(ip->srcipaddr); -#ifdef CONFIG_NETDEV_MULTINIC - destipaddr = net_ip4addr_conv32(ip->destipaddr); +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + if (IFF_IS_IPv6(dev->d_flags)) #endif - - while (conn) { - /* Find an open connection matching the TCP input. The following - * checks are performed: - * - * - The local port number is checked against the destination port - * number in the received packet. - * - The remote port number is checked if the connection is bound - * to a remote port. - * - If multiple network interfaces are supported, then the local - * IP address is available and we will insist that the - * destination IP matches the bound address. If a socket is - * bound to INADDRY_ANY, then it should receive all packets - * directed to the port. - * - Finally, if the connection is bound to a remote IP address, - * the source IP address of the packet is checked. - * - * If all of the above are true then the newly received TCP packet - * is destined for this TCP connection. - */ + return tcp_ipv6_active(dev, tcp); + } +#endif /* CONFIG_NET_IPv6 */ - if (conn->tcpstateflags != TCP_CLOSED && - tcp->destport == conn->lport && - tcp->srcport == conn->rport && -#ifdef CONFIG_NETDEV_MULTINIC - (net_ipv4addr_cmp(conn->u.ipv4.laddr, g_ipv4_allzeroaddr) || - net_ipv4addr_cmp(destipaddr, conn->u.ipv4.laddr)) && +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + else #endif - net_ipv4addr_cmp(srcipaddr, conn->u.ipv4.raddr)) - { - /* Matching connection found.. break out of the loop and return a - * reference to it. - */ - - break; - } - - /* Look at the next active connection */ - - conn = (FAR struct tcp_conn_s *)conn->node.flink; + { + return tcp_ipv4_active(dev, tcp); } - - return conn; +#endif /* CONFIG_NET_IPv4 */ } /**************************************************************************** @@ -587,14 +918,23 @@ FAR struct tcp_conn_s *tcp_nextconn(FAR struct tcp_conn_s *conn) FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, FAR struct tcp_hdr_s *tcp) { - FAR struct net_iphdr_s *ip = IPv4; FAR struct tcp_conn_s *conn; + uint8_t domain; -#ifdef CONFIG_NET_IPv4 - conn = tcp_alloc(PF_INET); -#else - conn = tcp_alloc(PF_INET6); + /* Get the appropriate IP domain */ + +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv4) + bool ipv6 = IFF_IS_IPv6(dev->d_flags); + domain = ipv6 ? PF_INET6 : PF_INET; +#elif defined(CONFIG_NET_IPv4) + domain = PF_INET; +#else /* defined(CONFIG_NET_IPv6) */ + domain = PF_INET6; #endif + + /* Allocate the connection structure */ + + conn = tcp_alloc(domain); if (conn) { /* Fill in the necessary fields for the new connection. */ @@ -606,19 +946,47 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, conn->nrtx = 0; conn->lport = tcp->destport; conn->rport = tcp->srcport; - conn->mss = TCP_IPv4_INITIAL_MSS(dev); - net_ipv4addr_copy(conn->u.ipv4.raddr, net_ip4addr_conv32(ip->srcipaddr)); + +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + if (ipv6) +#endif + { + FAR struct net_ipv6hdr_s *ip = IPv6BUF; + + conn->mss = TCP_IPv6_INITIAL_MSS(dev); + net_ipv6addr_copy(conn->u.ipv6.raddr, ip->srcipaddr); +#ifdef CONFIG_NETDEV_MULTINIC + net_ipv6addr_copy(conn->u.ipv6.laddr, ip->destipaddr); +#endif + } +#endif /* CONFIG_NET_IPv6 */ + +#ifdef CONFIG_NET_IPv4 +#ifdef CONFIG_NET_IPv6 + else +#endif + { + FAR struct net_iphdr_s *ip = IPv4BUF; + + conn->mss = TCP_IPv4_INITIAL_MSS(dev); + net_ipv4addr_copy(conn->u.ipv4.raddr, + net_ip4addr_conv32(ip->srcipaddr)); #ifdef CONFIG_NETDEV_MULTINIC - net_ipv4addr_copy(conn->u.ipv4.laddr, net_ip4addr_conv32(ip->destipaddr)); + net_ipv4addr_copy(conn->u.ipv4.laddr, + net_ip4addr_conv32(ip->destipaddr)); #endif + } +#endif /* CONFIG_NET_IPv4 */ + conn->tcpstateflags = TCP_SYN_RCVD; tcp_initsequence(conn->sndseq); - conn->unacked = 1; + conn->unacked = 1; #ifdef CONFIG_NET_TCP_WRITE_BUFFERS - conn->expired = 0; - conn->isn = 0; - conn->sent = 0; + conn->expired = 0; + conn->isn = 0; + conn->sent = 0; #endif /* rcvseq should be the seqno from the incoming packet + 1. */ @@ -663,60 +1031,31 @@ FAR struct tcp_conn_s *tcp_alloc_accept(FAR struct net_driver_s *dev, * ****************************************************************************/ -#ifdef CONFIG_NET_IPv6 -int tcp_bind(FAR struct tcp_conn_s *conn, - FAR const struct sockaddr_in6 *addr) -#else -int tcp_bind(FAR struct tcp_conn_s *conn, - FAR const struct sockaddr_in *addr) -#endif +int tcp_bind(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) { - net_lock_t flags; - int port; -#ifdef CONFIG_NETDEV_MULTINIC - in_addr_t ipaddr; -#endif - - /* Verify or select a local port and address */ - - flags = net_lock(); - -#ifdef CONFIG_NETDEV_MULTINIC +#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv6 - /* Get the IPv6 address that we are binding to */ - - ipaddr = addr->sin6_addr.in6_u.u6_addr16; - -#else - /* Get the IPv4 address that we are binding to */ - - ipaddr = addr->sin_addr.s_addr; - -#endif - - port = tcp_selectport(ipaddr, ntohs(addr->sin_port)); -#else - /* Verify or select a local port */ - - port = tcp_selectport(ntohs(addr->sin_port)); + if (conn->domain == PF_INET) #endif - - net_unlock(flags); - - if (port < 0) { - return port; - } - - /* Save the local address in the connection structure. */ + FAR const struct sockaddr_in *inaddr = + (FAR const struct sockaddr_in *)addr; - conn->lport = addr->sin_port; + return tcp_ipv4_bind(conn, inaddr); + } +#endif /* CONFIG_NET_IPv4 */ -#ifdef CONFIG_NETDEV_MULTINIC - net_ipv4addr_copy(conn->u.ipv4.laddr, ipaddr); +#ifdef CONFIG_NET_IPv6 +#ifdef CONFIG_NET_IPv4 + else #endif + { + FAR const struct sockaddr_in6 *inaddr = + (FAR const struct sockaddr_in6 *)addr; - return OK; + return tcp_ipv6_bind(conn, inaddr); + } +#endif /* CONFIG_NET_IPv6 */ } /**************************************************************************** @@ -761,7 +1100,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr) flags = net_lock(); #ifdef CONFIG_NETDEV_MULTINIC - port = tcp_selectport(conn->u.ipv4.laddr, ntohs(conn->lport)); + port = tcp_selectport(conn->domain, &conn->u, ntohs(conn->lport)); #else port = tcp_selectport(ntohs(conn->lport)); #endif -- cgit v1.2.3