Skip to content

Commit

Permalink
packetdrill: add test of tcp window clamp socket option
Browse files Browse the repository at this point in the history
Adds a test of TCP_WINDOW_CLAMP, including lowering, raising, and
lowering again the clamp while the connection is in progress,
including a test that ensures brief lowering before raising does
not have an unexpected consequence.

Requires a patch to tcp_set_window_clamp discussed as "tcp: enable mid
stream window clamp".

Signed-off-by: Neil Spring <[email protected]>
  • Loading branch information
nspring committed Aug 25, 2021
1 parent 827ea9d commit 21ed09d
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
1 change: 1 addition & 0 deletions gtests/net/packetdrill/symbols_linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ struct int_symbol platform_symbols_table[] = {
{ TCP_SYNCNT, "TCP_SYNCNT" },
{ TCP_LINGER2, "TCP_LINGER2" },
{ TCP_DEFER_ACCEPT, "TCP_DEFER_ACCEPT" },
{ TCP_WINDOW_CLAMP, "TCP_WINDOW_CLAMP" },
{ TCP_INFO, "TCP_INFO" },
{ TCP_QUICKACK, "TCP_QUICKACK" },
{ TCP_CONGESTION, "TCP_CONGESTION" },
Expand Down
115 changes: 115 additions & 0 deletions gtests/net/tcp/window_clamp/clamp-window-takes-effect.pkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Test that setsockopt( TCP_WINDOW_CLAMP ) limits the receive window.

`../common/defaults.sh`

// Establish a connection.
0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0

+.1 < S 0:0(0) win 32792 <mss 1000,sackOK,nop,nop,nop,wscale 8>
+0 > S. 0:0(0) ack 1 win 65535 <mss 1460,nop,nop,sackOK,nop,wscale 8>
+.1 < . 1:1(0) ack 1 win 320
+0 accept(3, ..., ...) = 4

// Receive data to raise rcv_ssthresh, receive buffer.
+.01 < . 1:64000(63999) ack 1 win 320
+0 > . 1:1(0) ack 64000 win 756
+.01 < . 64000:128000(64000) ack 1 win 320
+0 > . 1:1(0) ack 128000 win 798

// Read to clear the receive buffer.
+.01 read(4, ..., 129000) = 127999

// 1. Check that lowering the window clamp is supported.
// Set window clamp: 128000 == (500 << 8)
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [128000], 4) = 0

// Receive additional data, let clamp take effect.
+.01 < . 128000:192000(64000) ack 1 win 320
+0 > . 1:1(0) ack 192000 win 548
+.01 < . 192000:256000(64000) ack 1 win 320
+0 > . 1:1(0) ack 256000 win 500

// Read to clear the receive buffer.
+.01 read(4, ..., 129000) = 128000

// 2. Check that raising the window clamp is supported.
// Raise window clamp: 256000 == (1000 << 8)
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [256000], 4) = 0

// Receive additional data, reply with new clamp.
+.01 < . 256000:320000(64000) ack 1 win 320
+0 > . 1:1(0) ack 320000 win 1000
+.01 < . 320000:384000(64000) ack 1 win 320
+0 > . 1:1(0) ack 384000 win 1000

// Read to clear the receive buffer.
+.01 read(4, ..., 129000) = 128000

// 3. Check that lowering after raising is supported.
// Set window clamp very low: 12800 == (50 << 8)
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [12800], 4) = 0

+.01 < . 384000:448000(64000) ack 1 win 320
+0 > . 1:1(0) ack 448000 win 750
+.01 < . 448000:512000(64000) ack 1 win 320
+0 > . 1:1(0) ack 512000 win 500

// Read to clear the receive buffer, will not raise the window.
+.01 read(4, ..., 129000) = 128000

+.01 < . 512000:576000(64000) ack 1 win 320
+0 > . 1:1(0) ack 576000 win 250
+.01 < . 576000:640000(64000) ack 1 win 320
+0 > . 1:1(0) ack 640000 win 50

// Read to clear the receive buffer, will not raise the window.
+.01 read(4, ..., 129000) = 128000

// Raise briefly and lower the clamp to ensure the last write takes effect.
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [1280000], 4) = 0
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [128000], 4) = 0

// Small data, just to check that the clamp was raised; the increase
// opens in proportion to the amount of data sent to avoid epic burst
+.01 < . 640000:641000(1000) ack 1 win 320
+0 > . 1:1(0) ack 641000 win 62
+.01 < . 641000:643000(2000) ack 1 win 320
+0 > . 1:1(0) ack 643000 win 78
+.01 < . 643000:646000(3000) ack 1 win 320
+0 > . 1:1(0) ack 646000 win 101
+.01 < . 646000:704000(58000) ack 1 win 320
+0 > . 1:1(0) ack 704000 win 500

// Read to clear the receive buffer, will not raise the window.
+.01 read(4, ..., 129000) = 64000

// Lower briefly and return the clamp to ensure that the last write
// takes effect and that the window doesn't decrease unnecessarily.
// (It still increases slowly based on the volume of data received.)
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [12800], 4) = 0
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [256000], 4) = 0

+.01 < . 704000:705000(1000) ack 1 win 320
+0 > . 1:1(0) ack 705000 win 512
+.01 < . 705000:707000(2000) ack 1 win 320
+0 > . 1:1(0) ack 707000 win 528

+.01 < . 707000:768000(61000) ack 1 win 320
+0 > . 1:1(0) ack 768000 win 1000

+.01 read(4, ..., 129000) = 64000

// Repeat the transient drop, but include a small packet in between.
// The advertised window should return to the high value quickly,
// since the receiver never committed to a tiny window.
+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [12800], 4) = 0
+.01 < . 768000:769000(1000) ack 1 win 320
+0 > . 1:1(0) ack 769000 win 997

+0 setsockopt(4, IPPROTO_TCP, TCP_WINDOW_CLAMP, [256000], 4) = 0
+.01 < . 769000:770000(1000) ack 1 win 320
+0 > . 1:1(0) ack 770000 win 1000

0 comments on commit 21ed09d

Please sign in to comment.