Page MenuHomeFreeBSD

[tcp] Fix ECN on finalizing sessions.
ClosedPublic

Authored by rscheff on Apr 6 2021, 9:56 PM.
Tags
None
Referenced Files
Unknown Object (File)
Thu, Oct 24, 2:51 AM
Unknown Object (File)
Oct 1 2024, 11:27 AM
Unknown Object (File)
Sep 17 2024, 7:19 AM
Unknown Object (File)
Sep 10 2024, 7:52 PM
Unknown Object (File)
Sep 8 2024, 8:17 PM
Unknown Object (File)
Sep 8 2024, 1:31 PM
Unknown Object (File)
Sep 4 2024, 11:21 AM
Unknown Object (File)
Sep 2 2024, 10:52 AM
Subscribers

Details

Summary

A subtle oversight would leak information, if a
local session is in the process of being shut
down, as that TCP state transition would be
observable well ahead of the actual transmission
of the FIN.

This would also subtly change new data packet
markings and thereby possibly the treatment of
those by the network (loss rather than marking).

This was found while investigating PR 254725, but
is unrelated to the issue there.

MFC after: 3 days

Test Plan

'''

// Create a listening TCP socket.
0.50 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
+0.005 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
+0.005 setsockopt(3, SOL_SOCKET, SO_DEBUG, [1], 4) = 0
+0.005 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [1048576], 4) = 0
+0.005 bind(3, ..., ...) = 0
+0.005 listen(3, 1) = 0

// Establish a TCP connection with ECN to explicitly track CWR

+0.035 < SEW 0:0(0) win 65535 <mss 1012, sackOK, wscale 10, nop, TS val 1 ecr 0>
+0.000 > SE. 0:0(0) ack 1 win 65535 <mss 1460,nop,wscale 6,sackOK,TS val -1 ecr 1>
+0.000 < . 1:1(0) ack 1 win 65535 <nop,nop,TS val 2 ecr -1>
+0.000 accept(3, ..., ...) = 4
+0 %{
print("\t\tcwnd\tssthresh\n")
print("initial window:\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh))
if (tcpi_snd_cwnd != 10000):

print("Error - Initial Window after 3WHS is not equal 10 MSS")

assert tcpi_snd_cwnd == 10000
}%

// First, send IW plus 1 segment, drop 2nd packet to pull ssthresh low
0.700 write(4, ..., 15000) = 15000

+0 > . 1:1001(1000) ack 1 <nop,nop,TS val -2 ecr 2>
+0 %{ print("window at data:\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh))
if (tcpi_snd_cwnd != 10000):

print("Error - Initial Window not equal to 10 MSS!")

assert tcpi_snd_cwnd == 10000
}%
+0 > . 1001:2001(1000) ack 1 <nop,nop,TS val -3 ecr 2>
+0 > . 2001:3001(1000) ack 1 <nop,nop,TS val -4 ecr 2>
+0 > . 3001:4001(1000) ack 1 <nop,nop,TS val -5 ecr 2>
+0 > . 4001:5001(1000) ack 1 <nop,nop,TS val -6 ecr 2>
+0 > . 5001:6001(1000) ack 1 <nop,nop,TS val -7 ecr 2>
+0 > . 6001:7001(1000) ack 1 <nop,nop,TS val -8 ecr 2>
+0 > . 7001:8001(1000) ack 1 <nop,nop,TS val -9 ecr 2>
+0 > . 8001:9001(1000) ack 1 <nop,nop,TS val -10 ecr 2>
+0 > . 9001:10001(1000) ack 1 <nop,nop,TS val -11 ecr 2>
// 1st RTO after 230 msec
+0.22~+0.24 > . 1:1001(1000) ack 1 <nop,nop,TS val -12 ecr 2>
+0 %{ print("after RTO:\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh))
if (tcpi_snd_cwnd > 1000):

print("Error - Window after RTO larger than 1 MSS!")

assert tcpi_snd_cwnd == 1000
}%

Shutdown the session for the FIN
+0 shutdown(4, SHUT_WR) = 0
+0 %{print("tcp state")}%
Ack the initial packet
+0 < . 1:1(0) ack 1001 win 65535 <nop,nop,TS val 3 ecr -2>
+0 %{ print("after ACK:\t{}\t{}".format(tcpi_snd_cwnd, tcpi_snd_ssthresh))
if (tcpi_snd_cwnd < 11000):

print("Error - Window after ACK smaller than 11 MSS!")

assert tcpi_snd_cwnd >= 11000
}%
+0.0 > . 10001:11001(1000) ack 1 <nop,nop,TS val -13 ecr 3> CWR missing with shutdown
+0.0 > W. 10001:11001(1000) ack 1 <nop,nop,TS val -13 ecr 3>
+0.0 > . 11001:12001(1000) ack 1 <nop,nop,TS val -14 ecr 3>

'''

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable