diff --git a/nuttx/ChangeLog b/nuttx/ChangeLog index 122187410a..80944db66b 100644 --- a/nuttx/ChangeLog +++ b/nuttx/ChangeLog @@ -3989,3 +3989,7 @@ Marcelo, adapted to use kconfig-frontends. * net/send(): Add logic to work around delayed ACKs by splitting packets (contributed by Yan T.). + * net/recvfrom(): Fix a bug. When the host closes a connection + (gracefully). recv[from]() returned success and the closure + was never detected. Hmmm.. I don't know why the network monitor + did not catch this event. This is an important bug fix. diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 6bfbd31ad3..679b5e8ce6 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -83,7 +83,7 @@ struct recvfrom_s FAR struct sockaddr_in *rf_from; /* Address of sender */ #endif size_t rf_recvlen; /* The received length */ - int rf_result; /* OK:success, failure:negated errno */ + int rf_result; /* Success:OK, failure:negated errno */ }; #endif /* CONFIG_NET_UDP || CONFIG_NET_TCP */ @@ -553,6 +553,8 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn, else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) { + FAR struct socket *psock = 0; + nllvdbg("error\n"); /* Stop further callbacks */ @@ -563,9 +565,29 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn, /* If the peer gracefully closed the connection, then return zero * (end-of-file). Otherwise, report a not-connected error + * _SF_CONNECTED==0 && _SF_CLOSED==1 - the socket was + * gracefully disconnected + * _SF_CONNECTED==0 && _SF_CLOSED==0 - the socket was + * rudely disconnected */ + psock = pstate->rf_sock; if ((flags & UIP_CLOSE) != 0) + { + psock->s_flags &= ~_SF_CONNECTED; + psock->s_flags |= _SF_CLOSED; + } + else + { + psock->s_flags &= ~(_SF_CONNECTED |_SF_CLOSED); + } + + /* If no data has been received, then return ENOTCONN. + * Otherwise, let this return success. The failure will + * be reported the next time that recv[from]() is called. + */ + + if (pstate->rf_recvlen > 0) { pstate->rf_result = 0; } diff --git a/nuttx/net/send.c b/nuttx/net/send.c index b75a864e3b..8c07b391c8 100644 --- a/nuttx/net/send.c +++ b/nuttx/net/send.c @@ -324,7 +324,7 @@ static uint16_t send_interrupt(struct uip_driver_s *dev, void *pvconn, if (next_sndlen > 0 && (next_sndlen - uip_mss(conn)) < 0) { - /* Here, we know that sndlen must be MSS <= sndlen <= 2*MSS + /* Here, we know that sndlen must be MSS < sndlen <= 2*MSS * and so (sndlen / 2) is <= MSS. */