Skip to content
Snippets Groups Projects
Commit b3e96682 authored by hoelscher's avatar hoelscher
Browse files

add support for sctp_peer_addr_change notification

parent 52d10627
No related branches found
No related tags found
No related merge requests found
......@@ -329,6 +329,13 @@ pdapi_indication return PDAPI_INDICATION;
pdapi_stream return PDAPI_STREAM;
pdapi_seq return PDAPI_SEQ;
pdapi_assoc_id return PDAPI_ASSOC_ID;
spc_type return SPC_TYPE;
spc_length return SPC_LENGTH;
spc_flags return SPC_FLAGS;
spc_aaddr return SPC_AADDR;
spc_state return SPC_STATE;
spc_error return SPC_ERROR;
spc_assoc_id return SPC_ASSOC_ID;
CHUNK return CHUNK;
DATA return DATA;
INIT return INIT;
......
......@@ -559,6 +559,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> AUTH_TYPE AUTH_FLAGS AUTH_LENGTH AUTH_INDICATION AUTH_ASSOC_ID
%token <reserved> SRE_TYPE SRE_FLAGS SRE_LENGTH SRE_ERROR SRE_ASSOC_ID SRE_DATA PDAPI_ASSOC_ID
%token <reserved> PDAPI_TYPE PDAPI_FLAGS PDAPI_LENGTH PDAPI_INDICATION PDAPI_STREAM PDAPI_SEQ
%token <reserved> SPC_TYPE SPC_FLAGS SPC_LENGTH SPC_AADDR SPC_STATE SPC_ERROR SPC_ASSOC_ID
%token <floating> FLOAT
%token <integer> INTEGER HEX_INTEGER
%token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
......@@ -623,6 +624,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <expression> sctp_authkey_event auth_type auth_flags auth_length auth_keynumber auth_indication auth_assoc_id
%type <expression> sctp_remote_error sre_type sre_flags sre_length sre_error sre_assoc_id sre_data
%type <expression> sctp_pdapi_event pdapi_type pdapi_flags pdapi_length pdapi_indication pdapi_stream pdapi_seq pdapi_assoc_id
%type <expression> sctp_paddr_change spc_type spc_flags spc_length spc_aaddr spc_error spc_state spc_assoc_id
%type <errno_info> opt_errno
%type <chunk_list> sctp_chunk_list_spec
%type <chunk_list_item> sctp_chunk_spec
......@@ -2598,6 +2600,7 @@ sockaddr
data
: ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
| sctp_assoc_change { $$ = $1; }
| sctp_paddr_change { $$ = $1; }
| sctp_remote_error { $$ = $1; }
| sctp_shutdown_event { $$ = $1; }
| sctp_pdapi_event { $$ = $1; }
......@@ -4073,6 +4076,97 @@ sctp_remote_error
}
;
spc_type
: SPC_TYPE '=' INTEGER {
if (!is_valid_u16($3)) {
semantic_error("spc_type out of range");
}
$$ = new_integer_expression($3, "%hu");
}
| SPC_TYPE '=' WORD {
$$ = new_expression(EXPR_WORD);
$$->value.string = $3;
}
| SPC_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
spc_flags
: SPC_FLAGS '=' INTEGER {
if (!is_valid_u16($3)) {
semantic_error("spc_flags out of range");
}
$$ = new_integer_expression($3, "%hu");
}
| SPC_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
spc_length
: SPC_LENGTH '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("spc_length out of range");
}
$$ = new_integer_expression($3, "%u");
}
| SPC_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
spc_aaddr
: SPC_AADDR '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
| SPC_AADDR '=' sockaddr { $$ = $3; }
;
spc_state
: SPC_STATE '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("spc_state out of range");
}
$$ = new_integer_expression($3, "%u");
}
| SPC_STATE '=' WORD {
$$ = new_expression(EXPR_WORD);
$$->value.string = $3;
}
| SPC_STATE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
spc_error
: SPC_ERROR '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("spc_error out of range");
}
$$ = new_integer_expression($3, "%u");
}
| SPC_ERROR '=' WORD {
$$ = new_expression(EXPR_WORD);
$$->value.string = $3;
}
| SPC_ERROR '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
spc_assoc_id
: SPC_ASSOC_ID '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("spc_assoc_id out of range");
}
$$ = new_integer_expression($3, "%u");
}
| SPC_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
sctp_paddr_change
: '{' spc_type ',' spc_flags ',' spc_length ',' spc_aaddr ',' spc_state ',' spc_error ',' spc_assoc_id '}' {
$$ = new_expression(EXPR_SCTP_PADDR_CHANGE);
$$->value.sctp_paddr_change = calloc(1, sizeof(struct sctp_paddr_change_expr));
$$->value.sctp_paddr_change->spc_type = $2;
$$->value.sctp_paddr_change->spc_length = $4;
$$->value.sctp_paddr_change->spc_flags = $6;
$$->value.sctp_paddr_change->spc_aaddr = $8;
$$->value.sctp_paddr_change->spc_state = $10;
$$->value.sctp_paddr_change->spc_error = $12;
$$->value.sctp_paddr_change->spc_assoc_id = $14;
}
;
opt_errno
: { $$ = NULL; }
| WORD note {
......
......@@ -569,6 +569,7 @@ static int iovec_new(struct expression *expression,
assert(iov_expr->iov_base->type == EXPR_ELLIPSIS ||
iov_expr->iov_base->type == EXPR_SCTP_ASSOC_CHANGE ||
iov_expr->iov_base->type == EXPR_SCTP_PADDR_CHANGE ||
iov_expr->iov_base->type == EXPR_SCTP_REMOTE_ERROR ||
iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT ||
iov_expr->iov_base->type == EXPR_SCTP_PDAPI_EVENT ||
......@@ -3419,6 +3420,36 @@ static int check_sctp_assoc_change(struct sctp_assoc_change_expr *expr,
}
#endif
#if defined(__FreeBSD__) || defined(linux)
static int check_sctp_paddr_change(struct sctp_paddr_change_expr *expr,
struct sctp_paddr_change *sctp_event,
char **error) {
if (check_u16_expr(expr->spc_type, sctp_event->spc_type,
"sctp_paddr_change.spc_type", error))
return STATUS_ERR;
if (check_u16_expr(expr->spc_flags, sctp_event->spc_flags,
"sctp_paddr_change.spc_flags", error))
return STATUS_ERR;
if (check_u32_expr(expr->spc_length, sctp_event->spc_length,
"sctp_paddr_change.spc_length", error))
return STATUS_ERR;
if (check_sockaddr(expr->spc_aaddr,
(struct sockaddr *)&sctp_event->spc_aaddr, error))
return STATUS_ERR;
if (check_u32_expr(expr->spc_state, sctp_event->spc_state,
"sctp_paddr_change.spc_state", error))
return STATUS_ERR;
if (check_u32_expr(expr->spc_error, sctp_event->spc_error,
"sctp_paddr_change.spc_error", error))
return STATUS_ERR;
if (check_u32_expr(expr->spc_assoc_id, sctp_event->spc_assoc_id,
"sctp_paddr_change.spc_assoc_id", error))
return STATUS_ERR;
return STATUS_OK;
}
#endif
#if defined(__FreeBSD__) || defined(linux)
static int check_sctp_remote_error(struct sctp_remote_error_expr *expr,
struct sctp_remote_error *sctp_event,
......@@ -3602,6 +3633,12 @@ static int check_sctp_notification(struct iovec *iov,
error))
return STATUS_ERR;
break;
case EXPR_SCTP_PADDR_CHANGE:
if (check_sctp_paddr_change(script_iov_base->value.sctp_paddr_change,
(struct sctp_paddr_change *) iov[i].iov_base,
error))
return STATUS_ERR;
break;
case EXPR_SCTP_REMOTE_ERROR:
if (check_sctp_remote_error(script_iov_base->value.sctp_remote_error,
(struct sctp_remote_error *) iov[i].iov_base,
......
......@@ -87,6 +87,7 @@ struct expression_type_entry expression_type_table[] = {
{ EXPR_SCTP_NXTINFO, "sctp_nxtinfo" },
{ EXPR_SCTP_RECVV_RN, "sctp_recvv_rn " },
{ EXPR_SCTP_ASSOC_CHANGE, "sctp_assoc_change"},
{ EXPR_SCTP_PADDR_CHANGE, "sctp_paddr_change"},
{ EXPR_SCTP_REMOTE_ERROR, "sctp_remote_error"},
{ EXPR_SCTP_SHUTDOWN_EVENT, "sctp_shutdown_event"},
{ EXPR_SCTP_PDAPI_EVENT, "sctp_pdapi_event"},
......@@ -447,6 +448,15 @@ void free_expression(struct expression *expression)
free_expression(expression->value.sctp_assoc_change->sac_assoc_id);
free_expression(expression->value.sctp_assoc_change->sac_info);
break;
case EXPR_SCTP_PADDR_CHANGE:
free_expression(expression->value.sctp_paddr_change->spc_type);
free_expression(expression->value.sctp_paddr_change->spc_flags);
free_expression(expression->value.sctp_paddr_change->spc_length);
free_expression(expression->value.sctp_paddr_change->spc_aaddr);
free_expression(expression->value.sctp_paddr_change->spc_state);
free_expression(expression->value.sctp_paddr_change->spc_error);
free_expression(expression->value.sctp_paddr_change->spc_assoc_id);
break;
case EXPR_SCTP_REMOTE_ERROR:
free_expression(expression->value.sctp_remote_error->sre_type);
free_expression(expression->value.sctp_remote_error->sre_flags);
......@@ -1458,6 +1468,54 @@ static int evaluate_sctp_assoc_change_expression(struct expression *in,
return STATUS_OK;
}
static int evaluate_sctp_paddr_change_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_paddr_change_expr *in_event;
struct sctp_paddr_change_expr *out_event;
assert(in->type == EXPR_SCTP_PADDR_CHANGE);
assert(in->value.sctp_paddr_change);
assert(out->type == EXPR_SCTP_PADDR_CHANGE);
out->value.sctp_paddr_change = calloc(1, sizeof(struct sctp_paddr_change_expr));
in_event = in->value.sctp_paddr_change;
out_event = out->value.sctp_paddr_change;
if (evaluate(in_event->spc_type,
&out_event->spc_type,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_flags,
&out_event->spc_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_length,
&out_event->spc_length,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_aaddr,
&out_event->spc_aaddr,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_state,
&out_event->spc_state,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_error,
&out_event->spc_error,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_assoc_id,
&out_event->spc_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_remote_error_expression(struct expression *in,
struct expression *out,
char **error)
......@@ -1798,6 +1856,9 @@ static int evaluate(struct expression *in,
case EXPR_SCTP_ASSOC_CHANGE:
result = evaluate_sctp_assoc_change_expression(in, out, error);
break;
case EXPR_SCTP_PADDR_CHANGE:
result = evaluate_sctp_paddr_change_expression(in, out, error);
break;
case EXPR_SCTP_REMOTE_ERROR:
result = evaluate_sctp_remote_error_expression(in, out, error);
break;
......
......@@ -67,6 +67,7 @@ enum expression_t {
EXPR_SCTP_NXTINFO, /* struct sctp_nxtinfo for syscall sctp_recvv */
EXPR_SCTP_RECVV_RN, /* struct sctp_recvv_rn for syscall sctp_recvv */
EXPR_SCTP_ASSOC_CHANGE, /* expression tree for sctp_assoc_change_event */
EXPR_SCTP_PADDR_CHANGE, /* expression tree for sctp_peer_addr_change */
EXPR_SCTP_REMOTE_ERROR, /* expression tree for sctp_remote_error_event */
EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */
EXPR_SCTP_PDAPI_EVENT, /* expression tree for sctp_partial_delivery_event */
......@@ -113,6 +114,7 @@ struct expression {
struct sctp_nxtinfo_expr *sctp_nxtinfo;
struct sctp_recvv_rn_expr *sctp_recvv_rn;
struct sctp_assoc_change_expr *sctp_assoc_change;
struct sctp_paddr_change_expr *sctp_paddr_change;
struct sctp_remote_error_expr *sctp_remote_error;
struct sctp_shutdown_event_expr *sctp_shutdown_event;
struct sctp_pdapi_event_expr *sctp_pdapi_event;
......@@ -342,7 +344,18 @@ struct sctp_assoc_change_expr {
struct expression *sac_info;
};
/* Parse tree for sctp_assoc_change for notifications. */
/* Parse tree for sctp_paddr_change for notifications. */
struct sctp_paddr_change_expr {
struct expression *spc_type;
struct expression *spc_flags;
struct expression *spc_length;
struct expression *spc_aaddr;
struct expression *spc_state;
struct expression *spc_error;
struct expression *spc_assoc_id;
};
/* Parse tree for sctp_remote_error_event for notifications. */
struct sctp_remote_error_expr {
struct expression *sre_type;
struct expression *sre_flags;
......
......@@ -217,7 +217,10 @@ struct int_symbol platform_symbols_table[] = {
{ SCTP_ASSOC_SUPPORTS_ASCONF, "SCTP_ASSOC_SUPPORTS_ASCONF" },
{ SCTP_ASSOC_SUPPORTS_MULTIBUF, "SCTP_ASSOC_SUPPORTS_MULTIBUF" },
{ SCTP_PARTIAL_DELIVERY_ABORTED, "SCTP_PARTIAL_DELIVERY_ABORTED" },
{ SCTP_ADDR_AVAILABLE, "SCTP_ADDR_AVAILABLE" },
{ SCTP_ADDR_UNREACHABLE, "SCTP_ADDR_UNREACHABLE" },
{ SCTP_ADDR_REMOVED, "SCTP_ADDR_REMOVED" },
{ SCTP_ADDR_MADE_PRIM, "SCTP_ADDR_MADE_PRIM" },
/* /usr/include/netinet/tcp.h */
{ TCP_NODELAY, "TCP_NODELAY" },
{ TCP_MAXSEG, "TCP_MAXSEG" },
......
......@@ -9,13 +9,12 @@
+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]
+0.0 write(3, ..., 3000) = 3000
* > sctp: DATA[flgs=B, len=1468, tsn=1, sid=0, ssn=0, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]
* > sctp: DATA[flgs=0, len=1468, tsn=2, sid=0, ssn=0, ppid=0]
//+0.0 < sctp: ABORT[flgs=0, USER_INITIATED_ABORT[info="Testing"]]
+0.0 sctp_recvv(3, [{iov_base=..., iov_len=1000}, {iov_base={pdapi_type=SCTP_PARTIAL_DELIVERY_EVENT, pdapi_flags=0,pdapi_length=24,
+0.0 < sctp: DATA[flgs=B, len=300, tsn=1, sid=0, ssn=0, ppid=0]
+0.0 > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]]
+0.0 < sctp: DATA[flgs=0, len=300, tsn=2, sid=0, ssn=0, ppid=0]
* > sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=..., gaps=[], dups=[]]
+0.0 < sctp: ABORT[flgs=0]
+1.5 sctp_recvv(3, [{iov_base=..., iov_len=1000}, {iov_base={pdapi_type=SCTP_PARTIAL_DELIVERY_EVENT, pdapi_flags=0,pdapi_length=24,
pdapi_indication=SCTP_PARTIAL_DELIVERY_ABORTED, pdapi_stream=0, pdapi_seq=0, pdapi_assoc_id=3 }, iov_len=1000}], 2, ..., 20, NULL, [0],
[SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 21
+0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
+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 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_PEER_ADDR_CHANGE, se_on=1}, 8) = 0
+0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_PEER_ADDR_CHANGE, 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]
+0.0 sctp_recvv(3, [{iov_base={spc_type=SCTP_PEER_ADDR_CHANGE, spc_flags=0, spc_length=21, spc_aaddr=..., spc_state=SCTP_ADDR_MADE_PRIM, spc_error=0,
spc_assoc_id=3}, iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO],
[MSG_NOTIFICATION|MSG_EOR]) = 21
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