Popular Threads From Freebsd-net:
List Statistics
- Total Threads: 2088
- Total Posts: 3082
Phrases Used to Find This Thread
|
# 1

30-03-2012 03:22 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 2

30-03-2012 05:06 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 3

31-03-2012 09:53 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 4

31-03-2012 10:06 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 5

31-03-2012 11:39 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 6

31-03-2012 11:40 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 7

01-04-2012 08:27 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 8

03-04-2012 02:45 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 9

03-04-2012 04:38 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 10

03-04-2012 06:17 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 11

03-04-2012 11:08 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 12

03-04-2012 11:28 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
I should add that given the other end of this is NetBSD
I have also been following up discussion of this behaviour
on their appropriate list too. That discussion can be
found here:
http://mail-index.netbsd.org/tech-net/2012/04/01/msg003203.html
The currently last installment of which is here:
http://mail-index.netbsd.org/tech-net/2012/04/03/msg003216.html
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 13

03-04-2012 11:59 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
I should add that given the other end of this is NetBSD
I have also been following up discussion of this behaviour
on their appropriate list too. That discussion can be
found here:
http://mail-index.netbsd.org/tech-net/2012/04/01/msg003203.html
The currently last installment of which is here:
http://mail-index.netbsd.org/tech-net/2012/04/03/msg003216.html
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> On 01.04.2012 09:27, Darren Reed wrote:
>>> The problem here is that it only tracks the window size as
>>> it grows, not as it shrinks. Thus the remote end setting its
>>> window size to 0 is ignored.
>>
>> My patch is wrong as the acked count is already integrated
>> by the time we reach this spot. I'm working on a better
>> implementation.
>
> Ok, I'll look forward to seeing and testing it.
Please test this patch:
http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
I just completed a number of tests and inspected the debug output as
well as the corresponding tcpdumps. In all could simulate it behaved
correctly now with regard to tracking the window and updates.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 14

04-04-2012 03:57 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
I should add that given the other end of this is NetBSD
I have also been following up discussion of this behaviour
on their appropriate list too. That discussion can be
found here:
http://mail-index.netbsd.org/tech-net/2012/04/01/msg003203.html
The currently last installment of which is here:
http://mail-index.netbsd.org/tech-net/2012/04/03/msg003216.html
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> On 01.04.2012 09:27, Darren Reed wrote:
>>> The problem here is that it only tracks the window size as
>>> it grows, not as it shrinks. Thus the remote end setting its
>>> window size to 0 is ignored.
>>
>> My patch is wrong as the acked count is already integrated
>> by the time we reach this spot. I'm working on a better
>> implementation.
>
> Ok, I'll look forward to seeing and testing it.
Please test this patch:
http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
I just completed a number of tests and inspected the debug output as
well as the corresponding tcpdumps. In all could simulate it behaved
correctly now with regard to tracking the window and updates.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> On 01.04.2012 09:27, Darren Reed wrote:
>>>> The problem here is that it only tracks the window size as
>>>> it grows, not as it shrinks. Thus the remote end setting its
>>>> window size to 0 is ignored.
>>>
>>> My patch is wrong as the acked count is already integrated
>>> by the time we reach this spot. I'm working on a better
>>> implementation.
>>
>> Ok, I'll look forward to seeing and testing it.
>
> Please test this patch:
> http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
>
> I just completed a number of tests and inspected the debug output as
> well as the corresponding tcpdumps. In all could simulate it behaved
> correctly now with regard to tracking the window and updates.
As luck would have it, attempts to reproduce the problem today
have failed. I suspect this is because the server at the other
end is under less load than it has been in the recent past.
I'll keep the patch applied and try it again in the future when
I suspect that condition may arise again.
Thanks,
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 15

04-04-2012 11:13 AM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
I should add that given the other end of this is NetBSD
I have also been following up discussion of this behaviour
on their appropriate list too. That discussion can be
found here:
http://mail-index.netbsd.org/tech-net/2012/04/01/msg003203.html
The currently last installment of which is here:
http://mail-index.netbsd.org/tech-net/2012/04/03/msg003216.html
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> On 01.04.2012 09:27, Darren Reed wrote:
>>> The problem here is that it only tracks the window size as
>>> it grows, not as it shrinks. Thus the remote end setting its
>>> window size to 0 is ignored.
>>
>> My patch is wrong as the acked count is already integrated
>> by the time we reach this spot. I'm working on a better
>> implementation.
>
> Ok, I'll look forward to seeing and testing it.
Please test this patch:
http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
I just completed a number of tests and inspected the debug output as
well as the corresponding tcpdumps. In all could simulate it behaved
correctly now with regard to tracking the window and updates.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> On 01.04.2012 09:27, Darren Reed wrote:
>>>> The problem here is that it only tracks the window size as
>>>> it grows, not as it shrinks. Thus the remote end setting its
>>>> window size to 0 is ignored.
>>>
>>> My patch is wrong as the acked count is already integrated
>>> by the time we reach this spot. I'm working on a better
>>> implementation.
>>
>> Ok, I'll look forward to seeing and testing it.
>
> Please test this patch:
> http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
>
> I just completed a number of tests and inspected the debug output as
> well as the corresponding tcpdumps. In all could simulate it behaved
> correctly now with regard to tracking the window and updates.
As luck would have it, attempts to reproduce the problem today
have failed. I suspect this is because the server at the other
end is under less load than it has been in the recent past.
I'll keep the patch applied and try it again in the future when
I suspect that condition may arise again.
Thanks,
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 04.04.2012 17:03, wrote:
> Andre Oppermann<> wrote:
>
>> The other side is retransmitting data we have already received
>> and acknowledged ... That behavior is totally non-compliant.
>
> Any chance our ack of that data got dropped/lost enroute, and the
> other side is resending after timing out?
The correct ACK is retransmitted about a dozen times for
re-synchronization. Unlikely that all of them get lost.
On top of it the RST to terminate the session has the
correct SEQ. Something's munging the SEQ/ACK space along
the way here.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 16

04-04-2012 04:03 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
I should add that given the other end of this is NetBSD
I have also been following up discussion of this behaviour
on their appropriate list too. That discussion can be
found here:
http://mail-index.netbsd.org/tech-net/2012/04/01/msg003203.html
The currently last installment of which is here:
http://mail-index.netbsd.org/tech-net/2012/04/03/msg003216.html
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> On 01.04.2012 09:27, Darren Reed wrote:
>>> The problem here is that it only tracks the window size as
>>> it grows, not as it shrinks. Thus the remote end setting its
>>> window size to 0 is ignored.
>>
>> My patch is wrong as the acked count is already integrated
>> by the time we reach this spot. I'm working on a better
>> implementation.
>
> Ok, I'll look forward to seeing and testing it.
Please test this patch:
http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
I just completed a number of tests and inspected the debug output as
well as the corresponding tcpdumps. In all could simulate it behaved
correctly now with regard to tracking the window and updates.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> On 01.04.2012 09:27, Darren Reed wrote:
>>>> The problem here is that it only tracks the window size as
>>>> it grows, not as it shrinks. Thus the remote end setting its
>>>> window size to 0 is ignored.
>>>
>>> My patch is wrong as the acked count is already integrated
>>> by the time we reach this spot. I'm working on a better
>>> implementation.
>>
>> Ok, I'll look forward to seeing and testing it.
>
> Please test this patch:
> http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
>
> I just completed a number of tests and inspected the debug output as
> well as the corresponding tcpdumps. In all could simulate it behaved
> correctly now with regard to tracking the window and updates.
As luck would have it, attempts to reproduce the problem today
have failed. I suspect this is because the server at the other
end is under less load than it has been in the recent past.
I'll keep the patch applied and try it again in the future when
I suspect that condition may arise again.
Thanks,
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 04.04.2012 17:03, wrote:
> Andre Oppermann<> wrote:
>
>> The other side is retransmitting data we have already received
>> and acknowledged ... That behavior is totally non-compliant.
>
> Any chance our ack of that data got dropped/lost enroute, and the
> other side is resending after timing out?
The correct ACK is retransmitted about a dozen times for
re-synchronization. Unlikely that all of them get lost.
On top of it the RST to terminate the session has the
correct SEQ. Something's munging the SEQ/ACK space along
the way here.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann <> wrote:
> The other side is retransmitting data we have already received
> and acknowledged ... That behavior is totally non-compliant.
Any chance our ack of that data got dropped/lost enroute, and the
other side is resending after timing out?
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
# 17

15-06-2012 03:11 PM
|
|
|
I've been tracking down some problems with FreeBSD's sending
of TCP packets and seem to have come to the conclusion that
in FreeBSD 8.2-RELEASE, when the system is working with a
TCP connection that has a moderate delay in it, FreeBSD's
TCP ignores the other end telling it that the window size
is now 0 and continues to send data. I suspect that this is
meant to make sense because it is expecting that the ACK
that will open up the window is already in transit. But that
only accounts for the condition where the TCP on FreeBSD can
compute and decide that the remote TCP will have its buffer
full. What I find harder to accept is that when FreeBSD's
TCP receives a TCP packet from the remote end advertising
a window of 0, FreeBSD's response is to send more data and
not a window probe or is that now the expected behaviour?
And whilst you might say "ok" for a packet of data, I'm
somewhat hard pressed to explain why FreeBSD's TCP sends
multiple packets with data in them after receiving a TCP
packet from the other end advertising a zero window size.
However this causes a problem with firewalls (;_) that are
close to the FreeBSD end because for them, it appears that
FreeBSD is sending data outside of its window.
Is this a known problem?
If so, has it been fixed in a later version of FreeBSD?
(No, I haven't tested anything other than 8.2)
In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
is the other end.
Darren
--------------
DATA(1440):seq(5f665916|5f665eb6) ack(9349a95d)+4096=9349b95d
pass ip #48089 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349b485|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57457 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f665eb6|5f666456) ack(9349a95d)+4096=9349b95d
pass ip #48149 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57459 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666456|5f6669f6) ack(9349a95d)+4096=9349b95d
UFD2:td_end(5f6669f6) maxend(5f674556)
pass ip #48150 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57460 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f6669f6|5f666f96) ack(9349a95d)+4096=9349b95d
pass ip #48178 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57461 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f666f96|5f667536) ack(9349a95d)+4096=9349b95d
pass ip #48181 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57462 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667536|5f667ad6) ack(9349a95d)+4096=9349b95d
pass ip #48182 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57463 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f667ad6|5f668076) ack(9349a95d)+4096=9349b95d
pass ip #48183 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668076|5f668076) ack(9349a95d)+8192=9349c95d
ack(9349a95d)+win(8192)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349b95d|9349b95d) ack(5f664296)+66240=5f674556
pass ip #57464 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349b95d|9349bef1) ack(5f664296)+66240=5f674556
pass ip #57465 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349bef1|9349c485) ack(5f664296)+66240=5f674556
pass ip #57466 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668076|5f668616) ack(9349a95d)+8192=9349c95d
pass ip #48184 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f668bb6|5f668bb6) ack(9349a95d)+12288=9349d95d
ack(9349a95d)+win(12288)
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349c485|9349c95d) ack(5f664296)+66240=5f674556
pass ip #57467 1304(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349c95d|9349cef1) ack(5f664296)+66240=5f674556
pass ip #57468 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1428):seq(9349cef1|9349d485) ack(5f664296)+66240=5f674556
pass ip #57469 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f668bb6|5f669156) ack(9349a95d)+12288=9349d95d
pass ip #48186 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1240):seq(9349d485|9349d95d) ack(5f664296)+66240=5f674556
pass ip #57470 1312(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(5f664296|5f664836) ack(9349a95d)+12288=9349d95d
pass ip #48193 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+48960=5f674556
pass ip #57471 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+54088=5f67595e
ack(5f668616)+win(54088)
pass ip #57476 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+60632=5f6772ee
ack(5f668616)+win(60632)
pass ip #57489 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(9349d95d|9349d95d) ack(5f668616)+64728=5f6782ee
ack(5f668616)+win(64728)
pass ip #57491 64(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349b485)+9408=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349bef1)+6752=9349d951
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349c95d)+4096=9349d95d
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(0):seq(5f6696f6|5f6696f6) ack(9349d485)+1216=9349d945
pass ip #0 52(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
win==0
DATA(1440):seq(5f668616|5f668bb6) ack(9349d95d)+1=9349d95e
pass ip #48360 1492(20) 6 10.1.1.1,22 > 192.168.1.1,28808 A
--------------
DATA(1440):seq(9349d95d|9349defd) ack(5f669156)+63360=5f6788d6
ack(5f669156) seq(9349d95d)
block ip #57494 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349defd|9349e49d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349defd)
block ip #57495 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349e49d|9349ea3d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349e49d)
block ip #57496 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349ea3d|9349efdd) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349ea3d)
block ip #57497 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
DATA(1440):seq(9349efdd|9349f57d) ack(5f669156)+63360=5f6788d6
ackskew 1440
ack(5f669156) seq(9349efdd)
block ip #57498 1492(20) 6 192.168.1.1,28808 > 10.1.1.1,22 A
--------------
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 30.03.2012 16:22, Darren Reed wrote:
> I've been tracking down some problems with FreeBSD's sending
> of TCP packets and seem to have come to the conclusion that
> in FreeBSD 8.2-RELEASE, when the system is working with a
> TCP connection that has a moderate delay in it, FreeBSD's
> TCP ignores the other end telling it that the window size
> is now 0 and continues to send data. I suspect that this is
> meant to make sense because it is expecting that the ACK
> that will open up the window is already in transit. But that
> only accounts for the condition where the TCP on FreeBSD can
> compute and decide that the remote TCP will have its buffer
> full. What I find harder to accept is that when FreeBSD's
> TCP receives a TCP packet from the remote end advertising
> a window of 0, FreeBSD's response is to send more data and
> not a window probe or is that now the expected behaviour?
> And whilst you might say "ok" for a packet of data, I'm
> somewhat hard pressed to explain why FreeBSD's TCP sends
> multiple packets with data in them after receiving a TCP
> packet from the other end advertising a zero window size.
>
> However this causes a problem with firewalls (;_) that are
> close to the FreeBSD end because for them, it appears that
> FreeBSD is sending data outside of its window.
>
> Is this a known problem?
> If so, has it been fixed in a later version of FreeBSD?
> (No, I haven't tested anything other than 8.2)
The window update acceptance test is too restrictive. In your case
the last updated seq# tracking gets it wrong and prevents the update.
The code hasn't changed for a long time and newer versions behave the
same.
The concept patch below simplifies the logic, better tracks the seq#
and is a bit more permissive.
--
Andre
$ svn diff netinet/tcp_input.c
Index: netinet/tcp_input.c
===================================================================
--- netinet/tcp_input.c (revision 233227)
+++ netinet/tcp_input.c (working copy)
@@ -1717,7 +1730,7 @@
* Pull snd_wl1 up to prevent seq wrap relative to
* th_seq.
*/
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
/*
* Pull rcv_up up to prevent seq wrap relative to
* rcv_nxt.
@@ -2710,15 +2723,16 @@
* Don't look at window if no ACK: TAC's send garbage on first SYN.
*/
if ((thflags & TH_ACK) &&
- (SEQ_LT(tp->snd_wl1, th->th_seq) ||
- (tp->snd_wl1 == th->th_seq && (SEQ_LT(tp->snd_wl2, th->th_ack) ||
- (tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd))))) {
+ (BYTES_THIS_ACK(tp, th) > 0 || /* new data acked */
+ SEQ_GT(th->th_seq, tp->snd_wl1) || /* new data received */
+ (th->th_seq == tp->snd_wl1 && tiwin > tp->snd_wnd))) { /* pure win update */
+
/* keep track of pure window updates */
if (tlen == 0 &&
tp->snd_wl2 == th->th_ack && tiwin > tp->snd_wnd)
TCPSTAT_INC(tcps_rcvwinupd);
tp->snd_wnd = tiwin;
- tp->snd_wl1 = th->th_seq;
+ tp->snd_wl1 = th->th_seq + tlen;
tp->snd_wl2 = th->th_ack;
if (tp->snd_wnd > tp->max_sndwnd)
tp->max_sndwnd = tp->snd_wnd;
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Jason Hellenthal wrote:
> On Sat, Mar 31, 2012 at 01:22:27AM +1100, Darren Reed wrote:
>
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>>
>> In the packet flow below, 192.168.1.1 is FreeBSD and 10.1.1.1
>> is the other end.
>>
>> Darren
>>
>
> Hi Darren,
>
> I do believe this is the following bug at first glance that was patched
> after 8.2-RELEASE. and has to do more with x64 systems more than x32.
>
> See: "A Tale of a TCP Bug" for details...
>
> http://blogmal.42.org/tidbits/tcp-bug.story
>
> http://lists.freebsd.org/pipermail/freebsd-net/2011-April/028466.html
>
That patch alone is not enough to fix the problem - I still see FreeBSD 8.2
sending out data after it has received a TCP packet with a window size of 0.
Next I'll try adding Andre's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 30.03.2012 16:22, Darren Reed wrote:
>> I've been tracking down some problems with FreeBSD's sending
>> of TCP packets and seem to have come to the conclusion that
>> in FreeBSD 8.2-RELEASE, when the system is working with a
>> TCP connection that has a moderate delay in it, FreeBSD's
>> TCP ignores the other end telling it that the window size
>> is now 0 and continues to send data. I suspect that this is
>> meant to make sense because it is expecting that the ACK
>> that will open up the window is already in transit. But that
>> only accounts for the condition where the TCP on FreeBSD can
>> compute and decide that the remote TCP will have its buffer
>> full. What I find harder to accept is that when FreeBSD's
>> TCP receives a TCP packet from the remote end advertising
>> a window of 0, FreeBSD's response is to send more data and
>> not a window probe or is that now the expected behaviour?
>> And whilst you might say "ok" for a packet of data, I'm
>> somewhat hard pressed to explain why FreeBSD's TCP sends
>> multiple packets with data in them after receiving a TCP
>> packet from the other end advertising a zero window size.
>>
>> However this causes a problem with firewalls (;_) that are
>> close to the FreeBSD end because for them, it appears that
>> FreeBSD is sending data outside of its window.
>>
>> Is this a known problem?
>> If so, has it been fixed in a later version of FreeBSD?
>> (No, I haven't tested anything other than 8.2)
>
> The window update acceptance test is too restrictive. In your case
> the last updated seq# tracking gets it wrong and prevents the update.
>
> The code hasn't changed for a long time and newer versions behave the
> same.
>
> The concept patch below simplifies the logic, better tracks the seq#
> and is a bit more permissive.
>
This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
is not present in 8.2.)
I'll add in the obvious missing #defines and see how I go.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 31.03.2012 12:40, Darren Reed wrote:
> Darren Reed wrote:
>> Andre Oppermann wrote:
>>> On 30.03.2012 16:22, Darren Reed wrote:
>>>> I've been tracking down some problems with FreeBSD's sending
>>>> of TCP packets and seem to have come to the conclusion that
>>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>>> TCP connection that has a moderate delay in it, FreeBSD's
>>>> TCP ignores the other end telling it that the window size
>>>> is now 0 and continues to send data. I suspect that this is
>>>> meant to make sense because it is expecting that the ACK
>>>> that will open up the window is already in transit. But that
>>>> only accounts for the condition where the TCP on FreeBSD can
>>>> compute and decide that the remote TCP will have its buffer
>>>> full. What I find harder to accept is that when FreeBSD's
>>>> TCP receives a TCP packet from the remote end advertising
>>>> a window of 0, FreeBSD's response is to send more data and
>>>> not a window probe or is that now the expected behaviour?
>>>> And whilst you might say "ok" for a packet of data, I'm
>>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>>> multiple packets with data in them after receiving a TCP
>>>> packet from the other end advertising a zero window size.
>>>>
>>>> However this causes a problem with firewalls (;_) that are
>>>> close to the FreeBSD end because for them, it appears that
>>>> FreeBSD is sending data outside of its window.
>>>>
>>>> Is this a known problem?
>>>> If so, has it been fixed in a later version of FreeBSD?
>>>> (No, I haven't tested anything other than 8.2)
>>>
>>> The window update acceptance test is too restrictive. In your case
>>> the last updated seq# tracking gets it wrong and prevents the update.
>>>
>>> The code hasn't changed for a long time and newer versions behave the
>>> same.
>>>
>>> The concept patch below simplifies the logic, better tracks the seq#
>>> and is a bit more permissive.
>>>
>>
>> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
>> is not present in 8.2.)
>>
>> I'll add in the obvious missing #defines and see how I go.
>
> This patch does not resolve the problem either.
Is there a way to "easily" reproduce the traffic pattern that
causes this problem?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Darren Reed wrote:
> Andre Oppermann wrote:
>> On 30.03.2012 16:22, Darren Reed wrote:
>>> I've been tracking down some problems with FreeBSD's sending
>>> of TCP packets and seem to have come to the conclusion that
>>> in FreeBSD 8.2-RELEASE, when the system is working with a
>>> TCP connection that has a moderate delay in it, FreeBSD's
>>> TCP ignores the other end telling it that the window size
>>> is now 0 and continues to send data. I suspect that this is
>>> meant to make sense because it is expecting that the ACK
>>> that will open up the window is already in transit. But that
>>> only accounts for the condition where the TCP on FreeBSD can
>>> compute and decide that the remote TCP will have its buffer
>>> full. What I find harder to accept is that when FreeBSD's
>>> TCP receives a TCP packet from the remote end advertising
>>> a window of 0, FreeBSD's response is to send more data and
>>> not a window probe or is that now the expected behaviour?
>>> And whilst you might say "ok" for a packet of data, I'm
>>> somewhat hard pressed to explain why FreeBSD's TCP sends
>>> multiple packets with data in them after receiving a TCP
>>> packet from the other end advertising a zero window size.
>>>
>>> However this causes a problem with firewalls (;_) that are
>>> close to the FreeBSD end because for them, it appears that
>>> FreeBSD is sending data outside of its window.
>>>
>>> Is this a known problem?
>>> If so, has it been fixed in a later version of FreeBSD?
>>> (No, I haven't tested anything other than 8.2)
>>
>> The window update acceptance test is too restrictive. In your case
>> the last updated seq# tracking gets it wrong and prevents the update.
>>
>> The code hasn't changed for a long time and newer versions behave the
>> same.
>>
>> The concept patch below simplifies the logic, better tracks the seq#
>> and is a bit more permissive.
>>
>
> This patch does not apply cleanly against 8.2 (BYTES_THIS_ACK
> is not present in 8.2.)
>
> I'll add in the obvious missing #defines and see how I go.
This patch does not resolve the problem either.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre,
Your changes bring it closer to working correctly with a
small change: rather than "tiwin > tp->snd_wnd", it should
be "tiwin != tp->snd_wnd". In this trace, the remote end
has set a window scale factor of 5 during connection
establishment.
The same change should be made in the if() a few lines down.
The problem here is that it only tracks the window size as
it grows, not as it shrinks. Thus the remote end setting its
window size to 0 is ignored.
But having made that change, there appears to be still one
problem that still lingers. As can be seen below, freebsd 8.2
fails to properly ack the data that the remote end is trying
to send, ultimately causing the connection to be dropped.
Darren
16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440)
ack 367219 win 128
16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440)
ack 367219 win 128
16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440)
ack 371315 win 0
16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524)
ack 371315 win 0
16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0)
ack 371315 win 0
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 01.04.2012 09:27, Darren Reed wrote:
> Andre,
>
> Your changes bring it closer to working correctly with a
> small change: rather than "tiwin > tp->snd_wnd", it should
> be "tiwin != tp->snd_wnd". In this trace, the remote end
> has set a window scale factor of 5 during connection
> establishment.
>
> The same change should be made in the if() a few lines down.
Window updates are a tricky thing by that we must not accept
old and outdated segments to update our window. Hence we have
to test for freshness while at the same time be open enough
to handle weird cases like bidirectional data transfers on
lossy links with data waiting in reassembly queues on both
sides.
There are two clear cut cases we can accept a window update:
a) the incoming segment ACK'ed new data (moved snd_una).
b) the incoming segment carries new data (moved rcv_nxt).
The latter gets tricky already with the addition of the
reassembly queue. Here only segments that have a higher SEQ
than highest already present in the reassembly queue are OK.
And then we have a window probe where we'll get an answer
that neither moves our ACK (zero byte probes) nor carries
any data. Here the window update is vital for the future
progress of the session.
> The problem here is that it only tracks the window size as
> it grows, not as it shrinks. Thus the remote end setting its
> window size to 0 is ignored.
My patch is wrong as the acked count is already integrated
by the time we reach this spot. I'm working on a better
implementation.
> But having made that change, there appears to be still one
> problem that still lingers. As can be seen below, freebsd 8.2
> fails to properly ack the data that the remote end is trying
> to send, ultimately causing the connection to be dropped.
It's the other way around. remote.ssh is sending old data
which freebsd82.62922 has already ack'ed. The sessions seems
to be de-synchronized, perhaps some middle box mucking with
the segments trying to modulate something?
> Darren
>
> 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128
>
> 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100
> 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128
>
> 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK 6,271,493 for data segment preceeding it.
> 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38
> 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago.
> 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
ACK for highest SEQ seen again to re-synchronize.
> 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0
>
remote.ssh doesn't get and retransmits...
> 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
keeps on going with reduced MSS.
> 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0
> 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0
>
> 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280
> 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0
Retransmission timeout exhausted and sending a reset with the
correct SEQ that freebsd82.62922 is trying to ack all the time!
The time difference between that last sync-ack and the RST doesn't
make it look like a direct response as in a closed socket.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 3/04/2012 11:45 PM, Andre Oppermann wrote:
> On 01.04.2012 09:27, Darren Reed wrote:
>> Andre,
>>
>> Your changes bring it closer to working correctly with a
>> small change: rather than "tiwin > tp->snd_wnd", it should
>> be "tiwin != tp->snd_wnd". In this trace, the remote end
>> has set a window scale factor of 5 during connection
>> establishment.
>>
>> The same change should be made in the if() a few lines down.
>
> Window updates are a tricky thing by that we must not accept
> old and outdated segments to update our window. Hence we have
> to test for freshness while at the same time be open enough
> to handle weird cases like bidirectional data transfers on
> lossy links with data waiting in reassembly queues on both
> sides.
>
> There are two clear cut cases we can accept a window update:
>
> a) the incoming segment ACK'ed new data (moved snd_una).
> b) the incoming segment carries new data (moved rcv_nxt).
>
> The latter gets tricky already with the addition of the
> reassembly queue. Here only segments that have a higher SEQ
> than highest already present in the reassembly queue are OK.
>
> And then we have a window probe where we'll get an answer
> that neither moves our ACK (zero byte probes) nor carries
> any data. Here the window update is vital for the future
> progress of the session.
Hmmm, what about retransmitted data that fills a response
in response to a TCP packet with SACK present?
So that would be (b) from above but rcv_nxt does not get
moved?
So remote sends 4 packets with 1440 data bytes, freebsd82
receives pkts 1, 3 & 4, ACK's 1, uses SACK to repsond to
3 & 4, new data arrives from remote at freebsd82 but with
the TCP window set to 0.
>> The problem here is that it only tracks the window size as
>> it grows, not as it shrinks. Thus the remote end setting its
>> window size to 0 is ignored.
>
> My patch is wrong as the acked count is already integrated
> by the time we reach this spot. I'm working on a better
> implementation.
Ok, I'll look forward to seeing and testing it.
> It's the other way around. remote.ssh is sending old data
> which freebsd82.62922 has already ack'ed. The sessions seems
> to be de-synchronized, perhaps some middle box mucking with
> the segments trying to modulate something?
I suspect that the ISP is dropping packets and/or applying
some other means of throttling the connection. So, yes.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> It's the other way around. remote.ssh is sending old data
>> which freebsd82.62922 has already ack'ed. The sessions seems
>> to be de-synchronized, perhaps some middle box mucking with
>> the segments trying to modulate something?
>
> I suspect that the ISP is dropping packets and/or applying
> some other means of throttling the connection. So, yes.
That doesn't explain it. The other side is retransmitting data
we have already received and acknowledged! There is not
nothing we can do on our side. That behavior is totally
non-compliant.
The zero-window is not involved in this as it would affect
FreeBSD sending data, not the other end sending data.
Can you try to find out what kind of middle-box is mucking
TCP here on your side and the other side? It must be some
device that actively touches the TCP session transiting
through it. A router with active queue management (like WFQ
or RED) is not enough to cause this behavior.
What is the OS of your remote.ssh?
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
NetBSD.
So its TCP behaviour is going to be a lot like FreeBSD's.
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 4/04/2012 3:17 AM, Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> It's the other way around. remote.ssh is sending old data
>>> which freebsd82.62922 has already ack'ed. The sessions seems
>>> to be de-synchronized, perhaps some middle box mucking with
>>> the segments trying to modulate something?
>>
>> I suspect that the ISP is dropping packets and/or applying
>> some other means of throttling the connection. So, yes.
>
> That doesn't explain it. The other side is retransmitting data
> we have already received and acknowledged! There is not
> nothing we can do on our side. That behavior is totally
> non-compliant.
>
> The zero-window is not involved in this as it would affect
> FreeBSD sending data, not the other end sending data.
>
> Can you try to find out what kind of middle-box is mucking
> TCP here on your side and the other side? It must be some
> device that actively touches the TCP session transiting
> through it. A router with active queue management (like WFQ
> or RED) is not enough to cause this behavior.
>
> What is the OS of your remote.ssh?
I should add that given the other end of this is NetBSD
I have also been following up discussion of this behaviour
on their appropriate list too. That discussion can be
found here:
http://mail-index.netbsd.org/tech-net/2012/04/01/msg003203.html
The currently last installment of which is here:
http://mail-index.netbsd.org/tech-net/2012/04/03/msg003216.html
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 03.04.2012 17:38, Darren Reed wrote:
> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>> On 01.04.2012 09:27, Darren Reed wrote:
>>> The problem here is that it only tracks the window size as
>>> it grows, not as it shrinks. Thus the remote end setting its
>>> window size to 0 is ignored.
>>
>> My patch is wrong as the acked count is already integrated
>> by the time we reach this spot. I'm working on a better
>> implementation.
>
> Ok, I'll look forward to seeing and testing it.
Please test this patch:
http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
I just completed a number of tests and inspected the debug output as
well as the corresponding tcpdumps. In all could simulate it behaved
correctly now with regard to tracking the window and updates.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> On 01.04.2012 09:27, Darren Reed wrote:
>>>> The problem here is that it only tracks the window size as
>>>> it grows, not as it shrinks. Thus the remote end setting its
>>>> window size to 0 is ignored.
>>>
>>> My patch is wrong as the acked count is already integrated
>>> by the time we reach this spot. I'm working on a better
>>> implementation.
>>
>> Ok, I'll look forward to seeing and testing it.
>
> Please test this patch:
> http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
>
> I just completed a number of tests and inspected the debug output as
> well as the corresponding tcpdumps. In all could simulate it behaved
> correctly now with regard to tracking the window and updates.
As luck would have it, attempts to reproduce the problem today
have failed. I suspect this is because the server at the other
end is under less load than it has been in the recent past.
I'll keep the patch applied and try it again in the future when
I suspect that condition may arise again.
Thanks,
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
On 04.04.2012 17:03, wrote:
> Andre Oppermann<> wrote:
>
>> The other side is retransmitting data we have already received
>> and acknowledged ... That behavior is totally non-compliant.
>
> Any chance our ack of that data got dropped/lost enroute, and the
> other side is resending after timing out?
The correct ACK is retransmitted about a dozen times for
re-synchronization. Unlikely that all of them get lost.
On top of it the RST to terminate the session has the
correct SEQ. Something's munging the SEQ/ACK space along
the way here.
--
Andre
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann <> wrote:
> The other side is retransmitting data we have already received
> and acknowledged ... That behavior is totally non-compliant.
Any chance our ack of that data got dropped/lost enroute, and the
other side is resending after timing out?
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
Andre Oppermann wrote:
> On 03.04.2012 17:38, Darren Reed wrote:
>> On 3/04/2012 11:45 PM, Andre Oppermann wrote:
>>> On 01.04.2012 09:27, Darren Reed wrote:
>>>> The problem here is that it only tracks the window size as
>>>> it grows, not as it shrinks. Thus the remote end setting its
>>>> window size to 0 is ignored.
>>>
>>> My patch is wrong as the acked count is already integrated
>>> by the time we reach this spot. I'm working on a better
>>> implementation.
>>
>> Ok, I'll look forward to seeing and testing it.
>
> Please test this patch:
> http://people.freebsd.org/~andre/tcp_input.c-windowupdate-2012040.diff
>
> I just completed a number of tests and inspected the debug output as
> well as the corresponding tcpdumps. In all could simulate it behaved
> correctly now with regard to tracking the window and updates.
Today I ran a similar workload to what I had done previously and
it seemed to progress without incident. I had tcpdump running to
capture the entire session and upon review of that, there are indeed
instances where the window from the remote end is advertised as 0.
For now at least, that patch seems to do the magic trick.
Cheers,
Darren
_______________________________________________
freebsd- mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-"
)
|
NewsArc Lists
| Culture Pages
| Computing Archive
| Media-Pages
Link to this page on your blog or website by copying the HTML code below and pasting it into your site:
|
|