Lines Matching +full:break +full:- +full:control

1 /*-
2 * SPDX-License-Identifier: BSD-3-Clause
4 * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
5 * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
6 * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
62 sctp_add_chk_to_control(struct sctp_queued_to_read *control,
71 asoc->my_rwnd = sctp_calc_rwnd(stcb, asoc); in sctp_set_rwnd()
81 * This is really set wrong with respect to a 1-2-m socket. Since in sctp_calc_rwnd()
82 * the sb_cc is the count that everyone as put up. When we re-write in sctp_calc_rwnd()
86 if (stcb->sctp_socket == NULL) { in sctp_calc_rwnd()
90 KASSERT(asoc->cnt_on_reasm_queue > 0 || asoc->size_on_reasm_queue == 0, in sctp_calc_rwnd()
91 ("size_on_reasm_queue is %u", asoc->size_on_reasm_queue)); in sctp_calc_rwnd()
92 KASSERT(asoc->cnt_on_all_streams > 0 || asoc->size_on_all_streams == 0, in sctp_calc_rwnd()
93 ("size_on_all_streams is %u", asoc->size_on_all_streams)); in sctp_calc_rwnd()
94 if (stcb->asoc.sb_cc == 0 && in sctp_calc_rwnd()
95 asoc->cnt_on_reasm_queue == 0 && in sctp_calc_rwnd()
96 asoc->cnt_on_all_streams == 0) { in sctp_calc_rwnd()
98 calc = max(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), SCTP_MINIMAL_RWND); in sctp_calc_rwnd()
102 calc = (uint32_t)sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv); in sctp_calc_rwnd()
107 calc = sctp_sbspace_sub(calc, (uint32_t)(asoc->size_on_reasm_queue + in sctp_calc_rwnd()
108 asoc->cnt_on_reasm_queue * MSIZE)); in sctp_calc_rwnd()
109 calc = sctp_sbspace_sub(calc, (uint32_t)(asoc->size_on_all_streams + in sctp_calc_rwnd()
110 asoc->cnt_on_all_streams * MSIZE)); in sctp_calc_rwnd()
117 calc = sctp_sbspace_sub(calc, stcb->asoc.my_rwnd_control_len); in sctp_calc_rwnd()
119 * If the window gets too small due to ctrl-stuff, reduce it to 1, in sctp_calc_rwnd()
122 if (calc < stcb->asoc.my_rwnd_control_len) { in sctp_calc_rwnd()
146 read_queue_e->sinfo_stream = sid; in sctp_build_readq_entry()
147 read_queue_e->sinfo_flags = (flags << 8); in sctp_build_readq_entry()
148 read_queue_e->sinfo_ppid = ppid; in sctp_build_readq_entry()
149 read_queue_e->sinfo_context = context; in sctp_build_readq_entry()
150 read_queue_e->sinfo_tsn = tsn; in sctp_build_readq_entry()
151 read_queue_e->sinfo_cumtsn = tsn; in sctp_build_readq_entry()
152 read_queue_e->sinfo_assoc_id = sctp_get_associd(stcb); in sctp_build_readq_entry()
153 read_queue_e->mid = mid; in sctp_build_readq_entry()
154 read_queue_e->top_fsn = read_queue_e->fsn_included = 0xffffffff; in sctp_build_readq_entry()
155 TAILQ_INIT(&read_queue_e->reasm); in sctp_build_readq_entry()
156 read_queue_e->whoFrom = net; in sctp_build_readq_entry()
157 atomic_add_int(&net->ref_count, 1); in sctp_build_readq_entry()
158 read_queue_e->data = dm; in sctp_build_readq_entry()
159 read_queue_e->stcb = stcb; in sctp_build_readq_entry()
160 read_queue_e->port_from = stcb->rport; in sctp_build_readq_entry()
161 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) { in sctp_build_readq_entry()
162 read_queue_e->do_not_ref_stcb = 1; in sctp_build_readq_entry()
194 (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_AVAIL)) { in sctp_build_ctl_nchunk()
222 * Make sure that there is no un-initialized padding between the in sctp_build_ctl_nchunk()
227 cmh->cmsg_level = IPPROTO_SCTP; in sctp_build_ctl_nchunk()
228 cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_rcvinfo)); in sctp_build_ctl_nchunk()
229 cmh->cmsg_type = SCTP_RCVINFO; in sctp_build_ctl_nchunk()
231 rcvinfo->rcv_sid = sinfo->sinfo_stream; in sctp_build_ctl_nchunk()
232 rcvinfo->rcv_ssn = sinfo->sinfo_ssn; in sctp_build_ctl_nchunk()
233 rcvinfo->rcv_flags = sinfo->sinfo_flags; in sctp_build_ctl_nchunk()
234 rcvinfo->rcv_ppid = sinfo->sinfo_ppid; in sctp_build_ctl_nchunk()
235 rcvinfo->rcv_tsn = sinfo->sinfo_tsn; in sctp_build_ctl_nchunk()
236 rcvinfo->rcv_cumtsn = sinfo->sinfo_cumtsn; in sctp_build_ctl_nchunk()
237 rcvinfo->rcv_context = sinfo->sinfo_context; in sctp_build_ctl_nchunk()
238 rcvinfo->rcv_assoc_id = sinfo->sinfo_assoc_id; in sctp_build_ctl_nchunk()
243 cmh->cmsg_level = IPPROTO_SCTP; in sctp_build_ctl_nchunk()
244 cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_nxtinfo)); in sctp_build_ctl_nchunk()
245 cmh->cmsg_type = SCTP_NXTINFO; in sctp_build_ctl_nchunk()
247 nxtinfo->nxt_sid = seinfo->serinfo_next_stream; in sctp_build_ctl_nchunk()
248 nxtinfo->nxt_flags = 0; in sctp_build_ctl_nchunk()
249 if (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_IS_UNORDERED) { in sctp_build_ctl_nchunk()
250 nxtinfo->nxt_flags |= SCTP_UNORDERED; in sctp_build_ctl_nchunk()
252 if (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_IS_NOTIFICATION) { in sctp_build_ctl_nchunk()
253 nxtinfo->nxt_flags |= SCTP_NOTIFICATION; in sctp_build_ctl_nchunk()
255 if (seinfo->serinfo_next_flags & SCTP_NEXT_MSG_ISCOMPLETE) { in sctp_build_ctl_nchunk()
256 nxtinfo->nxt_flags |= SCTP_COMPLETE; in sctp_build_ctl_nchunk()
258 nxtinfo->nxt_ppid = seinfo->serinfo_next_ppid; in sctp_build_ctl_nchunk()
259 nxtinfo->nxt_length = seinfo->serinfo_next_length; in sctp_build_ctl_nchunk()
260 nxtinfo->nxt_assoc_id = seinfo->serinfo_next_aid; in sctp_build_ctl_nchunk()
265 cmh->cmsg_level = IPPROTO_SCTP; in sctp_build_ctl_nchunk()
268 cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_extrcvinfo)); in sctp_build_ctl_nchunk()
269 cmh->cmsg_type = SCTP_EXTRCV; in sctp_build_ctl_nchunk()
273 cmh->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); in sctp_build_ctl_nchunk()
274 cmh->cmsg_type = SCTP_SNDRCV; in sctp_build_ctl_nchunk()
291 if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) { in sctp_mark_non_revokable()
298 SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn); in sctp_mark_non_revokable()
299 in_r = SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap); in sctp_mark_non_revokable()
300 in_nr = SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap); in sctp_mark_non_revokable()
303 SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); in sctp_mark_non_revokable()
304 if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) { in sctp_mark_non_revokable()
305 asoc->highest_tsn_inside_nr_map = tsn; in sctp_mark_non_revokable()
309 SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap); in sctp_mark_non_revokable()
310 if (tsn == asoc->highest_tsn_inside_map) { in sctp_mark_non_revokable()
312 for (i = tsn - 1; SCTP_TSN_GE(i, asoc->mapping_array_base_tsn); i--) { in sctp_mark_non_revokable()
313 SCTP_CALC_TSN_TO_GAP(gap, i, asoc->mapping_array_base_tsn); in sctp_mark_non_revokable()
314 if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) { in sctp_mark_non_revokable()
315 asoc->highest_tsn_inside_map = i; in sctp_mark_non_revokable()
316 break; in sctp_mark_non_revokable()
319 if (!SCTP_TSN_GE(i, asoc->mapping_array_base_tsn)) { in sctp_mark_non_revokable()
320 asoc->highest_tsn_inside_map = asoc->mapping_array_base_tsn - 1; in sctp_mark_non_revokable()
329 struct sctp_queued_to_read *control) in sctp_place_control_in_stream() argument
335 flags = (control->sinfo_flags >> 8); in sctp_place_control_in_stream()
338 q = &strm->uno_inqueue; in sctp_place_control_in_stream()
339 if (asoc->idata_supported == 0) { in sctp_place_control_in_stream()
343 * -- abort in sctp_place_control_in_stream()
345 return (-1); in sctp_place_control_in_stream()
347 TAILQ_INSERT_TAIL(q, control, next_instrm); in sctp_place_control_in_stream()
348 control->on_strm_q = SCTP_ON_UNORDERED; in sctp_place_control_in_stream()
352 q = &strm->inqueue; in sctp_place_control_in_stream()
355 control->end_added = 1; in sctp_place_control_in_stream()
356 control->first_frag_seen = 1; in sctp_place_control_in_stream()
357 control->last_frag_seen = 1; in sctp_place_control_in_stream()
361 TAILQ_INSERT_HEAD(q, control, next_instrm); in sctp_place_control_in_stream()
363 control->on_strm_q = SCTP_ON_UNORDERED; in sctp_place_control_in_stream()
365 control->on_strm_q = SCTP_ON_ORDERED; in sctp_place_control_in_stream()
370 if (SCTP_MID_GT(asoc->idata_supported, at->mid, control->mid)) { in sctp_place_control_in_stream()
375 TAILQ_INSERT_BEFORE(at, control, next_instrm); in sctp_place_control_in_stream()
377 control->on_strm_q = SCTP_ON_UNORDERED; in sctp_place_control_in_stream()
379 control->on_strm_q = SCTP_ON_ORDERED; in sctp_place_control_in_stream()
381 break; in sctp_place_control_in_stream()
382 } else if (SCTP_MID_EQ(asoc->idata_supported, at->mid, control->mid)) { in sctp_place_control_in_stream()
385 * number?? return -1 to abort. in sctp_place_control_in_stream()
387 return (-1); in sctp_place_control_in_stream()
395 sctp_log_strm_del(control, at, in sctp_place_control_in_stream()
398 TAILQ_INSERT_AFTER(q, at, control, next_instrm); in sctp_place_control_in_stream()
400 control->on_strm_q = SCTP_ON_UNORDERED; in sctp_place_control_in_stream()
402 control->on_strm_q = SCTP_ON_ORDERED; in sctp_place_control_in_stream()
404 break; in sctp_place_control_in_stream()
414 struct sctp_queued_to_read *control, in sctp_abort_in_reasm() argument
421 if (stcb->asoc.idata_supported) { in sctp_abort_in_reasm()
425 control->fsn_included, in sctp_abort_in_reasm()
426 chk->rec.data.tsn, in sctp_abort_in_reasm()
427 chk->rec.data.sid, in sctp_abort_in_reasm()
428 chk->rec.data.fsn, chk->rec.data.mid); in sctp_abort_in_reasm()
433 control->fsn_included, in sctp_abort_in_reasm()
434 chk->rec.data.tsn, in sctp_abort_in_reasm()
435 chk->rec.data.sid, in sctp_abort_in_reasm()
436 chk->rec.data.fsn, in sctp_abort_in_reasm()
437 (uint16_t)chk->rec.data.mid); in sctp_abort_in_reasm()
440 sctp_m_freem(chk->data); in sctp_abort_in_reasm()
441 chk->data = NULL; in sctp_abort_in_reasm()
443 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_1; in sctp_abort_in_reasm()
444 sctp_abort_an_association(stcb->sctp_ep, stcb, oper, false, SCTP_SO_NOT_LOCKED); in sctp_abort_in_reasm()
449 sctp_clean_up_control(struct sctp_tcb *stcb, struct sctp_queued_to_read *control) in sctp_clean_up_control() argument
452 * The control could not be placed and must be cleaned. in sctp_clean_up_control()
456 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) { in sctp_clean_up_control()
457 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_clean_up_control()
458 if (chk->data) in sctp_clean_up_control()
459 sctp_m_freem(chk->data); in sctp_clean_up_control()
460 chk->data = NULL; in sctp_clean_up_control()
463 sctp_free_remote_addr(control->whoFrom); in sctp_clean_up_control()
464 if (control->data) { in sctp_clean_up_control()
465 sctp_m_freem(control->data); in sctp_clean_up_control()
466 control->data = NULL; in sctp_clean_up_control()
468 sctp_free_a_readq(stcb, control); in sctp_clean_up_control()
475 * long as the control's entered are non-fragmented.
480 struct sctp_queued_to_read *control, int *abort_flag, int *need_reasm) in sctp_queue_data_to_stream() argument
483 * FIX-ME maybe? What happens when the ssn wraps? If we are getting in sctp_queue_data_to_stream()
507 strm = &asoc->strmin[control->sinfo_stream]; in sctp_queue_data_to_stream()
509 sctp_log_strm_del(control, NULL, SCTP_STR_LOG_FROM_INTO_STRD); in sctp_queue_data_to_stream()
511 if (SCTP_MID_GT((asoc->idata_supported), strm->last_mid_delivered, control->mid)) { in sctp_queue_data_to_stream()
513 SCTPDBG(SCTP_DEBUG_INDATA1, "Duplicate S-SEQ: %u delivered: %u from peer, Abort association\n", in sctp_queue_data_to_stream()
514 strm->last_mid_delivered, control->mid); in sctp_queue_data_to_stream()
519 TAILQ_INSERT_HEAD(&strm->inqueue, control, next_instrm); in sctp_queue_data_to_stream()
520 if (asoc->idata_supported) { in sctp_queue_data_to_stream()
522 strm->last_mid_delivered, control->sinfo_tsn, in sctp_queue_data_to_stream()
523 control->sinfo_stream, control->mid); in sctp_queue_data_to_stream()
526 (uint16_t)strm->last_mid_delivered, in sctp_queue_data_to_stream()
527 control->sinfo_tsn, in sctp_queue_data_to_stream()
528 control->sinfo_stream, in sctp_queue_data_to_stream()
529 (uint16_t)control->mid); in sctp_queue_data_to_stream()
532 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_2; in sctp_queue_data_to_stream()
533 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_queue_data_to_stream()
538 asoc->size_on_all_streams += control->length; in sctp_queue_data_to_stream()
539 sctp_ucount_incr(asoc->cnt_on_all_streams); in sctp_queue_data_to_stream()
540 nxt_todel = strm->last_mid_delivered + 1; in sctp_queue_data_to_stream()
541 if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid)) { in sctp_queue_data_to_stream()
544 sctp_log_strm_del(control, NULL, SCTP_STR_LOG_FROM_IMMED_DEL); in sctp_queue_data_to_stream()
548 if (asoc->size_on_all_streams >= control->length) { in sctp_queue_data_to_stream()
549 asoc->size_on_all_streams -= control->length; in sctp_queue_data_to_stream()
552 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_queue_data_to_stream()
554 asoc->size_on_all_streams = 0; in sctp_queue_data_to_stream()
557 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_queue_data_to_stream()
558 strm->last_mid_delivered++; in sctp_queue_data_to_stream()
559 sctp_mark_non_revokable(asoc, control->sinfo_tsn); in sctp_queue_data_to_stream()
560 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_queue_data_to_stream()
561 control, in sctp_queue_data_to_stream()
562 &stcb->sctp_socket->so_rcv, 1, in sctp_queue_data_to_stream()
564 TAILQ_FOREACH_SAFE(control, &strm->inqueue, next_instrm, at) { in sctp_queue_data_to_stream()
566 nxt_todel = strm->last_mid_delivered + 1; in sctp_queue_data_to_stream()
567 if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid) && in sctp_queue_data_to_stream()
568 (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG)) { in sctp_queue_data_to_stream()
569 if (control->on_strm_q == SCTP_ON_ORDERED) { in sctp_queue_data_to_stream()
570 TAILQ_REMOVE(&strm->inqueue, control, next_instrm); in sctp_queue_data_to_stream()
571 if (asoc->size_on_all_streams >= control->length) { in sctp_queue_data_to_stream()
572 asoc->size_on_all_streams -= control->length; in sctp_queue_data_to_stream()
575 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_queue_data_to_stream()
577 asoc->size_on_all_streams = 0; in sctp_queue_data_to_stream()
580 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_queue_data_to_stream()
583 panic("Huh control: %p is on_strm_q: %d", in sctp_queue_data_to_stream()
584 control, control->on_strm_q); in sctp_queue_data_to_stream()
587 control->on_strm_q = 0; in sctp_queue_data_to_stream()
588 strm->last_mid_delivered++; in sctp_queue_data_to_stream()
592 * d-queue. And we have a finite number that in sctp_queue_data_to_stream()
596 sctp_log_strm_del(control, NULL, in sctp_queue_data_to_stream()
599 sctp_mark_non_revokable(asoc, control->sinfo_tsn); in sctp_queue_data_to_stream()
600 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_queue_data_to_stream()
601 control, in sctp_queue_data_to_stream()
602 &stcb->sctp_socket->so_rcv, 1, in sctp_queue_data_to_stream()
606 } else if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid)) { in sctp_queue_data_to_stream()
609 break; in sctp_queue_data_to_stream()
617 if (sctp_place_control_in_stream(strm, asoc, control)) { in sctp_queue_data_to_stream()
619 "Queue to str MID: %u duplicate", control->mid); in sctp_queue_data_to_stream()
620 sctp_clean_up_control(stcb, control); in sctp_queue_data_to_stream()
622 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_3; in sctp_queue_data_to_stream()
623 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_queue_data_to_stream()
630 sctp_setup_tail_pointer(struct sctp_queued_to_read *control) in sctp_setup_tail_pointer() argument
635 stcb = control->stcb; in sctp_setup_tail_pointer()
636 control->held_length = 0; in sctp_setup_tail_pointer()
637 control->length = 0; in sctp_setup_tail_pointer()
638 m = control->data; in sctp_setup_tail_pointer()
644 control->data = sctp_m_free(m); in sctp_setup_tail_pointer()
645 m = control->data; in sctp_setup_tail_pointer()
651 control->tail_mbuf = prev; in sctp_setup_tail_pointer()
656 atomic_add_int(&control->length, SCTP_BUF_LEN(m)); in sctp_setup_tail_pointer()
657 if (control->on_read_q) { in sctp_setup_tail_pointer()
662 sctp_sballoc(stcb, &stcb->sctp_socket->so_rcv, m); in sctp_setup_tail_pointer()
667 control->tail_mbuf = prev; in sctp_setup_tail_pointer()
672 sctp_add_to_tail_pointer(struct sctp_queued_to_read *control, struct mbuf *m, uint32_t *added) in sctp_add_to_tail_pointer() argument
677 stcb = control->stcb; in sctp_add_to_tail_pointer()
680 panic("Control broken"); in sctp_add_to_tail_pointer()
685 if (control->tail_mbuf == NULL) { in sctp_add_to_tail_pointer()
687 sctp_m_freem(control->data); in sctp_add_to_tail_pointer()
688 control->data = m; in sctp_add_to_tail_pointer()
689 sctp_setup_tail_pointer(control); in sctp_add_to_tail_pointer()
692 control->tail_mbuf->m_next = m; in sctp_add_to_tail_pointer()
698 control->tail_mbuf->m_next = sctp_m_free(m); in sctp_add_to_tail_pointer()
699 m = control->tail_mbuf->m_next; in sctp_add_to_tail_pointer()
705 control->tail_mbuf = prev; in sctp_add_to_tail_pointer()
710 if (control->on_read_q) { in sctp_add_to_tail_pointer()
715 sctp_sballoc(stcb, &stcb->sctp_socket->so_rcv, m); in sctp_add_to_tail_pointer()
718 atomic_add_int(&control->length, SCTP_BUF_LEN(m)); in sctp_add_to_tail_pointer()
722 control->tail_mbuf = prev; in sctp_add_to_tail_pointer()
727 sctp_build_readq_entry_from_ctl(struct sctp_queued_to_read *nc, struct sctp_queued_to_read *control) in sctp_build_readq_entry_from_ctl() argument
730 nc->sinfo_stream = control->sinfo_stream; in sctp_build_readq_entry_from_ctl()
731 nc->mid = control->mid; in sctp_build_readq_entry_from_ctl()
732 TAILQ_INIT(&nc->reasm); in sctp_build_readq_entry_from_ctl()
733 nc->top_fsn = control->top_fsn; in sctp_build_readq_entry_from_ctl()
734 nc->mid = control->mid; in sctp_build_readq_entry_from_ctl()
735 nc->sinfo_flags = control->sinfo_flags; in sctp_build_readq_entry_from_ctl()
736 nc->sinfo_ppid = control->sinfo_ppid; in sctp_build_readq_entry_from_ctl()
737 nc->sinfo_context = control->sinfo_context; in sctp_build_readq_entry_from_ctl()
738 nc->fsn_included = 0xffffffff; in sctp_build_readq_entry_from_ctl()
739 nc->sinfo_tsn = control->sinfo_tsn; in sctp_build_readq_entry_from_ctl()
740 nc->sinfo_cumtsn = control->sinfo_cumtsn; in sctp_build_readq_entry_from_ctl()
741 nc->sinfo_assoc_id = control->sinfo_assoc_id; in sctp_build_readq_entry_from_ctl()
742 nc->whoFrom = control->whoFrom; in sctp_build_readq_entry_from_ctl()
743 atomic_add_int(&nc->whoFrom->ref_count, 1); in sctp_build_readq_entry_from_ctl()
744 nc->stcb = control->stcb; in sctp_build_readq_entry_from_ctl()
745 nc->port_from = control->port_from; in sctp_build_readq_entry_from_ctl()
746 nc->do_not_ref_stcb = control->do_not_ref_stcb; in sctp_build_readq_entry_from_ctl()
753 struct sctp_queued_to_read *control, in sctp_handle_old_unordered_data() argument
758 * Special handling for the old un-ordered data chunk. All the in sctp_handle_old_unordered_data()
760 * to see if we have it all. If you return one, no other control in sctp_handle_old_unordered_data()
761 * entries on the un-ordered queue will be looked at. In theory in sctp_handle_old_unordered_data()
770 if (control->first_frag_seen == 0) { in sctp_handle_old_unordered_data()
777 fsn = control->fsn_included + 1; in sctp_handle_old_unordered_data()
779 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, lchk) { in sctp_handle_old_unordered_data()
780 if (chk->rec.data.fsn == fsn) { in sctp_handle_old_unordered_data()
784 break; in sctp_handle_old_unordered_data()
787 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_handle_old_unordered_data()
788 sctp_add_chk_to_control(control, strm, stcb, asoc, chk, inp_read_lock_held); in sctp_handle_old_unordered_data()
792 if (control->end_added) { in sctp_handle_old_unordered_data()
794 if (!TAILQ_EMPTY(&control->reasm)) { in sctp_handle_old_unordered_data()
797 * on the control queue to a new in sctp_handle_old_unordered_data()
798 * control. in sctp_handle_old_unordered_data()
800 sctp_build_readq_entry_from_ctl(nc, control); in sctp_handle_old_unordered_data()
801 tchk = TAILQ_FIRST(&control->reasm); in sctp_handle_old_unordered_data()
802 if (tchk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { in sctp_handle_old_unordered_data()
803 TAILQ_REMOVE(&control->reasm, tchk, sctp_next); in sctp_handle_old_unordered_data()
804 if (asoc->size_on_reasm_queue >= tchk->send_size) { in sctp_handle_old_unordered_data()
805 asoc->size_on_reasm_queue -= tchk->send_size; in sctp_handle_old_unordered_data()
808 …("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, tchk->send_si… in sctp_handle_old_unordered_data()
810 asoc->size_on_reasm_queue = 0; in sctp_handle_old_unordered_data()
813 sctp_ucount_decr(asoc->cnt_on_reasm_queue); in sctp_handle_old_unordered_data()
814 nc->first_frag_seen = 1; in sctp_handle_old_unordered_data()
815 nc->fsn_included = tchk->rec.data.fsn; in sctp_handle_old_unordered_data()
816 nc->data = tchk->data; in sctp_handle_old_unordered_data()
817 nc->sinfo_ppid = tchk->rec.data.ppid; in sctp_handle_old_unordered_data()
818 nc->sinfo_tsn = tchk->rec.data.tsn; in sctp_handle_old_unordered_data()
819 sctp_mark_non_revokable(asoc, tchk->rec.data.tsn); in sctp_handle_old_unordered_data()
820 tchk->data = NULL; in sctp_handle_old_unordered_data()
823 tchk = TAILQ_FIRST(&control->reasm); in sctp_handle_old_unordered_data()
827 TAILQ_REMOVE(&control->reasm, tchk, sctp_next); in sctp_handle_old_unordered_data()
828 TAILQ_INSERT_TAIL(&nc->reasm, tchk, sctp_next); in sctp_handle_old_unordered_data()
829 tchk = TAILQ_FIRST(&control->reasm); in sctp_handle_old_unordered_data()
833 * after removing control in sctp_handle_old_unordered_data()
835 TAILQ_INSERT_TAIL(&strm->uno_inqueue, nc, next_instrm); in sctp_handle_old_unordered_data()
836 nc->on_strm_q = SCTP_ON_UNORDERED; in sctp_handle_old_unordered_data()
837 if (control->on_strm_q) { in sctp_handle_old_unordered_data()
838 TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); in sctp_handle_old_unordered_data()
839 control->on_strm_q = 0; in sctp_handle_old_unordered_data()
842 if (control->pdapi_started) { in sctp_handle_old_unordered_data()
843 strm->pd_api_started = 0; in sctp_handle_old_unordered_data()
844 control->pdapi_started = 0; in sctp_handle_old_unordered_data()
846 if (control->on_strm_q) { in sctp_handle_old_unordered_data()
847 TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); in sctp_handle_old_unordered_data()
848 control->on_strm_q = 0; in sctp_handle_old_unordered_data()
851 if (control->on_read_q == 0) { in sctp_handle_old_unordered_data()
852 sctp_add_to_readq(stcb->sctp_ep, stcb, control, in sctp_handle_old_unordered_data()
853 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_handle_old_unordered_data()
856 sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_handle_old_unordered_data()
857 if ((nc->first_frag_seen) && !TAILQ_EMPTY(&nc->reasm)) { in sctp_handle_old_unordered_data()
862 control = nc; in sctp_handle_old_unordered_data()
865 if (nc->on_strm_q == 0) { in sctp_handle_old_unordered_data()
875 break; in sctp_handle_old_unordered_data()
878 if (cnt_added && strm->pd_api_started) { in sctp_handle_old_unordered_data()
879 sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_handle_old_unordered_data()
881 if ((control->length > pd_point) && (strm->pd_api_started == 0)) { in sctp_handle_old_unordered_data()
882 strm->pd_api_started = 1; in sctp_handle_old_unordered_data()
883 control->pdapi_started = 1; in sctp_handle_old_unordered_data()
884 sctp_add_to_readq(stcb->sctp_ep, stcb, control, in sctp_handle_old_unordered_data()
885 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_handle_old_unordered_data()
887 sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_handle_old_unordered_data()
897 struct sctp_queued_to_read *control, in sctp_inject_old_unordered_data() argument
905 * Here we need to place the chunk into the control structure sorted in sctp_inject_old_unordered_data()
908 if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { in sctp_inject_old_unordered_data()
912 chk->rec.data.fsn); in sctp_inject_old_unordered_data()
913 at = TAILQ_FIRST(&control->reasm); in sctp_inject_old_unordered_data()
914 if (at && SCTP_TSN_GT(chk->rec.data.fsn, at->rec.data.fsn)) { in sctp_inject_old_unordered_data()
922 if (control->first_frag_seen) { in sctp_inject_old_unordered_data()
924 * In old un-ordered we can reassembly on one in sctp_inject_old_unordered_data()
925 * control multiple messages. As long as the next in sctp_inject_old_unordered_data()
932 if (SCTP_TSN_GT(chk->rec.data.fsn, control->fsn_included)) { in sctp_inject_old_unordered_data()
939 if ((chk->rec.data.fsn == control->fsn_included) || in sctp_inject_old_unordered_data()
940 (control->pdapi_started)) { in sctp_inject_old_unordered_data()
943 * started the pd-api on the higher TSN in sctp_inject_old_unordered_data()
951 * pd-api-point. in sctp_inject_old_unordered_data()
953 sctp_abort_in_reasm(stcb, control, chk, in sctp_inject_old_unordered_data()
965 tdata = control->data; in sctp_inject_old_unordered_data()
966 control->data = chk->data; in sctp_inject_old_unordered_data()
967 chk->data = tdata; in sctp_inject_old_unordered_data()
969 chk->send_size = control->length; in sctp_inject_old_unordered_data()
970 /* Recompute length of control and tail pointer */ in sctp_inject_old_unordered_data()
971 sctp_setup_tail_pointer(control); in sctp_inject_old_unordered_data()
973 tmp = control->fsn_included; in sctp_inject_old_unordered_data()
974 control->fsn_included = chk->rec.data.fsn; in sctp_inject_old_unordered_data()
975 chk->rec.data.fsn = tmp; in sctp_inject_old_unordered_data()
977 tmp = control->sinfo_tsn; in sctp_inject_old_unordered_data()
978 control->sinfo_tsn = chk->rec.data.tsn; in sctp_inject_old_unordered_data()
979 chk->rec.data.tsn = tmp; in sctp_inject_old_unordered_data()
981 tmp = control->sinfo_ppid; in sctp_inject_old_unordered_data()
982 control->sinfo_ppid = chk->rec.data.ppid; in sctp_inject_old_unordered_data()
983 chk->rec.data.ppid = tmp; in sctp_inject_old_unordered_data()
987 control->first_frag_seen = 1; in sctp_inject_old_unordered_data()
988 control->fsn_included = chk->rec.data.fsn; in sctp_inject_old_unordered_data()
989 control->top_fsn = chk->rec.data.fsn; in sctp_inject_old_unordered_data()
990 control->sinfo_tsn = chk->rec.data.tsn; in sctp_inject_old_unordered_data()
991 control->sinfo_ppid = chk->rec.data.ppid; in sctp_inject_old_unordered_data()
992 control->data = chk->data; in sctp_inject_old_unordered_data()
993 sctp_mark_non_revokable(asoc, chk->rec.data.tsn); in sctp_inject_old_unordered_data()
994 chk->data = NULL; in sctp_inject_old_unordered_data()
996 sctp_setup_tail_pointer(control); in sctp_inject_old_unordered_data()
1001 TAILQ_FOREACH(at, &control->reasm, sctp_next) { in sctp_inject_old_unordered_data()
1002 if (SCTP_TSN_GT(at->rec.data.fsn, chk->rec.data.fsn)) { in sctp_inject_old_unordered_data()
1007 asoc->size_on_reasm_queue += chk->send_size; in sctp_inject_old_unordered_data()
1008 sctp_ucount_incr(asoc->cnt_on_reasm_queue); in sctp_inject_old_unordered_data()
1011 break; in sctp_inject_old_unordered_data()
1012 } else if (at->rec.data.fsn == chk->rec.data.fsn) { in sctp_inject_old_unordered_data()
1018 sctp_abort_in_reasm(stcb, control, chk, in sctp_inject_old_unordered_data()
1026 asoc->size_on_reasm_queue += chk->send_size; in sctp_inject_old_unordered_data()
1027 sctp_ucount_incr(asoc->cnt_on_reasm_queue); in sctp_inject_old_unordered_data()
1028 control->top_fsn = chk->rec.data.fsn; in sctp_inject_old_unordered_data()
1029 TAILQ_INSERT_TAIL(&control->reasm, chk, sctp_next); in sctp_inject_old_unordered_data()
1043 struct sctp_queued_to_read *control, *nctl = NULL; in sctp_deliver_reasm_check() local
1048 if (stcb->sctp_socket) { in sctp_deliver_reasm_check()
1049 pd_point = min(SCTP_SB_LIMIT_RCV(stcb->sctp_socket) >> SCTP_PARTIAL_DELIVERY_SHIFT, in sctp_deliver_reasm_check()
1050 stcb->sctp_ep->partial_delivery_point); in sctp_deliver_reasm_check()
1052 pd_point = stcb->sctp_ep->partial_delivery_point; in sctp_deliver_reasm_check()
1054 control = TAILQ_FIRST(&strm->uno_inqueue); in sctp_deliver_reasm_check()
1056 if ((control != NULL) && in sctp_deliver_reasm_check()
1057 (asoc->idata_supported == 0)) { in sctp_deliver_reasm_check()
1059 if (sctp_handle_old_unordered_data(stcb, asoc, strm, control, pd_point, inp_read_lock_held)) { in sctp_deliver_reasm_check()
1063 if (strm->pd_api_started) { in sctp_deliver_reasm_check()
1067 while (control) { in sctp_deliver_reasm_check()
1068 SCTPDBG(SCTP_DEBUG_XXX, "Looking at control: %p e(%d) ssn: %u top_fsn: %u inc_fsn: %u -uo\n", in sctp_deliver_reasm_check()
1069 control, control->end_added, control->mid, control->top_fsn, control->fsn_included); in sctp_deliver_reasm_check()
1070 nctl = TAILQ_NEXT(control, next_instrm); in sctp_deliver_reasm_check()
1071 if (control->end_added) { in sctp_deliver_reasm_check()
1073 if (control->on_strm_q) { in sctp_deliver_reasm_check()
1075 if (control->on_strm_q != SCTP_ON_UNORDERED) { in sctp_deliver_reasm_check()
1076 panic("Huh control: %p on_q: %d -- not unordered?", in sctp_deliver_reasm_check()
1077 control, control->on_strm_q); in sctp_deliver_reasm_check()
1081 TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); in sctp_deliver_reasm_check()
1082 if (asoc->size_on_all_streams >= control->length) { in sctp_deliver_reasm_check()
1083 asoc->size_on_all_streams -= control->length; in sctp_deliver_reasm_check()
1086 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_deliver_reasm_check()
1088 asoc->size_on_all_streams = 0; in sctp_deliver_reasm_check()
1091 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_deliver_reasm_check()
1092 control->on_strm_q = 0; in sctp_deliver_reasm_check()
1094 if (control->on_read_q == 0) { in sctp_deliver_reasm_check()
1095 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_deliver_reasm_check()
1096 control, in sctp_deliver_reasm_check()
1097 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_deliver_reasm_check()
1101 /* Can we do a PD-API for this un-ordered guy? */ in sctp_deliver_reasm_check()
1102 if ((control->length >= pd_point) && (strm->pd_api_started == 0)) { in sctp_deliver_reasm_check()
1103 strm->pd_api_started = 1; in sctp_deliver_reasm_check()
1104 control->pdapi_started = 1; in sctp_deliver_reasm_check()
1105 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_deliver_reasm_check()
1106 control, in sctp_deliver_reasm_check()
1107 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_deliver_reasm_check()
1110 break; in sctp_deliver_reasm_check()
1113 control = nctl; in sctp_deliver_reasm_check()
1116 control = TAILQ_FIRST(&strm->inqueue); in sctp_deliver_reasm_check()
1117 if (strm->pd_api_started) { in sctp_deliver_reasm_check()
1121 if (control == NULL) { in sctp_deliver_reasm_check()
1124 if (SCTP_MID_EQ(asoc->idata_supported, strm->last_mid_delivered, control->mid)) { in sctp_deliver_reasm_check()
1131 nctl = TAILQ_NEXT(control, next_instrm); in sctp_deliver_reasm_check()
1133 "Looking at control: %p e(%d) ssn: %u top_fsn: %u inc_fsn: %u (lastdel: %u)- o\n", in sctp_deliver_reasm_check()
1134 control, control->end_added, control->mid, in sctp_deliver_reasm_check()
1135 control->top_fsn, control->fsn_included, in sctp_deliver_reasm_check()
1136 strm->last_mid_delivered); in sctp_deliver_reasm_check()
1137 if (control->end_added) { in sctp_deliver_reasm_check()
1138 if (control->on_strm_q) { in sctp_deliver_reasm_check()
1140 if (control->on_strm_q != SCTP_ON_ORDERED) { in sctp_deliver_reasm_check()
1141 panic("Huh control: %p on_q: %d -- not ordered?", in sctp_deliver_reasm_check()
1142 control, control->on_strm_q); in sctp_deliver_reasm_check()
1146 TAILQ_REMOVE(&strm->inqueue, control, next_instrm); in sctp_deliver_reasm_check()
1147 if (asoc->size_on_all_streams >= control->length) { in sctp_deliver_reasm_check()
1148 asoc->size_on_all_streams -= control->length; in sctp_deliver_reasm_check()
1151 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_deliver_reasm_check()
1153 asoc->size_on_all_streams = 0; in sctp_deliver_reasm_check()
1156 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_deliver_reasm_check()
1157 control->on_strm_q = 0; in sctp_deliver_reasm_check()
1159 if (strm->pd_api_started && control->pdapi_started) { in sctp_deliver_reasm_check()
1160 control->pdapi_started = 0; in sctp_deliver_reasm_check()
1161 strm->pd_api_started = 0; in sctp_deliver_reasm_check()
1163 if (control->on_read_q == 0) { in sctp_deliver_reasm_check()
1164 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_deliver_reasm_check()
1165 control, in sctp_deliver_reasm_check()
1166 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_deliver_reasm_check()
1169 control = nctl; in sctp_deliver_reasm_check()
1172 if (strm->pd_api_started) { in sctp_deliver_reasm_check()
1174 * Can't add more must have gotten an un-ordered above being in sctp_deliver_reasm_check()
1180 next_to_del = strm->last_mid_delivered + 1; in sctp_deliver_reasm_check()
1181 if (control) { in sctp_deliver_reasm_check()
1183 "Looking at control: %p e(%d) ssn: %u top_fsn: %u inc_fsn: %u (nxtdel: %u)- o\n", in sctp_deliver_reasm_check()
1184 control, control->end_added, control->mid, control->top_fsn, control->fsn_included, in sctp_deliver_reasm_check()
1186 nctl = TAILQ_NEXT(control, next_instrm); in sctp_deliver_reasm_check()
1187 if (SCTP_MID_EQ(asoc->idata_supported, control->mid, next_to_del) && in sctp_deliver_reasm_check()
1188 (control->first_frag_seen)) { in sctp_deliver_reasm_check()
1192 if (control->end_added) { in sctp_deliver_reasm_check()
1194 if (control->on_strm_q) { in sctp_deliver_reasm_check()
1196 if (control->on_strm_q != SCTP_ON_ORDERED) { in sctp_deliver_reasm_check()
1197 panic("Huh control: %p on_q: %d -- not ordered?", in sctp_deliver_reasm_check()
1198 control, control->on_strm_q); in sctp_deliver_reasm_check()
1202 TAILQ_REMOVE(&strm->inqueue, control, next_instrm); in sctp_deliver_reasm_check()
1203 if (asoc->size_on_all_streams >= control->length) { in sctp_deliver_reasm_check()
1204 asoc->size_on_all_streams -= control->length; in sctp_deliver_reasm_check()
1207 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_deliver_reasm_check()
1209 asoc->size_on_all_streams = 0; in sctp_deliver_reasm_check()
1212 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_deliver_reasm_check()
1213 control->on_strm_q = 0; in sctp_deliver_reasm_check()
1217 if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) { in sctp_deliver_reasm_check()
1219 * A singleton now slipping through - mark in sctp_deliver_reasm_check()
1220 * it non-revokable too in sctp_deliver_reasm_check()
1222 sctp_mark_non_revokable(asoc, control->sinfo_tsn); in sctp_deliver_reasm_check()
1223 } else if (control->end_added == 0) { in sctp_deliver_reasm_check()
1228 if ((control->length < pd_point) || (strm->pd_api_started)) { in sctp_deliver_reasm_check()
1236 done = (control->end_added) && (control->last_frag_seen); in sctp_deliver_reasm_check()
1237 if (control->on_read_q == 0) { in sctp_deliver_reasm_check()
1239 if (asoc->size_on_all_streams >= control->length) { in sctp_deliver_reasm_check()
1240 asoc->size_on_all_streams -= control->length; in sctp_deliver_reasm_check()
1243 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_deliver_reasm_check()
1245 asoc->size_on_all_streams = 0; in sctp_deliver_reasm_check()
1248 strm->pd_api_started = 1; in sctp_deliver_reasm_check()
1249 control->pdapi_started = 1; in sctp_deliver_reasm_check()
1251 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_deliver_reasm_check()
1252 control, in sctp_deliver_reasm_check()
1253 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_deliver_reasm_check()
1256 strm->last_mid_delivered = next_to_del; in sctp_deliver_reasm_check()
1258 control = nctl; in sctp_deliver_reasm_check()
1268 sctp_add_chk_to_control(struct sctp_queued_to_read *control, in sctp_add_chk_to_control() argument
1274 * Given a control and a chunk, merge the data from the chk onto the in sctp_add_chk_to_control()
1275 * control and free up the chunk resources. in sctp_add_chk_to_control()
1280 if (control->on_read_q) { in sctp_add_chk_to_control()
1282 /* Its being pd-api'd so we must do some locks. */ in sctp_add_chk_to_control()
1283 SCTP_INP_READ_LOCK(stcb->sctp_ep); in sctp_add_chk_to_control()
1286 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_CANT_READ) { in sctp_add_chk_to_control()
1290 if (control->data == NULL) { in sctp_add_chk_to_control()
1291 control->data = chk->data; in sctp_add_chk_to_control()
1292 sctp_setup_tail_pointer(control); in sctp_add_chk_to_control()
1294 sctp_add_to_tail_pointer(control, chk->data, &added); in sctp_add_chk_to_control()
1296 control->fsn_included = chk->rec.data.fsn; in sctp_add_chk_to_control()
1297 asoc->size_on_reasm_queue -= chk->send_size; in sctp_add_chk_to_control()
1298 sctp_ucount_decr(asoc->cnt_on_reasm_queue); in sctp_add_chk_to_control()
1299 sctp_mark_non_revokable(asoc, chk->rec.data.tsn); in sctp_add_chk_to_control()
1300 chk->data = NULL; in sctp_add_chk_to_control()
1301 if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { in sctp_add_chk_to_control()
1302 control->first_frag_seen = 1; in sctp_add_chk_to_control()
1303 control->sinfo_tsn = chk->rec.data.tsn; in sctp_add_chk_to_control()
1304 control->sinfo_ppid = chk->rec.data.ppid; in sctp_add_chk_to_control()
1306 if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { in sctp_add_chk_to_control()
1308 if ((control->on_strm_q) && (control->on_read_q)) { in sctp_add_chk_to_control()
1309 if (control->pdapi_started) { in sctp_add_chk_to_control()
1310 control->pdapi_started = 0; in sctp_add_chk_to_control()
1311 strm->pd_api_started = 0; in sctp_add_chk_to_control()
1313 if (control->on_strm_q == SCTP_ON_UNORDERED) { in sctp_add_chk_to_control()
1315 TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); in sctp_add_chk_to_control()
1316 control->on_strm_q = 0; in sctp_add_chk_to_control()
1317 } else if (control->on_strm_q == SCTP_ON_ORDERED) { in sctp_add_chk_to_control()
1319 TAILQ_REMOVE(&strm->inqueue, control, next_instrm); in sctp_add_chk_to_control()
1322 * size_on_all_streams, since control is on in sctp_add_chk_to_control()
1325 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_add_chk_to_control()
1326 control->on_strm_q = 0; in sctp_add_chk_to_control()
1328 } else if (control->on_strm_q) { in sctp_add_chk_to_control()
1329 panic("Unknown state on ctrl: %p on_strm_q: %d", control, in sctp_add_chk_to_control()
1330 control->on_strm_q); in sctp_add_chk_to_control()
1334 control->end_added = 1; in sctp_add_chk_to_control()
1335 control->last_frag_seen = 1; in sctp_add_chk_to_control()
1339 SCTP_INP_READ_UNLOCK(stcb->sctp_ep); in sctp_add_chk_to_control()
1346 * Dump onto the re-assembly queue, in its proper place. After dumping on the
1353 struct sctp_queued_to_read *control, in sctp_queue_data_for_reasm() argument
1364 strm = &asoc->strmin[control->sinfo_stream]; in sctp_queue_data_for_reasm()
1366 * For old un-ordered data chunks. in sctp_queue_data_for_reasm()
1368 if ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) { in sctp_queue_data_for_reasm()
1373 /* Must be added to the stream-in queue */ in sctp_queue_data_for_reasm()
1375 if ((unordered == 0) || (asoc->idata_supported)) { in sctp_queue_data_for_reasm()
1376 sctp_ucount_incr(asoc->cnt_on_all_streams); in sctp_queue_data_for_reasm()
1378 if (sctp_place_control_in_stream(strm, asoc, control)) { in sctp_queue_data_for_reasm()
1380 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1383 sctp_clean_up_control(stcb, control); in sctp_queue_data_for_reasm()
1386 if ((tsn == (asoc->cumulative_tsn + 1) && (asoc->idata_supported == 0))) { in sctp_queue_data_for_reasm()
1388 * Ok we created this control and now lets validate in sctp_queue_data_for_reasm()
1390 * and we have up to the cum-ack then its invalid. in sctp_queue_data_for_reasm()
1392 if ((chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) == 0) { in sctp_queue_data_for_reasm()
1393 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1400 if ((asoc->idata_supported == 0) && (unordered == 1)) { in sctp_queue_data_for_reasm()
1401 sctp_inject_old_unordered_data(stcb, asoc, control, chk, abort_flag); in sctp_queue_data_for_reasm()
1406 * the first it goes to the control mbuf. o if its not first but the in sctp_queue_data_for_reasm()
1407 * next in sequence it goes to the control, and each succeeding one in sctp_queue_data_for_reasm()
1411 if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { in sctp_queue_data_for_reasm()
1415 chk->rec.data.fsn); in sctp_queue_data_for_reasm()
1416 if (control->first_frag_seen) { in sctp_queue_data_for_reasm()
1420 * un-ordered chunks that were fragmented at the in sctp_queue_data_for_reasm()
1423 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1428 control->first_frag_seen = 1; in sctp_queue_data_for_reasm()
1429 control->sinfo_ppid = chk->rec.data.ppid; in sctp_queue_data_for_reasm()
1430 control->sinfo_tsn = chk->rec.data.tsn; in sctp_queue_data_for_reasm()
1431 control->fsn_included = chk->rec.data.fsn; in sctp_queue_data_for_reasm()
1432 control->data = chk->data; in sctp_queue_data_for_reasm()
1433 sctp_mark_non_revokable(asoc, chk->rec.data.tsn); in sctp_queue_data_for_reasm()
1434 chk->data = NULL; in sctp_queue_data_for_reasm()
1436 sctp_setup_tail_pointer(control); in sctp_queue_data_for_reasm()
1437 asoc->size_on_all_streams += control->length; in sctp_queue_data_for_reasm()
1442 if (control->last_frag_seen == 0) { in sctp_queue_data_for_reasm()
1444 if (SCTP_TSN_GT(chk->rec.data.fsn, control->top_fsn)) { in sctp_queue_data_for_reasm()
1447 chk->rec.data.fsn); in sctp_queue_data_for_reasm()
1448 control->top_fsn = chk->rec.data.fsn; in sctp_queue_data_for_reasm()
1450 if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { in sctp_queue_data_for_reasm()
1453 chk->rec.data.fsn); in sctp_queue_data_for_reasm()
1454 control->last_frag_seen = 1; in sctp_queue_data_for_reasm()
1455 if (SCTP_TSN_GT(control->top_fsn, chk->rec.data.fsn)) { in sctp_queue_data_for_reasm()
1457 "New fsn: %u is not at top_fsn: %u -- abort\n", in sctp_queue_data_for_reasm()
1458 chk->rec.data.fsn, in sctp_queue_data_for_reasm()
1459 control->top_fsn); in sctp_queue_data_for_reasm()
1460 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1466 if (asoc->idata_supported || control->first_frag_seen) { in sctp_queue_data_for_reasm()
1473 if (SCTP_TSN_GE(control->fsn_included, chk->rec.data.fsn)) { in sctp_queue_data_for_reasm()
1478 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1485 if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { in sctp_queue_data_for_reasm()
1488 "Duplicate last fsn: %u (top: %u) -- abort\n", in sctp_queue_data_for_reasm()
1489 chk->rec.data.fsn, control->top_fsn); in sctp_queue_data_for_reasm()
1490 sctp_abort_in_reasm(stcb, control, in sctp_queue_data_for_reasm()
1495 if (asoc->idata_supported || control->first_frag_seen) { in sctp_queue_data_for_reasm()
1503 if (SCTP_TSN_GE(control->fsn_included, chk->rec.data.fsn)) { in sctp_queue_data_for_reasm()
1509 "New fsn: %u is already seen in included_fsn: %u -- abort\n", in sctp_queue_data_for_reasm()
1510 chk->rec.data.fsn, control->fsn_included); in sctp_queue_data_for_reasm()
1511 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1521 if (SCTP_TSN_GT(chk->rec.data.fsn, control->top_fsn)) { in sctp_queue_data_for_reasm()
1523 "New fsn: %u is beyond or at top_fsn: %u -- abort\n", in sctp_queue_data_for_reasm()
1524 chk->rec.data.fsn, in sctp_queue_data_for_reasm()
1525 control->top_fsn); in sctp_queue_data_for_reasm()
1526 sctp_abort_in_reasm(stcb, control, chk, in sctp_queue_data_for_reasm()
1534 * reassembly for this control. in sctp_queue_data_for_reasm()
1538 chk->rec.data.fsn); in sctp_queue_data_for_reasm()
1539 TAILQ_FOREACH(at, &control->reasm, sctp_next) { in sctp_queue_data_for_reasm()
1540 if (SCTP_TSN_GT(at->rec.data.fsn, chk->rec.data.fsn)) { in sctp_queue_data_for_reasm()
1541 if (chk->rec.data.rcv_flags & SCTP_DATA_LAST_FRAG) { in sctp_queue_data_for_reasm()
1544 "Last fragment not last in list: -- abort\n"); in sctp_queue_data_for_reasm()
1545 sctp_abort_in_reasm(stcb, control, in sctp_queue_data_for_reasm()
1556 at->rec.data.fsn); in sctp_queue_data_for_reasm()
1557 asoc->size_on_reasm_queue += chk->send_size; in sctp_queue_data_for_reasm()
1558 sctp_ucount_incr(asoc->cnt_on_reasm_queue); in sctp_queue_data_for_reasm()
1561 break; in sctp_queue_data_for_reasm()
1562 } else if (at->rec.data.fsn == chk->rec.data.fsn) { in sctp_queue_data_for_reasm()
1576 "Duplicate to fsn: %u -- abort\n", in sctp_queue_data_for_reasm()
1577 at->rec.data.fsn); in sctp_queue_data_for_reasm()
1578 sctp_abort_in_reasm(stcb, control, in sctp_queue_data_for_reasm()
1587 chk->rec.data.fsn); in sctp_queue_data_for_reasm()
1588 asoc->size_on_reasm_queue += chk->send_size; in sctp_queue_data_for_reasm()
1589 sctp_ucount_incr(asoc->cnt_on_reasm_queue); in sctp_queue_data_for_reasm()
1590 TAILQ_INSERT_TAIL(&control->reasm, chk, sctp_next); in sctp_queue_data_for_reasm()
1594 * Ok lets see if we can suck any up into the control structure that in sctp_queue_data_for_reasm()
1602 if (control->first_frag_seen) { in sctp_queue_data_for_reasm()
1603 next_fsn = control->fsn_included + 1; in sctp_queue_data_for_reasm()
1604 TAILQ_FOREACH_SAFE(at, &control->reasm, sctp_next, nat) { in sctp_queue_data_for_reasm()
1605 if (at->rec.data.fsn == next_fsn) { in sctp_queue_data_for_reasm()
1606 /* We can add this one now to the control */ in sctp_queue_data_for_reasm()
1608 "Adding more to control: %p at: %p fsn: %u next_fsn: %u included: %u\n", in sctp_queue_data_for_reasm()
1609 control, at, in sctp_queue_data_for_reasm()
1610 at->rec.data.fsn, in sctp_queue_data_for_reasm()
1611 next_fsn, control->fsn_included); in sctp_queue_data_for_reasm()
1612 TAILQ_REMOVE(&control->reasm, at, sctp_next); in sctp_queue_data_for_reasm()
1613 lenadded = sctp_add_chk_to_control(control, strm, stcb, asoc, at, SCTP_READ_LOCK_NOT_HELD); in sctp_queue_data_for_reasm()
1614 if (control->on_read_q) { in sctp_queue_data_for_reasm()
1619 * size-on-all-streams if its not on in sctp_queue_data_for_reasm()
1624 asoc->size_on_all_streams += lenadded; in sctp_queue_data_for_reasm()
1627 if (control->end_added && control->pdapi_started) { in sctp_queue_data_for_reasm()
1628 if (strm->pd_api_started) { in sctp_queue_data_for_reasm()
1629 strm->pd_api_started = 0; in sctp_queue_data_for_reasm()
1630 control->pdapi_started = 0; in sctp_queue_data_for_reasm()
1632 if (control->on_read_q == 0) { in sctp_queue_data_for_reasm()
1633 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_queue_data_for_reasm()
1634 control, in sctp_queue_data_for_reasm()
1635 &stcb->sctp_socket->so_rcv, control->end_added, in sctp_queue_data_for_reasm()
1638 break; in sctp_queue_data_for_reasm()
1641 break; in sctp_queue_data_for_reasm()
1647 sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); in sctp_queue_data_for_reasm()
1654 struct sctp_queued_to_read *control; in sctp_find_reasm_entry() local
1657 TAILQ_FOREACH(control, &strm->inqueue, next_instrm) { in sctp_find_reasm_entry()
1658 if (SCTP_MID_EQ(idata_supported, control->mid, mid)) { in sctp_find_reasm_entry()
1659 break; in sctp_find_reasm_entry()
1664 TAILQ_FOREACH(control, &strm->uno_inqueue, next_instrm) { in sctp_find_reasm_entry()
1665 if (SCTP_MID_EQ(idata_supported, control->mid, mid)) { in sctp_find_reasm_entry()
1666 break; in sctp_find_reasm_entry()
1670 control = TAILQ_FIRST(&strm->uno_inqueue); in sctp_find_reasm_entry()
1673 return (control); in sctp_find_reasm_entry()
1691 struct sctp_queued_to_read *control, *ncontrol; in sctp_process_a_data_chunk() local
1704 chk_flags = chunk->ch.chunk_flags; in sctp_process_a_data_chunk()
1706 tsn = ntohl(chunk->dp.tsn); in sctp_process_a_data_chunk()
1707 sid = ntohs(chunk->dp.sid); in sctp_process_a_data_chunk()
1708 mid = ntohl(chunk->dp.mid); in sctp_process_a_data_chunk()
1711 ppid = chunk->dp.ppid_fsn.ppid; in sctp_process_a_data_chunk()
1713 fsn = ntohl(chunk->dp.ppid_fsn.fsn); in sctp_process_a_data_chunk()
1721 chk_flags = chunk->ch.chunk_flags; in sctp_process_a_data_chunk()
1723 tsn = ntohl(chunk->dp.tsn); in sctp_process_a_data_chunk()
1724 sid = ntohs(chunk->dp.sid); in sctp_process_a_data_chunk()
1725 mid = (uint32_t)(ntohs(chunk->dp.ssn)); in sctp_process_a_data_chunk()
1727 ppid = chunk->dp.ppid; in sctp_process_a_data_chunk()
1734 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_16; in sctp_process_a_data_chunk()
1735 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_process_a_data_chunk()
1740 asoc->send_sack = 1; in sctp_process_a_data_chunk()
1744 sctp_log_map(tsn, asoc->cumulative_tsn, asoc->highest_tsn_inside_map, SCTP_MAP_TSN_ENTERS); in sctp_process_a_data_chunk()
1749 SCTP_LTRACE_CHK(stcb->sctp_ep, stcb, chk_type, tsn); in sctp_process_a_data_chunk()
1750 if (SCTP_TSN_GE(asoc->cumulative_tsn, tsn)) { in sctp_process_a_data_chunk()
1753 if (asoc->numduptsns < SCTP_MAX_DUP_TSNS) { in sctp_process_a_data_chunk()
1755 asoc->dup_tsns[asoc->numduptsns] = tsn; in sctp_process_a_data_chunk()
1756 asoc->numduptsns++; in sctp_process_a_data_chunk()
1758 asoc->send_sack = 1; in sctp_process_a_data_chunk()
1762 SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn); in sctp_process_a_data_chunk()
1767 if (gap >= (uint32_t)(asoc->mapping_array_size << 3)) { in sctp_process_a_data_chunk()
1778 if (SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap) || in sctp_process_a_data_chunk()
1779 SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap)) { in sctp_process_a_data_chunk()
1781 if (asoc->numduptsns < SCTP_MAX_DUP_TSNS) { in sctp_process_a_data_chunk()
1783 asoc->dup_tsns[asoc->numduptsns] = tsn; in sctp_process_a_data_chunk()
1784 asoc->numduptsns++; in sctp_process_a_data_chunk()
1786 asoc->send_sack = 1; in sctp_process_a_data_chunk()
1793 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || in sctp_process_a_data_chunk()
1794 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) || in sctp_process_a_data_chunk()
1795 (stcb->asoc.state & SCTP_STATE_CLOSED_SOCKET))) { in sctp_process_a_data_chunk()
1801 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_process_a_data_chunk()
1812 if (sid >= asoc->streamincnt) { in sctp_process_a_data_chunk()
1827 cause->cause.code = htons(SCTP_CAUSE_INVALID_STREAM); in sctp_process_a_data_chunk()
1828 cause->cause.length = htons(sizeof(struct sctp_error_invalid_stream)); in sctp_process_a_data_chunk()
1829 cause->stream_id = htons(sid); in sctp_process_a_data_chunk()
1830 cause->reserved = htons(0); in sctp_process_a_data_chunk()
1835 SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); in sctp_process_a_data_chunk()
1836 if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) { in sctp_process_a_data_chunk()
1837 asoc->highest_tsn_inside_nr_map = tsn; in sctp_process_a_data_chunk()
1839 if (tsn == (asoc->cumulative_tsn + 1)) { in sctp_process_a_data_chunk()
1840 /* Update cum-ack */ in sctp_process_a_data_chunk()
1841 asoc->cumulative_tsn = tsn; in sctp_process_a_data_chunk()
1846 * If its a fragmented message, lets see if we can find the control in sctp_process_a_data_chunk()
1860 control = sctp_find_reasm_entry(&asoc->strmin[sid], mid, ordered, asoc->idata_supported); in sctp_process_a_data_chunk()
1861 SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for control on queues %p\n", in sctp_process_a_data_chunk()
1862 chk_flags, control); in sctp_process_a_data_chunk()
1864 /* See if we can find the re-assembly entity */ in sctp_process_a_data_chunk()
1865 if (control != NULL) { in sctp_process_a_data_chunk()
1867 if (ordered && (mid != control->mid)) { in sctp_process_a_data_chunk()
1871 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_17; in sctp_process_a_data_chunk()
1872 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_process_a_data_chunk()
1876 if (ordered && ((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED)) { in sctp_process_a_data_chunk()
1886 if (!ordered && (((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) == 0)) { in sctp_process_a_data_chunk()
1900 * re-assembly going on with the same Stream/Seq (for in sctp_process_a_data_chunk()
1903 if (control != NULL) { in sctp_process_a_data_chunk()
1904 if (ordered || asoc->idata_supported) { in sctp_process_a_data_chunk()
1910 if ((control->first_frag_seen) && in sctp_process_a_data_chunk()
1911 (tsn == control->fsn_included + 1) && in sctp_process_a_data_chunk()
1912 (control->end_added == 0)) { in sctp_process_a_data_chunk()
1915 control->fsn_included); in sctp_process_a_data_chunk()
1918 control = NULL; in sctp_process_a_data_chunk()
1924 if (((asoc->cnt_on_all_streams + in sctp_process_a_data_chunk()
1925 asoc->cnt_on_reasm_queue + in sctp_process_a_data_chunk()
1926 asoc->cnt_msg_on_sb) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue)) || in sctp_process_a_data_chunk()
1927 (((int)asoc->my_rwnd) <= 0)) { in sctp_process_a_data_chunk()
1932 if (SCTP_SBAVAIL(&stcb->sctp_socket->so_rcv) > 0) { in sctp_process_a_data_chunk()
1933 /* some to read, wake-up */ in sctp_process_a_data_chunk()
1934 sctp_sorwakeup(stcb->sctp_ep, stcb->sctp_socket); in sctp_process_a_data_chunk()
1938 if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_map) && in sctp_process_a_data_chunk()
1939 SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) { in sctp_process_a_data_chunk()
1943 if ((asoc->cnt_on_all_streams + in sctp_process_a_data_chunk()
1944 asoc->cnt_on_reasm_queue + in sctp_process_a_data_chunk()
1945 asoc->cnt_msg_on_sb) >= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue)) { in sctp_process_a_data_chunk()
1954 if (control == NULL) { in sctp_process_a_data_chunk()
1957 if (SCTP_TSN_GT(fsn, control->top_fsn)) { in sctp_process_a_data_chunk()
1964 if (asoc->tsn_in_at >= SCTP_TSN_LOG_SIZE) { in sctp_process_a_data_chunk()
1965 asoc->tsn_in_at = 0; in sctp_process_a_data_chunk()
1966 asoc->tsn_in_wrapped = 1; in sctp_process_a_data_chunk()
1968 asoc->in_tsnlog[asoc->tsn_in_at].tsn = tsn; in sctp_process_a_data_chunk()
1969 asoc->in_tsnlog[asoc->tsn_in_at].strm = sid; in sctp_process_a_data_chunk()
1970 asoc->in_tsnlog[asoc->tsn_in_at].seq = mid; in sctp_process_a_data_chunk()
1971 asoc->in_tsnlog[asoc->tsn_in_at].sz = chk_length; in sctp_process_a_data_chunk()
1972 asoc->in_tsnlog[asoc->tsn_in_at].flgs = chunk_flags; in sctp_process_a_data_chunk()
1973 asoc->in_tsnlog[asoc->tsn_in_at].stcb = (void *)stcb; in sctp_process_a_data_chunk()
1974 asoc->in_tsnlog[asoc->tsn_in_at].in_pos = asoc->tsn_in_at; in sctp_process_a_data_chunk()
1975 asoc->in_tsnlog[asoc->tsn_in_at].in_out = 1; in sctp_process_a_data_chunk()
1976 asoc->tsn_in_at++; in sctp_process_a_data_chunk()
1986 (TAILQ_EMPTY(&asoc->resetHead)) && in sctp_process_a_data_chunk()
1988 SCTP_MID_GE(asoc->idata_supported, asoc->strmin[sid].last_mid_delivered, mid)) { in sctp_process_a_data_chunk()
1990 SCTPDBG(SCTP_DEBUG_INDATA1, "EVIL/Broken-Dup S-SEQ: %u delivered: %u from peer, Abort!\n", in sctp_process_a_data_chunk()
1991 mid, asoc->strmin[sid].last_mid_delivered); in sctp_process_a_data_chunk()
1993 if (asoc->idata_supported) { in sctp_process_a_data_chunk()
1995 asoc->strmin[sid].last_mid_delivered, in sctp_process_a_data_chunk()
2001 (uint16_t)asoc->strmin[sid].last_mid_delivered, in sctp_process_a_data_chunk()
2007 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_18; in sctp_process_a_data_chunk()
2008 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_process_a_data_chunk()
2013 the_len = (chk_length - sizeof(struct sctp_idata_chunk)); in sctp_process_a_data_chunk()
2015 the_len = (chk_length - sizeof(struct sctp_data_chunk)); in sctp_process_a_data_chunk()
2048 * this to often :-0 in sctp_process_a_data_chunk()
2059 m_adj(dmbuf, -(l_len - the_len)); in sctp_process_a_data_chunk()
2067 * Now no matter what, we need a control, get one if we don't have in sctp_process_a_data_chunk()
2071 if (control == NULL) { in sctp_process_a_data_chunk()
2072 sctp_alloc_a_readq(stcb, control); in sctp_process_a_data_chunk()
2073 sctp_build_readq_entry_mac(control, stcb, asoc->context, net, tsn, in sctp_process_a_data_chunk()
2078 if (control == NULL) { in sctp_process_a_data_chunk()
2085 control->data = dmbuf; in sctp_process_a_data_chunk()
2086 control->tail_mbuf = NULL; in sctp_process_a_data_chunk()
2087 for (mm = control->data; mm; mm = mm->m_next) { in sctp_process_a_data_chunk()
2088 control->length += SCTP_BUF_LEN(mm); in sctp_process_a_data_chunk()
2090 control->tail_mbuf = mm; in sctp_process_a_data_chunk()
2093 control->end_added = 1; in sctp_process_a_data_chunk()
2094 control->last_frag_seen = 1; in sctp_process_a_data_chunk()
2095 control->first_frag_seen = 1; in sctp_process_a_data_chunk()
2096 control->fsn_included = fsn; in sctp_process_a_data_chunk()
2097 control->top_fsn = fsn; in sctp_process_a_data_chunk()
2101 SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x ordered: %d MID: %u control: %p\n", in sctp_process_a_data_chunk()
2102 chk_flags, ordered, mid, control); in sctp_process_a_data_chunk()
2104 TAILQ_EMPTY(&asoc->resetHead) && in sctp_process_a_data_chunk()
2106 (SCTP_MID_EQ(asoc->idata_supported, asoc->strmin[sid].last_mid_delivered + 1, mid) && in sctp_process_a_data_chunk()
2107 TAILQ_EMPTY(&asoc->strmin[sid].inqueue)))) { in sctp_process_a_data_chunk()
2110 * Its not fragmented, No PD-API is up, Nothing in the in sctp_process_a_data_chunk()
2111 * delivery queue, Its un-ordered OR ordered and the next to in sctp_process_a_data_chunk()
2116 SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); in sctp_process_a_data_chunk()
2117 if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) { in sctp_process_a_data_chunk()
2118 asoc->highest_tsn_inside_nr_map = tsn; in sctp_process_a_data_chunk()
2120 SCTPDBG(SCTP_DEBUG_XXX, "Injecting control: %p to be read (MID: %u)\n", in sctp_process_a_data_chunk()
2121 control, mid); in sctp_process_a_data_chunk()
2123 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_process_a_data_chunk()
2124 control, &stcb->sctp_socket->so_rcv, in sctp_process_a_data_chunk()
2129 asoc->strmin[sid].last_mid_delivered++; in sctp_process_a_data_chunk()
2136 control = NULL; in sctp_process_a_data_chunk()
2152 chk->rec.data.tsn = tsn; in sctp_process_a_data_chunk()
2153 chk->no_fr_allowed = 0; in sctp_process_a_data_chunk()
2154 chk->rec.data.fsn = fsn; in sctp_process_a_data_chunk()
2155 chk->rec.data.mid = mid; in sctp_process_a_data_chunk()
2156 chk->rec.data.sid = sid; in sctp_process_a_data_chunk()
2157 chk->rec.data.ppid = ppid; in sctp_process_a_data_chunk()
2158 chk->rec.data.context = stcb->asoc.context; in sctp_process_a_data_chunk()
2159 chk->rec.data.doing_fast_retransmit = 0; in sctp_process_a_data_chunk()
2160 chk->rec.data.rcv_flags = chk_flags; in sctp_process_a_data_chunk()
2161 chk->asoc = asoc; in sctp_process_a_data_chunk()
2162 chk->send_size = the_len; in sctp_process_a_data_chunk()
2163 chk->whoTo = net; in sctp_process_a_data_chunk()
2164 SCTPDBG(SCTP_DEBUG_XXX, "Building ck: %p for control: %p to be read (MID: %u)\n", in sctp_process_a_data_chunk()
2166 control, mid); in sctp_process_a_data_chunk()
2167 atomic_add_int(&net->ref_count, 1); in sctp_process_a_data_chunk()
2168 chk->data = dmbuf; in sctp_process_a_data_chunk()
2172 SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, gap); in sctp_process_a_data_chunk()
2173 if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_nr_map)) { in sctp_process_a_data_chunk()
2174 asoc->highest_tsn_inside_nr_map = tsn; in sctp_process_a_data_chunk()
2177 SCTP_SET_TSN_PRESENT(asoc->mapping_array, gap); in sctp_process_a_data_chunk()
2178 if (SCTP_TSN_GT(tsn, asoc->highest_tsn_inside_map)) { in sctp_process_a_data_chunk()
2179 asoc->highest_tsn_inside_map = tsn; in sctp_process_a_data_chunk()
2192 if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) && in sctp_process_a_data_chunk()
2193 SCTP_TSN_GT(tsn, liste->tsn)) { in sctp_process_a_data_chunk()
2198 if (TAILQ_EMPTY(&asoc->pending_reply_queue)) { in sctp_process_a_data_chunk()
2200 TAILQ_INSERT_TAIL(&asoc->pending_reply_queue, control, next); in sctp_process_a_data_chunk()
2205 TAILQ_FOREACH_SAFE(lcontrol, &asoc->pending_reply_queue, next, nlcontrol) { in sctp_process_a_data_chunk()
2206 if (SCTP_TSN_GT(control->sinfo_tsn, lcontrol->sinfo_tsn)) { in sctp_process_a_data_chunk()
2210 TAILQ_INSERT_BEFORE(lcontrol, control, next); in sctp_process_a_data_chunk()
2212 break; in sctp_process_a_data_chunk()
2221 TAILQ_INSERT_TAIL(&asoc->pending_reply_queue, control, next); in sctp_process_a_data_chunk()
2228 SCTPDBG(SCTP_DEBUG_XXX, "Unordered data to be read control: %p MID: %u\n", in sctp_process_a_data_chunk()
2229 control, mid); in sctp_process_a_data_chunk()
2230 sctp_mark_non_revokable(asoc, control->sinfo_tsn); in sctp_process_a_data_chunk()
2231 sctp_add_to_readq(stcb->sctp_ep, stcb, in sctp_process_a_data_chunk()
2232 control, in sctp_process_a_data_chunk()
2233 &stcb->sctp_socket->so_rcv, 1, in sctp_process_a_data_chunk()
2237 SCTPDBG(SCTP_DEBUG_XXX, "Queue control: %p for reordering MID: %u\n", control, in sctp_process_a_data_chunk()
2239 sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check); in sctp_process_a_data_chunk()
2252 "Queue data to stream for reasm control: %p MID: %u\n", in sctp_process_a_data_chunk()
2253 control, mid); in sctp_process_a_data_chunk()
2254 sctp_queue_data_for_reasm(stcb, asoc, control, chk, created_control, abort_flag, tsn); in sctp_process_a_data_chunk()
2267 if (tsn == (asoc->cumulative_tsn + 1)) { in sctp_process_a_data_chunk()
2268 /* Update cum-ack */ in sctp_process_a_data_chunk()
2269 asoc->cumulative_tsn = tsn; in sctp_process_a_data_chunk()
2285 sctp_log_map(asoc->mapping_array_base_tsn, asoc->cumulative_tsn, in sctp_process_a_data_chunk()
2286 asoc->highest_tsn_inside_map, SCTP_MAP_PREPARE_SLIDE); in sctp_process_a_data_chunk()
2289 (void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[sid], SCTP_READ_LOCK_NOT_HELD); in sctp_process_a_data_chunk()
2293 if (((liste = TAILQ_FIRST(&asoc->resetHead)) != NULL) && in sctp_process_a_data_chunk()
2294 SCTP_TSN_GE(asoc->cumulative_tsn, liste->tsn)) { in sctp_process_a_data_chunk()
2301 sctp_reset_in_stream(stcb, liste->number_entries, liste->list_of_streams); in sctp_process_a_data_chunk()
2302 TAILQ_REMOVE(&asoc->resetHead, liste, next_resp); in sctp_process_a_data_chunk()
2306 liste = TAILQ_FIRST(&asoc->resetHead); in sctp_process_a_data_chunk()
2307 if (TAILQ_EMPTY(&asoc->resetHead)) { in sctp_process_a_data_chunk()
2309 TAILQ_FOREACH_SAFE(control, &asoc->pending_reply_queue, next, ncontrol) { in sctp_process_a_data_chunk()
2310 TAILQ_REMOVE(&asoc->pending_reply_queue, control, next); in sctp_process_a_data_chunk()
2311 strm = &asoc->strmin[control->sinfo_stream]; in sctp_process_a_data_chunk()
2312 sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check); in sctp_process_a_data_chunk()
2322 TAILQ_FOREACH_SAFE(control, &asoc->pending_reply_queue, next, ncontrol) { in sctp_process_a_data_chunk()
2323 if (SCTP_TSN_GT(control->sinfo_tsn, liste->tsn)) { in sctp_process_a_data_chunk()
2324 break; in sctp_process_a_data_chunk()
2327 * if control->sinfo_tsn is <= liste->tsn we in sctp_process_a_data_chunk()
2329 * control->sinfo_tsn > liste->tsn in sctp_process_a_data_chunk()
2331 TAILQ_REMOVE(&asoc->pending_reply_queue, control, next); in sctp_process_a_data_chunk()
2332 strm = &asoc->strmin[control->sinfo_stream]; in sctp_process_a_data_chunk()
2333 sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check); in sctp_process_a_data_chunk()
2387 * 1) Did we move the cum-ack point? in sctp_slide_mapping_arrays()
2390 * that make up the position of the cum-ack would be in the in sctp_slide_mapping_arrays()
2391 * nr-mapping array only.. i.e. things up to the cum-ack are always in sctp_slide_mapping_arrays()
2395 * mapping_array to get a true picture of the cum-ack. in sctp_slide_mapping_arrays()
2403 asoc = &stcb->asoc; in sctp_slide_mapping_arrays()
2405 old_cumack = asoc->cumulative_tsn; in sctp_slide_mapping_arrays()
2406 old_base = asoc->mapping_array_base_tsn; in sctp_slide_mapping_arrays()
2407 old_highest = asoc->highest_tsn_inside_map; in sctp_slide_mapping_arrays()
2410 * offset of the current cum-ack as the starting point. in sctp_slide_mapping_arrays()
2413 for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) { in sctp_slide_mapping_arrays()
2414 val = asoc->nr_mapping_array[slide_from] | asoc->mapping_array[slide_from]; in sctp_slide_mapping_arrays()
2420 break; in sctp_slide_mapping_arrays()
2423 asoc->cumulative_tsn = asoc->mapping_array_base_tsn + (at - 1); in sctp_slide_mapping_arrays()
2425 if (SCTP_TSN_GT(asoc->cumulative_tsn, asoc->highest_tsn_inside_map) && in sctp_slide_mapping_arrays()
2426 SCTP_TSN_GT(asoc->cumulative_tsn, asoc->highest_tsn_inside_nr_map)) { in sctp_slide_mapping_arrays()
2428 panic("huh, cumack 0x%x greater than high-tsn 0x%x in map", in sctp_slide_mapping_arrays()
2429 asoc->cumulative_tsn, asoc->highest_tsn_inside_map); in sctp_slide_mapping_arrays()
2431 SCTP_PRINTF("huh, cumack 0x%x greater than high-tsn 0x%x in map - should panic?\n", in sctp_slide_mapping_arrays()
2432 asoc->cumulative_tsn, asoc->highest_tsn_inside_map); in sctp_slide_mapping_arrays()
2435 sctp_log_map(0, 6, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); in sctp_slide_mapping_arrays()
2437 asoc->highest_tsn_inside_map = asoc->cumulative_tsn; in sctp_slide_mapping_arrays()
2438 asoc->highest_tsn_inside_nr_map = asoc->cumulative_tsn; in sctp_slide_mapping_arrays()
2441 if (SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->highest_tsn_inside_map)) { in sctp_slide_mapping_arrays()
2442 highest_tsn = asoc->highest_tsn_inside_nr_map; in sctp_slide_mapping_arrays()
2444 highest_tsn = asoc->highest_tsn_inside_map; in sctp_slide_mapping_arrays()
2446 if ((asoc->cumulative_tsn == highest_tsn) && (at >= 8)) { in sctp_slide_mapping_arrays()
2448 /* highest becomes the cum-ack */ in sctp_slide_mapping_arrays()
2456 if (clr > asoc->mapping_array_size) { in sctp_slide_mapping_arrays()
2457 clr = asoc->mapping_array_size; in sctp_slide_mapping_arrays()
2459 memset(asoc->mapping_array, 0, clr); in sctp_slide_mapping_arrays()
2460 memset(asoc->nr_mapping_array, 0, clr); in sctp_slide_mapping_arrays()
2462 for (i = 0; i < asoc->mapping_array_size; i++) { in sctp_slide_mapping_arrays()
2463 if ((asoc->mapping_array[i]) || (asoc->nr_mapping_array[i])) { in sctp_slide_mapping_arrays()
2469 asoc->mapping_array_base_tsn = asoc->cumulative_tsn + 1; in sctp_slide_mapping_arrays()
2470 asoc->highest_tsn_inside_nr_map = asoc->highest_tsn_inside_map = asoc->cumulative_tsn; in sctp_slide_mapping_arrays()
2479 SCTP_CALC_TSN_TO_GAP(lgap, highest_tsn, asoc->mapping_array_base_tsn); in sctp_slide_mapping_arrays()
2491 if (slide_end > asoc->mapping_array_size) { in sctp_slide_mapping_arrays()
2496 asoc->mapping_array_size, slide_end); in sctp_slide_mapping_arrays()
2497 slide_end = asoc->mapping_array_size; in sctp_slide_mapping_arrays()
2500 distance = (slide_end - slide_from) + 1; in sctp_slide_mapping_arrays()
2507 if (distance + slide_from > asoc->mapping_array_size || in sctp_slide_mapping_arrays()
2513 * don't think this should happen :-0 in sctp_slide_mapping_arrays()
2517 (uint32_t)asoc->mapping_array_size, in sctp_slide_mapping_arrays()
2524 asoc->mapping_array[ii] = asoc->mapping_array[slide_from + ii]; in sctp_slide_mapping_arrays()
2525 asoc->nr_mapping_array[ii] = asoc->nr_mapping_array[slide_from + ii]; in sctp_slide_mapping_arrays()
2527 for (ii = distance; ii < asoc->mapping_array_size; ii++) { in sctp_slide_mapping_arrays()
2528 asoc->mapping_array[ii] = 0; in sctp_slide_mapping_arrays()
2529 asoc->nr_mapping_array[ii] = 0; in sctp_slide_mapping_arrays()
2531 if (asoc->highest_tsn_inside_map + 1 == asoc->mapping_array_base_tsn) { in sctp_slide_mapping_arrays()
2532 asoc->highest_tsn_inside_map += (slide_from << 3); in sctp_slide_mapping_arrays()
2534 if (asoc->highest_tsn_inside_nr_map + 1 == asoc->mapping_array_base_tsn) { in sctp_slide_mapping_arrays()
2535 asoc->highest_tsn_inside_nr_map += (slide_from << 3); in sctp_slide_mapping_arrays()
2537 asoc->mapping_array_base_tsn += (slide_from << 3); in sctp_slide_mapping_arrays()
2539 sctp_log_map(asoc->mapping_array_base_tsn, in sctp_slide_mapping_arrays()
2540 asoc->cumulative_tsn, asoc->highest_tsn_inside_map, in sctp_slide_mapping_arrays()
2555 asoc = &stcb->asoc; in sctp_sack_check()
2556 if (SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->highest_tsn_inside_map)) { in sctp_sack_check()
2557 highest_tsn = asoc->highest_tsn_inside_nr_map; in sctp_sack_check()
2559 highest_tsn = asoc->highest_tsn_inside_map; in sctp_sack_check()
2562 is_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn); in sctp_sack_check()
2570 * Ok special case, in SHUTDOWN-SENT case. here we maker in sctp_sack_check()
2574 if (SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) { in sctp_sack_check()
2576 stcb->sctp_ep, stcb, NULL, in sctp_sack_check()
2580 ((stcb->asoc.alternate) ? stcb->asoc.alternate : stcb->asoc.primary_destination)); in sctp_sack_check()
2589 stcb->asoc.cmt_dac_pkts_rcvd++; in sctp_sack_check()
2591 if ((stcb->asoc.send_sack == 1) || /* We need to send a in sctp_sack_check()
2595 (stcb->asoc.numduptsns) || /* we have dup's */ in sctp_sack_check()
2597 (stcb->asoc.delayed_ack == 0) || /* Delayed sack disabled */ in sctp_sack_check()
2598 (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq)) { /* hit limit of pkts */ in sctp_sack_check()
2599 if ((stcb->asoc.sctp_cmt_on_off > 0) && in sctp_sack_check()
2601 (stcb->asoc.send_sack == 0) && in sctp_sack_check()
2602 (stcb->asoc.numduptsns == 0) && in sctp_sack_check()
2603 (stcb->asoc.delayed_ack) && in sctp_sack_check()
2604 (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer))) { in sctp_sack_check()
2616 stcb->sctp_ep, stcb, NULL); in sctp_sack_check()
2623 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, in sctp_sack_check()
2628 if (!SCTP_OS_TIMER_PENDING(&stcb->asoc.dack_timer.timer)) { in sctp_sack_check()
2630 stcb->sctp_ep, stcb, NULL); in sctp_sack_check()
2643 int num_chunks = 0; /* number of control chunks processed */ in sctp_process_data()
2652 sctp_set_rwnd(stcb, &stcb->asoc); in sctp_process_data()
2656 asoc = &stcb->asoc; in sctp_process_data()
2657 if (SCTP_TSN_GT(asoc->highest_tsn_inside_nr_map, asoc->highest_tsn_inside_map)) { in sctp_process_data()
2658 highest_tsn = asoc->highest_tsn_inside_nr_map; in sctp_process_data()
2660 highest_tsn = asoc->highest_tsn_inside_map; in sctp_process_data()
2662 was_a_gap = SCTP_TSN_GT(highest_tsn, stcb->asoc.cumulative_tsn); in sctp_process_data()
2668 asoc->last_data_chunk_from = net; in sctp_process_data()
2670 /*- in sctp_process_data()
2708 *high_tsn = asoc->cumulative_tsn; in sctp_process_data()
2710 asoc->data_pkts_seen++; in sctp_process_data()
2713 chk_length = ntohs(ch->chunk_length); in sctp_process_data()
2714 if (length - *offset < chk_length) { in sctp_process_data()
2719 if ((asoc->idata_supported == 1) && in sctp_process_data()
2720 (ch->chunk_type == SCTP_DATA)) { in sctp_process_data()
2724 SCTP_SNPRINTF(msg, sizeof(msg), "%s", "DATA chunk received when I-DATA was negotiated"); in sctp_process_data()
2726 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_21; in sctp_process_data()
2730 if ((asoc->idata_supported == 0) && in sctp_process_data()
2731 (ch->chunk_type == SCTP_IDATA)) { in sctp_process_data()
2735 SCTP_SNPRINTF(msg, sizeof(msg), "%s", "I-DATA chunk received when DATA was negotiated"); in sctp_process_data()
2737 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_22; in sctp_process_data()
2741 if ((ch->chunk_type == SCTP_DATA) || in sctp_process_data()
2742 (ch->chunk_type == SCTP_IDATA)) { in sctp_process_data()
2745 if (ch->chunk_type == SCTP_DATA) { in sctp_process_data()
2759 ch->chunk_type == SCTP_DATA ? "DATA" : "I-DATA", in sctp_process_data()
2762 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_23; in sctp_process_data()
2769 if (SCTP_SIZE32(chk_length) == (length - *offset)) { in sctp_process_data()
2776 last_chunk, ch->chunk_type)) { in sctp_process_data()
2792 switch (ch->chunk_type) { in sctp_process_data()
2830 ch->chunk_type); in sctp_process_data()
2850 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_24; in sctp_process_data()
2854 if (ch->chunk_type & 0x40) { in sctp_process_data()
2863 cause->code = htons(SCTP_CAUSE_UNRECOG_CHUNK); in sctp_process_data()
2864 cause->length = htons((uint16_t)(chk_length + sizeof(struct sctp_gen_error_cause))); in sctp_process_data()
2874 if ((ch->chunk_type & 0x80) == 0) { in sctp_process_data()
2879 break; in sctp_process_data()
2905 * Did we get data, if so update the time for auto-close and in sctp_process_data()
2911 stcb->asoc.overall_error_count, in sctp_process_data()
2916 stcb->asoc.overall_error_count = 0; in sctp_process_data()
2917 (void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_last_rcvd); in sctp_process_data()
2922 stcb->asoc.send_sack = 1; in sctp_process_data()
2944 tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue); in sctp_process_segment_range()
2949 if (tp1->rec.data.doing_fast_retransmit) in sctp_process_segment_range()
2952 /*- in sctp_process_segment_range()
2955 * next expected pseudo-cumack, or in sctp_process_segment_range()
2960 if ((tp1->sent < SCTP_DATAGRAM_RESEND) && in sctp_process_segment_range()
2961 (tp1->whoTo->find_pseudo_cumack == 1) && in sctp_process_segment_range()
2962 (tp1->snd_count == 1)) { in sctp_process_segment_range()
2963 tp1->whoTo->pseudo_cumack = tp1->rec.data.tsn; in sctp_process_segment_range()
2964 tp1->whoTo->find_pseudo_cumack = 0; in sctp_process_segment_range()
2966 if ((tp1->sent < SCTP_DATAGRAM_RESEND) && in sctp_process_segment_range()
2967 (tp1->whoTo->find_rtx_pseudo_cumack == 1) && in sctp_process_segment_range()
2968 (tp1->snd_count > 1)) { in sctp_process_segment_range()
2969 tp1->whoTo->rtx_pseudo_cumack = tp1->rec.data.tsn; in sctp_process_segment_range()
2970 tp1->whoTo->find_rtx_pseudo_cumack = 0; in sctp_process_segment_range()
2972 if (tp1->rec.data.tsn == theTSN) { in sctp_process_segment_range()
2973 if (tp1->sent != SCTP_DATAGRAM_UNSENT) { in sctp_process_segment_range()
2974 /*- in sctp_process_segment_range()
2976 * cum-ack passes in sctp_process_segment_range()
2978 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_process_segment_range()
2979 /*- in sctp_process_segment_range()
2981 * now no-longer in flight. in sctp_process_segment_range()
2986 if (SCTP_TSN_GT(tp1->rec.data.tsn, in sctp_process_segment_range()
2988 *biggest_newly_acked_tsn = tp1->rec.data.tsn; in sctp_process_segment_range()
2990 /*- in sctp_process_segment_range()
2991 * CMT: SFR algo (and HTNA) - set in sctp_process_segment_range()
2997 if (tp1->rec.data.chunk_was_revoked == 0) in sctp_process_segment_range()
2998 tp1->whoTo->saw_newack = 1; in sctp_process_segment_range()
3000 if (SCTP_TSN_GT(tp1->rec.data.tsn, in sctp_process_segment_range()
3001 tp1->whoTo->this_sack_highest_newack)) { in sctp_process_segment_range()
3002 tp1->whoTo->this_sack_highest_newack = in sctp_process_segment_range()
3003 tp1->rec.data.tsn; in sctp_process_segment_range()
3005 /*- in sctp_process_segment_range()
3013 tp1->rec.data.tsn, in sctp_process_segment_range()
3018 *this_sack_lowest_newack = tp1->rec.data.tsn; in sctp_process_segment_range()
3020 /*- in sctp_process_segment_range()
3021 * CMT: CUCv2 algorithm. If (rtx-)pseudo-cumack for corresp in sctp_process_segment_range()
3022 * dest is being acked, then we have a new (rtx-)pseudo-cumack. Set in sctp_process_segment_range()
3024 * updated. Also trigger search for the next expected (rtx-)pseudo-cumack. in sctp_process_segment_range()
3028 if (tp1->rec.data.tsn == tp1->whoTo->pseudo_cumack) { in sctp_process_segment_range()
3029 if (tp1->rec.data.chunk_was_revoked == 0) { in sctp_process_segment_range()
3030 tp1->whoTo->new_pseudo_cumack = 1; in sctp_process_segment_range()
3032 tp1->whoTo->find_pseudo_cumack = 1; in sctp_process_segment_range()
3035 sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK); in sctp_process_segment_range()
3037 if (tp1->rec.data.tsn == tp1->whoTo->rtx_pseudo_cumack) { in sctp_process_segment_range()
3038 if (tp1->rec.data.chunk_was_revoked == 0) { in sctp_process_segment_range()
3039 tp1->whoTo->new_pseudo_cumack = 1; in sctp_process_segment_range()
3041 tp1->whoTo->find_rtx_pseudo_cumack = 1; in sctp_process_segment_range()
3046 tp1->rec.data.tsn, in sctp_process_segment_range()
3053 tp1->whoTo->flight_size, in sctp_process_segment_range()
3054 tp1->book_size, in sctp_process_segment_range()
3055 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_process_segment_range()
3056 tp1->rec.data.tsn); in sctp_process_segment_range()
3059 if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) { in sctp_process_segment_range()
3060 (*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo, in sctp_process_segment_range()
3065 tp1->whoTo->net_ack += tp1->send_size; in sctp_process_segment_range()
3066 if (tp1->snd_count < 2) { in sctp_process_segment_range()
3067 /*- in sctp_process_segment_range()
3068 * True non-retransmitted chunk in sctp_process_segment_range()
3070 tp1->whoTo->net_ack2 += tp1->send_size; in sctp_process_segment_range()
3072 /*- in sctp_process_segment_range()
3075 if (tp1->do_rtt) { in sctp_process_segment_range()
3078 &stcb->asoc, in sctp_process_segment_range()
3079 tp1->whoTo, in sctp_process_segment_range()
3080 &tp1->sent_rcv_time, in sctp_process_segment_range()
3084 if (tp1->whoTo->rto_needed == 0) { in sctp_process_segment_range()
3085 tp1->whoTo->rto_needed = 1; in sctp_process_segment_range()
3087 tp1->do_rtt = 0; in sctp_process_segment_range()
3091 if (tp1->sent <= SCTP_DATAGRAM_RESEND) { in sctp_process_segment_range()
3092 if (SCTP_TSN_GT(tp1->rec.data.tsn, in sctp_process_segment_range()
3093 stcb->asoc.this_sack_highest_gap)) { in sctp_process_segment_range()
3094 stcb->asoc.this_sack_highest_gap = in sctp_process_segment_range()
3095 tp1->rec.data.tsn; in sctp_process_segment_range()
3097 if (tp1->sent == SCTP_DATAGRAM_RESEND) { in sctp_process_segment_range()
3098 sctp_ucount_decr(stcb->asoc.sent_queue_retran_cnt); in sctp_process_segment_range()
3101 (stcb->asoc.sent_queue_retran_cnt & 0x000000ff)); in sctp_process_segment_range()
3105 /*- in sctp_process_segment_range()
3107 * (leave PR-SCTP ones that are to skip alone though) in sctp_process_segment_range()
3109 if ((tp1->sent != SCTP_FORWARD_TSN_SKIP) && in sctp_process_segment_range()
3110 (tp1->sent != SCTP_DATAGRAM_NR_ACKED)) { in sctp_process_segment_range()
3111 tp1->sent = SCTP_DATAGRAM_MARKED; in sctp_process_segment_range()
3113 if (tp1->rec.data.chunk_was_revoked) { in sctp_process_segment_range()
3115 tp1->whoTo->cwnd -= tp1->book_size; in sctp_process_segment_range()
3116 tp1->rec.data.chunk_was_revoked = 0; in sctp_process_segment_range()
3120 (tp1->sent != SCTP_DATAGRAM_NR_ACKED)) { in sctp_process_segment_range()
3121 if (stcb->asoc.strmout[tp1->rec.data.sid].chunks_on_queues > 0) { in sctp_process_segment_range()
3122 stcb->asoc.strmout[tp1->rec.data.sid].chunks_on_queues--; in sctp_process_segment_range()
3125 panic("No chunks on the queues for sid %u.", tp1->rec.data.sid); in sctp_process_segment_range()
3128 if ((stcb->asoc.strmout[tp1->rec.data.sid].chunks_on_queues == 0) && in sctp_process_segment_range()
3129 (stcb->asoc.strmout[tp1->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) && in sctp_process_segment_range()
3130 TAILQ_EMPTY(&stcb->asoc.strmout[tp1->rec.data.sid].outqueue)) { in sctp_process_segment_range()
3131 stcb->asoc.trigger_reset = 1; in sctp_process_segment_range()
3133 tp1->sent = SCTP_DATAGRAM_NR_ACKED; in sctp_process_segment_range()
3134 if (tp1->data) { in sctp_process_segment_range()
3139 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1); in sctp_process_segment_range()
3140 sctp_m_freem(tp1->data); in sctp_process_segment_range()
3141 tp1->data = NULL; in sctp_process_segment_range()
3146 break; in sctp_process_segment_range()
3147 } /* if (tp1->tsn == theTSN) */ in sctp_process_segment_range()
3148 if (SCTP_TSN_GT(tp1->rec.data.tsn, theTSN)) { in sctp_process_segment_range()
3149 break; in sctp_process_segment_range()
3154 tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue); in sctp_process_segment_range()
3159 tp1 = TAILQ_FIRST(&stcb->asoc.sent_queue); in sctp_process_segment_range()
3164 return (wake_him); /* Return value only used for nr-sack */ in sctp_process_segment_range()
3181 tp1 = TAILQ_FIRST(&asoc->sent_queue); in sctp_handle_segments()
3188 tp1 = TAILQ_FIRST(&asoc->sent_queue); in sctp_handle_segments()
3196 frag_strt = ntohs(frag->start); in sctp_handle_segments()
3197 frag_end = ntohs(frag->end); in sctp_handle_segments()
3205 tp1 = TAILQ_FIRST(&asoc->sent_queue); in sctp_handle_segments()
3238 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_check_for_revoked()
3239 if (SCTP_TSN_GT(tp1->rec.data.tsn, cumack)) { in sctp_check_for_revoked()
3246 if (SCTP_TSN_GT(tp1->rec.data.tsn, biggest_tsn_acked)) { in sctp_check_for_revoked()
3247 break; in sctp_check_for_revoked()
3249 if (tp1->sent == SCTP_DATAGRAM_ACKED) { in sctp_check_for_revoked()
3251 tp1->sent = SCTP_DATAGRAM_SENT; in sctp_check_for_revoked()
3252 tp1->rec.data.chunk_was_revoked = 1; in sctp_check_for_revoked()
3259 tp1->whoTo->flight_size, in sctp_check_for_revoked()
3260 tp1->book_size, in sctp_check_for_revoked()
3261 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_check_for_revoked()
3262 tp1->rec.data.tsn); in sctp_check_for_revoked()
3270 tp1->whoTo->cwnd += tp1->book_size; in sctp_check_for_revoked()
3272 sctp_log_sack(asoc->last_acked_seq, in sctp_check_for_revoked()
3274 tp1->rec.data.tsn, in sctp_check_for_revoked()
3279 } else if (tp1->sent == SCTP_DATAGRAM_MARKED) { in sctp_check_for_revoked()
3280 /* it has been re-acked in this SACK */ in sctp_check_for_revoked()
3281 tp1->sent = SCTP_DATAGRAM_ACKED; in sctp_check_for_revoked()
3284 if (tp1->sent == SCTP_DATAGRAM_UNSENT) in sctp_check_for_revoked()
3285 break; in sctp_check_for_revoked()
3304 tp1 = TAILQ_FIRST(&stcb->asoc.send_queue); in sctp_strike_gap_ack_chunks()
3306 sending_seq = asoc->sending_seq; in sctp_strike_gap_ack_chunks()
3308 sending_seq = tp1->rec.data.tsn; in sctp_strike_gap_ack_chunks()
3312 if ((asoc->sctp_cmt_on_off > 0) && in sctp_strike_gap_ack_chunks()
3314 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_strike_gap_ack_chunks()
3315 if (net->saw_newack) in sctp_strike_gap_ack_chunks()
3319 if (stcb->asoc.prsctp_supported) { in sctp_strike_gap_ack_chunks()
3322 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_strike_gap_ack_chunks()
3324 if (tp1->no_fr_allowed) { in sctp_strike_gap_ack_chunks()
3329 if (tp1->sent < SCTP_DATAGRAM_RESEND) in sctp_strike_gap_ack_chunks()
3331 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3332 tp1->sent, in sctp_strike_gap_ack_chunks()
3335 if (SCTP_TSN_GT(tp1->rec.data.tsn, biggest_tsn_acked) || in sctp_strike_gap_ack_chunks()
3336 tp1->sent == SCTP_DATAGRAM_UNSENT) { in sctp_strike_gap_ack_chunks()
3338 break; in sctp_strike_gap_ack_chunks()
3340 if (stcb->asoc.prsctp_supported) { in sctp_strike_gap_ack_chunks()
3341 if ((PR_SCTP_TTL_ENABLED(tp1->flags)) && tp1->sent < SCTP_DATAGRAM_ACKED) { in sctp_strike_gap_ack_chunks()
3343 if (timevalcmp(&now, &tp1->rec.data.timetodrop, >)) { in sctp_strike_gap_ack_chunks()
3345 if (tp1->data != NULL) { in sctp_strike_gap_ack_chunks()
3353 if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->this_sack_highest_gap) && in sctp_strike_gap_ack_chunks()
3354 !(accum_moved && asoc->fast_retran_loss_recovery)) { in sctp_strike_gap_ack_chunks()
3356 break; in sctp_strike_gap_ack_chunks()
3358 if (tp1->sent >= SCTP_DATAGRAM_RESEND) { in sctp_strike_gap_ack_chunks()
3361 if (tp1->sent == SCTP_FORWARD_TSN_SKIP) { in sctp_strike_gap_ack_chunks()
3362 /* Continue strikin FWD-TSN chunks */ in sctp_strike_gap_ack_chunks()
3363 tp1->rec.data.fwd_tsn_cnt++; in sctp_strike_gap_ack_chunks()
3370 if (tp1->whoTo && tp1->whoTo->saw_newack == 0) { in sctp_strike_gap_ack_chunks()
3378 } else if (tp1->whoTo && in sctp_strike_gap_ack_chunks()
3379 SCTP_TSN_GT(tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3380 tp1->whoTo->this_sack_highest_newack) && in sctp_strike_gap_ack_chunks()
3381 !(accum_moved && asoc->fast_retran_loss_recovery)) { in sctp_strike_gap_ack_chunks()
3400 * asoc->fast_retran_loss_recovery && (sctp_cmt_on_off == in sctp_strike_gap_ack_chunks()
3403 if (accum_moved && asoc->fast_retran_loss_recovery) { in sctp_strike_gap_ack_chunks()
3405 * Strike the TSN if in fast-recovery and cum-ack in sctp_strike_gap_ack_chunks()
3410 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3411 tp1->sent, in sctp_strike_gap_ack_chunks()
3414 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_strike_gap_ack_chunks()
3415 tp1->sent++; in sctp_strike_gap_ack_chunks()
3417 if ((asoc->sctp_cmt_on_off > 0) && in sctp_strike_gap_ack_chunks()
3431 if ((tp1->sent < SCTP_DATAGRAM_RESEND) && (num_dests_sacked == 1) && in sctp_strike_gap_ack_chunks()
3432 SCTP_TSN_GT(this_sack_lowest_newack, tp1->rec.data.tsn)) { in sctp_strike_gap_ack_chunks()
3435 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3436 tp1->sent, in sctp_strike_gap_ack_chunks()
3439 tp1->sent++; in sctp_strike_gap_ack_chunks()
3442 } else if ((tp1->rec.data.doing_fast_retransmit) && in sctp_strike_gap_ack_chunks()
3443 (asoc->sctp_cmt_on_off == 0)) { in sctp_strike_gap_ack_chunks()
3458 (asoc->numnets < 2) in sctp_strike_gap_ack_chunks()
3464 tp1->rec.data.fast_retran_tsn)) { in sctp_strike_gap_ack_chunks()
3472 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3473 tp1->sent, in sctp_strike_gap_ack_chunks()
3476 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_strike_gap_ack_chunks()
3477 tp1->sent++; in sctp_strike_gap_ack_chunks()
3480 if ((asoc->sctp_cmt_on_off > 0) && in sctp_strike_gap_ack_chunks()
3501 if ((tp1->sent < SCTP_DATAGRAM_RESEND) && in sctp_strike_gap_ack_chunks()
3504 tp1->rec.data.tsn)) { in sctp_strike_gap_ack_chunks()
3507 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3508 tp1->sent, in sctp_strike_gap_ack_chunks()
3511 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_strike_gap_ack_chunks()
3512 tp1->sent++; in sctp_strike_gap_ack_chunks()
3522 } else if (SCTP_TSN_GT(tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3534 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3535 tp1->sent, in sctp_strike_gap_ack_chunks()
3538 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_strike_gap_ack_chunks()
3539 tp1->sent++; in sctp_strike_gap_ack_chunks()
3541 if ((asoc->sctp_cmt_on_off > 0) && in sctp_strike_gap_ack_chunks()
3555 if ((tp1->sent < SCTP_DATAGRAM_RESEND) && (num_dests_sacked == 1) && in sctp_strike_gap_ack_chunks()
3556 SCTP_TSN_GT(this_sack_lowest_newack, tp1->rec.data.tsn)) { in sctp_strike_gap_ack_chunks()
3559 tp1->rec.data.tsn, in sctp_strike_gap_ack_chunks()
3560 tp1->sent, in sctp_strike_gap_ack_chunks()
3563 tp1->sent++; in sctp_strike_gap_ack_chunks()
3567 if (tp1->sent == SCTP_DATAGRAM_RESEND) { in sctp_strike_gap_ack_chunks()
3573 (tp1->whoTo ? (tp1->whoTo->flight_size) : 0), in sctp_strike_gap_ack_chunks()
3574 tp1->book_size, in sctp_strike_gap_ack_chunks()
3575 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_strike_gap_ack_chunks()
3576 tp1->rec.data.tsn); in sctp_strike_gap_ack_chunks()
3578 if (tp1->whoTo) { in sctp_strike_gap_ack_chunks()
3579 tp1->whoTo->net_ack++; in sctp_strike_gap_ack_chunks()
3581 if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) { in sctp_strike_gap_ack_chunks()
3582 (*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo, in sctp_strike_gap_ack_chunks()
3589 asoc->peers_rwnd, tp1->send_size, SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)); in sctp_strike_gap_ack_chunks()
3592 asoc->peers_rwnd += (tp1->send_size + SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)); in sctp_strike_gap_ack_chunks()
3597 if ((stcb->asoc.prsctp_supported) && in sctp_strike_gap_ack_chunks()
3598 (PR_SCTP_RTX_ENABLED(tp1->flags))) { in sctp_strike_gap_ack_chunks()
3600 * Has it been retransmitted tv_sec times? - in sctp_strike_gap_ack_chunks()
3603 if (tp1->snd_count > tp1->rec.data.timetodrop.tv_sec) { in sctp_strike_gap_ack_chunks()
3605 if (tp1->data != NULL) { in sctp_strike_gap_ack_chunks()
3610 if (tp1->whoTo != NULL) { in sctp_strike_gap_ack_chunks()
3611 tp1->whoTo->net_ack++; in sctp_strike_gap_ack_chunks()
3621 sctp_log_fr(tp1->rec.data.tsn, tp1->snd_count, in sctp_strike_gap_ack_chunks()
3628 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); in sctp_strike_gap_ack_chunks()
3629 if (asoc->sctp_cmt_on_off > 0) { in sctp_strike_gap_ack_chunks()
3635 tp1->no_fr_allowed = 1; in sctp_strike_gap_ack_chunks()
3636 alt = tp1->whoTo; in sctp_strike_gap_ack_chunks()
3638 if (asoc->sctp_cmt_pf > 0) { in sctp_strike_gap_ack_chunks()
3640 * JRS 5/18/07 - If CMT PF is on, in sctp_strike_gap_ack_chunks()
3647 * JRS 5/18/07 - If only CMT is on, in sctp_strike_gap_ack_chunks()
3655 alt = tp1->whoTo; in sctp_strike_gap_ack_chunks()
3660 * (rtx-)pseudo_cumack needs to be tracked in sctp_strike_gap_ack_chunks()
3661 * for orig dest. Let CUCv2 track new (rtx-) in sctp_strike_gap_ack_chunks()
3662 * pseudo-cumack always. in sctp_strike_gap_ack_chunks()
3664 if (tp1->whoTo) { in sctp_strike_gap_ack_chunks()
3665 tp1->whoTo->find_pseudo_cumack = 1; in sctp_strike_gap_ack_chunks()
3666 tp1->whoTo->find_rtx_pseudo_cumack = 1; in sctp_strike_gap_ack_chunks()
3671 alt = sctp_find_alternate_net(stcb, tp1->whoTo, 0); in sctp_strike_gap_ack_chunks()
3678 alt = tp1->whoTo; in sctp_strike_gap_ack_chunks()
3682 tp1->rec.data.doing_fast_retransmit = 1; in sctp_strike_gap_ack_chunks()
3686 * (uint32_t)tpi->rec.data.tsn); in sctp_strike_gap_ack_chunks()
3688 if (TAILQ_EMPTY(&asoc->send_queue)) { in sctp_strike_gap_ack_chunks()
3695 tp1->rec.data.fast_retran_tsn = sending_seq; in sctp_strike_gap_ack_chunks()
3707 ttt = TAILQ_FIRST(&asoc->send_queue); in sctp_strike_gap_ack_chunks()
3708 tp1->rec.data.fast_retran_tsn = in sctp_strike_gap_ack_chunks()
3709 ttt->rec.data.tsn; in sctp_strike_gap_ack_chunks()
3712 if (tp1->do_rtt) { in sctp_strike_gap_ack_chunks()
3717 if ((tp1->whoTo != NULL) && in sctp_strike_gap_ack_chunks()
3718 (tp1->whoTo->rto_needed == 0)) { in sctp_strike_gap_ack_chunks()
3719 tp1->whoTo->rto_needed = 1; in sctp_strike_gap_ack_chunks()
3721 tp1->do_rtt = 0; in sctp_strike_gap_ack_chunks()
3723 if (alt != tp1->whoTo) { in sctp_strike_gap_ack_chunks()
3725 sctp_free_remote_addr(tp1->whoTo); in sctp_strike_gap_ack_chunks()
3727 tp1->whoTo = alt; in sctp_strike_gap_ack_chunks()
3728 atomic_add_int(&alt->ref_count, 1); in sctp_strike_gap_ack_chunks()
3742 if (asoc->prsctp_supported == 0) { in sctp_try_advance_peer_ack_point()
3745 TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { in sctp_try_advance_peer_ack_point()
3746 if (tp1->sent != SCTP_FORWARD_TSN_SKIP && in sctp_try_advance_peer_ack_point()
3747 tp1->sent != SCTP_DATAGRAM_RESEND && in sctp_try_advance_peer_ack_point()
3748 tp1->sent != SCTP_DATAGRAM_NR_ACKED) { in sctp_try_advance_peer_ack_point()
3750 break; in sctp_try_advance_peer_ack_point()
3753 if ((tp1->sent == SCTP_FORWARD_TSN_SKIP) || in sctp_try_advance_peer_ack_point()
3754 (tp1->sent == SCTP_DATAGRAM_NR_ACKED)) { in sctp_try_advance_peer_ack_point()
3756 asoc->advanced_peer_ack_point, in sctp_try_advance_peer_ack_point()
3757 tp1->rec.data.tsn, 0, 0); in sctp_try_advance_peer_ack_point()
3760 if (!PR_SCTP_ENABLED(tp1->flags)) { in sctp_try_advance_peer_ack_point()
3762 * We can't fwd-tsn past any that are reliable aka in sctp_try_advance_peer_ack_point()
3765 break; in sctp_try_advance_peer_ack_point()
3773 * retransmission to a PR-stream but has run out its chances in sctp_try_advance_peer_ack_point()
3777 if (tp1->sent == SCTP_DATAGRAM_RESEND && in sctp_try_advance_peer_ack_point()
3778 (PR_SCTP_TTL_ENABLED(tp1->flags))) { in sctp_try_advance_peer_ack_point()
3783 if (timevalcmp(&now, &tp1->rec.data.timetodrop, >)) { in sctp_try_advance_peer_ack_point()
3785 if (tp1->data) { in sctp_try_advance_peer_ack_point()
3794 break; in sctp_try_advance_peer_ack_point()
3802 if ((tp1->sent == SCTP_FORWARD_TSN_SKIP) || in sctp_try_advance_peer_ack_point()
3803 (tp1->sent == SCTP_DATAGRAM_NR_ACKED)) { in sctp_try_advance_peer_ack_point()
3805 if (SCTP_TSN_GT(tp1->rec.data.tsn, asoc->advanced_peer_ack_point)) { in sctp_try_advance_peer_ack_point()
3806 asoc->advanced_peer_ack_point = tp1->rec.data.tsn; in sctp_try_advance_peer_ack_point()
3808 } else if (tp1->rec.data.tsn == asoc->advanced_peer_ack_point) { in sctp_try_advance_peer_ack_point()
3817 break; in sctp_try_advance_peer_ack_point()
3835 entry_flight = asoc->total_flight; in sctp_fs_audit()
3836 entry_cnt = asoc->total_flight_count; in sctp_fs_audit()
3838 if (asoc->pr_sctp_cnt >= asoc->sent_queue_cnt) in sctp_fs_audit()
3841 TAILQ_FOREACH(chk, &asoc->sent_queue, sctp_next) { in sctp_fs_audit()
3842 if (chk->sent < SCTP_DATAGRAM_RESEND) { in sctp_fs_audit()
3844 chk->rec.data.tsn, in sctp_fs_audit()
3845 chk->send_size, in sctp_fs_audit()
3846 chk->snd_count); in sctp_fs_audit()
3848 } else if (chk->sent == SCTP_DATAGRAM_RESEND) { in sctp_fs_audit()
3850 } else if (chk->sent < SCTP_DATAGRAM_ACKED) { in sctp_fs_audit()
3852 } else if (chk->sent > SCTP_DATAGRAM_ACKED) { in sctp_fs_audit()
3861 panic("Flight size-express incorrect F: %d I: %d R: %d Ab: %d ACK: %d", in sctp_fs_audit()
3864 SCTP_PRINTF("asoc->total_flight: %d cnt: %d\n", in sctp_fs_audit()
3866 SCTP_PRINTF("Flight size-express incorrect F: %d I: %d R: %d Ab: %d ACK: %d\n", in sctp_fs_audit()
3879 tp1->window_probe = 0; in sctp_window_probe_recovery()
3880 if ((tp1->sent >= SCTP_DATAGRAM_ACKED) || (tp1->data == NULL)) { in sctp_window_probe_recovery()
3883 tp1->whoTo ? tp1->whoTo->flight_size : 0, in sctp_window_probe_recovery()
3884 tp1->book_size, in sctp_window_probe_recovery()
3885 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_window_probe_recovery()
3886 tp1->rec.data.tsn); in sctp_window_probe_recovery()
3890 if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) { in sctp_window_probe_recovery()
3891 (*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo, in sctp_window_probe_recovery()
3897 tp1->sent = SCTP_DATAGRAM_RESEND; in sctp_window_probe_recovery()
3898 sctp_ucount_incr(asoc->sent_queue_retran_cnt); in sctp_window_probe_recovery()
3902 tp1->whoTo->flight_size, in sctp_window_probe_recovery()
3903 tp1->book_size, in sctp_window_probe_recovery()
3904 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_window_probe_recovery()
3905 tp1->rec.data.tsn); in sctp_window_probe_recovery()
3925 rwnd, stcb->asoc.last_acked_seq, stcb->asoc.peers_rwnd); in sctp_express_handle_sack()
3929 stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cumack; in sctp_express_handle_sack()
3930 stcb->asoc.cumack_log_at++; in sctp_express_handle_sack()
3931 if (stcb->asoc.cumack_log_at > SCTP_TSN_LOG_SIZE) { in sctp_express_handle_sack()
3932 stcb->asoc.cumack_log_at = 0; in sctp_express_handle_sack()
3935 asoc = &stcb->asoc; in sctp_express_handle_sack()
3936 old_rwnd = asoc->peers_rwnd; in sctp_express_handle_sack()
3937 if (SCTP_TSN_GT(asoc->last_acked_seq, cumack)) { in sctp_express_handle_sack()
3940 } else if (asoc->last_acked_seq == cumack) { in sctp_express_handle_sack()
3942 asoc->peers_rwnd = sctp_sbspace_sub(rwnd, in sctp_express_handle_sack()
3943 …(uint32_t)(asoc->total_flight + (asoc->total_flight_count * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)))… in sctp_express_handle_sack()
3944 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { in sctp_express_handle_sack()
3946 asoc->peers_rwnd = 0; in sctp_express_handle_sack()
3948 if (asoc->peers_rwnd > old_rwnd) { in sctp_express_handle_sack()
3955 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_express_handle_sack()
3956 if (SCTP_TSN_GT(cumack, net->cwr_window_tsn)) { in sctp_express_handle_sack()
3958 net->cwr_window_tsn = cumack; in sctp_express_handle_sack()
3960 net->prev_cwnd = net->cwnd; in sctp_express_handle_sack()
3961 net->net_ack = 0; in sctp_express_handle_sack()
3962 net->net_ack2 = 0; in sctp_express_handle_sack()
3968 net->new_pseudo_cumack = 0; in sctp_express_handle_sack()
3969 net->will_exit_fast_recovery = 0; in sctp_express_handle_sack()
3970 if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) { in sctp_express_handle_sack()
3971 (*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net); in sctp_express_handle_sack()
3974 if (!TAILQ_EMPTY(&asoc->sent_queue)) { in sctp_express_handle_sack()
3975 tp1 = TAILQ_LAST(&asoc->sent_queue, in sctp_express_handle_sack()
3977 send_s = tp1->rec.data.tsn + 1; in sctp_express_handle_sack()
3979 send_s = asoc->sending_seq; in sctp_express_handle_sack()
3991 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_25; in sctp_express_handle_sack()
3992 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_express_handle_sack()
3995 asoc->this_sack_highest_gap = cumack; in sctp_express_handle_sack()
3998 stcb->asoc.overall_error_count, in sctp_express_handle_sack()
4003 stcb->asoc.overall_error_count = 0; in sctp_express_handle_sack()
4004 if (SCTP_TSN_GT(cumack, asoc->last_acked_seq)) { in sctp_express_handle_sack()
4006 TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { in sctp_express_handle_sack()
4007 if (SCTP_TSN_GE(cumack, tp1->rec.data.tsn)) { in sctp_express_handle_sack()
4008 if (tp1->sent == SCTP_DATAGRAM_UNSENT) { in sctp_express_handle_sack()
4011 if (tp1->sent < SCTP_DATAGRAM_ACKED) { in sctp_express_handle_sack()
4014 * now no-longer in flight. Higher in sctp_express_handle_sack()
4017 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_express_handle_sack()
4020 tp1->whoTo->flight_size, in sctp_express_handle_sack()
4021 tp1->book_size, in sctp_express_handle_sack()
4022 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_express_handle_sack()
4023 tp1->rec.data.tsn); in sctp_express_handle_sack()
4026 if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) { in sctp_express_handle_sack()
4027 (*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo, in sctp_express_handle_sack()
4033 tp1->whoTo->net_ack += tp1->send_size; in sctp_express_handle_sack()
4034 if (tp1->snd_count < 2) { in sctp_express_handle_sack()
4036 * True non-retransmitted in sctp_express_handle_sack()
4039 tp1->whoTo->net_ack2 += in sctp_express_handle_sack()
4040 tp1->send_size; in sctp_express_handle_sack()
4043 if (tp1->do_rtt) { in sctp_express_handle_sack()
4046 &stcb->asoc, in sctp_express_handle_sack()
4047 tp1->whoTo, in sctp_express_handle_sack()
4048 &tp1->sent_rcv_time, in sctp_express_handle_sack()
4052 if (tp1->whoTo->rto_needed == 0) { in sctp_express_handle_sack()
4053 tp1->whoTo->rto_needed = 1; in sctp_express_handle_sack()
4055 tp1->do_rtt = 0; in sctp_express_handle_sack()
4068 * expected (rtx-)pseudo-cumack. in sctp_express_handle_sack()
4070 tp1->whoTo->new_pseudo_cumack = 1; in sctp_express_handle_sack()
4071 tp1->whoTo->find_pseudo_cumack = 1; in sctp_express_handle_sack()
4072 tp1->whoTo->find_rtx_pseudo_cumack = 1; in sctp_express_handle_sack()
4075 sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK); in sctp_express_handle_sack()
4078 if (tp1->sent == SCTP_DATAGRAM_RESEND) { in sctp_express_handle_sack()
4079 sctp_ucount_decr(asoc->sent_queue_retran_cnt); in sctp_express_handle_sack()
4081 if (tp1->rec.data.chunk_was_revoked) { in sctp_express_handle_sack()
4083 tp1->whoTo->cwnd -= tp1->book_size; in sctp_express_handle_sack()
4084 tp1->rec.data.chunk_was_revoked = 0; in sctp_express_handle_sack()
4086 if (tp1->sent != SCTP_DATAGRAM_NR_ACKED) { in sctp_express_handle_sack()
4087 if (asoc->strmout[tp1->rec.data.sid].chunks_on_queues > 0) { in sctp_express_handle_sack()
4088 asoc->strmout[tp1->rec.data.sid].chunks_on_queues--; in sctp_express_handle_sack()
4091 panic("No chunks on the queues for sid %u.", tp1->rec.data.sid); in sctp_express_handle_sack()
4095 if ((asoc->strmout[tp1->rec.data.sid].chunks_on_queues == 0) && in sctp_express_handle_sack()
4096 (asoc->strmout[tp1->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) && in sctp_express_handle_sack()
4097 TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.sid].outqueue)) { in sctp_express_handle_sack()
4098 asoc->trigger_reset = 1; in sctp_express_handle_sack()
4100 TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); in sctp_express_handle_sack()
4101 if (tp1->data) { in sctp_express_handle_sack()
4104 sctp_m_freem(tp1->data); in sctp_express_handle_sack()
4105 tp1->data = NULL; in sctp_express_handle_sack()
4108 sctp_log_sack(asoc->last_acked_seq, in sctp_express_handle_sack()
4110 tp1->rec.data.tsn, in sctp_express_handle_sack()
4115 asoc->sent_queue_cnt--; in sctp_express_handle_sack()
4118 break; in sctp_express_handle_sack()
4123 if (stcb->sctp_socket) { in sctp_express_handle_sack()
4124 SOCKBUF_LOCK(&stcb->sctp_socket->so_snd); in sctp_express_handle_sack()
4129 sctp_sowwakeup_locked(stcb->sctp_ep, stcb->sctp_socket); in sctp_express_handle_sack()
4136 /* JRS - Use the congestion control given in the CC module */ in sctp_express_handle_sack()
4137 if ((asoc->last_acked_seq != cumack) && (ecne_seen == 0)) { in sctp_express_handle_sack()
4138 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_express_handle_sack()
4139 if (net->net_ack2 > 0) { in sctp_express_handle_sack()
4144 net->error_count = 0; in sctp_express_handle_sack()
4145 if ((net->dest_state & SCTP_ADDR_REACHABLE) == 0) { in sctp_express_handle_sack()
4147 net->dest_state |= SCTP_ADDR_REACHABLE; in sctp_express_handle_sack()
4151 if (net == stcb->asoc.primary_destination) { in sctp_express_handle_sack()
4152 if (stcb->asoc.alternate) { in sctp_express_handle_sack()
4157 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_express_handle_sack()
4158 stcb->asoc.alternate = NULL; in sctp_express_handle_sack()
4161 if (net->dest_state & SCTP_ADDR_PF) { in sctp_express_handle_sack()
4162 net->dest_state &= ~SCTP_ADDR_PF; in sctp_express_handle_sack()
4164 stcb->sctp_ep, stcb, net, in sctp_express_handle_sack()
4166 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); in sctp_express_handle_sack()
4167 asoc->cc_functions.sctp_cwnd_update_exit_pf(stcb, net); in sctp_express_handle_sack()
4169 net->net_ack = 0; in sctp_express_handle_sack()
4172 net->RTO = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv; in sctp_express_handle_sack()
4173 if (net->RTO < stcb->asoc.minrto) { in sctp_express_handle_sack()
4174 net->RTO = stcb->asoc.minrto; in sctp_express_handle_sack()
4176 if (net->RTO > stcb->asoc.maxrto) { in sctp_express_handle_sack()
4177 net->RTO = stcb->asoc.maxrto; in sctp_express_handle_sack()
4181 asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, 1, 0, 0); in sctp_express_handle_sack()
4183 asoc->last_acked_seq = cumack; in sctp_express_handle_sack()
4185 if (TAILQ_EMPTY(&asoc->sent_queue)) { in sctp_express_handle_sack()
4186 /* nothing left in-flight */ in sctp_express_handle_sack()
4187 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_express_handle_sack()
4188 net->flight_size = 0; in sctp_express_handle_sack()
4189 net->partial_bytes_acked = 0; in sctp_express_handle_sack()
4191 asoc->total_flight = 0; in sctp_express_handle_sack()
4192 asoc->total_flight_count = 0; in sctp_express_handle_sack()
4196 asoc->peers_rwnd = sctp_sbspace_sub(rwnd, in sctp_express_handle_sack()
4197 …(uint32_t)(asoc->total_flight + (asoc->total_flight_count * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)))… in sctp_express_handle_sack()
4198 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { in sctp_express_handle_sack()
4200 asoc->peers_rwnd = 0; in sctp_express_handle_sack()
4202 if (asoc->peers_rwnd > old_rwnd) { in sctp_express_handle_sack()
4208 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_express_handle_sack()
4209 if (win_probe_recovery && (net->window_probe)) { in sctp_express_handle_sack()
4216 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_express_handle_sack()
4217 if (tp1->window_probe) { in sctp_express_handle_sack()
4220 break; in sctp_express_handle_sack()
4224 if (net->flight_size) { in sctp_express_handle_sack()
4226 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net); in sctp_express_handle_sack()
4227 if (net->window_probe) { in sctp_express_handle_sack()
4228 net->window_probe = 0; in sctp_express_handle_sack()
4231 if (net->window_probe) { in sctp_express_handle_sack()
4236 net->window_probe = 0; in sctp_express_handle_sack()
4237 if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { in sctp_express_handle_sack()
4238 sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net); in sctp_express_handle_sack()
4240 } else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { in sctp_express_handle_sack()
4241 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in sctp_express_handle_sack()
4248 (!TAILQ_EMPTY(&asoc->sent_queue)) && in sctp_express_handle_sack()
4249 (asoc->sent_queue_retran_cnt == 0) && in sctp_express_handle_sack()
4254 * PR-SCTP and marked to skip of course. in sctp_express_handle_sack()
4257 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_express_handle_sack()
4258 net->flight_size = 0; in sctp_express_handle_sack()
4260 asoc->total_flight = 0; in sctp_express_handle_sack()
4261 asoc->total_flight_count = 0; in sctp_express_handle_sack()
4262 asoc->sent_queue_retran_cnt = 0; in sctp_express_handle_sack()
4263 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_express_handle_sack()
4264 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_express_handle_sack()
4267 } else if (tp1->sent == SCTP_DATAGRAM_RESEND) { in sctp_express_handle_sack()
4268 sctp_ucount_incr(asoc->sent_queue_retran_cnt); in sctp_express_handle_sack()
4278 if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue)) { in sctp_express_handle_sack()
4281 if ((asoc->stream_queue_cnt == 1) && in sctp_express_handle_sack()
4282 ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) || in sctp_express_handle_sack()
4284 ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc))) { in sctp_express_handle_sack()
4287 if (((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) || in sctp_express_handle_sack()
4289 (asoc->stream_queue_cnt == 1) && in sctp_express_handle_sack()
4290 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { in sctp_express_handle_sack()
4296 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_28; in sctp_express_handle_sack()
4297 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_express_handle_sack()
4300 if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) && in sctp_express_handle_sack()
4301 (asoc->stream_queue_cnt == 0)) { in sctp_express_handle_sack()
4310 if (asoc->alternate) { in sctp_express_handle_sack()
4311 netp = asoc->alternate; in sctp_express_handle_sack()
4313 netp = asoc->primary_destination; in sctp_express_handle_sack()
4317 stcb->sctp_ep, stcb, netp); in sctp_express_handle_sack()
4319 stcb->sctp_ep, stcb, NULL); in sctp_express_handle_sack()
4321 (asoc->stream_queue_cnt == 0)) { in sctp_express_handle_sack()
4327 if (asoc->alternate) { in sctp_express_handle_sack()
4328 netp = asoc->alternate; in sctp_express_handle_sack()
4330 netp = asoc->primary_destination; in sctp_express_handle_sack()
4334 stcb->sctp_ep, stcb, netp); in sctp_express_handle_sack()
4338 /* Here we perform PR-SCTP procedures */ in sctp_express_handle_sack()
4342 if (SCTP_TSN_GT(cumack, asoc->advanced_peer_ack_point)) { in sctp_express_handle_sack()
4343 asoc->advanced_peer_ack_point = cumack; in sctp_express_handle_sack()
4345 /* PR-Sctp issues need to be addressed too */ in sctp_express_handle_sack()
4346 if ((asoc->prsctp_supported) && (asoc->pr_sctp_cnt > 0)) { in sctp_express_handle_sack()
4350 old_adv_peer_ack_point = asoc->advanced_peer_ack_point; in sctp_express_handle_sack()
4352 /* C3. See if we need to send a Fwd-TSN */ in sctp_express_handle_sack()
4353 if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, cumack)) { in sctp_express_handle_sack()
4355 * ISSUE with ECN, see FWD-TSN processing. in sctp_express_handle_sack()
4357 if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, old_adv_peer_ack_point)) { in sctp_express_handle_sack()
4360 /* try to FR fwd-tsn's that get lost too */ in sctp_express_handle_sack()
4361 if (lchk->rec.data.fwd_tsn_cnt >= 3) { in sctp_express_handle_sack()
4367 if (lchk->whoTo != NULL) { in sctp_express_handle_sack()
4368 break; in sctp_express_handle_sack()
4374 stcb->sctp_ep, stcb, lchk->whoTo); in sctp_express_handle_sack()
4380 stcb->asoc.peers_rwnd, in sctp_express_handle_sack()
4381 stcb->asoc.total_flight, in sctp_express_handle_sack()
4382 stcb->asoc.total_output_queue_size); in sctp_express_handle_sack()
4417 * queue (cum-ack is equal to last acked) then you have a duplicate in sctp_handle_sack()
4419 * then return. 3) Process any new consecutive data i.e. cum-ack in sctp_handle_sack()
4425 * shutdown. If in shutdown recv, send off the shutdown-ack and in sctp_handle_sack()
4426 * start that timer, Ret. 9) Strike any non-acked things and do FR in sctp_handle_sack()
4427 * procedure if needed being sure to set the FR flag. 10) Do pr-sctp in sctp_handle_sack()
4438 stcb->asoc.cumack_log[stcb->asoc.cumack_log_at] = cum_ack; in sctp_handle_sack()
4439 stcb->asoc.cumack_log_at++; in sctp_handle_sack()
4440 if (stcb->asoc.cumack_log_at > SCTP_TSN_LOG_SIZE) { in sctp_handle_sack()
4441 stcb->asoc.cumack_log_at = 0; in sctp_handle_sack()
4448 rwnd, stcb->asoc.last_acked_seq, stcb->asoc.peers_rwnd); in sctp_handle_sack()
4451 old_rwnd = stcb->asoc.peers_rwnd; in sctp_handle_sack()
4454 stcb->asoc.overall_error_count, in sctp_handle_sack()
4459 stcb->asoc.overall_error_count = 0; in sctp_handle_sack()
4460 asoc = &stcb->asoc; in sctp_handle_sack()
4462 sctp_log_sack(asoc->last_acked_seq, in sctp_handle_sack()
4477 break; in sctp_handle_sack()
4483 if (!TAILQ_EMPTY(&asoc->sent_queue)) { in sctp_handle_sack()
4484 tp1 = TAILQ_LAST(&asoc->sent_queue, in sctp_handle_sack()
4486 send_s = tp1->rec.data.tsn + 1; in sctp_handle_sack()
4489 send_s = asoc->sending_seq; in sctp_handle_sack()
4503 tp1->rec.data.tsn, (void *)tp1); in sctp_handle_sack()
4512 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_29; in sctp_handle_sack()
4513 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_handle_sack()
4519 if (SCTP_TSN_GT(asoc->last_acked_seq, last_tsn)) { in sctp_handle_sack()
4525 if (TAILQ_EMPTY(&asoc->sent_queue) && in sctp_handle_sack()
4526 TAILQ_EMPTY(&asoc->send_queue) && in sctp_handle_sack()
4527 (asoc->stream_queue_cnt == 0)) { in sctp_handle_sack()
4531 asoc->peers_rwnd, 0, 0, a_rwnd); in sctp_handle_sack()
4533 asoc->peers_rwnd = a_rwnd; in sctp_handle_sack()
4534 if (asoc->sent_queue_retran_cnt) { in sctp_handle_sack()
4535 asoc->sent_queue_retran_cnt = 0; in sctp_handle_sack()
4537 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { in sctp_handle_sack()
4539 asoc->peers_rwnd = 0; in sctp_handle_sack()
4542 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
4543 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in sctp_handle_sack()
4545 net->partial_bytes_acked = 0; in sctp_handle_sack()
4546 net->flight_size = 0; in sctp_handle_sack()
4548 asoc->total_flight = 0; in sctp_handle_sack()
4549 asoc->total_flight_count = 0; in sctp_handle_sack()
4555 * netAck2 is used to track the total bytes acked that are un- in sctp_handle_sack()
4559 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
4560 if (SCTP_TSN_GT(cum_ack, net->cwr_window_tsn)) { in sctp_handle_sack()
4562 net->cwr_window_tsn = cum_ack; in sctp_handle_sack()
4564 net->prev_cwnd = net->cwnd; in sctp_handle_sack()
4565 net->net_ack = 0; in sctp_handle_sack()
4566 net->net_ack2 = 0; in sctp_handle_sack()
4572 net->new_pseudo_cumack = 0; in sctp_handle_sack()
4573 net->will_exit_fast_recovery = 0; in sctp_handle_sack()
4574 if (stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) { in sctp_handle_sack()
4575 (*stcb->asoc.cc_functions.sctp_cwnd_prepare_net_for_sack) (stcb, net); in sctp_handle_sack()
4579 * CMT: SFR algo (and HTNA) - this_sack_highest_newack has in sctp_handle_sack()
4583 net->saw_newack = 0; in sctp_handle_sack()
4584 net->this_sack_highest_newack = last_tsn; in sctp_handle_sack()
4587 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_handle_sack()
4588 if (SCTP_TSN_GE(last_tsn, tp1->rec.data.tsn)) { in sctp_handle_sack()
4589 if (tp1->sent != SCTP_DATAGRAM_UNSENT) { in sctp_handle_sack()
4591 if (tp1->sent < SCTP_DATAGRAM_ACKED) { in sctp_handle_sack()
4594 * now no-longer in flight. Higher in sctp_handle_sack()
4597 if ((tp1->whoTo->dest_state & in sctp_handle_sack()
4599 (tp1->snd_count < 2)) { in sctp_handle_sack()
4603 * un-confirmed and we sent in sctp_handle_sack()
4608 tp1->whoTo->dest_state &= in sctp_handle_sack()
4611 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_handle_sack()
4614 tp1->whoTo->flight_size, in sctp_handle_sack()
4615 tp1->book_size, in sctp_handle_sack()
4616 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_handle_sack()
4617 tp1->rec.data.tsn); in sctp_handle_sack()
4621 if (stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) { in sctp_handle_sack()
4622 (*stcb->asoc.cc_functions.sctp_cwnd_update_tsn_acknowledged) (tp1->whoTo, in sctp_handle_sack()
4626 tp1->whoTo->net_ack += tp1->send_size; in sctp_handle_sack()
4629 this_sack_lowest_newack = tp1->rec.data.tsn; in sctp_handle_sack()
4630 tp1->whoTo->saw_newack = 1; in sctp_handle_sack()
4632 if (tp1->snd_count < 2) { in sctp_handle_sack()
4634 * True non-retransmitted in sctp_handle_sack()
4637 tp1->whoTo->net_ack2 += in sctp_handle_sack()
4638 tp1->send_size; in sctp_handle_sack()
4641 if (tp1->do_rtt) { in sctp_handle_sack()
4644 &stcb->asoc, in sctp_handle_sack()
4645 tp1->whoTo, in sctp_handle_sack()
4646 &tp1->sent_rcv_time, in sctp_handle_sack()
4650 if (tp1->whoTo->rto_needed == 0) { in sctp_handle_sack()
4651 tp1->whoTo->rto_needed = 1; in sctp_handle_sack()
4653 tp1->do_rtt = 0; in sctp_handle_sack()
4666 * expected (rtx-)pseudo-cumack. in sctp_handle_sack()
4668 tp1->whoTo->new_pseudo_cumack = 1; in sctp_handle_sack()
4669 tp1->whoTo->find_pseudo_cumack = 1; in sctp_handle_sack()
4670 tp1->whoTo->find_rtx_pseudo_cumack = 1; in sctp_handle_sack()
4672 sctp_log_sack(asoc->last_acked_seq, in sctp_handle_sack()
4674 tp1->rec.data.tsn, in sctp_handle_sack()
4680 sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.tsn, SCTP_CWND_LOG_FROM_SACK); in sctp_handle_sack()
4683 if (tp1->sent == SCTP_DATAGRAM_RESEND) { in sctp_handle_sack()
4684 sctp_ucount_decr(asoc->sent_queue_retran_cnt); in sctp_handle_sack()
4687 (asoc->sent_queue_retran_cnt & 0x000000ff)); in sctp_handle_sack()
4690 if (tp1->rec.data.chunk_was_revoked) { in sctp_handle_sack()
4692 tp1->whoTo->cwnd -= tp1->book_size; in sctp_handle_sack()
4693 tp1->rec.data.chunk_was_revoked = 0; in sctp_handle_sack()
4695 if (tp1->sent != SCTP_DATAGRAM_NR_ACKED) { in sctp_handle_sack()
4696 tp1->sent = SCTP_DATAGRAM_ACKED; in sctp_handle_sack()
4700 break; in sctp_handle_sack()
4704 /* always set this up to cum-ack */ in sctp_handle_sack()
4705 asoc->this_sack_highest_gap = last_tsn; in sctp_handle_sack()
4734 /* cancel ALL T3-send timer if accum moved */ in sctp_handle_sack()
4736 if (asoc->sctp_cmt_on_off > 0) { in sctp_handle_sack()
4737 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
4738 if (net->new_pseudo_cumack) in sctp_handle_sack()
4739 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in sctp_handle_sack()
4745 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
4746 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in sctp_handle_sack()
4754 asoc->last_acked_seq = cum_ack; in sctp_handle_sack()
4756 TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { in sctp_handle_sack()
4757 if (SCTP_TSN_GT(tp1->rec.data.tsn, cum_ack)) { in sctp_handle_sack()
4758 break; in sctp_handle_sack()
4760 if (tp1->sent != SCTP_DATAGRAM_NR_ACKED) { in sctp_handle_sack()
4761 if (asoc->strmout[tp1->rec.data.sid].chunks_on_queues > 0) { in sctp_handle_sack()
4762 asoc->strmout[tp1->rec.data.sid].chunks_on_queues--; in sctp_handle_sack()
4765 panic("No chunks on the queues for sid %u.", tp1->rec.data.sid); in sctp_handle_sack()
4769 if ((asoc->strmout[tp1->rec.data.sid].chunks_on_queues == 0) && in sctp_handle_sack()
4770 (asoc->strmout[tp1->rec.data.sid].state == SCTP_STREAM_RESET_PENDING) && in sctp_handle_sack()
4771 TAILQ_EMPTY(&asoc->strmout[tp1->rec.data.sid].outqueue)) { in sctp_handle_sack()
4772 asoc->trigger_reset = 1; in sctp_handle_sack()
4774 TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); in sctp_handle_sack()
4775 if (PR_SCTP_ENABLED(tp1->flags)) { in sctp_handle_sack()
4776 if (asoc->pr_sctp_cnt != 0) in sctp_handle_sack()
4777 asoc->pr_sctp_cnt--; in sctp_handle_sack()
4779 asoc->sent_queue_cnt--; in sctp_handle_sack()
4780 if (tp1->data) { in sctp_handle_sack()
4783 sctp_m_freem(tp1->data); in sctp_handle_sack()
4784 tp1->data = NULL; in sctp_handle_sack()
4785 if (asoc->prsctp_supported && PR_SCTP_BUF_ENABLED(tp1->flags)) { in sctp_handle_sack()
4786 asoc->sent_queue_cnt_removeable--; in sctp_handle_sack()
4790 sctp_log_sack(asoc->last_acked_seq, in sctp_handle_sack()
4792 tp1->rec.data.tsn, in sctp_handle_sack()
4800 if (TAILQ_EMPTY(&asoc->sent_queue) && (asoc->total_flight > 0)) { in sctp_handle_sack()
4805 asoc->total_flight); in sctp_handle_sack()
4807 asoc->total_flight = 0; in sctp_handle_sack()
4811 if ((wake_him) && (stcb->sctp_socket)) { in sctp_handle_sack()
4812 SOCKBUF_LOCK(&stcb->sctp_socket->so_snd); in sctp_handle_sack()
4816 sctp_sowwakeup_locked(stcb->sctp_ep, stcb->sctp_socket); in sctp_handle_sack()
4823 if (asoc->fast_retran_loss_recovery && accum_moved) { in sctp_handle_sack()
4824 if (SCTP_TSN_GE(asoc->last_acked_seq, asoc->fast_recovery_tsn)) { in sctp_handle_sack()
4832 * if Previous sack - Had no frags then we can't have any revoked if in sctp_handle_sack()
4833 * Previous sack - Had frag's then - If we now have frags aka in sctp_handle_sack()
4835 * some of them. else - The peer revoked all ACKED fragments, since in sctp_handle_sack()
4841 asoc->saw_sack_with_frags = 1; in sctp_handle_sack()
4842 } else if (asoc->saw_sack_with_frags) { in sctp_handle_sack()
4846 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_handle_sack()
4847 if (tp1->sent == SCTP_DATAGRAM_ACKED) { in sctp_handle_sack()
4848 tp1->sent = SCTP_DATAGRAM_SENT; in sctp_handle_sack()
4851 tp1->whoTo->flight_size, in sctp_handle_sack()
4852 tp1->book_size, in sctp_handle_sack()
4853 (uint32_t)(uintptr_t)tp1->whoTo, in sctp_handle_sack()
4854 tp1->rec.data.tsn); in sctp_handle_sack()
4858 tp1->rec.data.chunk_was_revoked = 1; in sctp_handle_sack()
4865 tp1->whoTo->cwnd += tp1->book_size; in sctp_handle_sack()
4872 asoc->saw_sack_with_frags = 0; in sctp_handle_sack()
4875 asoc->saw_sack_with_nr_frags = 1; in sctp_handle_sack()
4877 asoc->saw_sack_with_nr_frags = 0; in sctp_handle_sack()
4879 /* JRS - Use the congestion control given in the CC module */ in sctp_handle_sack()
4881 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
4882 if (net->net_ack2 > 0) { in sctp_handle_sack()
4887 net->error_count = 0; in sctp_handle_sack()
4888 if ((net->dest_state & SCTP_ADDR_REACHABLE) == 0) { in sctp_handle_sack()
4890 net->dest_state |= SCTP_ADDR_REACHABLE; in sctp_handle_sack()
4895 if (net == stcb->asoc.primary_destination) { in sctp_handle_sack()
4896 if (stcb->asoc.alternate) { in sctp_handle_sack()
4901 sctp_free_remote_addr(stcb->asoc.alternate); in sctp_handle_sack()
4902 stcb->asoc.alternate = NULL; in sctp_handle_sack()
4906 if (net->dest_state & SCTP_ADDR_PF) { in sctp_handle_sack()
4907 net->dest_state &= ~SCTP_ADDR_PF; in sctp_handle_sack()
4909 stcb->sctp_ep, stcb, net, in sctp_handle_sack()
4911 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep, stcb, net); in sctp_handle_sack()
4912 asoc->cc_functions.sctp_cwnd_update_exit_pf(stcb, net); in sctp_handle_sack()
4914 net->net_ack = 0; in sctp_handle_sack()
4917 net->RTO = (net->lastsa >> SCTP_RTT_SHIFT) + net->lastsv; in sctp_handle_sack()
4918 if (net->RTO < stcb->asoc.minrto) { in sctp_handle_sack()
4919 net->RTO = stcb->asoc.minrto; in sctp_handle_sack()
4921 if (net->RTO > stcb->asoc.maxrto) { in sctp_handle_sack()
4922 net->RTO = stcb->asoc.maxrto; in sctp_handle_sack()
4926 …asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fas… in sctp_handle_sack()
4929 if (TAILQ_EMPTY(&asoc->sent_queue)) { in sctp_handle_sack()
4930 /* nothing left in-flight */ in sctp_handle_sack()
4931 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
4933 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in sctp_handle_sack()
4936 net->flight_size = 0; in sctp_handle_sack()
4937 net->partial_bytes_acked = 0; in sctp_handle_sack()
4939 asoc->total_flight = 0; in sctp_handle_sack()
4940 asoc->total_flight_count = 0; in sctp_handle_sack()
4946 if (TAILQ_EMPTY(&asoc->send_queue) && TAILQ_EMPTY(&asoc->sent_queue)) { in sctp_handle_sack()
4950 asoc->peers_rwnd, 0, 0, a_rwnd); in sctp_handle_sack()
4952 asoc->peers_rwnd = a_rwnd; in sctp_handle_sack()
4953 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { in sctp_handle_sack()
4955 asoc->peers_rwnd = 0; in sctp_handle_sack()
4958 if ((asoc->stream_queue_cnt == 1) && in sctp_handle_sack()
4959 ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) || in sctp_handle_sack()
4961 ((*asoc->ss_functions.sctp_ss_is_user_msgs_incomplete) (stcb, asoc))) { in sctp_handle_sack()
4964 if (((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) || in sctp_handle_sack()
4966 (asoc->stream_queue_cnt == 1) && in sctp_handle_sack()
4967 (asoc->state & SCTP_STATE_PARTIAL_MSG_LEFT)) { in sctp_handle_sack()
4973 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_35; in sctp_handle_sack()
4974 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_handle_sack()
4977 if ((asoc->state & SCTP_STATE_SHUTDOWN_PENDING) && in sctp_handle_sack()
4978 (asoc->stream_queue_cnt == 0)) { in sctp_handle_sack()
4987 if (asoc->alternate) { in sctp_handle_sack()
4988 netp = asoc->alternate; in sctp_handle_sack()
4990 netp = asoc->primary_destination; in sctp_handle_sack()
4994 stcb->sctp_ep, stcb, netp); in sctp_handle_sack()
4996 stcb->sctp_ep, stcb, NULL); in sctp_handle_sack()
4999 (asoc->stream_queue_cnt == 0)) { in sctp_handle_sack()
5005 if (asoc->alternate) { in sctp_handle_sack()
5006 netp = asoc->alternate; in sctp_handle_sack()
5008 netp = asoc->primary_destination; in sctp_handle_sack()
5012 stcb->sctp_ep, stcb, netp); in sctp_handle_sack()
5020 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
5021 net->net_ack = 0; in sctp_handle_sack()
5029 if ((asoc->sctp_cmt_on_off > 0) && in sctp_handle_sack()
5038 /* JRS - Use the congestion control given in the CC module */ in sctp_handle_sack()
5039 asoc->cc_functions.sctp_cwnd_update_after_fr(stcb, asoc); in sctp_handle_sack()
5044 asoc->fast_retran_loss_recovery = 0; in sctp_handle_sack()
5046 if ((asoc->sat_t3_loss_recovery) && in sctp_handle_sack()
5047 SCTP_TSN_GE(asoc->last_acked_seq, asoc->sat_t3_recovery_tsn)) { in sctp_handle_sack()
5049 asoc->sat_t3_loss_recovery = 0; in sctp_handle_sack()
5054 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
5055 if (net->will_exit_fast_recovery) { in sctp_handle_sack()
5057 net->fast_retran_loss_recovery = 0; in sctp_handle_sack()
5064 …asoc->peers_rwnd, asoc->total_flight, (asoc->total_flight_count * SCTP_BASE_SYSCTL(sctp_peer_chunk… in sctp_handle_sack()
5066 asoc->peers_rwnd = sctp_sbspace_sub(a_rwnd, in sctp_handle_sack()
5067 …(uint32_t)(asoc->total_flight + (asoc->total_flight_count * SCTP_BASE_SYSCTL(sctp_peer_chunk_oh)))… in sctp_handle_sack()
5068 if (asoc->peers_rwnd < stcb->sctp_ep->sctp_ep.sctp_sws_sender) { in sctp_handle_sack()
5070 asoc->peers_rwnd = 0; in sctp_handle_sack()
5072 if (asoc->peers_rwnd > old_rwnd) { in sctp_handle_sack()
5083 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
5084 if (win_probe_recovery && (net->window_probe)) { in sctp_handle_sack()
5086 /*- in sctp_handle_sack()
5092 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_handle_sack()
5093 if (tp1->window_probe) { in sctp_handle_sack()
5095 break; in sctp_handle_sack()
5099 if (net->flight_size) { in sctp_handle_sack()
5101 if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { in sctp_handle_sack()
5103 stcb->sctp_ep, stcb, net); in sctp_handle_sack()
5105 if (net->window_probe) { in sctp_handle_sack()
5106 net->window_probe = 0; in sctp_handle_sack()
5109 if (net->window_probe) { in sctp_handle_sack()
5114 if (!SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { in sctp_handle_sack()
5116 stcb->sctp_ep, stcb, net); in sctp_handle_sack()
5118 } else if (SCTP_OS_TIMER_PENDING(&net->rxt_timer.timer)) { in sctp_handle_sack()
5119 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, in sctp_handle_sack()
5126 (!TAILQ_EMPTY(&asoc->sent_queue)) && in sctp_handle_sack()
5127 (asoc->sent_queue_retran_cnt == 0) && in sctp_handle_sack()
5132 * PR-SCTP and marked to skip of course. in sctp_handle_sack()
5135 TAILQ_FOREACH(net, &asoc->nets, sctp_next) { in sctp_handle_sack()
5136 net->flight_size = 0; in sctp_handle_sack()
5138 asoc->total_flight = 0; in sctp_handle_sack()
5139 asoc->total_flight_count = 0; in sctp_handle_sack()
5140 asoc->sent_queue_retran_cnt = 0; in sctp_handle_sack()
5141 TAILQ_FOREACH(tp1, &asoc->sent_queue, sctp_next) { in sctp_handle_sack()
5142 if (tp1->sent < SCTP_DATAGRAM_RESEND) { in sctp_handle_sack()
5145 } else if (tp1->sent == SCTP_DATAGRAM_RESEND) { in sctp_handle_sack()
5146 sctp_ucount_incr(asoc->sent_queue_retran_cnt); in sctp_handle_sack()
5154 /* Here we perform PR-SCTP procedures */ in sctp_handle_sack()
5158 if (SCTP_TSN_GT(cum_ack, asoc->advanced_peer_ack_point)) { in sctp_handle_sack()
5159 asoc->advanced_peer_ack_point = cum_ack; in sctp_handle_sack()
5162 if ((asoc->prsctp_supported) && (asoc->pr_sctp_cnt > 0)) { in sctp_handle_sack()
5166 old_adv_peer_ack_point = asoc->advanced_peer_ack_point; in sctp_handle_sack()
5168 /* C3. See if we need to send a Fwd-TSN */ in sctp_handle_sack()
5169 if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, cum_ack)) { in sctp_handle_sack()
5171 * ISSUE with ECN, see FWD-TSN processing. in sctp_handle_sack()
5175 0xee, cum_ack, asoc->advanced_peer_ack_point, in sctp_handle_sack()
5178 if (SCTP_TSN_GT(asoc->advanced_peer_ack_point, old_adv_peer_ack_point)) { in sctp_handle_sack()
5181 /* try to FR fwd-tsn's that get lost too */ in sctp_handle_sack()
5182 if (lchk->rec.data.fwd_tsn_cnt >= 3) { in sctp_handle_sack()
5188 if (lchk->whoTo != NULL) { in sctp_handle_sack()
5189 break; in sctp_handle_sack()
5195 stcb->sctp_ep, stcb, lchk->whoTo); in sctp_handle_sack()
5201 stcb->asoc.peers_rwnd, in sctp_handle_sack()
5202 stcb->asoc.total_flight, in sctp_handle_sack()
5203 stcb->asoc.total_output_queue_size); in sctp_handle_sack()
5210 /* Copy cum-ack */ in sctp_update_acked()
5213 cum_ack = ntohl(cp->cumulative_tsn_ack); in sctp_update_acked()
5215 a_rwnd = stcb->asoc.peers_rwnd + stcb->asoc.total_flight; in sctp_update_acked()
5225 struct sctp_queued_to_read *control, *ncontrol; in sctp_kick_prsctp_reorder_queue() local
5232 SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); in sctp_kick_prsctp_reorder_queue()
5234 asoc = &stcb->asoc; in sctp_kick_prsctp_reorder_queue()
5235 mid = strmin->last_mid_delivered; in sctp_kick_prsctp_reorder_queue()
5240 TAILQ_FOREACH_SAFE(control, &strmin->inqueue, next_instrm, ncontrol) { in sctp_kick_prsctp_reorder_queue()
5241 if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) { in sctp_kick_prsctp_reorder_queue()
5243 if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) { in sctp_kick_prsctp_reorder_queue()
5244 if (control->on_strm_q) { in sctp_kick_prsctp_reorder_queue()
5245 if (control->on_strm_q == SCTP_ON_ORDERED) { in sctp_kick_prsctp_reorder_queue()
5246 TAILQ_REMOVE(&strmin->inqueue, control, next_instrm); in sctp_kick_prsctp_reorder_queue()
5247 } else if (control->on_strm_q == SCTP_ON_UNORDERED) { in sctp_kick_prsctp_reorder_queue()
5248 TAILQ_REMOVE(&strmin->uno_inqueue, control, next_instrm); in sctp_kick_prsctp_reorder_queue()
5252 strmin, control, control->on_strm_q); in sctp_kick_prsctp_reorder_queue()
5255 control->on_strm_q = 0; in sctp_kick_prsctp_reorder_queue()
5258 if (asoc->size_on_all_streams >= control->length) { in sctp_kick_prsctp_reorder_queue()
5259 asoc->size_on_all_streams -= control->length; in sctp_kick_prsctp_reorder_queue()
5262 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_kick_prsctp_reorder_queue()
5264 asoc->size_on_all_streams = 0; in sctp_kick_prsctp_reorder_queue()
5267 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_kick_prsctp_reorder_queue()
5268 /* deliver it to at least the delivery-q */ in sctp_kick_prsctp_reorder_queue()
5269 if (stcb->sctp_socket) { in sctp_kick_prsctp_reorder_queue()
5270 sctp_mark_non_revokable(asoc, control->sinfo_tsn); in sctp_kick_prsctp_reorder_queue()
5271 sctp_add_to_readq(stcb->sctp_ep, stcb, control, in sctp_kick_prsctp_reorder_queue()
5272 &stcb->sctp_socket->so_rcv, 1, in sctp_kick_prsctp_reorder_queue()
5277 if (control->first_frag_seen) { in sctp_kick_prsctp_reorder_queue()
5282 strmin->last_mid_delivered = control->mid - 1; in sctp_kick_prsctp_reorder_queue()
5284 break; in sctp_kick_prsctp_reorder_queue()
5289 break; in sctp_kick_prsctp_reorder_queue()
5295 ret = sctp_deliver_reasm_check(stcb, &stcb->asoc, strmin, SCTP_READ_LOCK_HELD); in sctp_kick_prsctp_reorder_queue()
5296 if (SCTP_MID_GT(asoc->idata_supported, mid, strmin->last_mid_delivered)) { in sctp_kick_prsctp_reorder_queue()
5298 strmin->last_mid_delivered = mid; in sctp_kick_prsctp_reorder_queue()
5310 mid = strmin->last_mid_delivered + 1; in sctp_kick_prsctp_reorder_queue()
5311 TAILQ_FOREACH_SAFE(control, &strmin->inqueue, next_instrm, ncontrol) { in sctp_kick_prsctp_reorder_queue()
5312 if (SCTP_MID_EQ(asoc->idata_supported, mid, control->mid)) { in sctp_kick_prsctp_reorder_queue()
5313 if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) { in sctp_kick_prsctp_reorder_queue()
5315 if (control->on_strm_q) { in sctp_kick_prsctp_reorder_queue()
5316 if (control->on_strm_q == SCTP_ON_ORDERED) { in sctp_kick_prsctp_reorder_queue()
5317 TAILQ_REMOVE(&strmin->inqueue, control, next_instrm); in sctp_kick_prsctp_reorder_queue()
5318 } else if (control->on_strm_q == SCTP_ON_UNORDERED) { in sctp_kick_prsctp_reorder_queue()
5319 TAILQ_REMOVE(&strmin->uno_inqueue, control, next_instrm); in sctp_kick_prsctp_reorder_queue()
5323 strmin, control, control->on_strm_q); in sctp_kick_prsctp_reorder_queue()
5326 control->on_strm_q = 0; in sctp_kick_prsctp_reorder_queue()
5329 if (asoc->size_on_all_streams >= control->length) { in sctp_kick_prsctp_reorder_queue()
5330 asoc->size_on_all_streams -= control->length; in sctp_kick_prsctp_reorder_queue()
5333 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_kick_prsctp_reorder_queue()
5335 asoc->size_on_all_streams = 0; in sctp_kick_prsctp_reorder_queue()
5338 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_kick_prsctp_reorder_queue()
5339 /* deliver it to at least the delivery-q */ in sctp_kick_prsctp_reorder_queue()
5340 strmin->last_mid_delivered = control->mid; in sctp_kick_prsctp_reorder_queue()
5341 if (stcb->sctp_socket) { in sctp_kick_prsctp_reorder_queue()
5342 sctp_mark_non_revokable(asoc, control->sinfo_tsn); in sctp_kick_prsctp_reorder_queue()
5343 sctp_add_to_readq(stcb->sctp_ep, stcb, control, in sctp_kick_prsctp_reorder_queue()
5344 &stcb->sctp_socket->so_rcv, 1, in sctp_kick_prsctp_reorder_queue()
5347 mid = strmin->last_mid_delivered + 1; in sctp_kick_prsctp_reorder_queue()
5350 if (control->first_frag_seen) { in sctp_kick_prsctp_reorder_queue()
5355 strmin->last_mid_delivered = control->mid - 1; in sctp_kick_prsctp_reorder_queue()
5357 break; in sctp_kick_prsctp_reorder_queue()
5361 break; in sctp_kick_prsctp_reorder_queue()
5365 (void)sctp_deliver_reasm_check(stcb, &stcb->asoc, strmin, SCTP_READ_LOCK_HELD); in sctp_kick_prsctp_reorder_queue()
5372 struct sctp_queued_to_read *control, int ordered, uint32_t cumtsn) in sctp_flush_reassm_for_str_seq() argument
5387 SCTP_INP_READ_LOCK_ASSERT(stcb->sctp_ep); in sctp_flush_reassm_for_str_seq()
5389 if (!asoc->idata_supported && !ordered && in sctp_flush_reassm_for_str_seq()
5390 control->first_frag_seen && in sctp_flush_reassm_for_str_seq()
5391 SCTP_TSN_GT(control->fsn_included, cumtsn)) { in sctp_flush_reassm_for_str_seq()
5394 TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) { in sctp_flush_reassm_for_str_seq()
5396 if (!asoc->idata_supported && !ordered) { in sctp_flush_reassm_for_str_seq()
5397 if (SCTP_TSN_GT(chk->rec.data.tsn, cumtsn)) { in sctp_flush_reassm_for_str_seq()
5398 break; in sctp_flush_reassm_for_str_seq()
5401 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_flush_reassm_for_str_seq()
5402 if (asoc->size_on_reasm_queue >= chk->send_size) { in sctp_flush_reassm_for_str_seq()
5403 asoc->size_on_reasm_queue -= chk->send_size; in sctp_flush_reassm_for_str_seq()
5406 …panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->sen… in sctp_flush_reassm_for_str_seq()
5408 asoc->size_on_reasm_queue = 0; in sctp_flush_reassm_for_str_seq()
5411 sctp_ucount_decr(asoc->cnt_on_reasm_queue); in sctp_flush_reassm_for_str_seq()
5412 if (chk->data) { in sctp_flush_reassm_for_str_seq()
5413 sctp_m_freem(chk->data); in sctp_flush_reassm_for_str_seq()
5414 chk->data = NULL; in sctp_flush_reassm_for_str_seq()
5418 if (!TAILQ_EMPTY(&control->reasm)) { in sctp_flush_reassm_for_str_seq()
5419 KASSERT(!asoc->idata_supported, in sctp_flush_reassm_for_str_seq()
5420 ("Reassembly queue not empty for I-DATA")); in sctp_flush_reassm_for_str_seq()
5423 if (control->data) { in sctp_flush_reassm_for_str_seq()
5424 sctp_m_freem(control->data); in sctp_flush_reassm_for_str_seq()
5425 control->data = NULL; in sctp_flush_reassm_for_str_seq()
5427 control->fsn_included = 0xffffffff; in sctp_flush_reassm_for_str_seq()
5428 control->first_frag_seen = 0; in sctp_flush_reassm_for_str_seq()
5429 control->last_frag_seen = 0; in sctp_flush_reassm_for_str_seq()
5430 if (control->on_read_q) { in sctp_flush_reassm_for_str_seq()
5433 * will work :-) in sctp_flush_reassm_for_str_seq()
5435 TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next); in sctp_flush_reassm_for_str_seq()
5436 control->on_read_q = 0; in sctp_flush_reassm_for_str_seq()
5438 chk = TAILQ_FIRST(&control->reasm); in sctp_flush_reassm_for_str_seq()
5439 if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) { in sctp_flush_reassm_for_str_seq()
5440 TAILQ_REMOVE(&control->reasm, chk, sctp_next); in sctp_flush_reassm_for_str_seq()
5441 sctp_add_chk_to_control(control, strm, stcb, asoc, in sctp_flush_reassm_for_str_seq()
5447 if (control->on_strm_q == SCTP_ON_ORDERED) { in sctp_flush_reassm_for_str_seq()
5448 TAILQ_REMOVE(&strm->inqueue, control, next_instrm); in sctp_flush_reassm_for_str_seq()
5449 if (asoc->size_on_all_streams >= control->length) { in sctp_flush_reassm_for_str_seq()
5450 asoc->size_on_all_streams -= control->length; in sctp_flush_reassm_for_str_seq()
5453 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_flush_reassm_for_str_seq()
5455 asoc->size_on_all_streams = 0; in sctp_flush_reassm_for_str_seq()
5458 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_flush_reassm_for_str_seq()
5459 control->on_strm_q = 0; in sctp_flush_reassm_for_str_seq()
5460 } else if (control->on_strm_q == SCTP_ON_UNORDERED) { in sctp_flush_reassm_for_str_seq()
5461 TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); in sctp_flush_reassm_for_str_seq()
5462 control->on_strm_q = 0; in sctp_flush_reassm_for_str_seq()
5464 } else if (control->on_strm_q) { in sctp_flush_reassm_for_str_seq()
5466 strm, control, control->on_strm_q); in sctp_flush_reassm_for_str_seq()
5469 control->on_strm_q = 0; in sctp_flush_reassm_for_str_seq()
5470 if (control->on_read_q == 0) { in sctp_flush_reassm_for_str_seq()
5471 sctp_free_remote_addr(control->whoFrom); in sctp_flush_reassm_for_str_seq()
5472 if (control->data) { in sctp_flush_reassm_for_str_seq()
5473 sctp_m_freem(control->data); in sctp_flush_reassm_for_str_seq()
5474 control->data = NULL; in sctp_flush_reassm_for_str_seq()
5476 sctp_free_a_readq(stcb, control); in sctp_flush_reassm_for_str_seq()
5485 /* The pr-sctp fwd tsn */ in sctp_handle_forward_tsn()
5488 * processing FwdTSN, as required in by pr-sctp draft: in sctp_handle_forward_tsn()
5493 * + others we have 3) examine and update re-ordering queue on in sctp_handle_forward_tsn()
5494 * pr-in-streams 4) clean up re-assembly queue 5) Send a sack to in sctp_handle_forward_tsn()
5501 struct sctp_queued_to_read *control, *ncontrol; in sctp_handle_forward_tsn() local
5503 asoc = &stcb->asoc; in sctp_handle_forward_tsn()
5504 if ((fwd_sz = ntohs(fwd->ch.chunk_length)) < sizeof(struct sctp_forward_tsn_chunk)) { in sctp_handle_forward_tsn()
5506 "Bad size too small/big fwd-tsn\n"); in sctp_handle_forward_tsn()
5509 m_size = (stcb->asoc.mapping_array_size << 3); in sctp_handle_forward_tsn()
5513 new_cum_tsn = ntohl(fwd->new_cumulative_tsn); in sctp_handle_forward_tsn()
5515 if (SCTP_TSN_GE(asoc->cumulative_tsn, new_cum_tsn)) { in sctp_handle_forward_tsn()
5523 SCTP_CALC_TSN_TO_GAP(gap, new_cum_tsn, asoc->mapping_array_base_tsn); in sctp_handle_forward_tsn()
5524 asoc->cumulative_tsn = new_cum_tsn; in sctp_handle_forward_tsn()
5526 if ((long)gap > sctp_sbspace(&stcb->asoc, &stcb->sctp_socket->so_rcv)) { in sctp_handle_forward_tsn()
5537 new_cum_tsn, asoc->highest_tsn_inside_map); in sctp_handle_forward_tsn()
5539 stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_37; in sctp_handle_forward_tsn()
5540 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, false, SCTP_SO_NOT_LOCKED); in sctp_handle_forward_tsn()
5545 memset(stcb->asoc.mapping_array, 0, stcb->asoc.mapping_array_size); in sctp_handle_forward_tsn()
5546 asoc->mapping_array_base_tsn = new_cum_tsn + 1; in sctp_handle_forward_tsn()
5547 asoc->highest_tsn_inside_map = new_cum_tsn; in sctp_handle_forward_tsn()
5549 memset(stcb->asoc.nr_mapping_array, 0, stcb->asoc.mapping_array_size); in sctp_handle_forward_tsn()
5550 asoc->highest_tsn_inside_nr_map = new_cum_tsn; in sctp_handle_forward_tsn()
5553 sctp_log_map(0, 3, asoc->highest_tsn_inside_map, SCTP_MAP_SLIDE_RESULT); in sctp_handle_forward_tsn()
5558 if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, i) && in sctp_handle_forward_tsn()
5559 !SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, i)) { in sctp_handle_forward_tsn()
5560 SCTP_SET_TSN_PRESENT(asoc->nr_mapping_array, i); in sctp_handle_forward_tsn()
5561 if (SCTP_TSN_GT(asoc->mapping_array_base_tsn + i, asoc->highest_tsn_inside_nr_map)) { in sctp_handle_forward_tsn()
5562 asoc->highest_tsn_inside_nr_map = asoc->mapping_array_base_tsn + i; in sctp_handle_forward_tsn()
5568 /* 2. Clear up re-assembly queue */ in sctp_handle_forward_tsn()
5572 if (asoc->idata_supported == 0) { in sctp_handle_forward_tsn()
5575 /* Flush all the un-ordered data based on cum-tsn */ in sctp_handle_forward_tsn()
5576 SCTP_INP_READ_LOCK(stcb->sctp_ep); in sctp_handle_forward_tsn()
5577 for (sid = 0; sid < asoc->streamincnt; sid++) { in sctp_handle_forward_tsn()
5578 strm = &asoc->strmin[sid]; in sctp_handle_forward_tsn()
5579 if (!TAILQ_EMPTY(&strm->uno_inqueue)) { in sctp_handle_forward_tsn()
5580 … sctp_flush_reassm_for_str_seq(stcb, asoc, strm, TAILQ_FIRST(&strm->uno_inqueue), 0, new_cum_tsn); in sctp_handle_forward_tsn()
5583 SCTP_INP_READ_UNLOCK(stcb->sctp_ep); in sctp_handle_forward_tsn()
5586 /* 3. Update the PR-stream re-ordering queues and fix */ in sctp_handle_forward_tsn()
5589 fwd_sz -= sizeof(*fwd); in sctp_handle_forward_tsn()
5601 SCTP_INP_READ_LOCK(stcb->sctp_ep); in sctp_handle_forward_tsn()
5602 if (asoc->idata_supported) { in sctp_handle_forward_tsn()
5608 if (asoc->idata_supported) { in sctp_handle_forward_tsn()
5614 break; in sctp_handle_forward_tsn()
5616 sid = ntohs(stseq_m->sid); in sctp_handle_forward_tsn()
5617 mid = ntohl(stseq_m->mid); in sctp_handle_forward_tsn()
5618 flags = ntohs(stseq_m->flags); in sctp_handle_forward_tsn()
5630 break; in sctp_handle_forward_tsn()
5632 sid = ntohs(stseq->sid); in sctp_handle_forward_tsn()
5633 mid = (uint32_t)ntohs(stseq->ssn); in sctp_handle_forward_tsn()
5645 if (sid >= asoc->streamincnt) { in sctp_handle_forward_tsn()
5647 break; in sctp_handle_forward_tsn()
5649 if ((asoc->str_of_pdapi == sid) && in sctp_handle_forward_tsn()
5650 (asoc->ssn_of_pdapi == mid)) { in sctp_handle_forward_tsn()
5655 * re-write. in sctp_handle_forward_tsn()
5657 asoc->fragmented_delivery_inprogress = 0; in sctp_handle_forward_tsn()
5659 strm = &asoc->strmin[sid]; in sctp_handle_forward_tsn()
5661 TAILQ_FOREACH_SAFE(control, &strm->inqueue, next_instrm, ncontrol) { in sctp_handle_forward_tsn()
5662 if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) { in sctp_handle_forward_tsn()
5663 sctp_flush_reassm_for_str_seq(stcb, asoc, strm, control, ordered, new_cum_tsn); in sctp_handle_forward_tsn()
5667 if (asoc->idata_supported) { in sctp_handle_forward_tsn()
5668 TAILQ_FOREACH_SAFE(control, &strm->uno_inqueue, next_instrm, ncontrol) { in sctp_handle_forward_tsn()
5669 if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) { in sctp_handle_forward_tsn()
5670 sctp_flush_reassm_for_str_seq(stcb, asoc, strm, control, ordered, new_cum_tsn); in sctp_handle_forward_tsn()
5674 if (!TAILQ_EMPTY(&strm->uno_inqueue)) { in sctp_handle_forward_tsn()
5675 …sctp_flush_reassm_for_str_seq(stcb, asoc, strm, TAILQ_FIRST(&strm->uno_inqueue), ordered, new_cum_… in sctp_handle_forward_tsn()
5679 TAILQ_FOREACH(control, &stcb->sctp_ep->read_queue, next) { in sctp_handle_forward_tsn()
5680 if ((control->sinfo_stream == sid) && in sctp_handle_forward_tsn()
5681 (SCTP_MID_EQ(asoc->idata_supported, control->mid, mid))) { in sctp_handle_forward_tsn()
5682 control->pdapi_aborted = 1; in sctp_handle_forward_tsn()
5683 control->end_added = 1; in sctp_handle_forward_tsn()
5684 if (control->on_strm_q == SCTP_ON_ORDERED) { in sctp_handle_forward_tsn()
5685 TAILQ_REMOVE(&strm->inqueue, control, next_instrm); in sctp_handle_forward_tsn()
5686 if (asoc->size_on_all_streams >= control->length) { in sctp_handle_forward_tsn()
5687 asoc->size_on_all_streams -= control->length; in sctp_handle_forward_tsn()
5690 …panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, contro… in sctp_handle_forward_tsn()
5692 asoc->size_on_all_streams = 0; in sctp_handle_forward_tsn()
5695 sctp_ucount_decr(asoc->cnt_on_all_streams); in sctp_handle_forward_tsn()
5696 } else if (control->on_strm_q == SCTP_ON_UNORDERED) { in sctp_handle_forward_tsn()
5697 TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); in sctp_handle_forward_tsn()
5699 } else if (control->on_strm_q) { in sctp_handle_forward_tsn()
5701 strm, control, control->on_strm_q); in sctp_handle_forward_tsn()
5704 control->on_strm_q = 0; in sctp_handle_forward_tsn()
5708 (void *)control, in sctp_handle_forward_tsn()
5710 break; in sctp_handle_forward_tsn()
5711 } else if ((control->sinfo_stream == sid) && in sctp_handle_forward_tsn()
5712 SCTP_MID_GT(asoc->idata_supported, control->mid, mid)) { in sctp_handle_forward_tsn()
5714 break; in sctp_handle_forward_tsn()
5717 if (SCTP_MID_GT(asoc->idata_supported, mid, strm->last_mid_delivered)) { in sctp_handle_forward_tsn()
5719 strm->last_mid_delivered = mid; in sctp_handle_forward_tsn()
5725 SCTP_INP_READ_UNLOCK(stcb->sctp_ep); in sctp_handle_forward_tsn()