Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / usrsctp / usrsctplib / netinet / sctputil.c
index 73cf3ab..87e770d 100755 (executable)
@@ -32,7 +32,7 @@
 
 #ifdef __FreeBSD__
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 267674 2014-06-20 13:26:49Z tuexen $");
+__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 271221 2014-09-07 09:06:26Z tuexen $");
 #endif
 
 #include <netinet/sctp_os.h>
@@ -963,6 +963,9 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
         * caller in the sctp_aloc_assoc() function.
         */
        int i;
+#if defined(SCTP_DETAILED_STR_STATS)
+       int j;
+#endif
 
        asoc = &stcb->asoc;
        /* init all variables to a known value. */
@@ -972,8 +975,13 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
        asoc->heart_beat_delay = TICKS_TO_MSEC(inp->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
        asoc->cookie_life = inp->sctp_ep.def_cookie_life;
        asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
-       asoc->ecn_allowed = inp->sctp_ecn_enable;
-       asoc->sctp_nr_sack_on_off = (uint8_t)SCTP_BASE_SYSCTL(sctp_nr_sack_on_off);
+       asoc->ecn_supported = inp->ecn_supported;
+       asoc->prsctp_supported = inp->prsctp_supported;
+       asoc->auth_supported = inp->auth_supported;
+       asoc->asconf_supported = inp->asconf_supported;
+       asoc->reconfig_supported = inp->reconfig_supported;
+       asoc->nrsack_supported = inp->nrsack_supported;
+       asoc->pktdrop_supported = inp->pktdrop_supported;
        asoc->sctp_cmt_pf = (uint8_t)0;
        asoc->sctp_frag_point = inp->sctp_frag_point;
        asoc->sctp_features = inp->sctp_features;
@@ -1004,7 +1012,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 
 #ifdef SCTP_ASOCLOG_OF_TSNS
        asoc->tsn_in_at = 0;
-       asoc->tsn_out_at = 0;
+       asoc->tsn_out_at = 0;
        asoc->tsn_in_wrapped = 0;
        asoc->tsn_out_wrapped = 0;
        asoc->cumack_log_at = 0;
@@ -1019,7 +1027,6 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
            sctp_select_initial_TSN(&inp->sctp_ep);
        asoc->asconf_seq_out_acked = asoc->asconf_seq_out - 1;
        /* we are optimisitic here */
-       asoc->peer_supports_pktdrop = 1;
        asoc->peer_supports_nat = 0;
        asoc->sent_queue_retran_cnt = 0;
 
@@ -1133,6 +1140,15 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
                asoc->strmout[i].next_sequence_send = 0x0;
                TAILQ_INIT(&asoc->strmout[i].outqueue);
                asoc->strmout[i].chunks_on_queues = 0;
+#if defined(SCTP_DETAILED_STR_STATS)
+               for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
+                       asoc->strmout[i].abandoned_sent[j] = 0;
+                       asoc->strmout[i].abandoned_unsent[j] = 0;
+               }
+#else
+               asoc->strmout[i].abandoned_sent[0] = 0;
+               asoc->strmout[i].abandoned_unsent[0] = 0;
+#endif
                asoc->strmout[i].stream_no = i;
                asoc->strmout[i].last_msg_incomplete = 0;
                asoc->ss_functions.sctp_ss_init_stream(&asoc->strmout[i], NULL);
@@ -1188,6 +1204,10 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
        asoc->timoshutdownack = 0;
        (void)SCTP_GETTIME_TIMEVAL(&asoc->start_time);
        asoc->discontinuity_time = asoc->start_time;
+       for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) {
+               asoc->abandoned_unsent[i] = 0;
+               asoc->abandoned_sent[i] = 0;
+       }
        /* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when
         * the association is freed.
         */
@@ -1273,7 +1293,7 @@ sctp_iterator_work(struct sctp_iterator *it)
 
        SCTP_INP_INFO_RLOCK();
        SCTP_ITERATOR_LOCK();
-       if (it->inp) {
+       if (it->inp) {
                SCTP_INP_RLOCK(it->inp);
                SCTP_INP_DECR_REF(it->inp);
        }
@@ -1816,7 +1836,7 @@ sctp_timeout_handler(void *t)
                        goto out_decr;
                }
                SCTP_STAT_INCR(sctps_timoshutdownack);
-               stcb->asoc.timoshutdownack++;
+               stcb->asoc.timoshutdownack++;
 #ifdef SCTP_AUDITING_ENABLED
                sctp_auditing(4, inp, stcb, net);
 #endif
@@ -2566,15 +2586,15 @@ sctp_calculate_rto(struct sctp_tcb *stcb,
                stcb->asoc.sat_network = 0;
                stcb->asoc.sat_network_lockout = 1;
        }
-       /* bound it, per C6/C7 in Section 5.3.1 */
-       if (new_rto < stcb->asoc.minrto) {
+       /* bound it, per C6/C7 in Section 5.3.1 */
+       if (new_rto < stcb->asoc.minrto) {
                new_rto = stcb->asoc.minrto;
        }
        if (new_rto > stcb->asoc.maxrto) {
                new_rto = stcb->asoc.maxrto;
        }
        /* we are now returning the RTO */
-       return (new_rto);
+       return (new_rto);
 }
 
 /*
@@ -2637,58 +2657,44 @@ sctp_get_next_param(struct mbuf *m,
 }
 
 
-int
+struct mbuf *
 sctp_add_pad_tombuf(struct mbuf *m, int padlen)
 {
-       /*
-        * add padlen bytes of 0 filled padding to the end of the mbuf. If
-        * padlen is > 3 this routine will fail.
-        */
-       uint8_t *dp;
-       int i;
+       struct mbuf *m_last;
+       caddr_t dp;
 
        if (padlen > 3) {
-               SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
-               return (ENOBUFS);
+               return (NULL);
        }
        if (padlen <= M_TRAILINGSPACE(m)) {
                /*
                 * The easy way. We hope the majority of the time we hit
                 * here :)
                 */
-               dp = (uint8_t *) (mtod(m, caddr_t) + SCTP_BUF_LEN(m));
-               SCTP_BUF_LEN(m) += padlen;
+               m_last = m;
        } else {
-               /* Hard way we must grow the mbuf */
-               struct mbuf *tmp;
-
-               tmp = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
-               if (tmp == NULL) {
-                       /* Out of space GAK! we are in big trouble. */
-                       SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
-                       return (ENOBUFS);
-               }
-               /* setup and insert in middle */
-               SCTP_BUF_LEN(tmp) = padlen;
-               SCTP_BUF_NEXT(tmp) = NULL;
-               SCTP_BUF_NEXT(m) = tmp;
-               dp = mtod(tmp, uint8_t *);
-       }
-       /* zero out the pad */
-       for (i = 0; i < padlen; i++) {
-               *dp = 0;
-               dp++;
+               /* Hard way we must grow the mbuf chain */
+               m_last = sctp_get_mbuf_for_msg(padlen, 0, M_NOWAIT, 1, MT_DATA);
+               if (m_last == NULL) {
+                       return (NULL);
+               }
+               SCTP_BUF_LEN(m_last) = 0;
+               SCTP_BUF_NEXT(m_last) = NULL;
+               SCTP_BUF_NEXT(m) = m_last;
        }
-       return (0);
+       dp = mtod(m_last, caddr_t) + SCTP_BUF_LEN(m_last);
+       SCTP_BUF_LEN(m_last) += padlen;
+       memset(dp, 0, padlen);
+       return (m_last);
 }
 
-int
+struct mbuf *
 sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
 {
        /* find the last mbuf in chain and pad it */
        struct mbuf *m_at;
 
-       if (last_mbuf) {
+       if (last_mbuf != NULL) {
                return (sctp_add_pad_tombuf(last_mbuf, padval));
        } else {
                for (m_at = m; m_at; m_at = SCTP_BUF_NEXT(m_at)) {
@@ -2697,8 +2703,7 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
                        }
                }
        }
-       SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
-       return (EFAULT);
+       return (NULL);
 }
 
 static void
@@ -2741,6 +2746,7 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
                }
                SCTP_BUF_NEXT(m_notify) = NULL;
                sac = mtod(m_notify, struct sctp_assoc_change *);
+               memset(sac, 0, notif_len);
                sac->sac_type = SCTP_ASSOC_CHANGE;
                sac->sac_flags = 0;
                sac->sac_length = sizeof(struct sctp_assoc_change);
@@ -2753,17 +2759,17 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
                if (notif_len > sizeof(struct sctp_assoc_change)) {
                        if ((state == SCTP_COMM_UP) || (state == SCTP_RESTART)) {
                                i = 0;
-                               if (stcb->asoc.peer_supports_prsctp) {
+                               if (stcb->asoc.prsctp_supported == 1) {
                                        sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_PR;
                                }
-                               if (stcb->asoc.peer_supports_auth) {
+                               if (stcb->asoc.auth_supported == 1) {
                                        sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_AUTH;
                                }
-                               if (stcb->asoc.peer_supports_asconf) {
+                               if (stcb->asoc.asconf_supported == 1) {
                                        sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
                                }
                                sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
-                               if (stcb->asoc.peer_supports_strreset) {
+                               if (stcb->asoc.reconfig_supported == 1) {
                                        sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
                                }
                                sac->sac_length += i;
@@ -2868,6 +2874,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
                return;
        SCTP_BUF_LEN(m_notify) = 0;
        spc = mtod(m_notify, struct sctp_paddr_change *);
+       memset(spc, 0, sizeof(struct sctp_paddr_change));
        spc->spc_type = SCTP_PEER_ADDR_CHANGE;
        spc->spc_flags = 0;
        spc->spc_length = sizeof(struct sctp_paddr_change);
@@ -2891,7 +2898,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
                        if (sin6->sin6_scope_id == 0) {
                                /* recover scope_id for user */
 #ifdef SCTP_KAME
-                               (void)sa6_recoverscope(sin6);
+                               (void)sa6_recoverscope(sin6);
 #else
                                (void)in6_recoverscope(sin6, &sin6->sin6_addr,
                                                       NULL);
@@ -2972,21 +2979,21 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
        if (m_notify == NULL)
                /* no space left */
                return;
-       length += chk->send_size;
-       length -= sizeof(struct sctp_data_chunk);
        SCTP_BUF_LEN(m_notify) = 0;
        if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
                ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+               memset(ssfe, 0, length);
                ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
                if (sent) {
                        ssfe->ssfe_flags = SCTP_DATA_SENT;
                } else {
                        ssfe->ssfe_flags = SCTP_DATA_UNSENT;
                }
+               length += chk->send_size;
+               length -= sizeof(struct sctp_data_chunk);
                ssfe->ssfe_length = length;
                ssfe->ssfe_error = error;
                /* not exactly what the user sent in, but should be close :) */
-               bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
                ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number;
                ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
                ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype;
@@ -2996,12 +3003,15 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
                SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
        } else {
                ssf = mtod(m_notify, struct sctp_send_failed *);
+               memset(ssf, 0, length);
                ssf->ssf_type = SCTP_SEND_FAILED;
                if (sent) {
                        ssf->ssf_flags = SCTP_DATA_SENT;
                } else {
                        ssf->ssf_flags = SCTP_DATA_UNSENT;
                }
+               length += chk->send_size;
+               length -= sizeof(struct sctp_data_chunk);
                ssf->ssf_length = length;
                ssf->ssf_error = error;
                /* not exactly what the user sent in, but should be close :) */
@@ -3086,16 +3096,16 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
                /* no space left */
                return;
        }
-       length += sp->length;
        SCTP_BUF_LEN(m_notify) = 0;
        if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
                ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+               memset(ssfe, 0, length);
                ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
                ssfe->ssfe_flags = SCTP_DATA_UNSENT;
+               length += sp->length;
                ssfe->ssfe_length = length;
                ssfe->ssfe_error = error;
                /* not exactly what the user sent in, but should be close :) */
-               bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
                ssfe->ssfe_info.snd_sid = sp->stream;
                if (sp->some_taken) {
                        ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
@@ -3109,12 +3119,13 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
                SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
        } else {
                ssf = mtod(m_notify, struct sctp_send_failed *);
+               memset(ssf, 0, length);
                ssf->ssf_type = SCTP_SEND_FAILED;
                ssf->ssf_flags = SCTP_DATA_UNSENT;
+               length += sp->length;
                ssf->ssf_length = length;
                ssf->ssf_error = error;
                /* not exactly what the user sent in, but should be close :) */
-               bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
                ssf->ssf_info.sinfo_stream = sp->stream;
                ssf->ssf_info.sinfo_ssn = 0;
                if (sp->some_taken) {
@@ -3177,6 +3188,7 @@ sctp_notify_adaptation_layer(struct sctp_tcb *stcb)
                return;
        SCTP_BUF_LEN(m_notify) = 0;
        sai = mtod(m_notify, struct sctp_adaptation_event *);
+       memset(sai, 0, sizeof(struct sctp_adaptation_event));
        sai->sai_type = SCTP_ADAPTATION_INDICATION;
        sai->sai_flags = 0;
        sai->sai_length = sizeof(struct sctp_adaptation_event);
@@ -3233,6 +3245,7 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
                return;
        SCTP_BUF_LEN(m_notify) = 0;
        pdapi = mtod(m_notify, struct sctp_pdapi_event *);
+       memset(pdapi, 0, sizeof(struct sctp_pdapi_event));
        pdapi->pdapi_type = SCTP_PARTIAL_DELIVERY_EVENT;
        pdapi->pdapi_flags = 0;
        pdapi->pdapi_length = sizeof(struct sctp_pdapi_event);
@@ -3343,6 +3356,7 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
                /* no space left */
                return;
        sse = mtod(m_notify, struct sctp_shutdown_event *);
+       memset(sse, 0, sizeof(struct sctp_shutdown_event));
        sse->sse_type = SCTP_SHUTDOWN_EVENT;
        sse->sse_flags = 0;
        sse->sse_length = sizeof(struct sctp_shutdown_event);
@@ -3394,6 +3408,7 @@ sctp_notify_sender_dry_event(struct sctp_tcb *stcb,
        }
        SCTP_BUF_LEN(m_notify) = 0;
        event = mtod(m_notify, struct sctp_sender_dry_event *);
+       memset(event, 0, sizeof(struct sctp_sender_dry_event));
        event->sender_dry_type = SCTP_SENDER_DRY_EVENT;
        event->sender_dry_flags = 0;
        event->sender_dry_length = sizeof(struct sctp_sender_dry_event);
@@ -3426,7 +3441,6 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
        struct mbuf *m_notify;
        struct sctp_queued_to_read *control;
        struct sctp_stream_change_event *stradd;
-       int len;
 
        if ((stcb == NULL) ||
            (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_STREAM_CHANGEEVNT))) {
@@ -3439,25 +3453,20 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
                return;
        }
        stcb->asoc.peer_req_out = 0;
-       m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
+       m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_stream_change_event), 0, M_NOWAIT, 1, MT_DATA);
        if (m_notify == NULL)
                /* no space left */
                return;
        SCTP_BUF_LEN(m_notify) = 0;
-       len = sizeof(struct sctp_stream_change_event);
-       if (len > M_TRAILINGSPACE(m_notify)) {
-               /* never enough room */
-               sctp_m_freem(m_notify);
-               return;
-       }
        stradd = mtod(m_notify, struct sctp_stream_change_event *);
+       memset(stradd, 0, sizeof(struct sctp_stream_change_event));
        stradd->strchange_type = SCTP_STREAM_CHANGE_EVENT;
        stradd->strchange_flags = flag;
-       stradd->strchange_length = len;
+       stradd->strchange_length = sizeof(struct sctp_stream_change_event);
        stradd->strchange_assoc_id = sctp_get_associd(stcb);
        stradd->strchange_instrms = numberin;
        stradd->strchange_outstrms = numberout;
-       SCTP_BUF_LEN(m_notify) = len;
+       SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_stream_change_event);
        SCTP_BUF_NEXT(m_notify) = NULL;
        if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
                /* no space */
@@ -3488,32 +3497,26 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
        struct mbuf *m_notify;
        struct sctp_queued_to_read *control;
        struct sctp_assoc_reset_event *strasoc;
-       int len;
 
        if ((stcb == NULL) ||
            (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_ASSOC_RESETEVNT))) {
                /* event not enabled */
                return;
        }
-       m_notify = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
+       m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_assoc_reset_event), 0, M_NOWAIT, 1, MT_DATA);
        if (m_notify == NULL)
                /* no space left */
                return;
        SCTP_BUF_LEN(m_notify) = 0;
-       len = sizeof(struct sctp_assoc_reset_event);
-       if (len > M_TRAILINGSPACE(m_notify)) {
-               /* never enough room */
-               sctp_m_freem(m_notify);
-               return;
-       }
        strasoc = mtod(m_notify, struct sctp_assoc_reset_event  *);
+       memset(strasoc, 0, sizeof(struct sctp_assoc_reset_event));
        strasoc->assocreset_type = SCTP_ASSOC_RESET_EVENT;
        strasoc->assocreset_flags = flag;
-       strasoc->assocreset_length = len;
+       strasoc->assocreset_length = sizeof(struct sctp_assoc_reset_event);
        strasoc->assocreset_assoc_id= sctp_get_associd(stcb);
        strasoc->assocreset_local_tsn = sending_tsn;
        strasoc->assocreset_remote_tsn = recv_tsn;
-       SCTP_BUF_LEN(m_notify) = len;
+       SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_assoc_reset_event);
        SCTP_BUF_NEXT(m_notify) = NULL;
        if (sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv) < SCTP_BUF_LEN(m_notify)) {
                /* no space */
@@ -3567,6 +3570,7 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
                return;
        }
        strreset = mtod(m_notify, struct sctp_stream_reset_event *);
+       memset(strreset, 0, len);
        strreset->strreset_type = SCTP_STREAM_RESET_EVENT;
        strreset->strreset_flags = flag;
        strreset->strreset_length = len;
@@ -3633,6 +3637,7 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
        }
        SCTP_BUF_NEXT(m_notify) = NULL;
        sre = mtod(m_notify, struct sctp_remote_error *);
+       memset(sre, 0, notif_len);
        sre->sre_type = SCTP_REMOTE_ERROR;
        sre->sre_flags = 0;
        sre->sre_length = sizeof(struct sctp_remote_error);
@@ -3708,7 +3713,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
                if (stcb->asoc.adaptation_needed && (stcb->asoc.adaptation_sent == 0)) {
                        sctp_notify_adaptation_layer(stcb);
                }
-               if (stcb->asoc.peer_supports_auth == 0) {
+               if (stcb->asoc.auth_supported == 0) {
                        sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
                                        NULL, so_locked);
                }
@@ -3797,7 +3802,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
                break;
        case SCTP_NOTIFY_ASSOC_RESTART:
                sctp_notify_assoc_change(SCTP_RESTART, stcb, error, NULL, 0, so_locked);
-               if (stcb->asoc.peer_supports_auth == 0) {
+               if (stcb->asoc.auth_supported == 0) {
                        sctp_ulp_notify(SCTP_NOTIFY_NO_PEER_AUTH, stcb, 0,
                                        NULL, so_locked);
                }
@@ -5173,6 +5178,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
        int ret_sz = 0;
        int notdone;
        int do_wakeup_routine = 0;
+
 #if defined(__APPLE__)
        if (so_locked) {
                sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep));
@@ -5182,6 +5188,21 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
 #endif
        stream = tp1->rec.data.stream_number;
        seq = tp1->rec.data.stream_seq;
+       if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) {
+               stcb->asoc.abandoned_sent[0]++;
+               stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
+               stcb->asoc.strmout[stream].abandoned_sent[0]++;
+#if defined(SCTP_DETAILED_STR_STATS)
+               stcb->asoc.strmout[stream].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++;
+#endif
+       } else {
+               stcb->asoc.abandoned_unsent[0]++;
+               stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
+               stcb->asoc.strmout[stream].abandoned_unsent[0]++;
+#if defined(SCTP_DETAILED_STR_STATS)
+               stcb->asoc.strmout[stream].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++;
+#endif
+       }
        do {
                ret_sz += tp1->book_size;
                if (tp1->data != NULL) {
@@ -5232,7 +5253,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
                 */
                TAILQ_FOREACH_SAFE(tp1, &stcb->asoc.send_queue, sctp_next, tp2) {
                        if ((tp1->rec.data.stream_number != stream) ||
-                           (tp1->rec.data.stream_seq != seq)) {
+                           (tp1->rec.data.stream_seq != seq)) {
                                break;
                        }
                        /* save to chk in case we have some on stream out
@@ -6904,9 +6925,12 @@ sctp_soreceive(  struct socket *so,
 #if defined(__APPLE__)
        SCTP_SOCKET_LOCK(so, 1);
 #endif
+       if (filling_sinfo) {
+               memset(&sinfo, 0, sizeof(struct sctp_extrcvinfo));
+       }
        error = sctp_sorecvmsg(so, uio, mp0, from, fromlen, flagsp,
            (struct sctp_sndrcvinfo *)&sinfo, filling_sinfo);
-       if ((controlp) && (filling_sinfo)) {
+       if (controlp != NULL) {
                /* copy back the sinfo in a CMSG format */
                if (filling_sinfo)
                        *controlp = sctp_build_ctl_nchunk(inp,
@@ -7561,7 +7585,7 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
                                        if (ipv4_addr_legal) {
                                                struct sockaddr_in *sin;
 
-                                               sin = (struct sockaddr_in *)&sctp_ifa->address.sa;
+                                               sin = &sctp_ifa->address.sin;
                                                if (sin->sin_addr.s_addr == 0) {
                                                        /* skip unspecified addrs */
                                                        continue;
@@ -7591,7 +7615,7 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
 #if defined(SCTP_EMBEDDED_V6_SCOPE) && !defined(SCTP_KAME)
                                                struct sockaddr_in6 lsa6;
 #endif
-                                               sin6 = (struct sockaddr_in6 *)&sctp_ifa->address.sa;
+                                               sin6 = &sctp_ifa->address.sin6;
                                                if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
                                                        continue;
                                                }