lwip-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-users] Recent tcp_rexmit() changes


From: Karl Jeacle
Subject: [lwip-users] Recent tcp_rexmit() changes
Date: Thu, 22 Jul 2004 20:20:31 +0100

Hi all,

I'm about a week late on this, but I've run into some problems with
the recently introduced changes to the TCP retransmission code.

The new Stevens-inspired Fast Retransmit code in tcp_receive() makes
sense, and therefore the change in tcp_rexmit() to move just a single
unacked segment to the unsent queue instead of all unacked segments
seems to make sense too. I was happy to see a bug fix!

However, these changes have an impact on how tcp_output() operates.
Lines 435-436 of tcp_out.c initiate a while loop that outputs segments
from the unsent queue:

  while (seg != NULL &&
  ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) {

The difference between the seqno of the first segment on the unsent
queue and the last ackno will normally be less than the window, so
segments are output as you would expect.

But what happens if A is sending data to B, large windows are in use,
and a number of packets are dropped? What will the new code do?

FR will halve the window, and the new tcp_rexmit() will place just one
unacked segment at the start of the unsent queue. This segment will
pass the while() check above and be transmitted, but the next segment
on the queue will have a much higher sequence number, and the halved
window will mean that the while() condition fails, and so tcp_output()
cannot send any more data.

tcp_slowtmr() will eventually call tcp_rexmit(), and one more unacked
segment will be moved to the unsent queue and transmitted. This cycle
of tcp_slowtmr() calling tcp_rexmit() to send one segment will continue
until all missing segments have arrived at the receiver. If a large
window is used and several packets are dropped, this causes a serious
delay in transmission.

Previously what happened was that ALL unacked segments were placed
on the unsent queue, so despite the halving of the window, the while()
condition would succeed, and tcp_output() would just continue (re)sending
older unacked segments before starting to send new segments again.

Introducing the new more economical tcp_rexmit() code means that we'll
need a smarter tcp_output() that doesn't choke when a number of older
unacked segments suddenly need to be retransmitted.

I'm not sure what the solution is, but I'd welcome comments on the
above. Sam's original problem has been solved, but for me at least,
the solution used has introduced a more serious problem!

Karl




reply via email to

[Prev in Thread] Current Thread [Next in Thread]