Skip to content

Commit

Permalink
Merge pull request #45 from fw-strlen/mptcp_reset_option
Browse files Browse the repository at this point in the history
Mptcp reset option
  • Loading branch information
dcaratti authored Feb 25, 2021
2 parents 2421fe0 + f24a513 commit e762c97
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 7 deletions.
2 changes: 1 addition & 1 deletion gtests/net/mptcp/fastclose/receive_fastclose_with_ack.pkt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// send another ack fastclose, this time with matching key
+0.1 < . 2001:2001(0) win 450 <mp_fastclose>
// expect peer to reset all subflows now:
+0.01 > R. 1:1(0) ack 2001
+0.01 > R. 1:1(0) ack 2001 <mp_reset 0>

// more data, expect a reset and win0 (no socket anymore)
+1.0 < P. 2001:3001(1000) ack 1 win 450 <nop, nop, dss dack8=1 dsn8=2001 ssn=2001 dll=1000 nocs>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
+0.1 < . 1002:1002(0) win 450 <mp_fastclose>

// expect peer to reset both subflows now:
+0.0 > addr[saddr0] > addr[caddr0] R. 1:1(0) ack 1001
+0.0 > addr[saddr1] > addr[caddr1] R. 1:1(0) ack 1002
+0.0 > addr[saddr0] > addr[caddr0] R. 1:1(0) ack 1001 <mp_reset 0>
+0.0 > addr[saddr1] > addr[caddr1] R. 1:1(0) ack 1002 <mp_reset 0>

+0 read(4, ..., 2002) = 2001
+0 close(4) = 0
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
+0.1 < R. 1002:1002(0) win 450 <mp_fastclose>

// expect peer to reset the original flow now:
+0.0 > addr[saddr0] > addr[caddr0] R. 1:1(0) ack 1001
+0.0 > addr[saddr0] > addr[caddr0] R. 1:1(0) ack 1001 <mp_reset 0>

+0 read(4, ..., 2002) = 2001
+0 close(4) = 0
4 changes: 2 additions & 2 deletions gtests/net/mptcp/mp_join/mp_join_server_bad_token.pkt
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0

+0.0 < S 0:0(0) win 65535 <mss 1460, mp_join_syn address_id=0 token=1>
+0.0 > R. 0:0(0) ack 1
+0.0 < S 0:0(0) win 65535 <mss 1460, mp_join_syn address_id=0 token=1>
+0.0 > R. 0:0(0) ack 1 <mp_reset 1>
56 changes: 56 additions & 0 deletions gtests/net/mptcp/mp_reset/mp_reset_multi_v4.pkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// connection initiated by packetdrill
--tolerance_usecs=100000
`../common/defaults.sh`

+0 `../common/server.sh`

+0 socket(..., SOCK_STREAM, IPPROTO_MPTCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0

+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0.0 < addr[caddr0] > addr[saddr0] S 0:0(0) win 65535 <mss 1460, nop, wscale 7, mpcapable v1 flags[flag_h] nokey>
+0.0 > S. 0:0(0) ack 1 <mss 1460, nop, wscale 8, mpcapable v1 flags[flag_h] key[skey]>
+0.0 < . 1:1(0) ack 1 win 256 <mpcapable v1 flags[flag_h] key[ckey=2, skey]>
+0 accept(3, ..., ...) = 4

// add_addr
+0.0 > . 1:1(0) ack 1 <add_address addr[saddr1] hmac=auto, dss dack4=1 dll=0 nocs>
// +0.0 < . 1:1(0) ack 1 win 256 <add_address addr[saddr1], dss dack8=1 dll=0 nocs>

+0.2 < P. 1:1001(1000) ack 1 win 450 <nop, nop, dss dack8=1 dsn8=1 ssn=1 dll=1000 nocs>
+0.0 > . 1:1(0) ack 1001 <dss dack8=1001 nocs>

+0.2 < P. 1:1(0) ack 1 win 450 <mpcapable v1 flags[flag_h] key[skey, ckey]>
+0.0 > . 1:1(0) ack 1001 <dss dack8=1001 nocs>

// add another subflow.
+0.5 < addr[caddr1] > addr[saddr1] S 0:0(0) win 65535 <mss 1460, nop, wscale 7, mp_join_syn address_id=2 token=sha256_32(skey)>
+0.0 > S. 0:0(0) ack 1 <mss 1460, nop, wscale 8, mp_join_syn_ack address_id=0 sender_hmac=auto>
+0.0 < . 1:1(0) ack 1 win 256 <mp_join_ack sender_hmac=auto>
+0.0 > . 1:1(0) ack 1 <dss dack8=1001 nocs>

// send more data.
+0.2 < P. 1:1002(1001) ack 1 win 450 <nop, nop, dss dack8=1 dsn8=1001 ssn=1 dll=1001 nocs>
+0 > . 1:1(0) ack 1002 <dss dack8=2002 dll=0 nocs>

// send rst option. RST is not set, so it should have no effect.
+0 < . 1002:1002(0) win 256 <mp_reset 1>

// again, this time with RST but out of window.
+0.1 < R. 3001:3001(0) win 450 <mp_reset 1>
// ... expect challenge ack.
+0 > . 1:1(0) ack 1002 <dss dack8=2002 dll=0 nocs>

// again. RST the 2nd subflow.
+0.1 < R. 1002:1002(0) win 450 <mp_reset 1>

// This should result in a RST, since subflow was closed.
+0.2 < P. 1:1002(1001) ack 1 win 450 <nop, nop, dss dack8=1 dsn8=1001 ssn=1 dll=1001 nocs>
+0 > R 1:1(0)

// More data.
+0.2 < addr[caddr0] > addr[saddr0] P. 1001:2003(1002) ack 1 win 450 <nop, nop, dss dack8=1 dsn8=2002 ssn=1001 dll=1002 nocs>

+1 read(4, ..., 3004) = 3003
+0 close(4) = 0
32 changes: 32 additions & 0 deletions gtests/net/mptcp/mp_reset/mp_reset_single.pkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// connection initiated by packetdrill
--tolerance_usecs=100000
`../common/defaults.sh`

+0 socket(..., SOCK_STREAM, IPPROTO_MPTCP) = 3
+0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0

+0 bind(3, ..., ...) = 0
+0 listen(3, 1) = 0
+0 < S 0:0(0) win 32792 <mss 1460, sackOK, nop, nop, nop, wscale 7, mpcapable v1 flags[flag_h] nokey>
+0 > S. 0:0(0) ack 1 <mss 1460, nop, nop, sackOK, nop, wscale 8, mpcapable v1 flags[flag_h] key[skey]>
+0.01 < . 1:1(0) ack 1 win 256 <mpcapable v1 flags[flag_h] key[ckey=2, skey]>
+0 accept(3, ..., ...) = 4

// ignore, out of window
+0 < R. 1002:1002(0) win 256
+0 > . 1:1(0) ack 1 <dss dack4=1>

// ignore, TCP RST flag not set
+0 < . 1:1(0) win 256 <mp_reset 1>

+0.0 write(4, ..., 1000) = 1000
+0 > P. 1:1001(1000) ack 1 <dss dack4=1 dsn8=1 dll=1000 nocs, nop, nop>
+0 < P. 1:1(0) ack 1001 win 256 <dss dack4=1001 dsn8=1 dll=0 nocs, nop, nop>

// should work.
+0 < R. 1:1(0) win 256 <mp_reset 1>

// probe. SF should be closed...
+0 < . 1:1(0) win 256
// .. and a reset should be sent.
+0 > R 0:0(0)
32 changes: 32 additions & 0 deletions gtests/net/mptcp/mp_reset/mp_reset_single_tcp.pkt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// connection initiated by packetdrill
--tolerance_usecs=100000
`../common/defaults.sh`

+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
+0 < S 0:0(0) win 32792 <mss 1460, sackOK, nop, nop, nop, wscale 7, mpcapable v1 flags[flag_h] nokey>
+0 > S. 0:0(0) ack 1 <mss 1460, nop, nop, sackOK, nop, wscale 8>
+0.01 < . 1:1(0) ack 1 win 256
+0 accept(3, ..., ...) = 4

// ignore, out of window
+0 < R. 1002:1002(0) win 256
+0 > . 1:1(0) ack 1

// ignore, TCP RST flag not set
+0 < . 1:1(0) win 256 <mp_reset 1>

+0.0 write(4, ..., 1000) = 1000
+0 > P. 1:1001(1000) ack 1
+0 < P. 1:1(0) ack 1001 win 256

// should work.
+0 < R. 1:1(0) win 256 <mp_reset 1>

// probe.
+0 < . 1:1(0) win 256
// .. and a reset should be sent.
+0 > R 0:0(0)
2 changes: 2 additions & 0 deletions gtests/net/packetdrill/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ flag_e return FLAG_E;
flag_f return FLAG_F;
flag_g return FLAG_G;
flag_h return FLAG_H;
flag_t return FLAG_T;
no_flags return NO_FLAGS;
nokey return NOKEY;
mp_join_syn return MP_JOIN_SYN;
Expand All @@ -261,6 +262,7 @@ list_id return LIST_ID;
mp_prio return MP_PRIO;
mp_fail return MP_FAIL;
mp_fastclose return MP_FASTCLOSE;
mp_reset return MP_TCPRST;
rand return RAND;
sender_hmac return SENDER_HMAC;
hmac return ADD_ADDR_HMAC;
Expand Down
5 changes: 5 additions & 0 deletions gtests/net/packetdrill/mptcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#define MP_PRIO_SUBTYPE 5 // TODO, Change Subflow Priority
#define MP_FAIL_SUBTYPE 6 // TODO
#define MP_FASTCLOSE_SUBTYPE 7 // TODO => enhancement
#define MP_TCPRST_SUBTYPE 8


/* MPTCP options subtypes length */
Expand Down Expand Up @@ -86,6 +87,8 @@
#define TCPOLEN_MP_FAIL 12
// MP_FASTCLOSE
#define TCPOLEN_MP_FASTCLOSE 12
// MP_RESET
#define TCPOLEN_MP_TCPRST 4
// MPTCP Flags
#define MP_CAPABLE_FLAGS 1
#define MP_CAPABLE_FLAGS_CS 129 //With checksum
Expand All @@ -107,6 +110,8 @@

#define MPTCP_VER_DEFAULT MPTCPV1

#define MP_TCPRST_FLAG_T 1

//SUBFLOW states
#define ESTABLISHED 1 //for Subflow state
#define PRE_ESTABLISHED 0 //Subflow state
Expand Down
34 changes: 33 additions & 1 deletion gtests/net/packetdrill/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ struct tcp_option *dss_do_dsn_dack( int dack_type, int dack_val,
%token <reserved> U32 U64 PTR
%token <reserved> ACK ECR EOL MSS NOP SACK SACKOK TIMESTAMP VAL WIN WSCALE
%token <reserved> URG MD5 FAST_OPEN FAST_OPEN_EXP
%token <reserved> MP_CAPABLE MP_CAPABLE_NO_CS MP_FASTCLOSE FLAG_A FLAG_B FLAG_C FLAG_D FLAG_E FLAG_F FLAG_G FLAG_H NO_FLAGS
%token <reserved> MP_CAPABLE MP_CAPABLE_NO_CS MP_FASTCLOSE FLAG_A FLAG_B FLAG_C FLAG_D FLAG_E FLAG_F FLAG_G FLAG_H FLAG_T NO_FLAGS
%token <reserved> MPCAPABLE V0 V1 NOKEY MPCDATALEN
%token <reserved> MP_JOIN_SYN MP_JOIN_ACK MP_JOIN_SYN_ACK
%token <reserved> DSS DACK4 DSN4 DACK8 DSN8 FIN SSN DLL NOCS CKSUM ADDR ADDRESS_ID BACKUP TOKEN AUTO RAND
Expand All @@ -854,6 +854,7 @@ struct tcp_option *dss_do_dsn_dack( int dack_type, int dack_val,
%token <reserved> ADD_ADDRESS ADD_ADDR_IPV4 ADD_ADDR_IPV6 PORT MP_FAIL
%token <reserved> REMOVE_ADDRESS ADDRESSES_ID LIST_ID
%token <reserved> MP_PRIO
%token <reserved> MP_TCPRST
%token <reserved> TOS FLAGS FLOWLABEL
%token <reserved> ECT0 ECT1 CE ECT01 NO_ECN
%token <reserved> IPV4 IPV6 ICMP UDP RAW GRE MTU ID
Expand Down Expand Up @@ -883,6 +884,8 @@ struct tcp_option *dss_do_dsn_dack( int dack_type, int dack_val,
%type <integer> opt_mpls_stack_bottom
%type <integer> opt_icmp_mtu fin ssn dll dss_checksum
%type <integer> mp_capable_no_cs is_backup address_id rand port
%type <integer> mptcprst_reason mptcprst_flags_list mptcprst_flags mptcprst_flag

%type <integer> flag_a flag_b flag_c flag_d flag_e flag_f flag_g flag_h no_flags
%type <integer> mpc_ver mpc_flags_list mpc_flags mpc_flag mpc_keys mpc_data
%type <integer> gre_flags_list gre_flags gre_flag
Expand Down Expand Up @@ -2048,6 +2051,27 @@ mpc_data
}
;

mptcprst_reason
: INTEGER {
if(!is_valid_u8($1))
semantic_error("mp_reset: reason code should be a 8 bits unsigned integer.");
$$ = $1;
}

mptcprst_flags_list
: FLAGS '[' mptcprst_flags ']' { $$ = $3; }
| { $$ = 0; }
;

mptcprst_flags
: mptcprst_flag { $$ = $1; }
;

mptcprst_flag
: NO_FLAGS { $$ = 0; }
| FLAG_T { $$ = MP_TCPRST_FLAG_T; }
;

tcp_option
: NOP { $$ = tcp_option_new(TCPOPT_NOP, 1); }
| EOL { $$ = tcp_option_new(TCPOPT_EOL, 1); }
Expand Down Expand Up @@ -2302,6 +2326,14 @@ tcp_option
$$->data.mp_prio.flags = $2;
$$->data.mp_capable.subtype = MP_PRIO_SUBTYPE;
}
| MP_TCPRST mptcprst_reason mptcprst_flags_list {
$$ = tcp_option_new(TCPOPT_MPTCP, TCPOLEN_MP_TCPRST);
$$->data.mp_tcprst.reason = $2;
$$->data.mp_tcprst.flag_transient = ($3 & MP_TCPRST_FLAG_T);
$$->data.mp_tcprst.reserved_bits = ZERO_RESERVED;

$$->data.mp_capable.subtype = MP_TCPRST_SUBTYPE;
}
| MP_FAIL dsn {
if($2.type == 4)
semantic_error("Value assigned to a MP_FAIL option is not a valid unsigned 64 bits number.");
Expand Down
8 changes: 8 additions & 0 deletions gtests/net/packetdrill/run_packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,14 @@ bool same_mptcp_opt(struct tcp_option *opt_a, struct tcp_option *opt_b, struct p
if(opt_a->data.mp_fastclose.receiver_key != opt_b->data.mp_fastclose.receiver_key)
return false;
break;
case MP_TCPRST_SUBTYPE:
if(opt_a->data.mp_tcprst.reason != opt_b->data.mp_tcprst.reason)
return false;
if(opt_a->data.mp_tcprst.flag_transient != opt_b->data.mp_tcprst.flag_transient)
return false;
if(opt_a->data.mp_tcprst.reserved_bits != opt_b->data.mp_tcprst.reserved_bits)
return false;
break;
default:
return false;
}
Expand Down
19 changes: 19 additions & 0 deletions gtests/net/packetdrill/tcp_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,25 @@ struct tcp_option {
+---------------------------------------------------------------+
*/
} __packed mp_fastclose;
struct {
#if __BYTE_ORDER == __LITTLE_ENDIAN
__u8 flag_transient:1, reserved_bits:3;
__u8 subtype:4;
__u8 reason;
#elif __BYTE_ORDER == __BIG_ENDIAN
__u8 subtype:4;
__u8 reserved_bits:3, flag_transient:1;
__u8 reason;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
/*
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+---------------+---------------+-------+-----------------------+
| Kind | Length |Subtype|U V W T| Reason |
+---------------+---------------+-------+-----------------------+
*/
} __packed mp_tcprst;
/*******END MPTCP options*********/
} data;
} __packed;
Expand Down
5 changes: 5 additions & 0 deletions gtests/net/packetdrill/tcp_options_to_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,11 @@ int tcp_options_to_string(struct packet *packet,
fprintf(s, "mp_fastclose receiver key: %lu",
(unsigned long)option->data.mp_fastclose.receiver_key);
break;
case MP_TCPRST_SUBTYPE:
fprintf(s, "mp_reset %u", option->data.mp_tcprst.reason);
if (option->data.mp_tcprst.flag_transient)
fprintf(s, "flags [ flag_t ]");
break;
default:
fprintf(s, "unknown MPTCP subtype");
break;
Expand Down

0 comments on commit e762c97

Please sign in to comment.