ulTxWindowLength in TCP lib decrease after unplug/plug cable and seems not return back to initialed value

In my application, freertos runs as a server to send data, PC to receive data. when I unplug and then plug cable quickly(must quick enough, socket not reconnect), will see throughput drop.
After debugging, I found the reason should be the ulTxWindowLength adjust, and seems the window size not recover after cable is stable.
after disable this window size adjust, the throughput will not drop.
To maximum the throughput, I initialed the tx window size as 46720, much larger than 2*1460.

/* If there have been several retransmissions (4), decrease the
                 * size of the transmission window to at most 2 times MSS. */
               *if( ( pxSegment->u.bits.ucTransmitCount == MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW ) &&
                    ( pxWindow->xSize.ulTxWindowLength > ( 2U * ( ( uint32_t ) pxWindow->usMSS ) ) ) )
                {
                    uint16_t usMSS2 = pxWindow->usMSS * 2U;
                    FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u - %u]: Change Tx window: %u -> %u\n",
                                             pxWindow->usPeerPortNumber,
                                             pxWindow->usOurPortNumber,
                                             ( unsigned ) pxWindow->xSize.ulTxWindowLength,
                                             usMSS2 ) );
                    pxWindow->xSize.ulTxWindowLength = usMSS2;
                }

BR
Guoxing

and my platform is ZYNQ, freertos version is 10.4.6 lts

As you know, the IP-stack was developed for applications with a low memory footprint. As for TCP, only the most essential features have been implemented.

Mentioned algorithm says:

“If there have been several retransmissions (4), decrease the size of the transmission window to at most 2 times MSS.”

We found that the algorithm is useful in case of a low-quality Internet connection.

You wrote:

I unplug and then plug cable quickly(must quick enough, socket not reconnect)

What amazes me, is that a segment gets 4 retransmission in a relatively short time.

Would it be possible for you to attach a zipped PCAP file that shows the TCP connection? Thanks

Hi Hein,
Happy to touch you here once more. Thanks you so much for your always quick support.
The PCAP have dumped. please see attachment. And in below picture I marked the operations I have done when running the dumping.
I have also tried to analyze it, seems it is related to tx window size(or congestion window size), not receive window size. But I don’t familiar with tcp. Still need your help. Thanks a lot.

For the application, most of the data traffic is freertos->pc, it send the buffer length at first(the small package with len=8), then send the data in buffer.

for the attachment, you have to rename the name, because forum doesn’t support .001, .002 pox-fix filename. then just unzip the window_size_5th.7z.001

window_size_5th.7z.001.7z → window_size_5th.7z.001
window_size_5th.7z.002.7z → window_size_5th.7z.002
window_size_5th.7z.003.7z → window_size_5th.7z.003


window_size_5th.7z.001.7z (4 MB)
window_size_5th.7z.002.7z (4 MB)
window_size_5th.7z.003.7z (2.3 MB)

@gsing, something must have gone wrong when you uploaded the 7zip files. My 7zip utility gives an error on each file.

If you want you also send the PCAP files to hein [at] htibosch [dot] net

Thank you

Thanks Hein, have send the pcap to your mail.

Communication is quick, here is a summary of the PCAP file that you sent me:
window_size_5th.zip (3.2 KB)

Thanks, I will study it and report my findings in this thread.

Conclusion:

It surprises me that after shrinking the TX window, it starts sending packets that have been sent and acknowledged earlier.

These packets are sent from the Zynq server:

00001-13141
14601-27741
29201-42341
43801-56941
58401-67161 also last packet is acknowledged by the client

And then erroneously, the Zynq starts repeating 8 packets that have been acknowledged already:

29201-40881

I’m afraid something goes wrong after setting ulTxWindowLength. Would you mind removing this piece of code:

if( ( pxSegment->u.bits.ucTransmitCount == MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW ) &&
    ( pxWindow->xSize.ulTxWindowLength > ( 2U * ( ( uint32_t ) pxWindow->usMSS ) ) ) )
{
    uint16_t usMSS2 = pxWindow->usMSS * 2U;
    pxWindow->xSize.ulTxWindowLength = usMSS2;
}

and then run the same test as before?

Normally I would do such a test myself, but I am still traveling without much hardware in my suitcase.

You can send a 7-zipped PCAP to my email address.

Thanks

Thank you @gsing for the results, summarised as
window_size_6th_remove_tx_size_decrease.zip (4.6 KB)

The whole recording showed this performance:

In other words, there is no performance loss, and the connection recovers quickly after reconnecting.

I will investigate what went wrong when ulTxWindowLength was decreased.
For now, I’d recommend not using mentioned code fragment.

1 Like

Thanks Hein, no problem, It is OK for me to not use the ulTxWindowLength decrease code. This is not a blocking issue for me, just an interesting phenomenon. As we know, in ZYNQ with DDR, ram footprint is not an issue. So enjoy you journey and investigate this when you free.