Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / usrsctp / usrsctplib / netinet / sctp_input.c
index f8f177a..889f9bb 100755 (executable)
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 254854 2013-08-25 12:44:03Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 263237 2014-03-16 12:32:16Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -108,7 +108,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
        }
        /* validate length */
        if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_chunk)) {
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
@@ -122,7 +122,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
        init = &cp->init;
        if (init->initiate_tag == 0) {
                /* protocol error... send abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
@@ -134,7 +134,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
        }
        if (ntohl(init->a_rwnd) < SCTP_MIN_RWND) {
                /* invalid parameter... send abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
@@ -146,7 +146,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
        }
        if (init->num_inbound_streams == 0) {
                /* protocol error... send abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
@@ -158,7 +158,7 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
        }
        if (init->num_outbound_streams == 0) {
                /* protocol error... send abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
@@ -171,7 +171,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
        if (sctp_validate_init_auth_params(m, offset + sizeof(*cp),
                                           offset + ntohs(cp->ch.chunk_length))) {
                /* auth parameter(s) error... send abort */
-               sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, NULL,
+               op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                            "Problem with AUTH parameters");
+               sctp_abort_association(inp, stcb, m, iphlen, src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
 #endif
@@ -199,7 +201,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset,
                 * this state :-)
                 */
                if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
-                       sctp_send_abort(m, iphlen, src, dst, sh, 0, NULL,
+                       op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                    "No listener");
+                       sctp_send_abort(m, iphlen, src, dst, sh, 0, op_err,
 #if defined(__FreeBSD__)
                                        use_mflowid, mflowid,
 #endif
@@ -464,7 +468,6 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
 
        /* First verify that we have no illegal param's */
        abort_flag = 0;
-       op_err = NULL;
 
        op_err = sctp_arethere_unrecognized_parameters(m,
                                                       (offset + sizeof(struct sctp_init_chunk)),
@@ -487,12 +490,13 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
        if ((retval = sctp_load_addresses_from_init(stcb, m,
            (offset + sizeof(struct sctp_init_chunk)), initack_limit,
            src, dst, NULL))) {
-               /* Huh, we should abort */
+               op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                            "Problem with address parameters");
                SCTPDBG(SCTP_DEBUG_INPUT1,
                        "Load addresses from INIT causes an abort %d\n",
                        retval);
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
-                                      src, dst, sh, NULL,
+                                      src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                       use_mflowid, mflowid,
 #endif
@@ -550,8 +554,7 @@ sctp_process_init_ack(struct mbuf *m, int iphlen, int offset,
                 */
                if (retval == -3) {
                        /* We abort with an error of missing mandatory param */
-                       op_err =
-                           sctp_generate_invmanparam(SCTP_CAUSE_MISSING_PARAM);
+                       op_err = sctp_generate_cause(SCTP_CAUSE_MISSING_PARAM, "");
                        if (op_err) {
                                /*
                                 * Expand beyond to include the mandatory
@@ -1346,7 +1349,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
        }
        if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_init_ack_chunk)) {
                /* Invalid length */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1360,7 +1363,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
        /* validate parameters */
        if (init_ack->initiate_tag == 0) {
                /* protocol error... send an abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1372,7 +1375,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
        }
        if (ntohl(init_ack->a_rwnd) < SCTP_MIN_RWND) {
                /* protocol error... send an abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1384,7 +1387,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
        }
        if (init_ack->num_inbound_streams == 0) {
                /* protocol error... send an abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1396,7 +1399,7 @@ sctp_handle_init_ack(struct mbuf *m, int iphlen, int offset,
        }
        if (init_ack->num_outbound_streams == 0) {
                /* protocol error... send an abort */
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_INVALID_PARAM);
+               op_err = sctp_generate_cause(SCTP_CAUSE_INVALID_PARAM, "");
                sctp_abort_association(stcb->sctp_ep, stcb, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -1514,7 +1517,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
        struct sctp_init_ack_chunk *initack_cp, initack_buf;
        struct sctp_nets *net;
        struct mbuf *op_err;
-       struct sctp_paramhdr *ph;
        int init_offset, initack_offset, i;
        int retval;
        int spec_flag = 0;
@@ -1533,17 +1535,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
        if (SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_ACK_SENT) {
                /* SHUTDOWN came in after sending INIT-ACK */
                sctp_send_shutdown_ack(stcb, stcb->asoc.primary_destination);
-               op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-                                              0, M_NOWAIT, 1, MT_DATA);
-               if (op_err == NULL) {
-                       /* FOOBAR */
-                       return (NULL);
-               }
-               /* Set the len */
-               SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-               ph = mtod(op_err, struct sctp_paramhdr *);
-               ph->param_type = htons(SCTP_CAUSE_COOKIE_IN_SHUTDOWN);
-               ph->param_length = htons(sizeof(struct sctp_paramhdr));
+               op_err = sctp_generate_cause(SCTP_CAUSE_COOKIE_IN_SHUTDOWN, "");
                sctp_send_operr_to(src, dst, sh, cookie->peers_vtag, op_err,
 #if defined(__FreeBSD__)
                                   use_mflowid, mflowid,
@@ -1611,7 +1603,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
                        return (NULL);
 
                }
-               switch SCTP_GET_STATE(asoc) {
+               switch (SCTP_GET_STATE(asoc)) {
                        case SCTP_STATE_COOKIE_WAIT:
                        case SCTP_STATE_COOKIE_ECHOED:
                                /*
@@ -1750,25 +1742,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
                 * from hsot-2 (or 1). Now we have colliding state. We must
                 * send an abort here with colliding state indication.
                 */
-               op_err = sctp_get_mbuf_for_msg(sizeof(struct sctp_paramhdr),
-                                              0, M_NOWAIT, 1, MT_DATA);
-               if (op_err == NULL) {
-                       /* FOOBAR */
-                       return (NULL);
-               }
-               /* pre-reserve some space */
-#ifdef INET6
-               SCTP_BUF_RESV_UF(op_err, sizeof(struct ip6_hdr));
-#else
-               SCTP_BUF_RESV_UF(op_err, sizeof(struct ip));
-#endif
-               SCTP_BUF_RESV_UF(op_err, sizeof(struct sctphdr));
-               SCTP_BUF_RESV_UF(op_err,  sizeof(struct sctp_chunkhdr));
-               /* Set the len */
-               SCTP_BUF_LEN(op_err) = sizeof(struct sctp_paramhdr);
-               ph = mtod(op_err, struct sctp_paramhdr *);
-               ph->param_type = htons(SCTP_CAUSE_NAT_COLLIDING_STATE);
-               ph->param_length = htons(sizeof(struct sctp_paramhdr));
+               op_err = sctp_generate_cause(SCTP_CAUSE_NAT_COLLIDING_STATE, "");
                sctp_send_abort(m, iphlen,  src, dst, sh, 0, op_err,
 #if defined(__FreeBSD__)
                                use_mflowid, mflowid,
@@ -2186,8 +2160,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
                /* memory problem? */
                SCTPDBG(SCTP_DEBUG_INPUT1,
                        "process_cookie_new: no room for another TCB!\n");
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
-
+               op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
                sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -2223,7 +2196,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
                 * association.
                 */
                atomic_add_int(&stcb->asoc.refcnt, 1);
-               op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+               op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
                sctp_abort_association(inp, (struct sctp_tcb *)NULL, m, iphlen,
                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -2912,7 +2885,7 @@ sctp_handle_cookie_echo(struct mbuf *m, int iphlen, int offset,
 #endif
                                /* Too many sockets */
                                SCTPDBG(SCTP_DEBUG_INPUT1, "process_cookie_new: no room for another socket!\n");
-                               op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+                               op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
                                sctp_abort_association(*inp_p, NULL, m, iphlen,
                                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -4533,6 +4506,8 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
     uint32_t vrf_id, uint16_t port)
 {
        struct sctp_association *asoc;
+       struct mbuf *op_err;
+       char msg[SCTP_DIAG_INFO_LEN];
        uint32_t vtag_in;
        int num_chunks = 0;     /* number of control chunks processed */
        uint32_t chk_length;
@@ -4683,8 +4658,11 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
                        }
                }
                if (stcb == NULL) {
+                       snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+                       op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                    msg);
                        /* no association, so it's out of the blue... */
-                       sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp,
+                       sctp_handle_ootb(m, iphlen, *offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
                                         use_mflowid, mflowid,
 #endif
@@ -4726,8 +4704,11 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
                                if (locked_tcb) {
                                        SCTP_TCB_UNLOCK(locked_tcb);
                                }
+                               snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+                               op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                            msg);
                                sctp_handle_ootb(m, iphlen, *offset, src, dst,
-                                                sh, inp,
+                                                sh, inp, op_err,
 #if defined(__FreeBSD__)
                                                 use_mflowid, mflowid,
 #endif
@@ -4872,8 +4853,10 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
                        /* The INIT chunk must be the only chunk. */
                        if ((num_chunks > 1) ||
                            (length - *offset > (int)SCTP_SIZE32(chk_length))) {
+                               op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                            "INIT not the only chunk");
                                sctp_abort_association(inp, stcb, m, iphlen,
-                                                      src, dst, sh, NULL,
+                                                      src, dst, sh, op_err,
 #if defined(__FreeBSD__)
                                                       use_mflowid, mflowid,
 #endif
@@ -4883,9 +4866,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
                        }
                        /* Honor our resource limit. */
                        if (chk_length > SCTP_LARGEST_INIT_ACCEPTED) {
-                               struct mbuf *op_err;
-
-                               op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+                               op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
                                sctp_abort_association(inp, stcb, m, iphlen,
                                                       src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -5252,9 +5233,7 @@ sctp_process_control(struct mbuf *m, int iphlen, int *offset, int length,
                        if ((stcb == NULL) && (inp->sctp_socket->so_qlen >= inp->sctp_socket->so_qlimit)) {
                                if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) &&
                                    (SCTP_BASE_SYSCTL(sctp_abort_if_one_2_one_hits_limit))) {
-                                       struct mbuf *op_err;
-
-                                       op_err = sctp_generate_invmanparam(SCTP_CAUSE_OUT_OF_RESC);
+                                       op_err = sctp_generate_cause(SCTP_CAUSE_OUT_OF_RESC, "");
                                        sctp_abort_association(inp, stcb, m, iphlen,
                                                               src, dst, sh, op_err,
 #if defined(__FreeBSD__)
@@ -5749,7 +5728,8 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
 {
        uint32_t high_tsn;
        int fwd_tsn_seen = 0, data_processed = 0;
-       struct mbuf *m = *mm;
+       struct mbuf *m = *mm, *op_err;
+       char msg[SCTP_DIAG_INFO_LEN];
        int un_sent;
        int cnt_ctrl_ready = 0;
        struct sctp_inpcb *inp = NULL, *inp_decr = NULL;
@@ -5843,8 +5823,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
                        if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
                            ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
                             (ch->chunk_type != SCTP_INIT))) {
+                               op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                            "Out of the blue");
                                sctp_send_abort(m, iphlen, src, dst,
-                                               sh, 0, NULL,
+                                               sh, 0, op_err,
 #if defined(__FreeBSD__)
                                                use_mflowid, mflowid,
 #endif
@@ -5912,7 +5894,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
                         */
                        SCTP_TCB_UNLOCK(stcb);
                        stcb = NULL;
-                       sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+                       snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+                       op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                    msg);
+                       sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
                                         use_mflowid, mflowid,
 #endif
@@ -5963,7 +5948,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
                }
                if (stcb == NULL) {
                        /* out of the blue DATA chunk */
-                       sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+                       snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+                       op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                    msg);
+                       sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
                                         use_mflowid, mflowid,
 #endif
@@ -6035,7 +6023,10 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
                        /*
                         * We consider OOTB any data sent during asoc setup.
                         */
-                       sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp,
+                       snprintf(msg, sizeof(msg), "OOTB, %s:%d at %s\n", __FILE__, __LINE__, __FUNCTION__);
+                       op_err = sctp_generate_cause(SCTP_BASE_SYSCTL(sctp_diag_info_code),
+                                                    msg);
+                       sctp_handle_ootb(m, iphlen, offset, src, dst, sh, inp, op_err,
 #if defined(__FreeBSD__)
                                         use_mflowid, mflowid,
 #endif