net/tcp: sanity check for the listen address
Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
parent
4ac3044cc3
commit
c132e5bed4
@ -52,6 +52,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
@ -852,9 +852,12 @@ void tcp_listen_initialize(void);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno, uint8_t domain);
|
FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
|
||||||
|
uint16_t portno,
|
||||||
|
uint8_t domain);
|
||||||
#else
|
#else
|
||||||
FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno);
|
FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
|
||||||
|
uint16_t portno);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -895,9 +898,10 @@ int tcp_listen(FAR struct tcp_conn_s *conn);
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
bool tcp_islistener(uint16_t portno, uint8_t domain);
|
bool tcp_islistener(FAR union ip_binding_u *uaddr, uint16_t portno,
|
||||||
|
uint8_t domain);
|
||||||
#else
|
#else
|
||||||
bool tcp_islistener(uint16_t portno);
|
bool tcp_islistener(FAR union ip_binding_u *uaddr, uint16_t portno);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -68,6 +68,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#define IPv4BUF ((FAR struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
#define IPv4BUF ((FAR struct ipv4_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||||
|
#define IPv6BUF ((FAR struct ipv6_hdr_s *)&dev->d_buf[NET_LL_HDRLEN(dev)])
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Functions
|
* Private Functions
|
||||||
@ -283,8 +284,9 @@ static void tcp_snd_wnd_update(FAR struct tcp_conn_s *conn,
|
|||||||
static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
|
static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
|
||||||
unsigned int iplen)
|
unsigned int iplen)
|
||||||
{
|
{
|
||||||
FAR struct tcp_hdr_s *tcp;
|
|
||||||
FAR struct tcp_conn_s *conn = NULL;
|
FAR struct tcp_conn_s *conn = NULL;
|
||||||
|
FAR struct tcp_hdr_s *tcp;
|
||||||
|
union ip_binding_u uaddr;
|
||||||
unsigned int tcpiplen;
|
unsigned int tcpiplen;
|
||||||
unsigned int hdrlen;
|
unsigned int hdrlen;
|
||||||
uint16_t tmp16;
|
uint16_t tmp16;
|
||||||
@ -370,10 +372,29 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tmp16 = tcp->destport;
|
tmp16 = tcp->destport;
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
# ifdef CONFIG_NET_IPv4
|
||||||
|
if (domain == PF_INET6)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
net_ipv6addr_copy(&uaddr.ipv6.laddr, IPv6BUF->destipaddr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
# ifdef CONFIG_NET_IPv6
|
||||||
|
if (domain == PF_INET)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
net_ipv4addr_copy(uaddr.ipv4.laddr,
|
||||||
|
net_ip4addr_conv32(IPv4BUF->destipaddr));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
if (tcp_islistener(tmp16, domain))
|
if (tcp_islistener(&uaddr, tmp16, domain))
|
||||||
#else
|
#else
|
||||||
if (tcp_islistener(tmp16))
|
if (tcp_islistener(&uaddr, tmp16))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* We matched the incoming packet with a connection in LISTEN.
|
/* We matched the incoming packet with a connection in LISTEN.
|
||||||
@ -541,10 +562,29 @@ found:
|
|||||||
|
|
||||||
/* Notify the listener for the connection of the reset event */
|
/* Notify the listener for the connection of the reset event */
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
# ifdef CONFIG_NET_IPv4
|
||||||
|
if (domain == PF_INET6)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
net_ipv6addr_copy(&uaddr.ipv6.laddr, IPv6BUF->destipaddr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
# ifdef CONFIG_NET_IPv6
|
||||||
|
if (domain == PF_INET)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
net_ipv4addr_copy(uaddr.ipv4.laddr,
|
||||||
|
net_ip4addr_conv32(IPv4BUF->destipaddr));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
listener = tcp_findlistener(conn->lport, domain);
|
listener = tcp_findlistener(&uaddr, conn->lport, domain);
|
||||||
#else
|
#else
|
||||||
listener = tcp_findlistener(conn->lport);
|
listener = tcp_findlistener(&uaddr, conn->lport);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We must free this TCP connection structure; this connection
|
/* We must free this TCP connection structure; this connection
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <nuttx/net/net.h>
|
#include <nuttx/net/net.h>
|
||||||
|
|
||||||
#include "devif/devif.h"
|
#include "devif/devif.h"
|
||||||
|
#include "inet/inet.h"
|
||||||
#include "tcp/tcp.h"
|
#include "tcp/tcp.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -78,9 +79,12 @@ static FAR struct tcp_conn_s *tcp_listenports[CONFIG_NET_MAX_LISTENPORTS];
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno, uint8_t domain)
|
FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
|
||||||
|
uint16_t portno,
|
||||||
|
uint8_t domain)
|
||||||
#else
|
#else
|
||||||
FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno)
|
FAR struct tcp_conn_s *tcp_findlistener(FAR union ip_binding_u *uaddr,
|
||||||
|
uint16_t portno)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
int ndx;
|
int ndx;
|
||||||
@ -100,11 +104,37 @@ FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno)
|
|||||||
if (conn && conn->lport == portno)
|
if (conn && conn->lport == portno)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_NET_IPv6
|
||||||
|
# ifdef CONFIG_NET_IPv4
|
||||||
|
if (domain == PF_INET6)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
if (net_ipv6addr_cmp(conn->u.ipv6.laddr, uaddr->ipv6.laddr) ||
|
||||||
|
net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_unspecaddr))
|
||||||
|
{
|
||||||
/* Yes.. we found a listener on this port */
|
/* Yes.. we found a listener on this port */
|
||||||
|
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_NET_IPv4
|
||||||
|
# ifdef CONFIG_NET_IPv6
|
||||||
|
if (domain == PF_INET)
|
||||||
|
# endif
|
||||||
|
{
|
||||||
|
if (net_ipv4addr_cmp(conn->u.ipv4.laddr, uaddr->ipv4.laddr) ||
|
||||||
|
net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_ANY))
|
||||||
|
{
|
||||||
|
/* Yes.. we found a listener on this port */
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* No listener for this port */
|
/* No listener for this port */
|
||||||
|
|
||||||
@ -192,9 +222,9 @@ int tcp_listen(FAR struct tcp_conn_s *conn)
|
|||||||
/* First, check if there is already a socket listening on this port */
|
/* First, check if there is already a socket listening on this port */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
if (tcp_islistener(conn->lport, conn->domain))
|
if (tcp_islistener(&conn->u, conn->lport, conn->domain))
|
||||||
#else
|
#else
|
||||||
if (tcp_islistener(conn->lport))
|
if (tcp_islistener(&conn->u, conn->lport))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Yes, then we must refuse this request */
|
/* Yes, then we must refuse this request */
|
||||||
@ -242,14 +272,15 @@ int tcp_listen(FAR struct tcp_conn_s *conn)
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
bool tcp_islistener(uint16_t portno, uint8_t domain)
|
bool tcp_islistener(FAR union ip_binding_u *uaddr, uint16_t portno,
|
||||||
|
uint8_t domain)
|
||||||
{
|
{
|
||||||
return tcp_findlistener(portno, domain) != NULL;
|
return tcp_findlistener(uaddr, portno, domain) != NULL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
bool tcp_islistener(uint16_t portno)
|
bool tcp_islistener(FAR union ip_binding_u *uaddr, uint16_t portno)
|
||||||
{
|
{
|
||||||
return tcp_findlistener(portno) != NULL;
|
return tcp_findlistener(uaddr, portno) != NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -276,9 +307,9 @@ int tcp_accept_connection(FAR struct net_driver_s *dev,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
listener = tcp_findlistener(portno, conn->domain);
|
listener = tcp_findlistener(&conn->u, portno, conn->domain);
|
||||||
#else
|
#else
|
||||||
listener = tcp_findlistener(portno);
|
listener = tcp_findlistener(&conn->u, portno);
|
||||||
#endif
|
#endif
|
||||||
if (listener != NULL)
|
if (listener != NULL)
|
||||||
{
|
{
|
||||||
|
@ -250,9 +250,10 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
|
|||||||
/* Find the listener for this connection. */
|
/* Find the listener for this connection. */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
|
||||||
listener = tcp_findlistener(conn->lport, conn->domain);
|
listener = tcp_findlistener(&conn->u, conn->lport,
|
||||||
|
conn->domain);
|
||||||
#else
|
#else
|
||||||
listener = tcp_findlistener(conn->lport);
|
listener = tcp_findlistener(&conn->u, conn->lport);
|
||||||
#endif
|
#endif
|
||||||
if (listener != NULL)
|
if (listener != NULL)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user