sctp: add stream reconf timer

This patch is to add a per transport timer based on sctp timer frame
for stream reconf chunk retransmission. It would start after sending
a reconf request chunk, and stop after receiving the response chunk.

If the timer expires, besides retransmitting the reconf request chunk,
it would also do the same thing with data RTO timer. like to increase
the appropriate error counts, and perform threshold management, possibly
destroying the asoc if sctp retransmission thresholds are exceeded, just
as section 5.1.1 describes.

This patch is also to add asoc strreset_chunk, it is used to save the
reconf request chunk, so that it can be retransmitted, and to check if
the response is really for this request by comparing the information
inside with the response chunk as well.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Xin Long
2017-01-18 00:44:43 +08:00
committed by David S. Miller
parent cc16f00f65
commit 7b9438de0c
8 changed files with 113 additions and 2 deletions

View File

@@ -436,6 +436,37 @@ out_unlock:
sctp_association_put(asoc);
}
/* Handle the timeout of the RE-CONFIG timer. */
void sctp_generate_reconf_event(unsigned long data)
{
struct sctp_transport *transport = (struct sctp_transport *)data;
struct sctp_association *asoc = transport->asoc;
struct sock *sk = asoc->base.sk;
struct net *net = sock_net(sk);
int error = 0;
bh_lock_sock(sk);
if (sock_owned_by_user(sk)) {
pr_debug("%s: sock is busy\n", __func__);
/* Try again later. */
if (!mod_timer(&transport->reconf_timer, jiffies + (HZ / 20)))
sctp_transport_hold(transport);
goto out_unlock;
}
error = sctp_do_sm(net, SCTP_EVENT_T_TIMEOUT,
SCTP_ST_TIMEOUT(SCTP_EVENT_TIMEOUT_RECONF),
asoc->state, asoc->ep, asoc,
transport, GFP_ATOMIC);
if (error)
sk->sk_err = -error;
out_unlock:
bh_unlock_sock(sk);
sctp_transport_put(transport);
}
/* Inject a SACK Timeout event into the state machine. */
static void sctp_generate_sack_event(unsigned long data)
@@ -453,6 +484,7 @@ sctp_timer_event_t *sctp_timer_events[SCTP_NUM_TIMEOUT_TYPES] = {
sctp_generate_t4_rto_event,
sctp_generate_t5_shutdown_guard_event,
NULL,
NULL,
sctp_generate_sack_event,
sctp_generate_autoclose_event,
};