Author: tuexen
Date: Sun Nov  7 17:44:04 2010
New Revision: 214928
URL: http://svn.freebsd.org/changeset/base/214928

Log:
  * Use exponential backoff for retransmission of SHUTDOWN and
    SHUTDOWN-ACK chunks.
  * While there, do some cleanups.
  
  MFC after: 3 days.

Modified:
  head/sys/netinet/sctp_timer.c

Modified: head/sys/netinet/sctp_timer.c
==============================================================================
--- head/sys/netinet/sctp_timer.c       Sun Nov  7 17:41:09 2010        
(r214927)
+++ head/sys/netinet/sctp_timer.c       Sun Nov  7 17:44:04 2010        
(r214928)
@@ -291,6 +291,10 @@ sctp_threshold_management(struct sctp_in
        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 
        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 
                        }
                        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 
        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
  * 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 *i
                /* 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
                /* 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);
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to