mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-31 02:16:53 +08:00
Fix an error the TCP/IP received sequence number counting
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4416 7fd9a85b-ad96-42d3-883c-3090e2eb8679
This commit is contained in:
@@ -11,7 +11,7 @@ Build Instructions
|
|||||||
|
|
||||||
Disclaimer: This installation steps have only been exercised using Ficl
|
Disclaimer: This installation steps have only been exercised using Ficl
|
||||||
4.1.0. With new versions you will likely have to make some adjustments
|
4.1.0. With new versions you will likely have to make some adjustments
|
||||||
to this instructtions or to the files within this directory. This of this
|
to this instructtions or to the files within this directory. Think of this
|
||||||
information as "recommendations" -- not necessarily proven instructions.
|
information as "recommendations" -- not necessarily proven instructions.
|
||||||
|
|
||||||
1. CD to apps/interpreters/ficl
|
1. CD to apps/interpreters/ficl
|
||||||
|
|||||||
@@ -2484,3 +2484,12 @@
|
|||||||
the accecpt() and connect() logic. Contributed by Max Nekludov.
|
the accecpt() and connect() logic. Contributed by Max Nekludov.
|
||||||
* net/recvfrom.c and net/uip/uip_tcpcallback.c: Fix a leak in the TCP
|
* net/recvfrom.c and net/uip/uip_tcpcallback.c: Fix a leak in the TCP
|
||||||
read-ahead logic. This is a *critical* bug fix!
|
read-ahead logic. This is a *critical* bug fix!
|
||||||
|
* net/uip/uip_tcpinput.c: Correct an error in the TCP stack. It was
|
||||||
|
incrementing the received sequence number BEFORE determining if the
|
||||||
|
incoming data could be handled. If the data was dropped (usually because
|
||||||
|
there is insufficient buffering space), then no ACK will be sent and the
|
||||||
|
sequence number will be wrong. The end consequence of the bad sequence
|
||||||
|
number was that the when the dropped packet was re-transmitted, it was
|
||||||
|
was ignored because its sequence number looked wrong. Fix was, obviously,
|
||||||
|
to only increment the recevied sequence number if the TCP data was
|
||||||
|
accepted.
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
* are used by uIP programs as well as internal uIP structures and function
|
* are used by uIP programs as well as internal uIP structures and function
|
||||||
* declarations.
|
* declarations.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* This logic was leveraged from uIP which also has a BSD-style license:
|
* This logic was leveraged from uIP which also has a BSD-style license:
|
||||||
*
|
*
|
||||||
|
|||||||
+14
-10
@@ -183,11 +183,15 @@ static inline void recvfrom_newtcpdata(FAR struct uip_driver_s *dev,
|
|||||||
|
|
||||||
nsaved = uip_datahandler(conn, buffer, buflen);
|
nsaved = uip_datahandler(conn, buffer, buflen);
|
||||||
|
|
||||||
/* There are complicated buffering issues that are not addressed
|
/* There are complicated buffering issues that are not addressed fully
|
||||||
* properly here. For example, what if up_datahandler() cannot buffer
|
* here. For example, what if up_datahandler() cannot buffer the
|
||||||
* the remainder of the packet? In that case, the data will be dropped
|
* remainder of the packet? In that case, the data will be dropped but
|
||||||
* but still ACKed. Therefore it will not be resent. Fixing this could be
|
* still ACKed. Therefore it would not be resent.
|
||||||
* tricky.
|
*
|
||||||
|
* This is probably not an issue here because we only get here if the
|
||||||
|
* read-ahead buffers are empty and there would have to be something
|
||||||
|
* serioulsy wrong with the configuration not to be able to buffer a
|
||||||
|
* partial packet in this context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_NET
|
#ifdef CONFIG_DEBUG_NET
|
||||||
@@ -469,7 +473,9 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn,
|
|||||||
|
|
||||||
if ((flags & UIP_NEWDATA) != 0)
|
if ((flags & UIP_NEWDATA) != 0)
|
||||||
{
|
{
|
||||||
/* Copy the data from the packet */
|
/* Copy the data from the packet (saving any unused bytes from the
|
||||||
|
* packet in the read-ahead buffer).
|
||||||
|
*/
|
||||||
|
|
||||||
recvfrom_newtcpdata(dev, pstate);
|
recvfrom_newtcpdata(dev, pstate);
|
||||||
|
|
||||||
@@ -489,10 +495,8 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn,
|
|||||||
{
|
{
|
||||||
nllvdbg("TCP resume\n");
|
nllvdbg("TCP resume\n");
|
||||||
|
|
||||||
/* The TCP receive buffer is full. Return now, perhaps truncating
|
/* The TCP receive buffer is full. Return now and don't allow
|
||||||
* the received data (need to fix that).
|
* any further TCP call backs.
|
||||||
*
|
|
||||||
* Don't allow any further TCP call backs.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pstate->rf_cb->flags = 0;
|
pstate->rf_cb->flags = 0;
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
* net/uip/uip_tcpinput.c
|
* net/uip/uip_tcpinput.c
|
||||||
* Handling incoming TCP input
|
* Handling incoming TCP input
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
*
|
*
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP)
|
#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP)
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -588,6 +589,10 @@ found:
|
|||||||
goto drop;
|
goto drop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the sequence number and indicate that the connection has
|
||||||
|
* been closed.
|
||||||
|
*/
|
||||||
|
|
||||||
uip_incr32(conn->rcvseq, dev->d_len + 1);
|
uip_incr32(conn->rcvseq, dev->d_len + 1);
|
||||||
flags |= UIP_CLOSE;
|
flags |= UIP_CLOSE;
|
||||||
|
|
||||||
@@ -631,24 +636,20 @@ found:
|
|||||||
{
|
{
|
||||||
dev->d_urglen = 0;
|
dev->d_urglen = 0;
|
||||||
#else /* CONFIG_NET_TCPURGDATA */
|
#else /* CONFIG_NET_TCPURGDATA */
|
||||||
dev->d_appdata =
|
dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((pbuf->urgp[0] << 8) | pbuf->urgp[1]);
|
||||||
((uint8_t*)dev->d_appdata) + ((pbuf->urgp[0] << 8) | pbuf->urgp[1]);
|
dev->d_len -= (pbuf->urgp[0] << 8) | pbuf->urgp[1];
|
||||||
dev->d_len -=
|
|
||||||
(pbuf->urgp[0] << 8) | pbuf->urgp[1];
|
|
||||||
#endif /* CONFIG_NET_TCPURGDATA */
|
#endif /* CONFIG_NET_TCPURGDATA */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If d_len > 0 we have TCP data in the packet, and we flag this
|
/* If d_len > 0 we have TCP data in the packet, and we flag this
|
||||||
* by setting the UIP_NEWDATA flag and update the sequence number
|
* by setting the UIP_NEWDATA flag. If the application has stopped
|
||||||
* we acknowledge. If the application has stopped the dataflow
|
* the dataflow using uip_stop(), we must not accept any data
|
||||||
* using uip_stop(), we must not accept any data packets from the
|
* packets from the remote host.
|
||||||
* remote host.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (dev->d_len > 0 && (conn->tcpstateflags & UIP_STOPPED) == 0)
|
if (dev->d_len > 0 && (conn->tcpstateflags & UIP_STOPPED) == 0)
|
||||||
{
|
{
|
||||||
flags |= UIP_NEWDATA;
|
flags |= UIP_NEWDATA;
|
||||||
uip_incr32(conn->rcvseq, dev->d_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the available buffer space advertised by the other end
|
/* Check if the available buffer space advertised by the other end
|
||||||
@@ -672,7 +673,7 @@ found:
|
|||||||
conn->mss = tmp16;
|
conn->mss = tmp16;
|
||||||
|
|
||||||
/* If this packet constitutes an ACK for outstanding data (flagged
|
/* If this packet constitutes an ACK for outstanding data (flagged
|
||||||
* by the UIP_ACKDATA flag, we should call the application since it
|
* by the UIP_ACKDATA flag), we should call the application since it
|
||||||
* might want to send more data. If the incoming packet had data
|
* might want to send more data. If the incoming packet had data
|
||||||
* from the peer (as flagged by the UIP_NEWDATA flag), the
|
* from the peer (as flagged by the UIP_NEWDATA flag), the
|
||||||
* application must also be notified.
|
* application must also be notified.
|
||||||
@@ -691,8 +692,33 @@ found:
|
|||||||
|
|
||||||
if ((flags & (UIP_NEWDATA | UIP_ACKDATA)) != 0)
|
if ((flags & (UIP_NEWDATA | UIP_ACKDATA)) != 0)
|
||||||
{
|
{
|
||||||
|
/* Clear sndlen and remember the size in d_len. The application
|
||||||
|
* may modify d_len and we will need this value later when we
|
||||||
|
* update the sequence number.
|
||||||
|
*/
|
||||||
|
|
||||||
dev->d_sndlen = 0;
|
dev->d_sndlen = 0;
|
||||||
result = uip_tcpcallback(dev, conn, flags);
|
len = dev->d_len;
|
||||||
|
|
||||||
|
/* Provide the packet to the application */
|
||||||
|
|
||||||
|
result = uip_tcpcallback(dev, conn, flags);
|
||||||
|
|
||||||
|
/* If the application successfully handled the incoming data,
|
||||||
|
* then UIP_SNDACK will be set in the result. In this case,
|
||||||
|
* we need to update the sequence number. The ACK will be
|
||||||
|
* send by uip_tcpappsend().
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((result & UIP_SNDACK) != 0)
|
||||||
|
{
|
||||||
|
/* Update the sequence number using the saved length */
|
||||||
|
|
||||||
|
uip_incr32(conn->rcvseq, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the response, ACKing the data or not, as appropriate */
|
||||||
|
|
||||||
uip_tcpappsend(dev, conn, result);
|
uip_tcpappsend(dev, conn, result);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/uip/uip_tcpsend.c
|
* net/uip/uip_tcpsend.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user