mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-17 10:26:15 +00:00
* Use exponential backoff for retransmission of SHUTDOWN and
SHUTDOWN-ACK chunks. * While there, do some cleanups. MFC after: 3 days.
This commit is contained in:
parent
43b838f75c
commit
b61c358887
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=214928
@ -291,6 +291,10 @@ sctp_threshold_management(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* sctp_find_alternate_net() returns a non-NULL pointer as long
|
||||
* the argument net is non-NULL.
|
||||
*/
|
||||
struct sctp_nets *
|
||||
sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net,
|
||||
@ -440,8 +444,7 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
else if (mode == 1) {
|
||||
TAILQ_FOREACH(mnet, &stcb->asoc.nets, sctp_next) {
|
||||
if (((mnet->dest_state & SCTP_ADDR_REACHABLE) != SCTP_ADDR_REACHABLE) ||
|
||||
(mnet->dest_state & SCTP_ADDR_UNCONFIRMED)
|
||||
) {
|
||||
(mnet->dest_state & SCTP_ADDR_UNCONFIRMED)) {
|
||||
/*
|
||||
* will skip ones that are not-reachable or
|
||||
* unconfirmed
|
||||
@ -505,12 +508,10 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
}
|
||||
alt->src_addr_selected = 0;
|
||||
}
|
||||
if (
|
||||
((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
|
||||
(alt->ro.ro_rt != NULL) &&
|
||||
/* sa_ignore NO_NULL_CHK */
|
||||
(!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))
|
||||
) {
|
||||
if (((alt->dest_state & SCTP_ADDR_REACHABLE) == SCTP_ADDR_REACHABLE) &&
|
||||
(alt->ro.ro_rt != NULL) &&
|
||||
(!(alt->dest_state & SCTP_ADDR_UNCONFIRMED))) {
|
||||
/* Found a reachable address */
|
||||
break;
|
||||
}
|
||||
@ -549,8 +550,6 @@ sctp_find_alternate_net(struct sctp_tcb *stcb,
|
||||
return (alt);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
sctp_backoff_on_timeout(struct sctp_tcb *stcb,
|
||||
struct sctp_nets *net,
|
||||
@ -1021,8 +1020,7 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp,
|
||||
* used, then pick dest with largest ssthresh for any
|
||||
* retransmission.
|
||||
*/
|
||||
alt = net;
|
||||
alt = sctp_find_alternate_net(stcb, alt, 1);
|
||||
alt = sctp_find_alternate_net(stcb, net, 1);
|
||||
/*
|
||||
* CUCv2: If a different dest is picked for the
|
||||
* retransmission, then new (rtx-)pseudo_cumack needs to be
|
||||
@ -1213,7 +1211,7 @@ sctp_t1init_timer(struct sctp_inpcb *inp,
|
||||
struct sctp_nets *alt;
|
||||
|
||||
alt = sctp_find_alternate_net(stcb, stcb->asoc.primary_destination, 0);
|
||||
if ((alt != NULL) && (alt != stcb->asoc.primary_destination)) {
|
||||
if (alt != stcb->asoc.primary_destination) {
|
||||
sctp_move_chunks_from_net(stcb, stcb->asoc.primary_destination);
|
||||
stcb->asoc.primary_destination = alt;
|
||||
}
|
||||
@ -1480,6 +1478,7 @@ sctp_delete_prim_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
* For the shutdown and shutdown-ack, we do not keep one around on the
|
||||
* control queue. This means we must generate a new one and call the general
|
||||
* chunk output routine, AFTER having done threshold management.
|
||||
* It is assumed that net is non-NULL.
|
||||
*/
|
||||
int
|
||||
sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
@ -1492,18 +1491,13 @@ sctp_shutdown_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* Assoc is over */
|
||||
return (1);
|
||||
}
|
||||
sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
|
||||
/* second select an alternative */
|
||||
alt = sctp_find_alternate_net(stcb, net, 0);
|
||||
|
||||
/* third generate a shutdown into the queue for out net */
|
||||
if (alt) {
|
||||
sctp_send_shutdown(stcb, alt);
|
||||
} else {
|
||||
/*
|
||||
* if alt is NULL, there is no dest to send to??
|
||||
*/
|
||||
return (0);
|
||||
}
|
||||
sctp_send_shutdown(stcb, alt);
|
||||
|
||||
/* fourth restart timer */
|
||||
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, inp, stcb, alt);
|
||||
return (0);
|
||||
@ -1520,6 +1514,7 @@ sctp_shutdownack_timer(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
|
||||
/* Assoc is over */
|
||||
return (1);
|
||||
}
|
||||
sctp_backoff_on_timeout(stcb, net, 1, 0, 0);
|
||||
/* second select an alternative */
|
||||
alt = sctp_find_alternate_net(stcb, net, 0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user