From c5218b4d93e867797835bd69ed57c61ded2c36d7 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Fri, 30 Oct 2015 16:18:13 +0100 Subject: [PATCH] add support for sctp_adaptation_indication_parameter in init chunk --- gtests/net/packetdrill/lexer.l | 2 ++ gtests/net/packetdrill/parser.y | 11 +++++++- gtests/net/packetdrill/sctp.h | 10 ++++++- gtests/net/packetdrill/sctp_chunk_to_string.c | 25 +++++++++++++++++- gtests/net/packetdrill/sctp_packet.c | 24 +++++++++++++++++ gtests/net/packetdrill/sctp_packet.h | 3 +++ .../notifications/sctp_adaptation_event.pkt | 26 ++++++++++++++----- 7 files changed, 91 insertions(+), 10 deletions(-) diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 4cadbae7..8aa42a8e 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -385,6 +385,7 @@ fsn return FSN; cum_tsn return CUM_TSN; gaps return GAPS; dups return DUPS; +adaptation_code_point return ADAPTATION_CODE_POINT; PARAMETER return PARAMETER; HEARTBEAT_INFORMATION return HEARTBEAT_INFORMATION; IPV4_ADDRESS return IPV4_ADDRESS; @@ -394,6 +395,7 @@ UNRECOGNIZED_PARAMETER return UNRECOGNIZED_PARAMETER; COOKIE_PRESERVATIVE return COOKIE_PRESERVATIVE; HOSTNAME_ADDRESS return HOSTNAME_ADDRESS; SUPPORTED_ADDRESS_TYPES return SUPPORTED_ADDRESS_TYPES; +ADAPTATION_INDICATION return ADAPTATION_INDICATION; ECN_CAPABLE return ECN_CAPABLE; SUPPORTED_EXTENSIONS return SUPPORTED_EXTENSIONS; addr return ADDR; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index f2d3fc5d..42e6c192 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -522,7 +522,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> PARAMETER HEARTBEAT_INFORMATION IPV4_ADDRESS IPV6_ADDRESS %token <reserved> STATE_COOKIE UNRECOGNIZED_PARAMETER COOKIE_PRESERVATIVE %token <reserved> HOSTNAME_ADDRESS SUPPORTED_ADDRESS_TYPES ECN_CAPABLE -%token <reserved> SUPPORTED_EXTENSIONS +%token <reserved> SUPPORTED_EXTENSIONS ADAPTATION_CODE_POINT ADAPTATION_INDICATION %token <reserved> ADDR INCR TYPES PARAMS %token <reserved> IPV4_TYPE IPV6_TYPE HOSTNAME_TYPE %token <reserved> CAUSE @@ -661,6 +661,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <parameter_list_item> sctp_supported_address_types_parameter_spec %type <parameter_list_item> sctp_ecn_capable_parameter_spec %type <parameter_list_item> sctp_supported_extensions_parameter_spec +%type <parameter_list_item> sctp_adaptation_indication_parameter_spec %type <parameter_list_item> sctp_pad_parameter_spec %type <cause_list> opt_cause_list_spec sctp_cause_list_spec %type <cause_list_item> sctp_cause_spec @@ -1599,6 +1600,7 @@ sctp_parameter_spec | sctp_supported_address_types_parameter_spec { $$ = $1; } | sctp_ecn_capable_parameter_spec { $$ = $1; } | sctp_supported_extensions_parameter_spec { $$ = $1; } +| sctp_adaptation_indication_parameter_spec { $$ = $1; } | sctp_pad_parameter_spec { $$ = $1; } ; @@ -1767,6 +1769,13 @@ chunk_types_list } ; +sctp_adaptation_indication_parameter_spec +: ADAPTATION_INDICATION '[' ADAPTATION_CODE_POINT '=' INTEGER ']' { + if (!is_valid_u32($5)) + semantic_error("adaptation_indication_code ot of range"); + $$ = sctp_adaptation_indication_parameter_new($5); +}; + sctp_supported_extensions_parameter_spec : SUPPORTED_EXTENSIONS '[' TYPES '=' ELLIPSIS ']' { $$ = sctp_supported_extensions_parameter_new(NULL); diff --git a/gtests/net/packetdrill/sctp.h b/gtests/net/packetdrill/sctp.h index dc9d2051..0c737cf6 100644 --- a/gtests/net/packetdrill/sctp.h +++ b/gtests/net/packetdrill/sctp.h @@ -244,8 +244,10 @@ struct sctp_pad_chunk { #define SCTP_ECN_CAPABLE_PARAMETER_TYPE 0x8000 #define SCTP_SUPPORTED_EXTENSIONS_PARAMETER_TYPE 0x8008 #define SCTP_PAD_PARAMETER_TYPE 0x8005 +#define SCTP_Set_Primary_Address 0xc004 +#define SCTP_ADAPTATION_INDICATION_PARAMETER_TYPE 0xc006 -#define MAX_SCTP_PARAMETER_BYTES 0xffff +#define MAX_SCTP_PARAMETER_BYTES 0xffff struct sctp_parameter { __be16 type; @@ -318,6 +320,12 @@ struct sctp_pad_parameter { __be16 padding_data[]; } __packed; +struct sctp_adaptation_indication_parameter { + __be16 type; + __be16 length; + __be32 adaptation_code_point; +} __packed; + #define SCTP_INVALID_STREAM_IDENTIFIER_CAUSE_CODE 0x0001 #define SCTP_MISSING_MANDATORY_PARAMETER_CAUSE_CODE 0x0002 #define SCTP_STALE_COOKIE_ERROR_CAUSE_CODE 0x0003 diff --git a/gtests/net/packetdrill/sctp_chunk_to_string.c b/gtests/net/packetdrill/sctp_chunk_to_string.c index 8dc2ca83..e7216bec 100644 --- a/gtests/net/packetdrill/sctp_chunk_to_string.c +++ b/gtests/net/packetdrill/sctp_chunk_to_string.c @@ -338,12 +338,31 @@ static int sctp_unknown_parameter_to_string( return STATUS_OK; } +static int sctp_adaptation_indication_parameter_to_string( + FILE *s, + struct sctp_adaptation_indication_parameter *parameter, + char **error) +{ + u16 length; + length = ntohs(parameter->length); + if (length < sizeof(struct sctp_parameter)) { + asprintf(error, "PARAMETER too short (type=0x%04x, length=%u)", + ntohs(parameter->type), length); + return STATUS_ERR; + } + fputs("ADAPTATION_INDICATION[", s); + fprintf(s, "type=0x%04x, ", ntohs(parameter->type)); + fprintf(s, "len=%hu, ", ntohs(parameter->length)); + fprintf(s, "val=%u", parameter->adaptation_code_point); + fputs("]", s); + return STATUS_OK; +} + static int sctp_parameter_to_string(FILE *s, struct sctp_parameter *parameter, char **error) { int result; - switch (ntohs(parameter->type)) { case SCTP_HEARTBEAT_INFORMATION_PARAMETER_TYPE: result = sctp_heartbeat_information_parameter_to_string(s, @@ -394,6 +413,10 @@ static int sctp_parameter_to_string(FILE *s, result = sctp_pad_parameter_to_string(s, (struct sctp_pad_parameter *)parameter, error); break; + case SCTP_ADAPTATION_INDICATION_PARAMETER_TYPE: + result = sctp_adaptation_indication_parameter_to_string(s, + (struct sctp_adaptation_indication_parameter *)parameter, error); + break; default: result = sctp_unknown_parameter_to_string(s, parameter, error); break; diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c index 70f81259..b3ce132f 100644 --- a/gtests/net/packetdrill/sctp_packet.c +++ b/gtests/net/packetdrill/sctp_packet.c @@ -1570,6 +1570,8 @@ sctp_supported_address_types_parameter_new(struct sctp_address_type_list *list) parameter_length, flags); } + + struct sctp_parameter_list_item * sctp_supported_extensions_parameter_new(struct sctp_byte_list *list) { @@ -1611,6 +1613,28 @@ sctp_supported_extensions_parameter_new(struct sctp_byte_list *list) parameter_length, flags); } +struct sctp_parameter_list_item * +sctp_adaptation_indication_parameter_new(u32 val) +{ + u32 flags; + struct sctp_adaptation_indication_parameter *parameter; + u16 parameter_length; + + flags = 0; + parameter_length = sizeof(struct sctp_adaptation_indication_parameter); + + parameter = malloc(parameter_length); + assert(parameter != NULL); + memset(parameter, 0, parameter_length); + + parameter->type = htons(SCTP_ADAPTATION_INDICATION_PARAMETER_TYPE); + parameter->length = htons(parameter_length); + parameter->adaptation_code_point = htonl(val); + + return sctp_parameter_list_item_new((struct sctp_parameter *)parameter, + parameter_length, flags); +} + struct sctp_parameter_list_item * sctp_pad_parameter_new(s64 len, u8 *padding) { diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h index c32e8d9d..e7c8c491 100644 --- a/gtests/net/packetdrill/sctp_packet.h +++ b/gtests/net/packetdrill/sctp_packet.h @@ -340,6 +340,9 @@ sctp_ecn_capable_parameter_new(void); struct sctp_parameter_list_item * sctp_pad_parameter_new(s64 len, u8 *padding); +struct sctp_parameter_list_item * +sctp_adaptation_indication_parameter_new(u32 val); + struct sctp_parameter_list_item * sctp_supported_extensions_parameter_new(struct sctp_byte_list *list); diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt index e5b5e282..a0e7baf2 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt @@ -2,14 +2,26 @@ +0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) +0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 // Check the handshake with an empty(!) cookie -+0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) ++0.0 bind(3, ..., ...) = 0 ++0.0 listen(3, 1) = 0 + +// Enable Event notification +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_ADAPTATION_INDICATION, se_on=1}, 8) = 0 +0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_ADAPTATION_INDICATION, se_on=1}, [8]) = 0 -+0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=1, ...] -+0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=1, is=1, tsn=1, STATE_COOKIE[len=4, val=...]] -+0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...] -+0.1 < sctp: COOKIE_ACK[flgs=0] + +// Send Adaptation Indication with Init chunk ++0.0 < sctp: INIT[flgs=0, tag=1, a_rwnd=1500, os=1, is=1, tsn=0, + ECN_CAPABLE[], + ADAPTATION_INDICATION[adaptation_code_point=3], + COOKIE_PRESERVATIVE[incr=12345], + SUPPORTED_ADDRESS_TYPES[types=[IPv4]]] + ++0.0 > sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=..., os=..., is=..., tsn=10, ...] ++0.1 < sctp: COOKIE_ECHO[flgs=0, len=..., val=...] ++0.0 > sctp: COOKIE_ACK[flgs=0] + ++0.0 accept(3, ..., ...) = 4 //TODO: Packetdrill does not support Path reconfiguration, after that update this test -+0.0 sctp_recvv(3, [{iov_base={sai_type=SCTP_ADAPTATION_INDICATION, sai_flags=0, sai_length=16, sai_adaptation_ind=0, sai_assoc_id=...}, -iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO],[MSG_NOTIFICATION|MSG_EOR]) = 21 ++0.0 sctp_recvv(4, [{iov_base={sai_type=SCTP_ADAPTATION_INDICATION, sai_flags=0, sai_length=16, sai_adaptation_ind=3, sai_assoc_id=...}, +iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO],[MSG_NOTIFICATION|MSG_EOR]) = 16 -- GitLab