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:
patacongo 2012-02-23 15:53:27 +00:00
parent 0362fd4c22
commit 112e4f55ba
6 changed files with 108 additions and 69 deletions

View File

@ -1,42 +1,42 @@
apps/interpreter/README.txt
===========================
Ficl is a programming language interpreter designed to be embedded into
other systems as a command, macro, and development prototyping language.
Ficl is an acronym for "Forth Inspired Command Language". See
http://ficl.sourceforge.net/
Build Instructions
------------------
Disclaimer: This installation steps have only been exercised using Ficl
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
information as "recommendations" -- not necessarily proven instructions.
1. CD to apps/interpreters/ficl
2. Download Ficl: http://sourceforge.net/projects/ficl/files/
3. Uznip the Ficl compressed file.
For example, 'unzip ficl-4.1.0.zip' will leave the file
apps/interpreters/ficl/ficl-4.1.0
4. Configure to build Ficl in the apps/interpreters/ficl directory using
the configure.sh script.
For example, './configure.sh ficl-4.1.0' will leave the Makefile
fragment 'Make.srcs' in the ficl build directory.
5. Create your NuttX configuration. The appconfig file should include
(1) the path to your application code, and (2) the path to the Ficl
build directory. That latter would appear as the following line in
your appconfig file:
CONFIGURED_APPS += interpreters/ficl
6. Configure and build NuttX. On successful completion, the Ficl objects
will be available in apps/libapps.a and that NuttX binary will be
linked against that file. Of course, Ficl will do nothing unless
you have written some application code that uses it!
apps/interpreter/README.txt
===========================
Ficl is a programming language interpreter designed to be embedded into
other systems as a command, macro, and development prototyping language.
Ficl is an acronym for "Forth Inspired Command Language". See
http://ficl.sourceforge.net/
Build Instructions
------------------
Disclaimer: This installation steps have only been exercised using Ficl
4.1.0. With new versions you will likely have to make some adjustments
to this instructtions or to the files within this directory. Think of this
information as "recommendations" -- not necessarily proven instructions.
1. CD to apps/interpreters/ficl
2. Download Ficl: http://sourceforge.net/projects/ficl/files/
3. Uznip the Ficl compressed file.
For example, 'unzip ficl-4.1.0.zip' will leave the file
apps/interpreters/ficl/ficl-4.1.0
4. Configure to build Ficl in the apps/interpreters/ficl directory using
the configure.sh script.
For example, './configure.sh ficl-4.1.0' will leave the Makefile
fragment 'Make.srcs' in the ficl build directory.
5. Create your NuttX configuration. The appconfig file should include
(1) the path to your application code, and (2) the path to the Ficl
build directory. That latter would appear as the following line in
your appconfig file:
CONFIGURED_APPS += interpreters/ficl
6. Configure and build NuttX. On successful completion, the Ficl objects
will be available in apps/libapps.a and that NuttX binary will be
linked against that file. Of course, Ficl will do nothing unless
you have written some application code that uses it!

View File

@ -2484,3 +2484,12 @@
the accecpt() and connect() logic. Contributed by Max Nekludov.
* net/recvfrom.c and net/uip/uip_tcpcallback.c: Fix a leak in the TCP
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.

View File

@ -5,8 +5,8 @@
* are used by uIP programs as well as internal uIP structures and function
* declarations.
*
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* This logic was leveraged from uIP which also has a BSD-style license:
*

View File

@ -183,11 +183,15 @@ static inline void recvfrom_newtcpdata(FAR struct uip_driver_s *dev,
nsaved = uip_datahandler(conn, buffer, buflen);
/* There are complicated buffering issues that are not addressed
* properly here. For example, what if up_datahandler() cannot buffer
* the remainder of the packet? In that case, the data will be dropped
* but still ACKed. Therefore it will not be resent. Fixing this could be
* tricky.
/* There are complicated buffering issues that are not addressed fully
* here. For example, what if up_datahandler() cannot buffer the
* remainder of the packet? In that case, the data will be dropped but
* still ACKed. Therefore it would not be resent.
*
* 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
@ -469,7 +473,9 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn,
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);
@ -489,10 +495,8 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn,
{
nllvdbg("TCP resume\n");
/* The TCP receive buffer is full. Return now, perhaps truncating
* the received data (need to fix that).
*
* Don't allow any further TCP call backs.
/* The TCP receive buffer is full. Return now and don't allow
* any further TCP call backs.
*/
pstate->rf_cb->flags = 0;

View File

@ -2,8 +2,8 @@
* net/uip/uip_tcpinput.c
* Handling incoming TCP input
*
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
*
@ -43,6 +43,7 @@
****************************************************************************/
#include <nuttx/config.h>
#if defined(CONFIG_NET) && defined(CONFIG_NET_TCP)
#include <stdint.h>
@ -588,6 +589,10 @@ found:
goto drop;
}
/* Update the sequence number and indicate that the connection has
* been closed.
*/
uip_incr32(conn->rcvseq, dev->d_len + 1);
flags |= UIP_CLOSE;
@ -631,24 +636,20 @@ found:
{
dev->d_urglen = 0;
#else /* CONFIG_NET_TCPURGDATA */
dev->d_appdata =
((uint8_t*)dev->d_appdata) + ((pbuf->urgp[0] << 8) | pbuf->urgp[1]);
dev->d_len -=
(pbuf->urgp[0] << 8) | pbuf->urgp[1];
dev->d_appdata = ((uint8_t*)dev->d_appdata) + ((pbuf->urgp[0] << 8) | pbuf->urgp[1]);
dev->d_len -= (pbuf->urgp[0] << 8) | pbuf->urgp[1];
#endif /* CONFIG_NET_TCPURGDATA */
}
/* 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
* we acknowledge. If the application has stopped the dataflow
* using uip_stop(), we must not accept any data packets from the
* remote host.
* by setting the UIP_NEWDATA flag. If the application has stopped
* the dataflow using uip_stop(), we must not accept any data
* packets from the remote host.
*/
if (dev->d_len > 0 && (conn->tcpstateflags & UIP_STOPPED) == 0)
{
flags |= UIP_NEWDATA;
uip_incr32(conn->rcvseq, dev->d_len);
}
/* Check if the available buffer space advertised by the other end
@ -672,7 +673,7 @@ found:
conn->mss = tmp16;
/* 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
* from the peer (as flagged by the UIP_NEWDATA flag), the
* application must also be notified.
@ -691,8 +692,33 @@ found:
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;
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);
return;
}

View File

@ -1,8 +1,8 @@
/****************************************************************************
* net/uip/uip_tcpsend.c
*
* Copyright (C) 2007-2010 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
* Copyright (C) 2007-2010, 2012 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Adapted for NuttX from logic in uIP which also has a BSD-like license:
*