net/tcp: correct the port byte order

1. unify the byte order to network
2. Do not re-select the port if the local port has been bind()

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2021-03-04 14:03:09 +08:00 committed by David Sidrane
parent 51283bd99a
commit a5613e6008

View File

@ -240,11 +240,11 @@ static FAR struct tcp_conn_s *
* been created with this port number. * been created with this port number.
* *
* Input Parameters: * Input Parameters:
* portno -- the selected port number in host order. Zero means no port * portno -- the selected port number in network order. Zero means no port
* selected. * selected.
* *
* Returned Value: * Returned Value:
* Selected or verified port number in host order on success, a negated * Selected or verified port number in network order on success, a negated
* errno on failure: * errno on failure:
* *
* EADDRINUSE * EADDRINUSE
@ -257,7 +257,8 @@ static FAR struct tcp_conn_s *
* *
****************************************************************************/ ****************************************************************************/
static int tcp_selectport(uint8_t domain, FAR const union ip_addr_u *ipaddr, static int tcp_selectport(uint8_t domain,
FAR const union ip_addr_u *ipaddr,
uint16_t portno) uint16_t portno)
{ {
static uint16_t g_last_tcp_port; static uint16_t g_last_tcp_port;
@ -285,19 +286,18 @@ static int tcp_selectport(uint8_t domain, FAR const union ip_addr_u *ipaddr,
do do
{ {
/* Guess that the next available port number will be the one after /* Guess that the next available port number will be the one after
* the last port number assigned. * the last port number assigned. Make sure that the port number
* is within range.
*/ */
portno = ++g_last_tcp_port; if (++g_last_tcp_port >= 32000)
/* Make sure that the port number is within range */
if (g_last_tcp_port >= 32000)
{ {
g_last_tcp_port = 4096; g_last_tcp_port = 4096;
} }
portno = htons(g_last_tcp_port);
} }
while (tcp_listener(domain, ipaddr, htons(g_last_tcp_port))); while (tcp_listener(domain, ipaddr, portno));
} }
else else
{ {
@ -478,11 +478,11 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
net_lock(); net_lock();
/* Verify or select a local port (host byte order) */ /* Verify or select a local port (network byte order) */
port = tcp_selectport(PF_INET, port = tcp_selectport(PF_INET,
(FAR const union ip_addr_u *)&addr->sin_addr.s_addr, (FAR const union ip_addr_u *)&addr->sin_addr.s_addr,
ntohs(addr->sin_port)); addr->sin_port);
if (port < 0) if (port < 0)
{ {
nerr("ERROR: tcp_selectport failed: %d\n", port); nerr("ERROR: tcp_selectport failed: %d\n", port);
@ -491,7 +491,7 @@ static inline int tcp_ipv4_bind(FAR struct tcp_conn_s *conn,
/* Save the local address in the connection structure (network order). */ /* Save the local address in the connection structure (network order). */
conn->lport = htons(port); conn->lport = port;
net_ipv4addr_copy(conn->u.ipv4.laddr, addr->sin_addr.s_addr); net_ipv4addr_copy(conn->u.ipv4.laddr, addr->sin_addr.s_addr);
/* Find the device that can receive packets on the network associated with /* Find the device that can receive packets on the network associated with
@ -543,13 +543,13 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
net_lock(); net_lock();
/* Verify or select a local port (host byte order) */ /* Verify or select a local port (network byte order) */
/* The port number must be unique for this address binding */ /* The port number must be unique for this address binding */
port = tcp_selectport(PF_INET6, port = tcp_selectport(PF_INET6,
(FAR const union ip_addr_u *)addr->sin6_addr.in6_u.u6_addr16, (FAR const union ip_addr_u *)addr->sin6_addr.in6_u.u6_addr16,
ntohs(addr->sin6_port)); addr->sin6_port);
if (port < 0) if (port < 0)
{ {
nerr("ERROR: tcp_selectport failed: %d\n", port); nerr("ERROR: tcp_selectport failed: %d\n", port);
@ -558,7 +558,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
/* Save the local address in the connection structure (network order). */ /* Save the local address in the connection structure (network order). */
conn->lport = htons(port); conn->lport = port;
net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16); net_ipv6addr_copy(conn->u.ipv6.laddr, addr->sin6_addr.in6_u.u6_addr16);
/* Find the device that can receive packets on the network /* Find the device that can receive packets on the network
@ -1133,18 +1133,24 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
net_lock(); net_lock();
/* Check if the local port has been bind() */
port = conn->lport;
if (port == 0)
{
#ifdef CONFIG_NET_IPv4 #ifdef CONFIG_NET_IPv4
#ifdef CONFIG_NET_IPv6 #ifdef CONFIG_NET_IPv6
if (conn->domain == PF_INET) if (conn->domain == PF_INET)
#endif #endif
{ {
/* Select a port that is unique for this IPv4 local address (host /* Select a port that is unique for this IPv4 local address
* order). * (network order).
*/ */
port = tcp_selectport(PF_INET, port = tcp_selectport(PF_INET,
(FAR const union ip_addr_u *)&conn->u.ipv4.laddr, (FAR const union ip_addr_u *)
ntohs(conn->lport)); &conn->u.ipv4.laddr, 0);
} }
#endif /* CONFIG_NET_IPv4 */ #endif /* CONFIG_NET_IPv4 */
@ -1153,13 +1159,13 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
else else
#endif #endif
{ {
/* Select a port that is unique for this IPv6 local address (host /* Select a port that is unique for this IPv6 local address
* order). * (network order).
*/ */
port = tcp_selectport(PF_INET6, port = tcp_selectport(PF_INET6,
(FAR const union ip_addr_u *)conn->u.ipv6.laddr, (FAR const union ip_addr_u *)
ntohs(conn->lport)); conn->u.ipv6.laddr, 0);
} }
#endif /* CONFIG_NET_IPv6 */ #endif /* CONFIG_NET_IPv6 */
@ -1170,6 +1176,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
ret = port; ret = port;
goto errout_with_lock; goto errout_with_lock;
} }
}
/* Set up the local address (laddr) and the remote address (raddr) that /* Set up the local address (laddr) and the remote address (raddr) that
* describes the TCP connection. * describes the TCP connection.
@ -1287,7 +1294,7 @@ int tcp_connect(FAR struct tcp_conn_s *conn, FAR const struct sockaddr *addr)
conn->rto = TCP_RTO; conn->rto = TCP_RTO;
conn->sa = 0; conn->sa = 0;
conn->sv = 16; /* Initial value of the RTT variance. */ conn->sv = 16; /* Initial value of the RTT variance. */
conn->lport = htons((uint16_t)port); conn->lport = (uint16_t)port;
#ifdef CONFIG_NET_TCP_WRITE_BUFFERS #ifdef CONFIG_NET_TCP_WRITE_BUFFERS
conn->expired = 0; conn->expired = 0;
conn->isn = 0; conn->isn = 0;