Skip to content

MPJ: Fallback to TCP if the client receives a 4th ACK without DSS options from the server #91

@matttbe

Description

@matttbe

In packetdrill tests, there was a mistake: the (forged) 4th ACK after a MP_JOIN didn't contain MPTCP

// MP CAPABLE
+0.0 > addr[caddr0] > addr[saddr0] S 0:0(0) <mss 1460,sackOK,TS val 4074410674 ecr 0,nop,wscale 8,mpcapable v1 flags[flag_h] nokey>
+0.0 < S. 0:0(0) ack 1 win 65535 <mss 1460,sackOK,TS val 4074410674 ecr 4074410674,nop,wscale 8,mpcapable v1 flags[flag_h] key[skey=2]>
+0.0 > . 1:1(0) ack 1 <nop,nop,TS val 4074410674 ecr 4074410674,mpcapable v1 flags[flag_h] key[ckey,skey]>

(...)

// Some data
+0.0 > P. 1:3(2) ack 1 <nop,nop,TS val 4074418292 ecr 4074410674,mpcapable v1 flags[flag_h] key[ckey,skey] mpcdatalen 2,nop,nop>
+0.0 < . 1:1(0) ack 3 win 256 <nop,nop,TS val 4074418293 ecr 4074418292,add_address addr[saddr1] hmac=auto,dss dack8=3 dll=0 nocs>

// MP_JOIN
+0.0 > > addr[saddr1] S 0:0(0) <mss 1460,sackOK,TS val 448955294 ecr 0,nop,wscale 8,mp_join_syn address_id=0 token=sha256_32(skey)>
+0.0 < S. 0:0(0) ack 1 win 65535 <mss 1460,sackOK,TS val 448955294 ecr 448955294,nop,wscale 8,mp_join_syn_ack address_id=1 sender_hmac=auto>
+0.0 > . 1:1(0) ack 1 <nop,nop,TS val 448955294 ecr 448955294,mp_join_ack sender_hmac=auto>

// ==> the mistake: no DSS here
+0.0 < . 1:1(0) ack 1 win 256 <nop,nop,TS val 448955294 ecr 448955294>

// Close both
+1.0 close(3) = 0
+0.0 > addr[caddr0] > addr[saddr0] F. 3:3(0) ack 1 <nop,nop,TS val 4074418292 ecr 4074418293,dss dack4=1 dsn8=3 ssn=0 dll=1 nocs fin,nop,nop>
+0.0 > > addr[saddr1] F. 1:1(0) ack 1 <nop,nop,TS val 448955294 ecr 448955294>

But as a consequence, the kernel seems doing a fallback which is not normal:

14:42:31.631240 tun0  In  IP 192.0.2.1.8080 > 192.168.137.193.34288: Flags [S.], seq 0, ack 3672433911, win 65535, options [mss 1460,sackOK,TS val 4074410674 ecr 23677036,nop,wscale 8,mptcp capable v1 {0x200000000000000}], length 0
14:42:31.631322 tun0  Out IP 192.168.137.193.34288 > 192.0.2.1.8080: Flags [.], ack 1, win 256, options [nop,nop,TS val 23677036 ecr 4074410674,mptcp capable v1 {0xdf1df5d4974e06e5,0x200000000000000}], length 0
14:42:32.832132 tun0  Out IP 192.168.137.193.34288 > 192.0.2.1.8080: Flags [P.], seq 1:3, ack 1, win 256, options [nop,nop,TS val 23678237 ecr 4074410674,mptcp capable v1 {0xdf1df5d4974e06e5,0x200000000000000},nop,nop], length 2: HTTP
14:42:32.832394 tun0  In  IP 192.0.2.1.8080 > 192.168.137.193.34288: Flags [.], ack 3, win 256, options [nop,nop,TS val 4074418293 ecr 23678237,mptcp add-addr id 1 192.0.2.2 hmac 0xed69d21193ad1ffb,mptcp dss ack 6714959902413302923], length 0
14:42:32.832613 tun0  Out IP 192.168.137.193.33201 > 192.0.2.2.8080: Flags [S], seq 45472746, win 65535, options [mss 1460,sackOK,TS val 881046498 ecr 0,nop,wscale 8,mptcp join id 0 token 0xd86e8112 nonce 0xdf44aac9], length 0
14:42:32.832711 tun0  In  IP 192.0.2.2.8080 > 192.168.137.193.33201: Flags [S.], seq 0, ack 45472747, win 65535, options [mss 1460,sackOK,TS val 448955294 ecr 881046498,nop,wscale 8,mptcp join id 1 hmac 0xfd53c3ffce16983 nonce 0x42ff47fd], length 0
14:42:32.832731 tun0  Out IP 192.168.137.193.33201 > 192.0.2.2.8080: Flags [.], ack 1, win 256, options [nop,nop,TS val 881046498 ecr 448955294,mptcp join hmac 0xa631cf6be608b59af2710e9c2e00de3cd5622189], length 0
14:42:32.832778 tun0  In  IP 192.0.2.2.8080 > 192.168.137.193.33201: Flags [.], ack 1, win 256, options [nop,nop,TS val 448955294 ecr 881046498], length 0
14:42:33.833079 ?     Out IP 192.168.137.193.34288 > 192.0.2.1.8080: Flags [F.], seq 3, ack 1, win 256, options [nop,nop,TS val 23679238 ecr 4074418293], length 0
14:42:33.833105 ?     Out IP 192.168.137.193.33201 > 192.0.2.2.8080: Flags [F.], seq 1, ack 1, win 256, options [nop,nop,TS val 881047498 ecr 448955294], length 0

The error:

mp_join_client.pkt:28: error handling packet: live packet field ipv4_total_length: expected: 76 (0x4c) vs actual: 52 (0x34)
script packet:  2.312435 F. 3:3(0) ack 1 <nop,nop,TS val 4074418292 ecr 4074418293,dss dack4 16777216 dsn8 216172782113783808 ssn 0 dll 256 no_checksum flags: MmAF,nop,nop>
actual packet:  2.312364 F. 3:3(0) ack 1 win 256 <nop,nop,TS val 4074412876 ecr 4074418293>

So at the end, the packetdrill test is useful because it tests this corner case where we should not fallback but a reset should be sent.

This test needs to be kept like that somewhere (once the bug will be fixed).

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions