diff options
author | Ole Troan <ot@cisco.com> | 2022-03-17 11:58:38 +0100 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2022-04-21 10:35:58 +0000 |
commit | 5297447bd64ab253ab3ab3e144605dd39f995f12 (patch) | |
tree | d351435893287349ebb9ca5736a627ff53cc28f9 /test | |
parent | e0c875551fa0cd49131671be0f521801e06764f8 (diff) |
nat: tweak rfc7857 tcp connection tracking
The RFC7857 state machine introduced in 56c492a is a trade-off.
It tries to retain sessions as much as possible and also offers
some protection against spurious RST by re-establishing sessions if data
is received after the RST. From experience in the wild, this algorithm is
a little too liberal, as it leaves too many spurious established sessions
in the session table.
E.g. a oberserved pattern is:
client server
<- FIN, ACK
ACK ->
ACK ->
RST, ACK ->
With the current state machine this would leave the session in established state.
These proposed changes do:
- require 3-way handshake to establish session.
(current requires only to see SYNs from both sides)
- RST will move session to transitory without recovery if data is sent after
- Only a single FIN is needed to move to transitory
Fixes: 56c492aa0502751de2dd9d890096a82c5f04776d
Type: fix
Signed-off-by: Ole Troan <ot@cisco.com>
Change-Id: I92e593e00b2efe48d04997642d85bd59e0eaa2ea
Signed-off-by: Ole Troan <ot@cisco.com>
Diffstat (limited to 'test')
-rw-r--r-- | test/test_nat44_ed.py | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/test/test_nat44_ed.py b/test/test_nat44_ed.py index f172dabe98b..21eebb22de4 100644 --- a/test/test_nat44_ed.py +++ b/test/test_nat44_ed.py @@ -2609,8 +2609,8 @@ class TestNAT44EDMW(TestNAT44ED): self.tcp_external_port) # Wait at least the transitory time, the session is in established - # state anyway. RST followed by a data packet should keep it - # established. + # state anyway. RST followed by a data packet should move it to + # transitory state. self.virtual_sleep(6) p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / @@ -2624,15 +2624,6 @@ class TestNAT44EDMW(TestNAT44ED): flags="P")) self.send_and_expect(self.pg0, p, self.pg1) - # State is established, session should be still open after 6 seconds - self.virtual_sleep(6) - - p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / - IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / - TCP(sport=self.tcp_port_in, dport=self.tcp_external_port, - flags="R")) - self.send_and_expect(self.pg0, p, self.pg1) - # State is transitory, session should be closed after 6 seconds self.virtual_sleep(6) @@ -3135,9 +3126,16 @@ class TestNAT44EDMW(TestNAT44ED): # SYN out2in p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / IP(src=self.pg1.remote_ip4, dst=self.nat_addr) / - TCP(sport=self.tcp_external_port, dport=self.tcp_port_out)) + TCP(sport=self.tcp_external_port, dport=self.tcp_port_out, + flags='SA')) self.send_and_expect(self.pg1, p, self.pg0) + p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / + IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / + TCP(sport=self.tcp_port_in, dport=self.tcp_external_port, + flags="A")) + self.send_and_expect(self.pg0, p, self.pg1) + # FIN in2out p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / @@ -3152,17 +3150,8 @@ class TestNAT44EDMW(TestNAT44ED): flags="F")) self.send_and_expect(self.pg1, p, self.pg0) - # SYN in2out - p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) / - IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / - TCP(sport=self.tcp_port_in, dport=self.tcp_external_port)) - self.send_and_expect(self.pg0, p, self.pg1) - - # SYN out2in - p = (Ether(dst=self.pg1.local_mac, src=self.pg1.remote_mac) / - IP(src=self.pg1.remote_ip4, dst=self.nat_addr) / - TCP(sport=self.tcp_external_port, dport=self.tcp_port_out)) - self.send_and_expect(self.pg1, p, self.pg0) + self.init_tcp_session(self.pg0, self.pg1, self.tcp_port_in, + self.tcp_external_port) # 2 records should be produced - first one del & add capture = self.pg3.get_capture(2) @@ -3746,9 +3735,16 @@ class TestNAT44EDMW(TestNAT44ED): p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) / TCP(sport=in_port, dport=ext_port, - flags="S", seq=101, ack=301)) + flags="SA", seq=101, ack=301)) self.send_and_expect(self.pg0, p, self.pg1) + # send ACK packet out -> in + p = (Ether(src=self.pg1.remote_mac, dst=self.pg1.local_mac) / + IP(src=self.pg1.remote_ip4, dst=self.nat_addr) / + TCP(sport=ext_port, dport=out_port, + flags="A", seq=300, ack=101)) + self.send_and_expect(self.pg1, p, self.pg0) + self.virtual_sleep(3) # send ACK packet in -> out - should be forwarded and session alive p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) / |