diff options
author | Marco Varlese <marco.varlese@suse.com> | 2018-02-26 14:52:25 +0100 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-02-26 22:27:50 +0000 |
commit | eacf3cfdaf04395c07830b046037f46ae94b06ab (patch) | |
tree | 79dc7b072cdb27596ca9748b7556c36cd0e47ebe /src/vnet/sctp/sctp_input.c | |
parent | 2ae03d2f8f8336454edb34187e222544c1452014 (diff) |
SCTP: handle INIT corner-case handling
As per RFC4960 the INIT chunk could be received in unexpected scenarios
and - depending on the state of the internal state-machine - the INIT
chunk requires different treatment.
This patch addresses section 5.2.1 and 5.2.2 of the RFC4960.
Change-Id: Ib23ef490c6a5ca3da6c46a9584b75e7577cb7042
Signed-off-by: Marco Varlese <marco.varlese@suse.com>
Diffstat (limited to 'src/vnet/sctp/sctp_input.c')
-rw-r--r-- | src/vnet/sctp/sctp_input.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/src/vnet/sctp/sctp_input.c b/src/vnet/sctp/sctp_input.c index 615cdefd134..82adc2aa5b0 100644 --- a/src/vnet/sctp/sctp_input.c +++ b/src/vnet/sctp/sctp_input.c @@ -304,12 +304,24 @@ sctp_handle_init (sctp_header_t * sctp_hdr, { /* UNEXPECTED scenario */ switch (sctp_conn->state) { - case SCTP_STATE_COOKIE_WAIT: /* TODO */ + case SCTP_STATE_COOKIE_WAIT: SCTP_ADV_DBG ("Received INIT chunk while in COOKIE_WAIT state"); - break; - case SCTP_STATE_COOKIE_ECHOED: /* TODO */ + sctp_prepare_initack_chunk_for_collision (sctp_conn, + MAIN_SCTP_SUB_CONN_IDX, + b0, ip4_addr, ip6_addr); + return SCTP_ERROR_NONE; + case SCTP_STATE_COOKIE_ECHOED: + case SCTP_STATE_SHUTDOWN_ACK_SENT: SCTP_ADV_DBG ("Received INIT chunk while in COOKIE_ECHOED state"); - break; + if (sctp_conn->forming_association_changed == 0) + sctp_prepare_initack_chunk_for_collision (sctp_conn, + MAIN_SCTP_SUB_CONN_IDX, + b0, ip4_addr, ip6_addr); + else + sctp_prepare_abort_for_collision (sctp_conn, + MAIN_SCTP_SUB_CONN_IDX, b0, + ip4_addr, ip6_addr); + return SCTP_ERROR_NONE; } } @@ -2353,7 +2365,7 @@ do { \ _(SHUTDOWN_RECEIVED, SHUTDOWN_COMPLETE, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SHUTDOWN_COMPLETE_VIOLATION); /* UNEXPECTED SHUTDOWN_COMPLETE chunk */ _(SHUTDOWN_ACK_SENT, DATA, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_DATA_CHUNK_VIOLATION); /* UNEXPECTED DATA chunk */ - _(SHUTDOWN_ACK_SENT, INIT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_INIT_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */ + _(SHUTDOWN_ACK_SENT, INIT, SCTP_INPUT_NEXT_RCV_PHASE, SCTP_ERROR_NONE); /* UNEXPECTED INIT chunk */ _(SHUTDOWN_ACK_SENT, INIT_ACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_ACK_DUP); /* UNEXPECTED INIT_ACK chunk */ _(SHUTDOWN_ACK_SENT, SACK, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_SACK_CHUNK_VIOLATION); /* UNEXPECTED INIT chunk */ _(SHUTDOWN_ACK_SENT, HEARTBEAT, SCTP_INPUT_NEXT_DROP, SCTP_ERROR_HEARTBEAT_CHUNK_VIOLATION); /* UNEXPECTED HEARTBEAT chunk */ |