summaryrefslogtreecommitdiffstats
path: root/src/vnet/sctp/sctp_input.c
diff options
context:
space:
mode:
authorMarco Varlese <marco.varlese@suse.com>2018-02-06 13:48:30 +0100
committerFlorin Coras <florin.coras@gmail.com>2018-02-06 17:44:23 +0000
commitdf5a99cef13ff6a22c195091be45152dc65f5d71 (patch)
tree229afaffac54a30e0c318c0e5d35c440dd364a5b /src/vnet/sctp/sctp_input.c
parente060ed1e1891f0fdf88b53865eccded38728f44c (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.c35
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: