Author: tuexen
Date: Fri Mar  8 01:21:48 2013
New Revision: 248018
URL: http://svnweb.freebsd.org/changeset/base/248018

Log:
  MFC r246588:
  
  Fix a bug where HEARTBEATs were still sent in SHUTDOWN_SENT or
  SHUTDOWN_ACK_SENT state. While there, make the corresponding
  code consistent.

Modified:
  stable/8/sys/netinet/sctp_indata.c
  stable/8/sys/netinet/sctp_input.c
  stable/8/sys/netinet/sctp_output.c
  stable/8/sys/netinet/sctp_pcb.c
  stable/8/sys/netinet/sctp_timer.c
  stable/8/sys/netinet/sctp_usrreq.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/netinet/   (props changed)

Modified: stable/8/sys/netinet/sctp_indata.c
==============================================================================
--- stable/8/sys/netinet/sctp_indata.c  Fri Mar  8 01:19:46 2013        
(r248017)
+++ stable/8/sys/netinet/sctp_indata.c  Fri Mar  8 01:21:48 2013        
(r248018)
@@ -4262,19 +4262,19 @@ again:
                    (asoc->stream_queue_cnt == 0)) {
                        struct sctp_nets *netp;
 
-                       if (asoc->alternate) {
-                               netp = asoc->alternate;
-                       } else {
-                               netp = asoc->primary_destination;
-                       }
                        if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
                                goto abort_out_now;
                        }
                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                        SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
                        SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
-                       sctp_send_shutdown_ack(stcb, netp);
                        sctp_stop_timers_for_shutdown(stcb);
+                       if (asoc->alternate) {
+                               netp = asoc->alternate;
+                       } else {
+                               netp = asoc->primary_destination;
+                       }
+                       sctp_send_shutdown_ack(stcb, netp);
                        sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
                            stcb->sctp_ep, stcb, netp);
                }
@@ -4973,11 +4973,6 @@ sctp_handle_sack(struct mbuf *m, int off
                        } else {
                                struct sctp_nets *netp;
 
-                               if (asoc->alternate) {
-                                       netp = asoc->alternate;
-                               } else {
-                                       netp = asoc->primary_destination;
-                               }
                                if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
                                    (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
                                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
@@ -4985,6 +4980,11 @@ sctp_handle_sack(struct mbuf *m, int off
                                SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
                                SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
                                sctp_stop_timers_for_shutdown(stcb);
+                               if (asoc->alternate) {
+                                       netp = asoc->alternate;
+                               } else {
+                                       netp = asoc->primary_destination;
+                               }
                                sctp_send_shutdown(stcb, netp);
                                sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
                                    stcb->sctp_ep, stcb, netp);
@@ -4996,19 +4996,19 @@ sctp_handle_sack(struct mbuf *m, int off
                    (asoc->stream_queue_cnt == 0)) {
                        struct sctp_nets *netp;
 
-                       if (asoc->alternate) {
-                               netp = asoc->alternate;
-                       } else {
-                               netp = asoc->primary_destination;
-                       }
                        if (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT) {
                                goto abort_out_now;
                        }
                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                        SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
                        SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
-                       sctp_send_shutdown_ack(stcb, netp);
                        sctp_stop_timers_for_shutdown(stcb);
+                       if (asoc->alternate) {
+                               netp = asoc->alternate;
+                       } else {
+                               netp = asoc->primary_destination;
+                       }
+                       sctp_send_shutdown_ack(stcb, netp);
                        sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK,
                            stcb->sctp_ep, stcb, netp);
                        return;

Modified: stable/8/sys/netinet/sctp_input.c
==============================================================================
--- stable/8/sys/netinet/sctp_input.c   Fri Mar  8 01:19:46 2013        
(r248017)
+++ stable/8/sys/netinet/sctp_input.c   Fri Mar  8 01:21:48 2013        
(r248018)
@@ -956,7 +956,6 @@ sctp_handle_shutdown(struct sctp_shutdow
        } else {
                /* no outstanding data to send, so move on... */
                /* send SHUTDOWN-ACK */
-               sctp_send_shutdown_ack(stcb, net);
                /* move to SHUTDOWN-ACK-SENT state */
                if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
                    (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
@@ -965,6 +964,7 @@ sctp_handle_shutdown(struct sctp_shutdow
                SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_ACK_SENT);
                SCTP_CLEAR_SUBSTATE(asoc, SCTP_STATE_SHUTDOWN_PENDING);
                sctp_stop_timers_for_shutdown(stcb);
+               sctp_send_shutdown_ack(stcb, net);
                sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNACK, stcb->sctp_ep,
                    stcb, net);
        }

Modified: stable/8/sys/netinet/sctp_output.c
==============================================================================
--- stable/8/sys/netinet/sctp_output.c  Fri Mar  8 01:19:46 2013        
(r248017)
+++ stable/8/sys/netinet/sctp_output.c  Fri Mar  8 01:21:48 2013        
(r248018)
@@ -6579,12 +6579,13 @@ sctp_sendall_iterator(struct sctp_inpcb 
                                         * only send SHUTDOWN the first time
                                         * through
                                         */
-                                       sctp_send_shutdown(stcb, net);
                                        if (SCTP_GET_STATE(asoc) == 
SCTP_STATE_OPEN) {
                                                
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                                        }
                                        SCTP_SET_STATE(asoc, 
SCTP_STATE_SHUTDOWN_SENT);
                                        SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
+                                       sctp_stop_timers_for_shutdown(stcb);
+                                       sctp_send_shutdown(stcb, net);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb,
                                            net);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, stcb->sctp_ep, stcb,
@@ -13097,18 +13098,19 @@ dataless_eof:
                            (SCTP_GET_STATE(asoc) != 
SCTP_STATE_SHUTDOWN_ACK_SENT)) {
                                struct sctp_nets *netp;
 
-                               if (stcb->asoc.alternate) {
-                                       netp = stcb->asoc.alternate;
-                               } else {
-                                       netp = stcb->asoc.primary_destination;
-                               }
                                /* only send SHUTDOWN the first time through */
-                               sctp_send_shutdown(stcb, netp);
                                if (SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) {
                                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                                }
                                SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
                                SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
+                               sctp_stop_timers_for_shutdown(stcb);
+                               if (stcb->asoc.alternate) {
+                                       netp = stcb->asoc.alternate;
+                               } else {
+                                       netp = stcb->asoc.primary_destination;
+                               }
+                               sctp_send_shutdown(stcb, netp);
                                sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, 
stcb->sctp_ep, stcb,
                                    netp);
                                sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, 
stcb->sctp_ep, stcb,

Modified: stable/8/sys/netinet/sctp_pcb.c
==============================================================================
--- stable/8/sys/netinet/sctp_pcb.c     Fri Mar  8 01:19:46 2013        
(r248017)
+++ stable/8/sys/netinet/sctp_pcb.c     Fri Mar  8 01:21:48 2013        
(r248018)
@@ -3332,22 +3332,23 @@ sctp_inpcb_free(struct sctp_inpcb *inp, 
                                    (SCTP_GET_STATE(&asoc->asoc) != 
SCTP_STATE_SHUTDOWN_ACK_SENT)) {
                                        struct sctp_nets *netp;
 
-                                       if (asoc->asoc.alternate) {
-                                               netp = asoc->asoc.alternate;
-                                       } else {
-                                               netp = 
asoc->asoc.primary_destination;
-                                       }
                                        /*
                                         * there is nothing queued to send,
                                         * so I send shutdown
                                         */
-                                       sctp_send_shutdown(asoc, netp);
                                        if ((SCTP_GET_STATE(&asoc->asoc) == 
SCTP_STATE_OPEN) ||
                                            (SCTP_GET_STATE(&asoc->asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
                                                
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                                        }
                                        SCTP_SET_STATE(&asoc->asoc, 
SCTP_STATE_SHUTDOWN_SENT);
                                        SCTP_CLEAR_SUBSTATE(&asoc->asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
+                                       sctp_stop_timers_for_shutdown(asoc);
+                                       if (asoc->asoc.alternate) {
+                                               netp = asoc->asoc.alternate;
+                                       } else {
+                                               netp = 
asoc->asoc.primary_destination;
+                                       }
+                                       sctp_send_shutdown(asoc, netp);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN, asoc->sctp_ep, asoc,
                                            netp);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD, asoc->sctp_ep, asoc,

Modified: stable/8/sys/netinet/sctp_timer.c
==============================================================================
--- stable/8/sys/netinet/sctp_timer.c   Fri Mar  8 01:19:46 2013        
(r248017)
+++ stable/8/sys/netinet/sctp_timer.c   Fri Mar  8 01:21:48 2013        
(r248018)
@@ -1560,18 +1560,19 @@ sctp_autoclose_timer(struct sctp_inpcb *
                                        /* only send SHUTDOWN 1st time thru */
                                        struct sctp_nets *netp;
 
-                                       if (stcb->asoc.alternate) {
-                                               netp = stcb->asoc.alternate;
-                                       } else {
-                                               netp = 
stcb->asoc.primary_destination;
-                                       }
-                                       sctp_send_shutdown(stcb, netp);
                                        if ((SCTP_GET_STATE(asoc) == 
SCTP_STATE_OPEN) ||
                                            (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
                                                
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                                        }
                                        SCTP_SET_STATE(asoc, 
SCTP_STATE_SHUTDOWN_SENT);
                                        SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
+                                       sctp_stop_timers_for_shutdown(stcb);
+                                       if (stcb->asoc.alternate) {
+                                               netp = stcb->asoc.alternate;
+                                       } else {
+                                               netp = 
stcb->asoc.primary_destination;
+                                       }
+                                       sctp_send_shutdown(stcb, netp);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
                                            stcb->sctp_ep, stcb,
                                            netp);

Modified: stable/8/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/8/sys/netinet/sctp_usrreq.c  Fri Mar  8 01:19:46 2013        
(r248017)
+++ stable/8/sys/netinet/sctp_usrreq.c  Fri Mar  8 01:21:48 2013        
(r248018)
@@ -794,25 +794,24 @@ sctp_disconnect(struct socket *so)
                                        /* only send SHUTDOWN 1st time thru */
                                        struct sctp_nets *netp;
 
-                                       if (stcb->asoc.alternate) {
-                                               netp = stcb->asoc.alternate;
-                                       } else {
-                                               netp = 
stcb->asoc.primary_destination;
-                                       }
-                                       sctp_stop_timers_for_shutdown(stcb);
-                                       sctp_send_shutdown(stcb, netp);
-                                       sctp_chunk_output(stcb->sctp_ep, stcb, 
SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
                                        if ((SCTP_GET_STATE(asoc) == 
SCTP_STATE_OPEN) ||
                                            (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
                                                
SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                                        }
                                        SCTP_SET_STATE(asoc, 
SCTP_STATE_SHUTDOWN_SENT);
                                        SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
+                                       sctp_stop_timers_for_shutdown(stcb);
+                                       if (stcb->asoc.alternate) {
+                                               netp = stcb->asoc.alternate;
+                                       } else {
+                                               netp = 
stcb->asoc.primary_destination;
+                                       }
+                                       sctp_send_shutdown(stcb, netp);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
                                            stcb->sctp_ep, stcb, netp);
                                        
sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
                                            stcb->sctp_ep, stcb, netp);
-
+                                       sctp_chunk_output(stcb->sctp_ep, stcb, 
SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
                                }
                        } else {
                                /*
@@ -1014,24 +1013,24 @@ sctp_shutdown(struct socket *so)
                                /* only send SHUTDOWN the first time through */
                                struct sctp_nets *netp;
 
-                               if (stcb->asoc.alternate) {
-                                       netp = stcb->asoc.alternate;
-                               } else {
-                                       netp = stcb->asoc.primary_destination;
-                               }
-                               sctp_stop_timers_for_shutdown(stcb);
-                               sctp_send_shutdown(stcb, netp);
-                               sctp_chunk_output(stcb->sctp_ep, stcb, 
SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
                                if ((SCTP_GET_STATE(asoc) == SCTP_STATE_OPEN) ||
                                    (SCTP_GET_STATE(asoc) == 
SCTP_STATE_SHUTDOWN_RECEIVED)) {
                                        SCTP_STAT_DECR_GAUGE32(sctps_currestab);
                                }
                                SCTP_SET_STATE(asoc, SCTP_STATE_SHUTDOWN_SENT);
                                SCTP_CLEAR_SUBSTATE(asoc, 
SCTP_STATE_SHUTDOWN_PENDING);
+                               sctp_stop_timers_for_shutdown(stcb);
+                               if (stcb->asoc.alternate) {
+                                       netp = stcb->asoc.alternate;
+                               } else {
+                                       netp = stcb->asoc.primary_destination;
+                               }
+                               sctp_send_shutdown(stcb, netp);
                                sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWN,
                                    stcb->sctp_ep, stcb, netp);
                                sctp_timer_start(SCTP_TIMER_TYPE_SHUTDOWNGUARD,
                                    stcb->sctp_ep, stcb, netp);
+                               sctp_chunk_output(stcb->sctp_ep, stcb, 
SCTP_OUTPUT_FROM_T3, SCTP_SO_LOCKED);
                        }
                } else {
                        /*
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to