Author: tuexen
Date: Fri May 11 19:15:33 2012
New Revision: 235283
URL: http://svn.freebsd.org/changeset/base/235283

Log:
  Fix a bug in the handling of association reset request.
  
  MFC after: 3 days

Modified:
  head/sys/netinet/sctp_input.c

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c       Fri May 11 18:07:36 2012        
(r235282)
+++ head/sys/netinet/sctp_input.c       Fri May 11 19:15:33 2012        
(r235283)
@@ -3773,46 +3773,40 @@ sctp_handle_str_reset_request_tsn(struct
 
        seq = ntohl(req->request_seq);
        if (asoc->str_reset_seq_in == seq) {
+               asoc->last_reset_action[1] = stcb->asoc.last_reset_action[0];
                if (!(asoc->local_strreset_support & 
SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
-                       stcb->asoc.last_reset_action[1] = 
stcb->asoc.last_reset_action[0];
-                       stcb->asoc.last_reset_action[0] = 
SCTP_STREAM_RESET_RESULT_PERFORMED;
-
                        asoc->last_reset_action[0] = 
SCTP_STREAM_RESET_RESULT_DENIED;
-               } else
+               } else {
                        fwdtsn.ch.chunk_length = htons(sizeof(struct 
sctp_forward_tsn_chunk));
-               fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
-               fwdtsn.ch.chunk_flags = 0;
-               fwdtsn.new_cumulative_tsn = 
htonl(stcb->asoc.highest_tsn_inside_map + 1);
-               sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, NULL, 0);
-               if (abort_flag) {
-                       return (1);
-               }
-               asoc->highest_tsn_inside_map += SCTP_STREAM_RESET_TSN_DELTA;
-               if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_MAP_LOGGING_ENABLE) {
-                       sctp_log_map(0, 10, asoc->highest_tsn_inside_map, 
SCTP_MAP_SLIDE_RESULT);
-               }
-               asoc->tsn_last_delivered = asoc->cumulative_tsn = 
asoc->highest_tsn_inside_map;
-               asoc->mapping_array_base_tsn = asoc->highest_tsn_inside_map + 1;
-               memset(asoc->mapping_array, 0, asoc->mapping_array_size);
-               asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map;
-               memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
-               atomic_add_int(&asoc->sending_seq, 1);
-               /* save off historical data for retrans */
-               asoc->last_sending_seq[1] = asoc->last_sending_seq[0];
-               asoc->last_sending_seq[0] = asoc->sending_seq;
-               asoc->last_base_tsnsent[1] = asoc->last_base_tsnsent[0];
-               asoc->last_base_tsnsent[0] = asoc->mapping_array_base_tsn;
-
-               sctp_add_stream_reset_result_tsn(chk,
-                   ntohl(req->request_seq),
-                   SCTP_STREAM_RESET_RESULT_PERFORMED,
-                   asoc->sending_seq,
-                   asoc->mapping_array_base_tsn);
-               sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
-               sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
-               asoc->last_reset_action[1] = asoc->last_reset_action[0];
-               asoc->last_reset_action[0] = SCTP_STREAM_RESET_RESULT_PERFORMED;
-               sctp_notify_stream_reset_tsn(stcb, asoc->sending_seq, 
(asoc->mapping_array_base_tsn + 1), 0);
+                       fwdtsn.ch.chunk_type = SCTP_FORWARD_CUM_TSN;
+                       fwdtsn.ch.chunk_flags = 0;
+                       fwdtsn.new_cumulative_tsn = 
htonl(stcb->asoc.highest_tsn_inside_map + 1);
+                       sctp_handle_forward_tsn(stcb, &fwdtsn, &abort_flag, 
NULL, 0);
+                       if (abort_flag) {
+                               return (1);
+                       }
+                       asoc->highest_tsn_inside_map += 
SCTP_STREAM_RESET_TSN_DELTA;
+                       if (SCTP_BASE_SYSCTL(sctp_logging_level) & 
SCTP_MAP_LOGGING_ENABLE) {
+                               sctp_log_map(0, 10, 
asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT);
+                       }
+                       asoc->tsn_last_delivered = asoc->cumulative_tsn = 
asoc->highest_tsn_inside_map;
+                       asoc->mapping_array_base_tsn = 
asoc->highest_tsn_inside_map + 1;
+                       memset(asoc->mapping_array, 0, 
asoc->mapping_array_size);
+                       asoc->highest_tsn_inside_nr_map = 
asoc->highest_tsn_inside_map;
+                       memset(asoc->nr_mapping_array, 0, 
asoc->mapping_array_size);
+                       atomic_add_int(&asoc->sending_seq, 1);
+                       /* save off historical data for retrans */
+                       asoc->last_sending_seq[1] = asoc->last_sending_seq[0];
+                       asoc->last_sending_seq[0] = asoc->sending_seq;
+                       asoc->last_base_tsnsent[1] = asoc->last_base_tsnsent[0];
+                       asoc->last_base_tsnsent[0] = 
asoc->mapping_array_base_tsn;
+                       sctp_reset_out_streams(stcb, 0, (uint16_t *) NULL);
+                       sctp_reset_in_stream(stcb, 0, (uint16_t *) NULL);
+                       asoc->last_reset_action[0] = 
SCTP_STREAM_RESET_RESULT_PERFORMED;
+                       sctp_notify_stream_reset_tsn(stcb, asoc->sending_seq, 
(asoc->mapping_array_base_tsn + 1), 0);
+               }
+               sctp_add_stream_reset_result_tsn(chk, seq, 
asoc->last_reset_action[0],
+                   asoc->last_sending_seq[0], asoc->last_base_tsnsent[0]);
                asoc->str_reset_seq_in++;
        } else if (asoc->str_reset_seq_in - 1 == seq) {
                sctp_add_stream_reset_result_tsn(chk, seq, 
asoc->last_reset_action[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