lwip-users
[Top][All Lists]
Advanced

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

Re: [lwip-users] Not responding to TCP keep-alives


From: David Haas
Subject: Re: [lwip-users] Not responding to TCP keep-alives
Date: Mon, 16 Aug 2004 15:39:24 -0400
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.1) Gecko/20040707

I've been looking at this a bit further and here is what I've found:

There are two different kind of keep-alives. In one variety, there is no data in the segment and the probe simply has the sequence number as one less than the next sequence number to be sent. LWIP handles this keep-alive properly. It has code to deal with it.

It turns out that a keep alive can also be sent where the sequence number is also one less than the sequence number to be sent, but there is also 1 byte of garbage data. In other words len is 1, but since the sequence number has already been acked, the receiver should ignore the data, but SHOULD send out another ack. LWIP is not handling this situation properly.

Stevens Volume 1, page 335 says:

Some older implementations based on 4.2BSD do not respond to these keepalive probes unless the sement contains data. Some systems can be configured to send one garbage byte of data in the probe to elicit the response. The garbage byte causes no harm, because it's not the expected byte (it's a byte that the receiver has previously received and acknowledged), so it's thrown away by the receiver. Otther systems send the 4.3BSD-style segment (no data) for the first half of the probe period, and if no respose is received, switch to the 4.2BSD-style segment for the last half.

Apparently Windows 2000 just starts out doing this when it does keep-alives against a zero window.

I added some code to deal with this in tcp_receive(). It might not be the most elegant, but I was afraid of breaking other stuff. I attach the patch.

Here is a ethereal display from the patched code:

No. Time Source Destination Protocol Info 784 1231.389373 192.168.10.252 192.168.10.242 TCP 1944 > 1101 [PSH, ACK] Seq=70212 Ack=1 Win=17520 Len=1176 785 1231.390301 192.168.10.242 192.168.10.252 TCP 1101 > 1944 [ACK] Seq=1 Ack=70212 Win=1580 Len=0 786 1231.684792 192.168.10.242 192.168.10.252 TCP 1101 > 1944 [ACK] Seq=1 Ack=71388 Win=404 Len=0 787 1236.598107 192.168.10.252 192.168.10.242 TCP 1944 > 1101 [ACK] Seq=71388 Ack=1 Win=17520 Len=404 788 1236.813665 192.168.10.242 192.168.10.252 TCP [TCP ZeroWindow] 1101 > 1944 [ACK] Seq=1 Ack=71792 Win=0 Len=0 789 1237.298859 192.168.10.252 192.168.10.242 TCP 1944 > 1101 [ACK] Seq=71792 Ack=1 Win=17520 Len=1 790 1237.299636 192.168.10.242 192.168.10.252 TCP [TCP ZeroWindow] [TCP Dup ACK 788#1] 1101 > 1944 [ACK] Seq=1 Ack=71792 Win=0 Len=0 791 1238.300340 192.168.10.252 192.168.10.242 TCP [TCP Keep-Alive] 1944 > 1101 [ACK] Seq=71792 Ack=1 Win=17520 Len=1 792 1238.301060 192.168.10.242 192.168.10.252 TCP [TCP ZeroWindow] [TCP Keep-Alive ACK] 1101 > 1944 [ACK] Seq=1 Ack=71792 Win=0 Len=0 793 1240.303391 192.168.10.252 192.168.10.242 TCP [TCP Keep-Alive] 1944 > 1101 [ACK] Seq=71792 Ack=1 Win=17520 Len=1 794 1240.304002 192.168.10.242 192.168.10.252 TCP [TCP ZeroWindow] [TCP Keep-Alive ACK] 1101 > 1944 [ACK] Seq=1 Ack=71792 Win=0 Len=0

--- devel/lwip/src/core/tcp_in.c        2004-07-25 19:17:07.000000000 -0400
+++ ../cfimage/lwip/core/tcp_in.c       2004-08-16 15:23:24.357617600 -0400
@@ -1162,6 +1162,11 @@
 #endif /* TCP_QUEUE_OOSEQ */
 
       }
+    } else {
+      if (TCP_SEQ_GT(pcb->rcv_nxt, seqno) ||
+          TCP_SEQ_GEQ(seqno, pcb->rcv_nxt + pcb->rcv_wnd)) {
+        tcp_ack_now(pcb);
+      }
     }
   } else {
     /* Segments with length 0 is taken care of here. Segments that

reply via email to

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