diff options
author | Marco Varlese <marco.varlese@suse.com> | 2018-02-06 13:48:30 +0100 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2018-02-06 17:44:23 +0000 |
commit | df5a99cef13ff6a22c195091be45152dc65f5d71 (patch) | |
tree | 229afaffac54a30e0c318c0e5d35c440dd364a5b /src/vnet/sctp/sctp_input.c | |
parent | e060ed1e1891f0fdf88b53865eccded38728f44c (diff) |
SCTP: handling of heartbeating and max-retransmits
This patch address the need to send/receive heartbeats between peers.
At the same time, the number of unacked heartbeats is tracked and when
the peer requests to send DATA to the remote-peer the value of unacked
heartbeats needs to be checked against the maximum value allowed for
retransmissions. If the unacked heartbeats value is higher then the
remote-peer is considered unreachable and the connetion needs to be
shutdown.
Change-Id: I2b1a21c26775e734dbe82486f40982ed5702dc63
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 | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/vnet/sctp/sctp_input.c b/src/vnet/sctp/sctp_input.c index 0337e9f8aa0..66536884482 100644 --- a/src/vnet/sctp/sctp_input.c +++ b/src/vnet/sctp/sctp_input.c @@ -798,6 +798,9 @@ sctp_handle_cookie_echo (sctp_header_t * sctp_hdr, /* Change state */ sctp_conn->state = SCTP_STATE_ESTABLISHED; + sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT, + sctp_conn->sub_conn[idx].RTO); + stream_session_accept_notify (&sctp_conn->sub_conn[idx].connection); return SCTP_ERROR_NONE; @@ -825,6 +828,9 @@ sctp_handle_cookie_ack (sctp_header_t * sctp_hdr, /* Change state */ sctp_conn->state = SCTP_STATE_ESTABLISHED; + sctp_timer_set (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT, + sctp_conn->sub_conn[idx].RTO); + stream_session_accept_notify (&sctp_conn->sub_conn[idx].connection); return SCTP_ERROR_NONE; @@ -1433,17 +1439,34 @@ sctp_handle_sack (sctp_selective_ack_chunk_t * sack_chunk, always_inline u16 sctp_handle_heartbeat (sctp_hb_req_chunk_t * sctp_hb_chunk, - sctp_connection_t * sctp_conn, vlib_buffer_t * b0, - u16 * next0) + sctp_connection_t * sctp_conn, u8 idx, + vlib_buffer_t * b0, u16 * next0) { + /* Check that the LOCALLY generated tag is being used by the REMOTE peer as the verification tag */ + if (sctp_conn->local_tag != sctp_hb_chunk->sctp_hdr.verification_tag) + { + return SCTP_ERROR_INVALID_TAG; + } + + sctp_prepare_heartbeat_ack_chunk (sctp_conn, b0); + + *next0 = sctp_next_output (sctp_conn->sub_conn[idx].connection.is_ip4); + return SCTP_ERROR_NONE; } always_inline u16 sctp_handle_heartbeat_ack (sctp_hb_ack_chunk_t * sctp_hb_ack_chunk, - sctp_connection_t * sctp_conn, vlib_buffer_t * b0, - u16 * next0) + sctp_connection_t * sctp_conn, u8 idx, + vlib_buffer_t * b0, u16 * next0) { + sctp_conn->sub_conn[idx].unacknowledged_hb -= 1; + + sctp_timer_update (sctp_conn, idx, SCTP_TIMER_T4_HEARTBEAT, + sctp_conn->sub_conn[idx].RTO); + + *next0 = sctp_next_output (sctp_conn->sub_conn[idx].connection.is_ip4); + return SCTP_ERROR_NONE; } @@ -1766,13 +1789,13 @@ sctp46_established_phase_inline (vlib_main_t * vm, vlib_node_runtime_t * node, case HEARTBEAT: error0 = sctp_handle_heartbeat ((sctp_hb_req_chunk_t *) sctp_hdr, - sctp_conn, b0, &next0); + sctp_conn, idx, b0, &next0); break; case HEARTBEAT_ACK: error0 = sctp_handle_heartbeat_ack ((sctp_hb_ack_chunk_t *) sctp_hdr, - sctp_conn, b0, &next0); + sctp_conn, idx, b0, &next0); break; case DATA: |