summaryrefslogtreecommitdiffstats
path: root/src/vnet/sctp/sctp_input.c
diff options
context:
space:
mode:
authorMarco Varlese <marco.varlese@suse.com>2018-02-26 14:52:25 +0100
committerDamjan Marion <dmarion.lists@gmail.com>2018-02-26 22:27:50 +0000
commiteacf3cfdaf04395c07830b046037f46ae94b06ab (patch)
tree79dc7b072cdb27596ca9748b7556c36cd0e47ebe /src/vnet/sctp/sctp_input.c
parent2ae03d2f8f8336454edb34187e222544c1452014 (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.c22
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 */