diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-19 19:18:44 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2013-01-19 19:18:44 +0000 |
commit | 1094575ce544860bc66b7c88d6b5eaf419d5ed7d (patch) | |
tree | 7bd1ddce49503ee6c07ef50fa6e76ce44388f6a4 /nuttx/net | |
parent | 070651221f4f60c2074e7641affa10e2b8714f07 (diff) | |
download | px4-firmware-1094575ce544860bc66b7c88d6b5eaf419d5ed7d.tar.gz px4-firmware-1094575ce544860bc66b7c88d6b5eaf419d5ed7d.tar.bz2 px4-firmware-1094575ce544860bc66b7c88d6b5eaf419d5ed7d.zip |
Fix a bug where recv[from]() would hang when remote host gracefully closed connection
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5539 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/net')
-rw-r--r-- | nuttx/net/recvfrom.c | 24 | ||||
-rw-r--r-- | nuttx/net/send.c | 2 |
2 files changed, 24 insertions, 2 deletions
diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index 6bfbd31ad..679b5e8ce 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,10 +565,30 @@ 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; } else diff --git a/nuttx/net/send.c b/nuttx/net/send.c index b75a864e3..8c07b391c 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. */ |