Skip to content
Snippets Groups Projects
Commit ff94828d authored by Michael Tüxen's avatar Michael Tüxen
Browse files

Merge pull request #48 from hoelscher/sctp_sack_info

Change [gs]etsockopt for handling for struct sctp_sack_info with expressions
parents f3f7ad42 aa877138
No related branches found
No related tags found
No related merge requests found
......@@ -574,7 +574,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <expression> sctp_status sstat_state sstat_rwnd sstat_unackdata sstat_penddata
%type <expression> sstat_instrms sstat_outstrms sstat_fragmentation_point sstat_primary
%type <expression> sctp_initmsg sinit_num_ostreams sinit_max_instreams sinit_max_attempts
%type <expression> sinit_max_init_timeo sctp_assoc_value sctp_stream_value sctp_sackinfo
%type <expression> sinit_max_init_timeo sctp_assoc_value sctp_stream_value
%type <expression> sctp_sackinfo sack_delay sack_freq
%type <expression> sctp_rtoinfo srto_initial srto_max srto_min sctp_paddrinfo
%type <expression> sctp_paddrparams spp_address spp_hbinterval spp_pathmtu spp_pathmaxrxt
%type <expression> spp_flags spp_ipv6_flowlabel spp_dscp
......@@ -2629,18 +2630,31 @@ sctp_assoc_value
}
;
sctp_sackinfo
: '{' SACK_DELAY '=' INTEGER ',' SACK_FREQ '=' INTEGER '}' {
#ifdef SCTP_DELAYED_SACK
$$ = new_expression(EXPR_SCTP_SACKINFO);
if (!is_valid_u32($4)) {
sack_delay
: SACK_DELAY '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("sack_delay out of range");
}
$$->value.sctp_sack_info.sack_delay = $4;
if (!is_valid_u32($8)) {
$$ = new_integer_expression($3, "%u");
}
| SACK_DELAY '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
sack_freq
: SACK_FREQ '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("sack_freq out of range");
}
$$->value.sctp_sack_info.sack_freq = $8;
$$ = new_integer_expression($3, "%u");
}
| SACK_FREQ '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
sctp_sackinfo
: '{' sack_delay ',' sack_freq '}' {
#ifdef SCTP_DELAYED_SACK
$$ = new_expression(EXPR_SCTP_SACKINFO);
$$->value.sctp_sack_info = calloc(1, sizeof(struct sctp_sack_info_expr));
$$->value.sctp_sack_info->sack_delay = $2;
$$->value.sctp_sack_info->sack_freq = $4;
#else
$$ = NULL;
#endif
......
......@@ -1811,6 +1811,39 @@ static int check_sctp_initmsg(struct sctp_initmsg_expr *expr,
}
#endif
#ifdef SCTP_DELAYED_SACK
static int check_sctp_sack_info(struct sctp_sack_info_expr *expr,
struct sctp_sack_info *sctp_sack_info,
char **error)
{
if (expr->sack_delay->type != EXPR_ELLIPSIS) {
u32 sack_delay;
if (get_u32(expr->sack_delay, &sack_delay, error)) {
return STATUS_ERR;
}
if (sctp_sack_info->sack_delay != sack_delay) {
asprintf(error, "Bad getsockopt sctp_sack_info.sack_delay: expected: %u actual: %u",
sack_delay, sctp_sack_info->sack_delay);
return STATUS_ERR;
}
}
if (expr->sack_freq->type != EXPR_ELLIPSIS) {
u32 sack_freq;
if (get_u32(expr->sack_freq, &sack_freq, error)) {
return STATUS_ERR;
}
if (sctp_sack_info->sack_freq != sack_freq) {
asprintf(error, "Bad getsockopt sctp_sack_info.sack_freq: expected: %u actual: %u",
sack_freq, sctp_sack_info->sack_freq);
return STATUS_ERR;
}
}
return STATUS_OK;
}
#endif
#ifdef SCTP_STATUS
static int check_sctp_paddrinfo(struct sctp_paddrinfo_expr *expr,
struct sctp_paddrinfo *sctp_paddrinfo,
......@@ -2161,6 +2194,12 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
live_optval = malloc(sizeof(struct sctp_initmsg));
live_optlen = (socklen_t)sizeof(struct sctp_initmsg);
#endif
#ifdef SCTP_DELAYED_SACK
} else if (val_expression->type == EXPR_SCTP_SACKINFO) {
live_optval = malloc(sizeof(struct sctp_sack_info));
live_optlen = (socklen_t)sizeof(struct sctp_sack_info);
((struct sctp_sack_info*) live_optval)->sack_assoc_id = 0;
#endif
#ifdef SCTP_STATUS
} else if (val_expression->type == EXPR_SCTP_STATUS) {
live_optval = malloc(sizeof(struct sctp_status));
......@@ -2248,6 +2287,13 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
return STATUS_ERR;
}
#endif
#ifdef SCTP_DELAYED_SACK
} else if (val_expression->type == EXPR_SCTP_SACKINFO) {
if (check_sctp_sack_info(val_expression->value.sctp_sack_info, live_optval, error)) {
free(live_optval);
return STATUS_ERR;
}
#endif
#ifdef SCTP_STATUS
} else if (val_expression->type == EXPR_SCTP_STATUS) {
if (check_sctp_status(val_expression->value.sctp_status, live_optval, error)) {
......@@ -2304,6 +2350,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
struct sctp_assoc_value assoc_value;
#endif
#ifdef SCTP_DELAYED_SACK
struct sctp_sack_info sack_info;
#endif
#ifdef SCTP_STATUS
struct sctp_status status;
#endif
......@@ -2415,7 +2464,16 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#endif
#ifdef SCTP_DELAYED_SACK
case EXPR_SCTP_SACKINFO:
optval = &val_expression->value.sctp_sack_info;
sack_info.sack_assoc_id = 0;
if (get_u32(val_expression->value.sctp_sack_info->sack_delay,
&sack_info.sack_delay, error)) {
return STATUS_ERR;
}
if (get_u32(val_expression->value.sctp_sack_info->sack_freq,
&sack_info.sack_freq, error)) {
return STATUS_ERR;
}
optval = &sack_info;
break;
#endif
#ifdef SCTP_STATUS
......
......@@ -323,8 +323,11 @@ void free_expression(struct expression *expression)
#endif
#ifdef SCTP_DELAYED_SACK
case EXPR_SCTP_SACKINFO:
#endif
assert(expression->value.sctp_sack_info);
free_expression(expression->value.sctp_sack_info->sack_delay);
free_expression(expression->value.sctp_sack_info->sack_freq);
break;
#endif
#ifdef SCTP_STATUS
case EXPR_SCTP_PADDRINFO:
assert(expression->value.sctp_paddrinfo);
......@@ -650,6 +653,36 @@ static int evaluate_sctp_assoc_value_expression(struct expression *in,
}
#endif
#ifdef SCTP_DELAYED_SACK
static int evaluate_sctp_sack_info_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sack_info_expr *in_sack_info;
struct sctp_sack_info_expr *out_sack_info;
assert(in->type == EXPR_SCTP_SACKINFO);
assert(in->value.sctp_sack_info);
assert(out->type == EXPR_SCTP_SACKINFO);
out->value.sctp_sack_info = calloc(1, sizeof(struct sctp_sack_info_expr));
in_sack_info = in->value.sctp_sack_info;
out_sack_info = out->value.sctp_sack_info;
if (evaluate(in_sack_info->sack_delay,
&out_sack_info->sack_delay,
error))
return STATUS_ERR;
if (evaluate(in_sack_info->sack_freq,
&out_sack_info->sack_freq,
error))
return STATUS_ERR;
return STATUS_OK;
}
#endif
#ifdef SCTP_STATUS
static int evaluate_sctp_paddrinfo_expression(struct expression *in,
struct expression *out,
......@@ -867,9 +900,8 @@ static int evaluate(struct expression *in,
break;
#endif
#ifdef SCTP_DELAYED_SACK
case EXPR_SCTP_SACKINFO: /* copy as-is */
memcpy(&out->value.sctp_sack_info, &in->value.sctp_sack_info,
sizeof(in->value.sctp_sack_info));
case EXPR_SCTP_SACKINFO:
evaluate_sctp_sack_info_expression(in, out, error);
break;
#endif
#ifdef SCTP_STATUS
......
......@@ -55,7 +55,7 @@ enum expression_t {
EXPR_SCTP_ASSOC_VALUE, /* struct sctp_assoc_value */
#endif
#ifdef SCTP_DELAYED_SACK
EXPR_SCTP_SACKINFO, /* struct sctp_sack_info for
EXPR_SCTP_SACKINFO, /* struct sctp_sack_info_expr for
* SCTP_DELAYED_SACK */
#endif
#ifdef SCTP_STATUS
......@@ -97,7 +97,7 @@ struct expression {
struct sctp_assoc_value_expr *sctp_assoc_value;
#endif
#ifdef SCTP_DELAYED_SACK
struct sctp_sack_info sctp_sack_info;
struct sctp_sack_info_expr *sctp_sack_info;
#endif
#ifdef SCTP_STATUS
struct sctp_status_expr *sctp_status;
......@@ -190,6 +190,13 @@ struct sctp_stream_value_expr {
};
#endif
#ifdef SCTP_DELAYED_SACK
/* Parse tree for a sctp_sack_info struct in a [gs]etsockopt syscall. */
struct sctp_sack_info_expr {
struct expression *sack_delay;
struct expression *sack_freq;
};
#endif
/* Parse tree for a sctp_status struct in a [gs]etsockopt syscall. */
#ifdef SCTP_STATUS
struct sctp_status_expr {
......
......@@ -78,4 +78,10 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv
+0 getsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=..., sinit_max_instreams=2, sinit_max_attempts=2, sinit_max_init_timeo=30}, [8]) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=2, sinit_max_instreams=..., sinit_max_attempts=2, sinit_max_init_timeo=30}, [8]) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=2, sinit_max_instreams=2, sinit_max_attempts=..., sinit_max_init_timeo=30}, [8]) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=1}, 12) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=1}, [12]) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=..., sack_freq=1}, [12]) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=...}, [12]) = 0
+0 close(3) = 0
......@@ -5,7 +5,7 @@
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=200, srto_max=200, srto_min=50}, 16) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=50, srto_min=50}, 16) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 17) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=..., srto_max=200, srto_min=50}, 15) = -1 EINVAL (Invalid argument)
//+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=..., srto_max=200, srto_min=50}, 15) = -1 EINVAL (Invalid argument)
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=25, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=225, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=50, srto_min=200}, 16) = -1 EINVAL (Invalid argument)
......@@ -43,6 +43,6 @@
+0 setsockopt(3, IPPROTO_SCTP, SCTP_MAX_BURST, {assoc_value=1}, 7) = -1 (Invalid argument)
+0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
spp_hbinterval=30000, spp_pathmtu=1468, spp_pathmaxrxt=100, spp_flags=0, spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0
spp_hbinterval=30000, spp_pathmaxrxt=100, spp_pathmtu=1468, spp_flags=0, spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0
+0 close(3) = 0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment