Author: tuexen
Date: Thu May 15 20:13:44 2014
New Revision: 266186
URL: http://svnweb.freebsd.org/changeset/base/266186

Log:
  MFC r264679:
  
  Send the correct error cause, when a DATA chunk with no user data
  is received. This bug was reported by Irene Ruengeler.

Modified:
  stable/9/sys/netinet/sctp.h
  stable/9/sys/netinet/sctp_indata.c
  stable/9/sys/netinet/sctputil.c
  stable/9/sys/netinet/sctputil.h
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/netinet/sctp.h
==============================================================================
--- stable/9/sys/netinet/sctp.h Thu May 15 20:10:58 2014        (r266185)
+++ stable/9/sys/netinet/sctp.h Thu May 15 20:13:44 2014        (r266186)
@@ -408,6 +408,11 @@ struct sctp_error_unrecognized_chunk {
        struct sctp_chunkhdr ch;/* header from chunk in error */
 }                             SCTP_PACKED;
 
+struct sctp_error_no_user_data {
+       struct sctp_error_cause cause;  /* code=SCTP_CAUSE_NO_USER_DATA */
+       uint32_t tsn;           /* TSN of the empty data chunk */
+}                       SCTP_PACKED;
+
 /*
  * Main SCTP chunk types we place these here so natd and f/w's in user land
  * can find them.

Modified: stable/9/sys/netinet/sctp_indata.c
==============================================================================
--- stable/9/sys/netinet/sctp_indata.c  Thu May 15 20:10:58 2014        
(r266185)
+++ stable/9/sys/netinet/sctp_indata.c  Thu May 15 20:13:44 2014        
(r266186)
@@ -2322,7 +2322,7 @@ sctp_process_data(struct mbuf **mm, int 
                        continue;
                }
                if (ch->ch.chunk_type == SCTP_DATA) {
-                       if ((size_t)chk_length < sizeof(struct sctp_data_chunk) 
+ 1) {
+                       if ((size_t)chk_length < sizeof(struct 
sctp_data_chunk)) {
                                /*
                                 * Need to send an abort since we had a
                                 * invalid data chunk.
@@ -2340,6 +2340,21 @@ sctp_process_data(struct mbuf **mm, int 
                                    vrf_id, port);
                                return (2);
                        }
+                       if ((size_t)chk_length == sizeof(struct 
sctp_data_chunk)) {
+                               /*
+                                * Need to send an abort since we had an
+                                * empty data chunk.
+                                */
+                               struct mbuf *op_err;
+
+                               op_err = 
sctp_generate_no_user_data_cause(ch->dp.tsn);
+                               stcb->sctp_ep->last_abort_code = 
SCTP_FROM_SCTP_INDATA + SCTP_LOC_19;
+                               sctp_abort_association(inp, stcb, m, iphlen,
+                                   src, dst, sh, op_err,
+                                   use_mflowid, mflowid,
+                                   vrf_id, port);
+                               return (2);
+                       }
 #ifdef SCTP_AUDITING_ENABLED
                        sctp_audit_log(0xB1, 0);
 #endif

Modified: stable/9/sys/netinet/sctputil.c
==============================================================================
--- stable/9/sys/netinet/sctputil.c     Thu May 15 20:10:58 2014        
(r266185)
+++ stable/9/sys/netinet/sctputil.c     Thu May 15 20:13:44 2014        
(r266186)
@@ -4654,6 +4654,25 @@ sctp_generate_cause(uint16_t code, char 
        return (m);
 }
 
+struct mbuf *
+sctp_generate_no_user_data_cause(uint32_t tsn)
+{
+       struct mbuf *m;
+       struct sctp_error_no_user_data *no_user_data_cause;
+       size_t len;
+
+       len = sizeof(struct sctp_error_no_user_data);
+       m = sctp_get_mbuf_for_msg(len, 0, M_NOWAIT, 1, MT_DATA);
+       if (m != NULL) {
+               SCTP_BUF_LEN(m) = len;
+               no_user_data_cause = mtod(m, struct sctp_error_no_user_data *);
+               no_user_data_cause->cause.code = htons(SCTP_CAUSE_NO_USER_DATA);
+               no_user_data_cause->cause.length = htons((uint16_t) len);
+               no_user_data_cause->tsn = tsn;  /* tsn is passed in as NBO */
+       }
+       return (m);
+}
+
 #ifdef SCTP_MBCNT_LOGGING
 void
 sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,

Modified: stable/9/sys/netinet/sctputil.h
==============================================================================
--- stable/9/sys/netinet/sctputil.h     Thu May 15 20:10:58 2014        
(r266185)
+++ stable/9/sys/netinet/sctputil.h     Thu May 15 20:13:44 2014        
(r266186)
@@ -254,6 +254,7 @@ sctp_release_pr_sctp_chunk(struct sctp_t
 );
 
 struct mbuf *sctp_generate_cause(uint16_t, char *);
+struct mbuf *sctp_generate_no_user_data_cause(uint32_t);
 
 void 
 sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
_______________________________________________
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