buglwIP - A Lightweight TCP/IP stack - Bugs: bug #34426, tcp_zero_window_probe() transmits...

 
 

You are not allowed to post comments on this tracker with your current authentication level.

bug #34426: tcp_zero_window_probe() transmits incorrect byte value when pcb->unacked != NULL

Submitter:  Min Xu <maximalmin>
Submitted:  Thu 29 Sep 2011 12:14:59 AM UTC
   
 
Category:  TCP Severity:  3 - Normal
Item Group:  Faulty Behaviour Status:  Fixed
Privacy:  Public Assigned to:  goldsimon
Open/Closed:  Closed Planned Release:  None
lwIP version:  1.4.0

Sun 09 Oct 2011 06:20:19 PM UTC, comment #5: 

Corrected summary and fixed the bug, thanks for reporting.

However, we should discuss if it is correct behaviour to send a zero-windo-probe instead of a simple retransmission...

Simon Goldschmidt <goldsimon>
Group administrator
Fri 30 Sep 2011 01:42:07 AM UTC, comment #4: 

Using example1.pcap, and the relative sequence number from wireshark, just after the ARP flood, DSP was able to transmit TWO 1460 byte TCP payload to the DSP, at which time the desktop's receive window is "full":
DSP Tx SEQ + 1460 - Desktop Rx ACK =
93276 + 1460 - 30496 = 64240.

However, at that moment, the desktop only ACKd  30496 so it will expect the next TCP to start at 30496, which the DSP did, but for only 1 byte.  So the FOUR 1 byte "retransmissions" from the DSP at SEQ 30496 are inside the window, but should not be called through the zero-window code...

Min Xu <maximalmin>
Thu 29 Sep 2011 09:10:37 PM UTC, comment #3: 

Per your question "why does lwIP's TCP not enter fast-retransmission after receiving 2 dupacks", quote from the ARP flooding bug entry:

the DSP main loop polls the drive receive function (to see if
there are packets already received by DMA/Interrupt) with a priority of 4096 -- it polls the receive function 4096 times,  OR until the polling function returns false, indicating there are no packets [whole or broken..].  So if the LwIP stack spends a lot of time in the tcp_output routine (to write out to the
ethernet, arp or tcp packets) it won't be able to processing incoming ARP response and/or ACK / DupACK messages until it's done.

Min Xu <maximalmin>
Thu 29 Sep 2011 08:38:01 PM UTC, comment #2: 

Since the consumed tx window suppose to include the UNACK list, shouldn't retransmission not look at the tx-window?

The reason I didn't turn on arq queuing is because of the comments above the option in the lwipopts.h where it said multiple packet queing is not working...

Attaching the options file

(file #24050)

Min Xu <maximalmin>
Thu 29 Sep 2011 08:20:11 PM UTC, comment #1: 

In both pcap captures, at the point where lwIP starts transmitting the 1-byte-segments, the TX window is full (from lwIP's TX seqno + length - the remote host's ACKno = 64240 == TX window).

This and the fact that lwIP transmits 1 byte suggests that this is the zero-window-code that transmits the wrong byte (however, since this is out of the window, I don't know if it is valid for the remote host to process this byte).

From reading the code, it copies the 1st byte from the head of unacked, but that doesn't seem to work...

Another question is why does lwIP's TCP not enter fast-retransmission after receiving 2 dupacks?

However, a real problem is that TCP doesn't know of the ARP state (and therefore the TX window is full without actually transmitting any segment). Could you please attach your lwipopts.h so that I can see the ARP_QUEUEING setting? If this would be enabled, the etharp code would have transmitted the TCP packets...

Simon Goldschmidt <goldsimon>
Group administrator
Thu 29 Sep 2011 12:14:59 AM UTC, original submission:  

Hi

We have developed a driver for an integrated EMAC module on the TI DSP that can achieve a high throughput using RAW / NO_SYS mode.  In the following description, DSP application is the software that is based on the LwIP stack and the Desktop application is a Win32 application. 

In order to maximize that throughput, we increased the receive buffer size on the desktop application to 65535 (max).  When the DSP application sends out data, it first check the send buffer size available (by calling tcp_sndbuf).  When the returned value is large, the DSP application calls tcp_write (with TCP_WRITE_FLAG_COPY) with a large payload.  The problem however, is that when the arp entry for the desktop has expired (either because ETHARP_TRUST_IP_MAC was defined as 0,  --OR-- MORE importantly, when there is a lack of network activity for a while, and the desktop then initiates another transfer), each of the packet that would've been sent out is then transmitted as an ARP REQ (for desktop's IP address).

After the large number of ARPs (I have observed 43 consecutive ARP REQ, each of which is dutifully responded by the desktop, corresponding to 62780 bytes if each ARP REQ was representative of 1460 TCP payload),  the DSP begins to transmit a new packet, followed by "retransmission" of the lost TCP pdus.  However, after 1 ack, then a DUP ack from the desktop, the DSP transmits a 1 byte TCP packet 4 times (since there is only 1 DUP ack -- as captured by Wireshark with large buffer -- , it's unlikely a fast retransmission).  Each of those 4 retransmits has the correct TCP and IP checksum, so there's no memory corruption.  The problem is that the next retransmission has the same TCP sequence number (in example1.pcap, rel seqno = 347699281;  in example2.pcap, rel seqno = 22944221), but with the proper 1460 bytes payload, and the first byte of the payload data has a different value from the 4 previous retransmissions.

Min Xu <maximalmin>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attached Files
file #24050:  lwipopts.h added by maximalmin (14KiB - text/plain)
file #24039:  example1.pcap added by maximalmin (44KiB - application/cap - Example wireshark capture showing the invalid retransmissions)
file #24040:  example2.pcap added by maximalmin (35KiB - application/cap - Example wireshark capture showing the invalid retransmissions)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by goldsimon (Posted a comment)
  • -email is unavailable- added by maximalmin (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2011-10-09 goldsimon StatusNone Fixed
        Assigned toNone goldsimon
        Open/ClosedOpen Closed
        SummaryTCP retransmission transmits 1 byte instead of original packet, with incorrect byte value tcp_zero_window_probe() transmits incorrect byte value when pcb->unacked != NULL
    2011-09-29 maximalmin Attached File- Added lwipopts.h, #24050
    2011-09-29 maximalmin Attached File- Added example1.pcap, #24039
        Attached File- Added example2.pcap, #24040

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code