summaryrefslogtreecommitdiffstats
path: root/src/vnet/sctp/sctp.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.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.c')
-rw-r--r--src/vnet/sctp/sctp.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/src/vnet/sctp/sctp.c b/src/vnet/sctp/sctp.c
index f8cd21c63ec..61c0252b1ba 100644
--- a/src/vnet/sctp/sctp.c
+++ b/src/vnet/sctp/sctp.c
@@ -606,33 +606,43 @@ sctp_expired_timers_cb (u32 conn_index, u32 timer_id)
/* note: the connection may have already disappeared */
if (PREDICT_FALSE (sctp_conn == 0))
return;
- ASSERT (sctp_conn->state == SCTP_STATE_COOKIE_ECHOED);
+
+ SCTP_DBG ("%s expired", sctp_timer_to_string (timer_id));
switch (timer_id)
{
+ case SCTP_TIMER_T1_INIT:
+ case SCTP_TIMER_T1_COOKIE:
+ case SCTP_TIMER_T2_SHUTDOWN:
+ case SCTP_TIMER_T3_RXTX:
+ clib_smp_atomic_add (&sctp_conn->sub_conn[conn_index].unacknowledged_hb,
+ 1);
+ sctp_timer_reset (sctp_conn, conn_index, timer_id);
+ break;
case SCTP_TIMER_T4_HEARTBEAT:
- {
- clib_warning ("Heartbeat timeout");
- break;
- }
+ sctp_timer_reset (sctp_conn, conn_index, timer_id);
+ goto heartbeat;
}
- /* Start cleanup. App wasn't notified yet so use delete notify as
- * opposed to delete to cleanup session layer state. */
- stream_session_delete_notify (&sctp_conn->
- sub_conn[MAIN_SCTP_SUB_CONN_IDX].connection);
- sctp_connection_timers_reset (sctp_conn);
+ if (sctp_conn->sub_conn[conn_index].unacknowledged_hb >
+ SCTP_ASSOCIATION_MAX_RETRANS)
+ {
+ // The remote-peer is considered to be unreachable hence shutting down
- sctp_connection_cleanup (sctp_conn);
-}
+ /* Start cleanup. App wasn't notified yet so use delete notify as
+ * opposed to delete to cleanup session layer state. */
+ stream_session_delete_notify (&sctp_conn->sub_conn
+ [MAIN_SCTP_SUB_CONN_IDX].connection);
-/* *INDENT OFF* */
-static sctp_timer_expiration_handler
- * sctp_timer_expiration_handlers[SCTP_N_TIMERS] = {
- sctp_expired_timers_cb
-};
+ sctp_connection_timers_reset (sctp_conn);
-/* *INDENT ON* */
+ sctp_connection_cleanup (sctp_conn);
+ }
+ return;
+
+heartbeat:
+ sctp_send_heartbeat (sctp_conn);
+}
static void
sctp_expired_timers_dispatch (u32 * expired_timers)
@@ -649,8 +659,7 @@ sctp_expired_timers_dispatch (u32 * expired_timers)
SCTP_DBG ("Expired timer ID: %u", timer_id);
/* Handle expiration */
- (*sctp_timer_expiration_handlers[timer_id]) (connection_index,
- timer_id);
+ sctp_expired_timers_cb (connection_index, timer_id);
}
}