From 32a638cdfeefddb2897fd4b9f422dabf0f9107a9 Mon Sep 17 00:00:00 2001 From: Masayuki Ishikawa Date: Thu, 25 May 2017 16:48:55 +0900 Subject: [PATCH] TCP: Fix tcp_findlistner() in dual stack mode Signed-off-by: Masayuki Ishikawa --- net/tcp/tcp.h | 8 ++++++++ net/tcp/tcp_input.c | 20 ++++++++++++++++++++ net/tcp/tcp_listen.c | 23 +++++++++++++++++++++++ net/tcp/tcp_timer.c | 4 ++++ 4 files changed, 55 insertions(+) diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index 2797f4f3bc..83891b1024 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -708,7 +708,11 @@ void tcp_listen_initialize(void); * ****************************************************************************/ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno, uint8_t domain); +#else FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno); +#endif /**************************************************************************** * Name: tcp_unlisten @@ -747,7 +751,11 @@ int tcp_listen(FAR struct tcp_conn_s *conn); * ****************************************************************************/ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +bool tcp_islistener(uint16_t portno, uint8_t domain); +#else bool tcp_islistener(uint16_t portno); +#endif /**************************************************************************** * Name: tcp_accept_connection diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index a064fb0763..d299feeb0b 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -96,6 +96,18 @@ static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen) int len; int i; +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + uint8_t domain = PF_UNSPEC; + if (iplen == IPv4_HDRLEN) + { + domain = PF_INET; + } + else if (iplen == IPv6_HDRLEN) + { + domain = PF_INET6; + } +#endif + #ifdef CONFIG_NET_STATISTICS /* Bump up the count of TCP packets received */ @@ -165,7 +177,11 @@ static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen) */ tmp16 = tcp->destport; +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + if (tcp_islistener(tmp16, domain)) +#else if (tcp_islistener(tmp16)) +#endif { /* We matched the incoming packet with a connection in LISTEN. * We now need to create a new connection and send a SYNACK in @@ -327,7 +343,11 @@ found: /* Notify the listener for the connection of the reset event */ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + listener = tcp_findlistener(conn->lport, domain); +#else listener = tcp_findlistener(conn->lport); +#endif /* We must free this TCP connection structure; this connection * will never be established. diff --git a/net/tcp/tcp_listen.c b/net/tcp/tcp_listen.c index b3d36a126d..8b3b686137 100644 --- a/net/tcp/tcp_listen.c +++ b/net/tcp/tcp_listen.c @@ -77,7 +77,11 @@ static FAR struct tcp_conn_s *tcp_listenports[CONFIG_NET_MAX_LISTENPORTS]; * ****************************************************************************/ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno, uint8_t domain) +#else FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno) +#endif { int ndx; @@ -90,7 +94,11 @@ FAR struct tcp_conn_s *tcp_findlistener(uint16_t portno) */ FAR struct tcp_conn_s *conn = tcp_listenports[ndx]; +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + if (conn && conn->lport == portno && conn->domain == domain) +#else if (conn && conn->lport == portno) +#endif { /* Yes.. we found a listener on this port */ @@ -183,7 +191,11 @@ int tcp_listen(FAR struct tcp_conn_s *conn) /* First, check if there is already a socket listening on this port */ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + if (tcp_islistener(conn->lport, conn->domain)) +#else if (tcp_islistener(conn->lport)) +#endif { /* Yes, then we must refuse this request */ @@ -229,10 +241,17 @@ int tcp_listen(FAR struct tcp_conn_s *conn) * ****************************************************************************/ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) +bool tcp_islistener(uint16_t portno, uint8_t domain) +{ + return tcp_findlistener(portno, domain) != NULL; +} +#else bool tcp_islistener(uint16_t portno) { return tcp_findlistener(portno) != NULL; } +#endif /**************************************************************************** * Name: tcp_accept_connection @@ -256,7 +275,11 @@ int tcp_accept_connection(FAR struct net_driver_s *dev, * connection. */ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + listener = tcp_findlistener(portno, conn->domain); +#else listener = tcp_findlistener(portno); +#endif if (listener != NULL) { /* Yes, there is a listener. Is it accepting connections now? */ diff --git a/net/tcp/tcp_timer.c b/net/tcp/tcp_timer.c index 03935c964b..3c760c1429 100644 --- a/net/tcp/tcp_timer.c +++ b/net/tcp/tcp_timer.c @@ -235,7 +235,11 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn, /* Find the listener for this connection. */ +#if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6) + listener = tcp_findlistener(conn->lport, conn->domain); +#else listener = tcp_findlistener(conn->lport); +#endif if (listener != NULL) { /* We call tcp_callback() for the connection with