TCP-stack fix for stalled tcp sockets due to broken keepalive

Fixes an issue where tcp sockets with activated keepalives stalled and
were not properly closed. Poll would not indicate a POLLHUP and therefore
locks down the application.

* tcp_conn_s.tcp_conn_s & tcp_conn_s.keepintvl changed to uint32_t
  According RFC1122 keepidle MUST have a default of 2 hours.
This commit is contained in:
GAEHWILER Reto
2020-10-22 12:07:39 +02:00
committed by Xiang Xiao
parent 892c6b254a
commit 83745652c4
4 changed files with 46 additions and 12 deletions
+28 -7
View File
@@ -341,13 +341,36 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
case TCP_ESTABLISHED:
/* In the ESTABLISHED state, we call upon the application
* to do the actual retransmit after which we jump into
* the code for sending out the packet.
/* In the ESTABLISHED state, we have to differentiate
* between a keepalive and actual transmitted data.
*/
result = tcp_callback(dev, conn, TCP_REXMIT);
tcp_rexmit(dev, conn, result);
#ifdef CONFIG_NET_TCP_KEEPALIVE
if (conn->keepretries > 0)
{
/* In case of a keepalive timeout (based on RTT) the
* state has to be set back into idle so that a new
* keepalive can be fired.
*/
uint32_t saveseq = tcp_getsequence(conn->sndseq);
saveseq += conn->tx_unacked;
tcp_setsequence(conn->sndseq, saveseq);
conn->tx_unacked--;
}
else
#endif
{
/* If there is a timeout on outstanding data we call
* upon the application to do the actual retransmit
* after which we jump into the code for sending out
* the packet.
*/
result = tcp_callback(dev, conn, TCP_REXMIT);
tcp_rexmit(dev, conn, result);
}
goto done;
case TCP_FIN_WAIT_1:
@@ -462,8 +485,6 @@ void tcp_timer(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn,
tcp_send(dev, conn, TCP_ACK, tcpiplen + 1);
tcp_setsequence(conn->sndseq, saveseq);
/* Increment the number of un-ACKed bytes due to
* the dummy byte that we just sent.
*/