diff options
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r-- | sys/netinet/sctputil.c | 114 |
1 files changed, 59 insertions, 55 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c index 9434f06..ced18fe 100644 --- a/sys/netinet/sctputil.c +++ b/sys/netinet/sctputil.c @@ -970,11 +970,13 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off; asoc->ecn_supported = inp->ecn_supported; asoc->prsctp_supported = inp->prsctp_supported; + asoc->idata_supported = inp->idata_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->idata_supported = inp->idata_supported; asoc->sctp_cmt_pf = (uint8_t) 0; asoc->sctp_frag_point = inp->sctp_frag_point; asoc->sctp_features = inp->sctp_features; @@ -1163,7 +1165,6 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, TAILQ_INIT(&asoc->asconf_send_queue); TAILQ_INIT(&asoc->send_queue); TAILQ_INIT(&asoc->sent_queue); - TAILQ_INIT(&asoc->reasmqueue); TAILQ_INIT(&asoc->resetHead); asoc->max_inbound_streams = inp->sctp_ep.max_open_streams_intome; TAILQ_INIT(&asoc->asconf_queue); @@ -2736,6 +2737,9 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb, if (stcb->asoc.asconf_supported == 1) { sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF; } + if (stcb->asoc.idata_supported == 1) { + sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_INTERLEAVING; + } sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF; if (stcb->asoc.reconfig_supported == 1) { sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG; @@ -4450,6 +4454,43 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, } void +sctp_wakeup_the_read_socket(struct sctp_inpcb *inp) +{ + if (inp && inp->sctp_socket) { + if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { + SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); + } else { +#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + struct socket *so; + + so = SCTP_INP_SO(inp); + if (!so_locked) { + if (stcb) { + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); + } + SCTP_SOCKET_LOCK(so, 1); + if (stcb) { + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); + } + if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { + SCTP_SOCKET_UNLOCK(so, 1); + return; + } + } +#endif + sctp_sorwakeup(inp, inp->sctp_socket); +#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) + if (!so_locked) { + SCTP_SOCKET_UNLOCK(so, 1); + } +#endif + } + } +} + +void sctp_add_to_readq(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_queued_to_read *control, @@ -4484,7 +4525,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp, sctp_m_freem(control->data); control->data = NULL; } - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), control); + sctp_free_a_readq(stcb, control); if (inp_read_lock_held == 0) SCTP_INP_READ_UNLOCK(inp); return; @@ -4530,7 +4571,7 @@ sctp_add_to_readq(struct sctp_inpcb *inp, } else { /* Everything got collapsed out?? */ sctp_free_remote_addr(control->whoFrom); - SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_readq), control); + sctp_free_a_readq(stcb, control); if (inp_read_lock_held == 0) SCTP_INP_READ_UNLOCK(inp); return; @@ -4539,39 +4580,11 @@ sctp_add_to_readq(struct sctp_inpcb *inp, control->end_added = 1; } TAILQ_INSERT_TAIL(&inp->read_queue, control, next); + control->on_read_q = 1; if (inp_read_lock_held == 0) SCTP_INP_READ_UNLOCK(inp); if (inp && inp->sctp_socket) { - if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { - SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); - } else { -#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) - struct socket *so; - - so = SCTP_INP_SO(inp); - if (!so_locked) { - if (stcb) { - atomic_add_int(&stcb->asoc.refcnt, 1); - SCTP_TCB_UNLOCK(stcb); - } - SCTP_SOCKET_LOCK(so, 1); - if (stcb) { - SCTP_TCB_LOCK(stcb); - atomic_subtract_int(&stcb->asoc.refcnt, 1); - } - if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) { - SCTP_SOCKET_UNLOCK(so, 1); - return; - } - } -#endif - sctp_sorwakeup(inp, inp->sctp_socket); -#if defined(__APPLE__) || defined(SCTP_SO_LOCK_TESTING) - if (!so_locked) { - SCTP_SOCKET_UNLOCK(so, 1); - } -#endif - } + sctp_wakeup_the_read_socket(inp); } } @@ -5552,6 +5565,10 @@ restart_nosblocks: sctp_m_free(control->aux_data); control->aux_data = NULL; } + if (control->on_strm_q) { + panic("About to free ctl:%p so:%p and its in %d", + control, so, control->on_strm_q); + } sctp_free_remote_addr(control->whoFrom); sctp_free_a_readq(stcb, control); if (hold_rlock) { @@ -5822,15 +5839,8 @@ get_more_data: /* error we are out of here */ goto release; } - if ((SCTP_BUF_NEXT(m) == NULL) && - (cp_len >= SCTP_BUF_LEN(m)) && - ((control->end_added == 0) || - (control->end_added && - (TAILQ_NEXT(control, next) == NULL))) - ) { - SCTP_INP_READ_LOCK(inp); - hold_rlock = 1; - } + SCTP_INP_READ_LOCK(inp); + hold_rlock = 1; if (cp_len == SCTP_BUF_LEN(m)) { if ((SCTP_BUF_NEXT(m) == NULL) && (control->end_added)) { @@ -5948,19 +5958,9 @@ get_more_data: #endif } done_with_control: - if (TAILQ_NEXT(control, next) == NULL) { - /* - * If we don't have a next we need a - * lock, if there is a next - * interrupt is filling ahead of us - * and we don't need a lock to - * remove this guy (which is the - * head of the queue). - */ - if (hold_rlock == 0) { - SCTP_INP_READ_LOCK(inp); - hold_rlock = 1; - } + if (hold_rlock == 0) { + SCTP_INP_READ_LOCK(inp); + hold_rlock = 1; } TAILQ_REMOVE(&inp->read_queue, control, next); /* Add back any hiddend data */ @@ -5976,6 +5976,10 @@ get_more_data: no_rcv_needed = control->do_not_ref_stcb; sctp_free_remote_addr(control->whoFrom); control->data = NULL; + if (control->on_strm_q) { + panic("About to free ctl:%p so:%p and its in %d", + control, so, control->on_strm_q); + } sctp_free_a_readq(stcb, control); control = NULL; if ((freed_so_far >= rwnd_req) && |