Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / usrsctp / usrsctplib / netinet / sctp_output.c
index a305ea5..57cc8c6 100755 (executable)
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 271230 2014-09-07 18:05:37Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 273634 2014-10-25 09:25:29Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -3477,7 +3477,12 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
        if (ro->ro_rt == NULL) {
                return (NULL);
        }
+#if defined(__Userspace_os_Windows)
+       /* On Windows the sa_family is U_SHORT or ADDRESS_FAMILY */
+       fam = (sa_family_t)ro->ro_dst.sa_family;
+#else
        fam = ro->ro_dst.sa_family;
+#endif
        dest_is_priv = dest_is_loop = 0;
        /* Setup our scopes for the destination */
        switch (fam) {
@@ -7160,9 +7165,10 @@ sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr,
        if (do_chunk_output)
                sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_USR_SEND, SCTP_SO_NOT_LOCKED);
        else if (added_control) {
-               int num_out = 0, reason = 0, now_filled = 0;
+               int num_out, reason, now_filled = 0;
                struct timeval now;
                int frag_point;
+
                frag_point = sctp_get_frag_point(stcb, &stcb->asoc);
                (void)sctp_med_chunk_output(inp, stcb, &stcb->asoc, &num_out,
                                      &reason, 1, 1, &now, &now_filled, frag_point, SCTP_SO_NOT_LOCKED);
@@ -7195,13 +7201,6 @@ sctp_sendall_completes(void *ptr, uint32_t val SCTP_UNUSED)
        SCTP_FREE(ca, SCTP_M_COPYAL);
 }
 
-
-#define        MC_ALIGN(m, len) do {                                           \
-       SCTP_BUF_RESV_UF(m, ((MCLBYTES - (len)) & ~(sizeof(long) - 1)); \
-} while (0)
-
-
-
 static struct mbuf *
 sctp_copy_out_all(struct uio *uio, int len)
 {
@@ -8249,6 +8248,7 @@ sctp_med_chunk_output(struct sctp_inpcb *inp,
        }
 #endif
        *num_out = 0;
+       *reason_code = 0;
        auth_keyid = stcb->asoc.authinfo.active_keyid;
        if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) ||
            (asoc->state & SCTP_STATE_SHUTDOWN_RECEIVED) ||
@@ -9372,16 +9372,11 @@ sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
                return;
        }
        chk->send_size = 0;
-       mat = op_err;
-       while (mat != NULL) {
+       for (mat = op_err; mat != NULL; mat = SCTP_BUF_NEXT(mat)) {
                chk->send_size += SCTP_BUF_LEN(mat);
-               mat = SCTP_BUF_NEXT(mat);
        }
-       chk->rec.chunk_id.id = SCTP_OPERATION_ERROR;
-       chk->rec.chunk_id.can_take_data = 1;
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
-       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->data = op_err;
        chk->whoTo = NULL;
@@ -9469,12 +9464,12 @@ sctp_send_cookie_echo(struct mbuf *m,
                return (-5);
        }
        chk->copy_by_ref = 0;
-       chk->send_size = plen;
        chk->rec.chunk_id.id = SCTP_COOKIE_ECHO;
        chk->rec.chunk_id.can_take_data = 0;
+       chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
+       chk->send_size = plen;
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
-       chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
        chk->asoc = &stcb->asoc;
        chk->data = cookie;
        chk->whoTo = net;
@@ -9537,12 +9532,12 @@ sctp_send_heartbeat_ack(struct sctp_tcb *stcb,
                return;
        }
        chk->copy_by_ref = 0;
-       chk->send_size = chk_length;
        chk->rec.chunk_id.id = SCTP_HEARTBEAT_ACK;
        chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
+       chk->send_size = chk_length;
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
-       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->data = outchain;
        chk->whoTo = net;
@@ -9574,12 +9569,12 @@ sctp_send_cookie_ack(struct sctp_tcb *stcb)
                return;
        }
        chk->copy_by_ref = 0;
-       chk->send_size = sizeof(struct sctp_chunkhdr);
        chk->rec.chunk_id.id = SCTP_COOKIE_ACK;
        chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
+       chk->send_size = sizeof(struct sctp_chunkhdr);
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
-       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->data = cookie_ack;
        if (chk->asoc->last_control_chunk_from != NULL) {
@@ -9620,9 +9615,10 @@ sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
                return;
        }
        chk->copy_by_ref = 0;
-       chk->send_size = sizeof(struct sctp_chunkhdr);
        chk->rec.chunk_id.id = SCTP_SHUTDOWN_ACK;
        chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
+       chk->send_size = sizeof(struct sctp_chunkhdr);
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
        chk->flags = 0;
@@ -9663,9 +9659,10 @@ sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
                return;
        }
        chk->copy_by_ref = 0;
-       chk->send_size = sizeof(struct sctp_shutdown_chunk);
        chk->rec.chunk_id.id = SCTP_SHUTDOWN;
        chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
+       chk->send_size = sizeof(struct sctp_shutdown_chunk);
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
        chk->flags = 0;
@@ -9719,13 +9716,13 @@ sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked)
        }
 
        chk->copy_by_ref = 0;
-       chk->data = m_asconf;
-       chk->send_size = len;
        chk->rec.chunk_id.id = SCTP_ASCONF;
        chk->rec.chunk_id.can_take_data = 0;
+       chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
+       chk->data = m_asconf;
+       chk->send_size = len;
        chk->sent = SCTP_DATAGRAM_UNSENT;
        chk->snd_count = 0;
-       chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
        chk->asoc = &stcb->asoc;
        chk->whoTo = net;
        if (chk->whoTo) {
@@ -9815,7 +9812,9 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb)
                        return;
                }
                chk->copy_by_ref = 0;
-
+               chk->rec.chunk_id.id = SCTP_ASCONF_ACK;
+               chk->rec.chunk_id.can_take_data = 1;
+               chk->flags = CHUNK_FLAGS_FRAGMENT_OK;
                chk->whoTo = net;
                if (chk->whoTo) {
                        atomic_add_int(&chk->whoTo->ref_count, 1);
@@ -9824,11 +9823,8 @@ sctp_send_asconf_ack(struct sctp_tcb *stcb)
                chk->send_size = 0;
                /* Get size */
                chk->send_size = ack->len;
-               chk->rec.chunk_id.id = SCTP_ASCONF_ACK;
-               chk->rec.chunk_id.can_take_data = 1;
                chk->sent = SCTP_DATAGRAM_UNSENT;
                chk->snd_count = 0;
-               chk->flags |= CHUNK_FLAGS_FRAGMENT_OK; /* XXX */
                chk->asoc = &stcb->asoc;
 
                TAILQ_INSERT_TAIL(&chk->asoc->control_send_queue, chk, sctp_next);
@@ -10411,7 +10407,7 @@ sctp_chunk_output (struct sctp_inpcb *inp,
         */
        struct sctp_association *asoc;
        struct sctp_nets *net;
-       int error = 0, num_out = 0, tot_out = 0, ret = 0, reason_code = 0;
+       int error = 0, num_out, tot_out = 0, ret = 0, reason_code;
        unsigned int burst_cnt = 0;
        struct timeval now;
        int now_filled = 0;
@@ -10741,6 +10737,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
        chk->copy_by_ref = 0;
        chk->rec.chunk_id.id = SCTP_FORWARD_CUM_TSN;
        chk->rec.chunk_id.can_take_data = 0;
+       chk->flags = 0;
        chk->asoc = asoc;
        chk->whoTo = NULL;
        chk->data = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
@@ -10974,6 +10971,7 @@ sctp_send_sack(struct sctp_tcb *stcb, int so_locked
        /* Clear our pkt counts */
        asoc->data_pkts_seen = 0;
 
+       a_chk->flags = 0;
        a_chk->asoc = asoc;
        a_chk->snd_count = 0;
        a_chk->send_size = 0;   /* fill in later */
@@ -11897,6 +11895,7 @@ sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net,int so_locked
        chk->copy_by_ref = 0;
        chk->rec.chunk_id.id = SCTP_HEARTBEAT_REQUEST;
        chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->send_size = sizeof(struct sctp_heartbeat_chunk);
 
@@ -11924,7 +11923,7 @@ sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net,int so_locked
        hb->heartbeat.hb_info.time_value_1 = now.tv_sec;
        hb->heartbeat.hb_info.time_value_2 = now.tv_usec;
        /* Did our user request this one, put it in */
-       hb->heartbeat.hb_info.addr_family = net->ro._l_addr.sa.sa_family;
+       hb->heartbeat.hb_info.addr_family = (uint8_t)net->ro._l_addr.sa.sa_family;
 #ifdef HAVE_SA_LEN
        hb->heartbeat.hb_info.addr_len = net->ro._l_addr.sa.sa_len;
 #else
@@ -12027,10 +12026,11 @@ sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
        if (chk == NULL) {
                return;
        }
-       chk->copy_by_ref = 0;
        SCTP_STAT_INCR(sctps_queue_upd_ecne);
+       chk->copy_by_ref = 0;
        chk->rec.chunk_id.id = SCTP_ECN_ECHO;
        chk->rec.chunk_id.can_take_data = 0;
+       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->send_size = sizeof(struct sctp_ecne_chunk);
        chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
@@ -12090,6 +12090,9 @@ sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net,
                return;
        }
        chk->copy_by_ref = 0;
+       chk->rec.chunk_id.id = SCTP_PACKET_DROPPED;
+       chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
        len -= iphlen;
        chk->send_size = len;
         /* Validate that we do not have an ABORT in here. */
@@ -12175,8 +12178,6 @@ jump_out:
        } else {
                chk->whoTo = NULL;
        }
-       chk->rec.chunk_id.id = SCTP_PACKET_DROPPED;
-       chk->rec.chunk_id.can_take_data = 1;
        drp->ch.chunk_type = SCTP_PACKET_DROPPED;
        drp->ch.chunk_length = htons(chk->send_size);
        spc = SCTP_SB_LIMIT_RCV(stcb->sctp_socket);
@@ -12238,6 +12239,7 @@ sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, u
        chk->copy_by_ref = 0;
        chk->rec.chunk_id.id = SCTP_ECN_CWR;
        chk->rec.chunk_id.can_take_data = 1;
+       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->send_size = sizeof(struct sctp_cwr_chunk);
        chk->data = sctp_get_mbuf_for_msg(chk->send_size, 0, M_NOWAIT, 1, MT_HEADER);
@@ -12500,7 +12502,7 @@ sctp_add_an_in_stream(struct sctp_tmit_chunk *chk,
 
 int
 sctp_send_str_reset_req(struct sctp_tcb *stcb,
-                        int number_entries, uint16_t *list,
+                        uint16_t number_entries, uint16_t *list,
                         uint8_t send_out_req,
                         uint8_t send_in_req,
                         uint8_t send_tsn_req,
@@ -12533,6 +12535,14 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
                SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
                return (EINVAL);
        }
+       if (number_entries > (MCLBYTES -
+                             SCTP_MIN_OVERHEAD -
+                             sizeof(struct sctp_chunkhdr) -
+                             sizeof(struct sctp_stream_reset_out_request)) /
+                            sizeof(uint16_t)) {
+               SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
+               return (ENOMEM);
+       }
        sctp_alloc_a_chunk(stcb, chk);
        if (chk == NULL) {
                SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, ENOMEM);
@@ -12541,6 +12551,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
        chk->copy_by_ref = 0;
        chk->rec.chunk_id.id = SCTP_STREAM_RESET;
        chk->rec.chunk_id.can_take_data = 0;
+       chk->flags = 0;
        chk->asoc = &stcb->asoc;
        chk->book_size = sizeof(struct sctp_chunkhdr);
        chk->send_size = SCTP_SIZE32(chk->book_size);