kocian at slac.stanford.edu
Wed Sep 14 04:30:31 UTC 2011
Thank you for the suggestion. I had a look at newer versions of FreeBSD.
tcp_output.c has evolved quite a bit but I think the same situation could
in principle still happen. The only thing that could prevent it is that
the congestion window after an idle period is now set up by a
configurable congestion algorithm module so it depends on the choice of
algorithm. In the New Reno algorithm, for example, the initial window size
is at least 2 * t_maxseg which means my second send would not hang
because len would be set to t_maxseg and send would immediately be called.
I'm not sure I would suggest initializing cwnd as 2 * t_maxseg as a
bugfix, though, because the BSD code has changed so much that I would be
worried that a selective update like that could be incompatible with the
old version of the code (also New Reno really intializes to 2*t_maxseg or
cwnd before the idle period, whichever is smaller).
On Tue, 13 Sep 2011, Joel Sherrill wrote:
> Is the code similar or different in recent FreeBSD? This sounds like a bug that should have been fixed there. You may be able to go through the BSD history of that file and see the fix. It has happened before and we can hope it happens this time.
> Martin Kocian <kocian at slac.stanford.edu> wrote:
>> I discovered an issue with TCP where RTEMS hangs when after an idle
>> period it tries to send a small message followed by a large message.
>> Looking at tcp_output.c I think I understand what's going on:
>> When TCP is idle for awhile the congestion window gets reset to t_maxseg.
>> Then the first message I send is smaller than t_maxseg so it is sent out
>> in a single packet. The receiver (Linux) only sends an ACK on every other
>> packet so no ACK comes back which means the RTEMS congestion window stays
>> at t_maxseg.
>> Now we send a message that is larger than t_maxseg. Len (the number of
>> bytes to be sent) gets set to congestion window size (t_maxseg) minus
>> the length of the first (unacknowledged) message.
>> The conditions in the code to actually send the next packet are:
>> - len = t_maxseg
>> - This is the last part in a send and idle or NODELAY set
>> - Time-out
>> - We have more then 1/2 the maximum send window's worth of data
>> - Retransmitting
>> All of the conditions are false so the send hangs until the Linux side
>> times out and sends the ACK.
>> This looks like a bug to me but I'm no TCP expert so any confirmation or
>> suggestion on how to fix this would be greatly appreciated.
>> Thank you,
>> rtems-users mailing list
>> rtems-users at rtems.org
| Martin Kocian |
| kocian at slac.stanford.edu |
| Stanford Linear Accelerator Center |
| M.S. 95, P.O. Box 20450 |
| Stanford, CA 94309 |
| Tel. (650)926-2887 Fax (650)926-2923 |
More information about the users