diff --git a/net/tcp/tcp.h b/net/tcp/tcp.h index c1338825425..0d0acd73564 100644 --- a/net/tcp/tcp.h +++ b/net/tcp/tcp.h @@ -1430,7 +1430,7 @@ int tcp_backlogadd(FAR struct tcp_conn_s *conn, #endif /**************************************************************************** - * Name: tcp_backlogavailable + * Name: tcp_backlogpending * * Description: * Called from poll(). Before waiting for a new connection, poll will @@ -1441,10 +1441,28 @@ int tcp_backlogadd(FAR struct tcp_conn_s *conn, * ****************************************************************************/ +#ifdef CONFIG_NET_TCPBACKLOG +bool tcp_backlogpending(FAR struct tcp_conn_s *conn); +#else +# define tcp_backlogpending(c) (false) +#endif + +/**************************************************************************** + * Name: tcp_backlogavailable + * + * Description: + * Called from tcp_input(). Before alloc a new accept connection, tcp_input + * will call this API to see if there are free node in the backlog. + * + * Assumptions: + * Called from network socket logic with the network locked + * + ****************************************************************************/ + #ifdef CONFIG_NET_TCPBACKLOG bool tcp_backlogavailable(FAR struct tcp_conn_s *conn); #else -# define tcp_backlogavailable(c) (false) +# define tcp_backlogavailable(c) (true) #endif /**************************************************************************** diff --git a/net/tcp/tcp_backlog.c b/net/tcp/tcp_backlog.c index b20317057d4..4edcfdbd5ab 100644 --- a/net/tcp/tcp_backlog.c +++ b/net/tcp/tcp_backlog.c @@ -252,7 +252,7 @@ int tcp_backlogadd(FAR struct tcp_conn_s *conn, } /**************************************************************************** - * Name: tcp_backlogremove + * Name: tcp_backlogpending * * Description: * Called from poll(). Before waiting for a new connection, poll will @@ -263,11 +263,28 @@ int tcp_backlogadd(FAR struct tcp_conn_s *conn, * ****************************************************************************/ -bool tcp_backlogavailable(FAR struct tcp_conn_s *conn) +bool tcp_backlogpending(FAR struct tcp_conn_s *conn) { return (conn && conn->backlog && !sq_empty(&conn->backlog->bl_pending)); } +/**************************************************************************** + * Name: tcp_backlogavailable + * + * Description: + * Called from tcp_input(). Before alloc a new accept connection, tcp_input + * will call this API to see if there are free node in the backlog. + * + * Assumptions: + * Called from network socket logic with the network locked + * + ****************************************************************************/ + +bool tcp_backlogavailable(FAR struct tcp_conn_s *conn) +{ + return (conn && conn->backlog && !sq_empty(&conn->backlog->bl_free)); +} + /**************************************************************************** * Name: tcp_backlogremove * diff --git a/net/tcp/tcp_input.c b/net/tcp/tcp_input.c index 47bbb6950fb..a4f0786eef1 100644 --- a/net/tcp/tcp_input.c +++ b/net/tcp/tcp_input.c @@ -761,6 +761,12 @@ static void tcp_input(FAR struct net_driver_s *dev, uint8_t domain, if ((conn = tcp_findlistener(&uaddr, tmp16)) != NULL) #endif { + if (!tcp_backlogavailable(conn)) + { + nerr("ERROR: no free containers for TCP BACKLOG!\n"); + goto drop; + } + /* We matched the incoming packet with a connection in LISTEN. * We now need to create a new connection and send a SYNACK in * response. diff --git a/net/tcp/tcp_netpoll.c b/net/tcp/tcp_netpoll.c index b5e9893d403..2f1ca92b565 100644 --- a/net/tcp/tcp_netpoll.c +++ b/net/tcp/tcp_netpoll.c @@ -288,7 +288,7 @@ int tcp_pollsetup(FAR struct socket *psock, FAR struct pollfd *fds) /* Check for read data or backlogged connection availability now */ - if (conn->readahead != NULL || tcp_backlogavailable(conn)) + if (conn->readahead != NULL || tcp_backlogpending(conn)) { /* Normal data may be read without blocking. */