From 8dc7f6d79e63b26b5890fcee318334f196d0a595 Mon Sep 17 00:00:00 2001 From: Simon Piriou Date: Sun, 14 May 2017 09:08:32 -0600 Subject: [PATCH] tcp: wait for 3-Way Handshare before accept() returns --- net/tcp/Kconfig | 7 +++++++ net/tcp/tcp_input.c | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/net/tcp/Kconfig b/net/tcp/Kconfig index fac41794dc..1660b080ee 100644 --- a/net/tcp/Kconfig +++ b/net/tcp/Kconfig @@ -156,6 +156,13 @@ config NET_TCPBACKLOG Incoming connections pend in a backlog until accept() is called. The size of the backlog is selected when listen() is called. +config NET_ACCEPT_ON_ACK + bool "accept() returns on TCP 3-Way Handshake completion" + default n + ---help--- + accept() returns after 3-Way Handshake is complete (SYN, SYN/ACK, ACK). + Without this flag it returns after SYN packet is received. + config NET_TCP_SPLIT bool "Enable packet splitting" default n diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 1918bd3492..22e11be7ae 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -185,6 +185,8 @@ static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen) */ conn->crefs = 1; + +#ifndef CONFIG_NET_ACCEPT_ON_ACK if (tcp_accept_connection(dev, conn, tmp16) != OK) { /* No, then we have to give the connection back and drop the packet */ @@ -193,6 +195,7 @@ static void tcp_input(FAR struct net_driver_s *dev, unsigned int iplen) tcp_free(conn); conn = NULL; } +#endif } if (!conn) @@ -464,6 +467,23 @@ found: { conn->tcpstateflags = TCP_ESTABLISHED; +#ifdef CONFIG_NET_ACCEPT_ON_ACK + if (tcp_accept_connection(dev, conn, tcp->destport) != OK) + { + /* No more listener for current port. We can free conn here + * because it has not been shared with upper layers yet as + * handshake is not complete + */ + + nerr("Listen canceled while waiting for ACK on port %d\n", + tcp->destport); + conn->crefs = 0; + tcp_free(conn); + conn = NULL; + goto drop; + } +#endif + #ifdef CONFIG_NET_TCP_WRITE_BUFFERS conn->isn = tcp_getsequence(tcp->ackno); tcp_setsequence(conn->sndseq, conn->isn);