panic in TCP Limited Transmit after RTO
demizu at dd.iij4u.or.jp
Sat Mar 12 19:49:46 PST 2005
> Limited Transmit is supposed to send new data,
In normal cases, Limited Transmit sends new data. But in my
experiences, the difference between snd_una and snd_max becomes
about 500KB. After an RTO, sender has to send 500KB. So it is
possible or likely to receive duplicate ACKs before snd_nxt reaches
snd_max. In such case, Limited Transmit has to send old data.
And Limited Transmit of DragonFlyBSD does this well.
(I assume "new data" here means data higher than snd_max.)
> and, we are out of SACK recovery at this point,
Retransmission timeout is an internal event of a sender. A receiver
does not know of it. So, even just after a retransmission timeout, a
sender receives ACKs with SACK blocks.
If DragonFlyBSD receives SACK blocks after RTO, it avoids sending such
SACKed data by the effect of tcp_sack_skip_sacked(). When a SACKed
block is skipped by this function, snd_nxt advances more than t_maxseg.
In such case, the following line calculates larger value than t_maxseg.
sent = tp->snd_nxt - oldsndnxt;
But if it is the first duplicate ACK, the following KASSERT() will fail.
(Note: in such case, t_dupacks=1, snd_limited=0, FIN has not been sent.)
KASSERT((tp->t_dupacks == 2 && tp->snd_limited == 0) ||
(sent == tp->t_maxseg + 1 && tp->t_flags & TF_SENTFIN),
("sent too much"));
> so I think we can safely ignore any old SACK blocks.
Yes, we can ignore old SACK blocks that are discarded on an RTO.
But I think we cannot ignore new SACK blocks received after an RTO,
especially when calculating for a variable "sent" above.
> Please try this patch.
I will try this patch on Monday in Japan time.
But could you reconsider about SACKed bytes?
More information about the Bugs