Fix the accounting and add code to detect errors in accounting.
Joint work with rrs@ MFC after: 1 week
This commit is contained in:
parent
1d2fef9b9a
commit
28cd0699b6
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=321197
@ -1797,8 +1797,8 @@ sctp_notify_authentication(struct sctp_tcb *stcb, uint32_t indication,
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb, control,
|
||||
|
@ -59,7 +59,7 @@ __FBSDID("$FreeBSD$");
|
||||
* This will cause sctp_service_queues() to get called on the top entry in
|
||||
* the list.
|
||||
*/
|
||||
static void
|
||||
static uint32_t
|
||||
sctp_add_chk_to_control(struct sctp_queued_to_read *control,
|
||||
struct sctp_stream_in *strm,
|
||||
struct sctp_tcb *stcb,
|
||||
@ -92,6 +92,8 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
|
||||
asoc->size_on_reasm_queue == 0 &&
|
||||
asoc->size_on_all_streams == 0) {
|
||||
/* Full rwnd granted */
|
||||
KASSERT(asoc->cnt_on_reasm_queue == 0, ("cnt_on_reasm_queue is %u", asoc->cnt_on_reasm_queue));
|
||||
KASSERT(asoc->cnt_on_all_streams == 0, ("cnt_on_all_streams is %u", asoc->cnt_on_all_streams));
|
||||
calc = max(SCTP_SB_LIMIT_RCV(stcb->sctp_socket), SCTP_MINIMAL_RWND);
|
||||
return (calc);
|
||||
}
|
||||
@ -558,7 +560,15 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
|
||||
}
|
||||
/* EY it wont be queued if it could be delivered directly */
|
||||
queue_needed = 0;
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
strm->last_mid_delivered++;
|
||||
sctp_mark_non_revokable(asoc, control->sinfo_tsn);
|
||||
@ -571,10 +581,18 @@ sctp_queue_data_to_stream(struct sctp_tcb *stcb,
|
||||
nxt_todel = strm->last_mid_delivered + 1;
|
||||
if (SCTP_MID_EQ(asoc->idata_supported, nxt_todel, control->mid) &&
|
||||
(((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG)) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
if (control->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
#ifdef INVARIANTS
|
||||
} else {
|
||||
panic("Huh control: %p is on_strm_q: %d",
|
||||
@ -671,7 +689,7 @@ sctp_setup_tail_pointer(struct sctp_queued_to_read *control)
|
||||
}
|
||||
|
||||
static void
|
||||
sctp_add_to_tail_pointer(struct sctp_queued_to_read *control, struct mbuf *m)
|
||||
sctp_add_to_tail_pointer(struct sctp_queued_to_read *control, struct mbuf *m, uint32_t *added)
|
||||
{
|
||||
struct mbuf *prev = NULL;
|
||||
struct sctp_tcb *stcb;
|
||||
@ -715,6 +733,7 @@ sctp_add_to_tail_pointer(struct sctp_queued_to_read *control, struct mbuf *m)
|
||||
*/
|
||||
sctp_sballoc(stcb, &stcb->sctp_socket->so_rcv, m);
|
||||
}
|
||||
*added += SCTP_BUF_LEN(m);
|
||||
atomic_add_int(&control->length, SCTP_BUF_LEN(m));
|
||||
m = SCTP_BUF_NEXT(m);
|
||||
}
|
||||
@ -815,7 +834,15 @@ sctp_handle_old_unordered_data(struct sctp_tcb *stcb,
|
||||
tchk = TAILQ_FIRST(&control->reasm);
|
||||
if (tchk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
|
||||
TAILQ_REMOVE(&control->reasm, tchk, sctp_next);
|
||||
asoc->size_on_reasm_queue -= tchk->send_size;
|
||||
if (asoc->size_on_reasm_queue >= tchk->send_size) {
|
||||
asoc->size_on_reasm_queue -= tchk->send_size;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, tchk->send_size);
|
||||
#else
|
||||
asoc->size_on_reasm_queue = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_reasm_queue);
|
||||
nc->first_frag_seen = 1;
|
||||
nc->fsn_included = tchk->rec.data.fsn;
|
||||
@ -1127,6 +1154,16 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
#endif
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs);
|
||||
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
control->on_strm_q = 0;
|
||||
}
|
||||
if (strm->pd_api_started && control->pdapi_started) {
|
||||
@ -1173,6 +1210,16 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
#endif
|
||||
SCTP_STAT_INCR_COUNTER64(sctps_reasmusrmsgs);
|
||||
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
control->on_strm_q = 0;
|
||||
}
|
||||
ret++;
|
||||
@ -1219,7 +1266,7 @@ sctp_deliver_reasm_check(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uint32_t
|
||||
sctp_add_chk_to_control(struct sctp_queued_to_read *control,
|
||||
struct sctp_stream_in *strm,
|
||||
struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
@ -1229,6 +1276,7 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
|
||||
* Given a control and a chunk, merge the data from the chk onto the
|
||||
* control and free up the chunk resources.
|
||||
*/
|
||||
uint32_t added = 0;
|
||||
int i_locked = 0;
|
||||
|
||||
if (control->on_read_q && (hold_rlock == 0)) {
|
||||
@ -1242,7 +1290,7 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
|
||||
control->data = chk->data;
|
||||
sctp_setup_tail_pointer(control);
|
||||
} else {
|
||||
sctp_add_to_tail_pointer(control, chk->data);
|
||||
sctp_add_to_tail_pointer(control, chk->data, &added);
|
||||
}
|
||||
control->fsn_included = chk->rec.data.fsn;
|
||||
asoc->size_on_reasm_queue -= chk->send_size;
|
||||
@ -1268,6 +1316,16 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
|
||||
} else if (control->on_strm_q == SCTP_ON_ORDERED) {
|
||||
/* Ordered */
|
||||
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
control->on_strm_q = 0;
|
||||
#ifdef INVARIANTS
|
||||
} else if (control->on_strm_q) {
|
||||
@ -1283,6 +1341,7 @@ sctp_add_chk_to_control(struct sctp_queued_to_read *control,
|
||||
SCTP_INP_READ_UNLOCK(stcb->sctp_ep);
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
return (added);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1302,6 +1361,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
struct sctp_tmit_chunk *at, *nat;
|
||||
struct sctp_stream_in *strm;
|
||||
int do_wakeup, unordered;
|
||||
uint32_t lenadded;
|
||||
|
||||
strm = &asoc->strmin[control->sinfo_stream];
|
||||
/*
|
||||
@ -1314,6 +1374,9 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
}
|
||||
/* Must be added to the stream-in queue */
|
||||
if (created_control) {
|
||||
if (unordered == 0) {
|
||||
sctp_ucount_incr(asoc->cnt_on_all_streams);
|
||||
}
|
||||
if (sctp_place_control_in_stream(strm, asoc, control)) {
|
||||
/* Duplicate SSN? */
|
||||
sctp_clean_up_control(stcb, control);
|
||||
@ -1373,6 +1436,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
chk->data = NULL;
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
sctp_setup_tail_pointer(control);
|
||||
asoc->size_on_all_streams += control->length;
|
||||
} else {
|
||||
/* Place the chunk in our list */
|
||||
int inserted = 0;
|
||||
@ -1529,7 +1593,8 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
at->rec.data.fsn,
|
||||
next_fsn, control->fsn_included);
|
||||
TAILQ_REMOVE(&control->reasm, at, sctp_next);
|
||||
sctp_add_chk_to_control(control, strm, stcb, asoc, at, SCTP_READ_LOCK_NOT_HELD);
|
||||
lenadded = sctp_add_chk_to_control(control, strm, stcb, asoc, at, SCTP_READ_LOCK_NOT_HELD);
|
||||
asoc->size_on_all_streams += lenadded;
|
||||
if (control->on_read_q) {
|
||||
do_wakeup = 1;
|
||||
}
|
||||
@ -1600,7 +1665,7 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
uint16_t sid;
|
||||
struct mbuf *op_err;
|
||||
char msg[SCTP_DIAG_INFO_LEN];
|
||||
struct sctp_queued_to_read *control = NULL;
|
||||
struct sctp_queued_to_read *control, *ncontrol;
|
||||
uint32_t ppid;
|
||||
uint8_t chk_flags;
|
||||
struct sctp_stream_reset_list *liste;
|
||||
@ -2006,7 +2071,13 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
return (0);
|
||||
}
|
||||
if ((chk_flags & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
|
||||
struct mbuf *m;
|
||||
|
||||
control->data = dmbuf;
|
||||
m = control->data;
|
||||
for (m = control->data; m; m = m->m_next) {
|
||||
control->length += SCTP_BUF_LEN(m);
|
||||
}
|
||||
control->tail_mbuf = NULL;
|
||||
control->end_added = 1;
|
||||
control->last_frag_seen = 1;
|
||||
@ -2116,16 +2187,16 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
/* first one on */
|
||||
TAILQ_INSERT_TAIL(&asoc->pending_reply_queue, control, next);
|
||||
} else {
|
||||
struct sctp_queued_to_read *ctlOn, *nctlOn;
|
||||
struct sctp_queued_to_read *lcontrol, *nlcontrol;
|
||||
unsigned char inserted = 0;
|
||||
|
||||
TAILQ_FOREACH_SAFE(ctlOn, &asoc->pending_reply_queue, next, nctlOn) {
|
||||
if (SCTP_TSN_GT(control->sinfo_tsn, ctlOn->sinfo_tsn)) {
|
||||
TAILQ_FOREACH_SAFE(lcontrol, &asoc->pending_reply_queue, next, nlcontrol) {
|
||||
if (SCTP_TSN_GT(control->sinfo_tsn, lcontrol->sinfo_tsn)) {
|
||||
|
||||
continue;
|
||||
} else {
|
||||
/* found it */
|
||||
TAILQ_INSERT_BEFORE(ctlOn, control, next);
|
||||
TAILQ_INSERT_BEFORE(lcontrol, control, next);
|
||||
inserted = 1;
|
||||
break;
|
||||
}
|
||||
@ -2216,8 +2287,6 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
* pending_reply space 3: distribute any chunks in
|
||||
* pending_reply_queue.
|
||||
*/
|
||||
struct sctp_queued_to_read *ctl, *nctl;
|
||||
|
||||
sctp_reset_in_stream(stcb, liste->number_entries, liste->list_of_streams);
|
||||
TAILQ_REMOVE(&asoc->resetHead, liste, next_resp);
|
||||
sctp_send_deferred_reset_response(stcb, liste, SCTP_STREAM_RESET_RESULT_PERFORMED);
|
||||
@ -2226,34 +2295,34 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
|
||||
liste = TAILQ_FIRST(&asoc->resetHead);
|
||||
if (TAILQ_EMPTY(&asoc->resetHead)) {
|
||||
/* All can be removed */
|
||||
TAILQ_FOREACH_SAFE(ctl, &asoc->pending_reply_queue, next, nctl) {
|
||||
TAILQ_REMOVE(&asoc->pending_reply_queue, ctl, next);
|
||||
sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag, &need_reasm_check);
|
||||
TAILQ_FOREACH_SAFE(control, &asoc->pending_reply_queue, next, ncontrol) {
|
||||
TAILQ_REMOVE(&asoc->pending_reply_queue, control, next);
|
||||
sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check);
|
||||
if (*abort_flag) {
|
||||
return (0);
|
||||
}
|
||||
if (need_reasm_check) {
|
||||
(void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[ctl->sinfo_stream], SCTP_READ_LOCK_NOT_HELD);
|
||||
(void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[control->sinfo_stream], SCTP_READ_LOCK_NOT_HELD);
|
||||
need_reasm_check = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
TAILQ_FOREACH_SAFE(ctl, &asoc->pending_reply_queue, next, nctl) {
|
||||
if (SCTP_TSN_GT(ctl->sinfo_tsn, liste->tsn)) {
|
||||
TAILQ_FOREACH_SAFE(control, &asoc->pending_reply_queue, next, ncontrol) {
|
||||
if (SCTP_TSN_GT(control->sinfo_tsn, liste->tsn)) {
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* if ctl->sinfo_tsn is <= liste->tsn we can
|
||||
* process it which is the NOT of
|
||||
* ctl->sinfo_tsn > liste->tsn
|
||||
* if control->sinfo_tsn is <= liste->tsn we
|
||||
* can process it which is the NOT of
|
||||
* control->sinfo_tsn > liste->tsn
|
||||
*/
|
||||
TAILQ_REMOVE(&asoc->pending_reply_queue, ctl, next);
|
||||
sctp_queue_data_to_stream(stcb, asoc, ctl, abort_flag, &need_reasm_check);
|
||||
TAILQ_REMOVE(&asoc->pending_reply_queue, control, next);
|
||||
sctp_queue_data_to_stream(stcb, asoc, control, abort_flag, &need_reasm_check);
|
||||
if (*abort_flag) {
|
||||
return (0);
|
||||
}
|
||||
if (need_reasm_check) {
|
||||
(void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[ctl->sinfo_stream], SCTP_READ_LOCK_NOT_HELD);
|
||||
(void)sctp_deliver_reasm_check(stcb, asoc, &asoc->strmin[control->sinfo_stream], SCTP_READ_LOCK_NOT_HELD);
|
||||
need_reasm_check = 0;
|
||||
}
|
||||
}
|
||||
@ -5181,7 +5250,7 @@ static void
|
||||
sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
|
||||
struct sctp_stream_in *strmin)
|
||||
{
|
||||
struct sctp_queued_to_read *ctl, *nctl;
|
||||
struct sctp_queued_to_read *control, *ncontrol;
|
||||
struct sctp_association *asoc;
|
||||
uint32_t mid;
|
||||
int need_reasm_check = 0;
|
||||
@ -5192,43 +5261,51 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
|
||||
* First deliver anything prior to and including the stream no that
|
||||
* came in.
|
||||
*/
|
||||
TAILQ_FOREACH_SAFE(ctl, &strmin->inqueue, next_instrm, nctl) {
|
||||
if (SCTP_MID_GE(asoc->idata_supported, mid, ctl->mid)) {
|
||||
TAILQ_FOREACH_SAFE(control, &strmin->inqueue, next_instrm, ncontrol) {
|
||||
if (SCTP_MID_GE(asoc->idata_supported, mid, control->mid)) {
|
||||
/* this is deliverable now */
|
||||
if (((ctl->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
|
||||
if (ctl->on_strm_q) {
|
||||
if (ctl->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strmin->inqueue, ctl, next_instrm);
|
||||
} else if (ctl->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strmin->uno_inqueue, ctl, next_instrm);
|
||||
if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
|
||||
if (control->on_strm_q) {
|
||||
if (control->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strmin->inqueue, control, next_instrm);
|
||||
} else if (control->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strmin->uno_inqueue, control, next_instrm);
|
||||
#ifdef INVARIANTS
|
||||
} else {
|
||||
panic("strmin: %p ctl: %p unknown %d",
|
||||
strmin, ctl, ctl->on_strm_q);
|
||||
strmin, control, control->on_strm_q);
|
||||
#endif
|
||||
}
|
||||
ctl->on_strm_q = 0;
|
||||
control->on_strm_q = 0;
|
||||
}
|
||||
/* subtract pending on streams */
|
||||
asoc->size_on_all_streams -= ctl->length;
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
/* deliver it to at least the delivery-q */
|
||||
if (stcb->sctp_socket) {
|
||||
sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
|
||||
sctp_mark_non_revokable(asoc, control->sinfo_tsn);
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
ctl,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv,
|
||||
1, SCTP_READ_LOCK_HELD,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
} else {
|
||||
/* Its a fragmented message */
|
||||
if (ctl->first_frag_seen) {
|
||||
if (control->first_frag_seen) {
|
||||
/*
|
||||
* Make it so this is next to
|
||||
* deliver, we restore later
|
||||
*/
|
||||
strmin->last_mid_delivered = ctl->mid - 1;
|
||||
strmin->last_mid_delivered = control->mid - 1;
|
||||
need_reasm_check = 1;
|
||||
break;
|
||||
}
|
||||
@ -5257,32 +5334,40 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
|
||||
* now ready.
|
||||
*/
|
||||
mid = strmin->last_mid_delivered + 1;
|
||||
TAILQ_FOREACH_SAFE(ctl, &strmin->inqueue, next_instrm, nctl) {
|
||||
if (SCTP_MID_EQ(asoc->idata_supported, mid, ctl->mid)) {
|
||||
if (((ctl->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
|
||||
TAILQ_FOREACH_SAFE(control, &strmin->inqueue, next_instrm, ncontrol) {
|
||||
if (SCTP_MID_EQ(asoc->idata_supported, mid, control->mid)) {
|
||||
if (((control->sinfo_flags >> 8) & SCTP_DATA_NOT_FRAG) == SCTP_DATA_NOT_FRAG) {
|
||||
/* this is deliverable now */
|
||||
if (ctl->on_strm_q) {
|
||||
if (ctl->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strmin->inqueue, ctl, next_instrm);
|
||||
} else if (ctl->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strmin->uno_inqueue, ctl, next_instrm);
|
||||
if (control->on_strm_q) {
|
||||
if (control->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strmin->inqueue, control, next_instrm);
|
||||
} else if (control->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strmin->uno_inqueue, control, next_instrm);
|
||||
#ifdef INVARIANTS
|
||||
} else {
|
||||
panic("strmin: %p ctl: %p unknown %d",
|
||||
strmin, ctl, ctl->on_strm_q);
|
||||
strmin, control, control->on_strm_q);
|
||||
#endif
|
||||
}
|
||||
ctl->on_strm_q = 0;
|
||||
control->on_strm_q = 0;
|
||||
}
|
||||
/* subtract pending on streams */
|
||||
asoc->size_on_all_streams -= ctl->length;
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
/* deliver it to at least the delivery-q */
|
||||
strmin->last_mid_delivered = ctl->mid;
|
||||
strmin->last_mid_delivered = control->mid;
|
||||
if (stcb->sctp_socket) {
|
||||
sctp_mark_non_revokable(asoc, ctl->sinfo_tsn);
|
||||
sctp_mark_non_revokable(asoc, control->sinfo_tsn);
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
ctl,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1,
|
||||
SCTP_READ_LOCK_HELD, SCTP_SO_NOT_LOCKED);
|
||||
|
||||
@ -5290,12 +5375,12 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
|
||||
mid = strmin->last_mid_delivered + 1;
|
||||
} else {
|
||||
/* Its a fragmented message */
|
||||
if (ctl->first_frag_seen) {
|
||||
if (control->first_frag_seen) {
|
||||
/*
|
||||
* Make it so this is next to
|
||||
* deliver
|
||||
*/
|
||||
strmin->last_mid_delivered = ctl->mid - 1;
|
||||
strmin->last_mid_delivered = control->mid - 1;
|
||||
need_reasm_check = 1;
|
||||
break;
|
||||
}
|
||||
@ -5347,7 +5432,15 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
|
||||
}
|
||||
cnt_removed++;
|
||||
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
|
||||
asoc->size_on_reasm_queue -= chk->send_size;
|
||||
if (asoc->size_on_reasm_queue >= chk->send_size) {
|
||||
asoc->size_on_reasm_queue -= chk->send_size;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_size);
|
||||
#else
|
||||
asoc->size_on_reasm_queue = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_reasm_queue);
|
||||
if (chk->data) {
|
||||
sctp_m_freem(chk->data);
|
||||
@ -5373,6 +5466,16 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
|
||||
}
|
||||
if (control->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
control->on_strm_q = 0;
|
||||
} else if (control->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm);
|
||||
@ -5416,7 +5519,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
unsigned int i, fwd_sz, m_size;
|
||||
uint32_t str_seq;
|
||||
struct sctp_stream_in *strm;
|
||||
struct sctp_queued_to_read *ctl, *sv;
|
||||
struct sctp_queued_to_read *control, *sv;
|
||||
|
||||
asoc = &stcb->asoc;
|
||||
if ((fwd_sz = ntohs(fwd->ch.chunk_length)) < sizeof(struct sctp_forward_tsn_chunk)) {
|
||||
@ -5575,25 +5678,35 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
for (cur_mid = strm->last_mid_delivered; SCTP_MID_GE(asoc->idata_supported, mid, cur_mid); cur_mid++) {
|
||||
sctp_flush_reassm_for_str_seq(stcb, asoc, sid, cur_mid, ordered, new_cum_tsn);
|
||||
}
|
||||
TAILQ_FOREACH(ctl, &stcb->sctp_ep->read_queue, next) {
|
||||
if ((ctl->sinfo_stream == sid) &&
|
||||
(SCTP_MID_EQ(asoc->idata_supported, ctl->mid, mid))) {
|
||||
TAILQ_FOREACH(control, &stcb->sctp_ep->read_queue, next) {
|
||||
if ((control->sinfo_stream == sid) &&
|
||||
(SCTP_MID_EQ(asoc->idata_supported, control->mid, mid))) {
|
||||
str_seq = (sid << 16) | (0x0000ffff & mid);
|
||||
ctl->pdapi_aborted = 1;
|
||||
control->pdapi_aborted = 1;
|
||||
sv = stcb->asoc.control_pdapi;
|
||||
ctl->end_added = 1;
|
||||
if (ctl->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strm->inqueue, ctl, next_instrm);
|
||||
} else if (ctl->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strm->uno_inqueue, ctl, next_instrm);
|
||||
control->end_added = 1;
|
||||
if (control->on_strm_q == SCTP_ON_ORDERED) {
|
||||
TAILQ_REMOVE(&strm->inqueue, control, next_instrm);
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
} else if (ctl->on_strm_q) {
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
} else if (control->on_strm_q == SCTP_ON_UNORDERED) {
|
||||
TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm);
|
||||
#ifdef INVARIANTS
|
||||
} else if (control->on_strm_q) {
|
||||
panic("strm: %p ctl: %p unknown %d",
|
||||
strm, ctl, ctl->on_strm_q);
|
||||
strm, control, control->on_strm_q);
|
||||
#endif
|
||||
}
|
||||
ctl->on_strm_q = 0;
|
||||
stcb->asoc.control_pdapi = ctl;
|
||||
control->on_strm_q = 0;
|
||||
stcb->asoc.control_pdapi = control;
|
||||
sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
|
||||
stcb,
|
||||
SCTP_PARTIAL_DELIVERY_ABORTED,
|
||||
@ -5601,8 +5714,8 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
|
||||
SCTP_SO_NOT_LOCKED);
|
||||
stcb->asoc.control_pdapi = sv;
|
||||
break;
|
||||
} else if ((ctl->sinfo_stream == sid) &&
|
||||
SCTP_MID_GT(asoc->idata_supported, ctl->mid, mid)) {
|
||||
} else if ((control->sinfo_stream == sid) &&
|
||||
SCTP_MID_GT(asoc->idata_supported, control->mid, mid)) {
|
||||
/* We are past our victim SSN */
|
||||
break;
|
||||
}
|
||||
|
@ -4599,21 +4599,21 @@ void
|
||||
sctp_clean_up_stream(struct sctp_tcb *stcb, struct sctp_readhead *rh)
|
||||
{
|
||||
struct sctp_tmit_chunk *chk, *nchk;
|
||||
struct sctp_queued_to_read *ctl, *nctl;
|
||||
struct sctp_queued_to_read *control, *ncontrol;
|
||||
|
||||
TAILQ_FOREACH_SAFE(ctl, rh, next_instrm, nctl) {
|
||||
TAILQ_REMOVE(rh, ctl, next_instrm);
|
||||
ctl->on_strm_q = 0;
|
||||
if (ctl->on_read_q == 0) {
|
||||
sctp_free_remote_addr(ctl->whoFrom);
|
||||
if (ctl->data) {
|
||||
sctp_m_freem(ctl->data);
|
||||
ctl->data = NULL;
|
||||
TAILQ_FOREACH_SAFE(control, rh, next_instrm, ncontrol) {
|
||||
TAILQ_REMOVE(rh, control, next_instrm);
|
||||
control->on_strm_q = 0;
|
||||
if (control->on_read_q == 0) {
|
||||
sctp_free_remote_addr(control->whoFrom);
|
||||
if (control->data) {
|
||||
sctp_m_freem(control->data);
|
||||
control->data = NULL;
|
||||
}
|
||||
}
|
||||
/* Reassembly free? */
|
||||
TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
|
||||
TAILQ_REMOVE(&ctl->reasm, chk, sctp_next);
|
||||
TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
|
||||
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
|
||||
if (chk->data) {
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
@ -4629,8 +4629,8 @@ sctp_clean_up_stream(struct sctp_tcb *stcb, struct sctp_readhead *rh)
|
||||
* We don't free the address here since all the net's were
|
||||
* freed above.
|
||||
*/
|
||||
if (ctl->on_read_q == 0) {
|
||||
sctp_free_a_readq(stcb, ctl);
|
||||
if (control->on_read_q == 0) {
|
||||
sctp_free_a_readq(stcb, control);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6801,7 +6801,7 @@ sctp_drain_mbufs(struct sctp_tcb *stcb)
|
||||
struct sctp_association *asoc;
|
||||
struct sctp_tmit_chunk *chk, *nchk;
|
||||
uint32_t cumulative_tsn_p1;
|
||||
struct sctp_queued_to_read *ctl, *nctl;
|
||||
struct sctp_queued_to_read *control, *ncontrol;
|
||||
int cnt, strmat;
|
||||
uint32_t gap, i;
|
||||
int fnd = 0;
|
||||
@ -6818,88 +6818,124 @@ sctp_drain_mbufs(struct sctp_tcb *stcb)
|
||||
cnt = 0;
|
||||
/* Ok that was fun, now we will drain all the inbound streams? */
|
||||
for (strmat = 0; strmat < asoc->streamincnt; strmat++) {
|
||||
TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[strmat].inqueue, next_instrm, nctl) {
|
||||
TAILQ_FOREACH_SAFE(control, &asoc->strmin[strmat].inqueue, next_instrm, ncontrol) {
|
||||
#ifdef INVARIANTS
|
||||
if (ctl->on_strm_q != SCTP_ON_ORDERED) {
|
||||
if (control->on_strm_q != SCTP_ON_ORDERED) {
|
||||
panic("Huh control: %p on_q: %d -- not ordered?",
|
||||
ctl, ctl->on_strm_q);
|
||||
control, control->on_strm_q);
|
||||
}
|
||||
#endif
|
||||
if (SCTP_TSN_GT(ctl->sinfo_tsn, cumulative_tsn_p1)) {
|
||||
if (SCTP_TSN_GT(control->sinfo_tsn, cumulative_tsn_p1)) {
|
||||
/* Yep it is above cum-ack */
|
||||
cnt++;
|
||||
SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
|
||||
asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
|
||||
SCTP_CALC_TSN_TO_GAP(gap, control->sinfo_tsn, asoc->mapping_array_base_tsn);
|
||||
KASSERT(control->length > 0, ("control has zero length"));
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
|
||||
if (ctl->on_read_q) {
|
||||
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, ctl, next);
|
||||
ctl->on_read_q = 0;
|
||||
if (control->on_read_q) {
|
||||
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
|
||||
control->on_read_q = 0;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, ctl, next_instrm);
|
||||
ctl->on_strm_q = 0;
|
||||
if (ctl->data) {
|
||||
sctp_m_freem(ctl->data);
|
||||
ctl->data = NULL;
|
||||
TAILQ_REMOVE(&asoc->strmin[strmat].inqueue, control, next_instrm);
|
||||
control->on_strm_q = 0;
|
||||
if (control->data) {
|
||||
sctp_m_freem(control->data);
|
||||
control->data = NULL;
|
||||
}
|
||||
sctp_free_remote_addr(ctl->whoFrom);
|
||||
sctp_free_remote_addr(control->whoFrom);
|
||||
/* Now its reasm? */
|
||||
TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
|
||||
TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
|
||||
cnt++;
|
||||
SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn);
|
||||
asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
|
||||
KASSERT(chk->send_size > 0, ("chunk has zero length"));
|
||||
if (asoc->size_on_reasm_queue >= chk->send_size) {
|
||||
asoc->size_on_reasm_queue -= chk->send_size;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_size);
|
||||
#else
|
||||
asoc->size_on_reasm_queue = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_reasm_queue);
|
||||
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
|
||||
TAILQ_REMOVE(&ctl->reasm, chk, sctp_next);
|
||||
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
|
||||
if (chk->data) {
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
sctp_free_a_readq(stcb, ctl);
|
||||
sctp_free_a_readq(stcb, control);
|
||||
}
|
||||
}
|
||||
TAILQ_FOREACH_SAFE(ctl, &asoc->strmin[strmat].uno_inqueue, next_instrm, nctl) {
|
||||
TAILQ_FOREACH_SAFE(control, &asoc->strmin[strmat].uno_inqueue, next_instrm, ncontrol) {
|
||||
#ifdef INVARIANTS
|
||||
if (ctl->on_strm_q != SCTP_ON_UNORDERED) {
|
||||
if (control->on_strm_q != SCTP_ON_UNORDERED) {
|
||||
panic("Huh control: %p on_q: %d -- not unordered?",
|
||||
ctl, ctl->on_strm_q);
|
||||
control, control->on_strm_q);
|
||||
}
|
||||
#endif
|
||||
if (SCTP_TSN_GT(ctl->sinfo_tsn, cumulative_tsn_p1)) {
|
||||
if (SCTP_TSN_GT(control->sinfo_tsn, cumulative_tsn_p1)) {
|
||||
/* Yep it is above cum-ack */
|
||||
cnt++;
|
||||
SCTP_CALC_TSN_TO_GAP(gap, ctl->sinfo_tsn, asoc->mapping_array_base_tsn);
|
||||
asoc->size_on_all_streams = sctp_sbspace_sub(asoc->size_on_all_streams, ctl->length);
|
||||
SCTP_CALC_TSN_TO_GAP(gap, control->sinfo_tsn, asoc->mapping_array_base_tsn);
|
||||
KASSERT(control->length > 0, ("control has zero length"));
|
||||
if (asoc->size_on_all_streams >= control->length) {
|
||||
asoc->size_on_all_streams -= control->length;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_all_streams = %u smaller than control length %u", asoc->size_on_all_streams, control->length);
|
||||
#else
|
||||
asoc->size_on_all_streams = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_all_streams);
|
||||
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
|
||||
if (ctl->on_read_q) {
|
||||
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, ctl, next);
|
||||
ctl->on_read_q = 0;
|
||||
if (control->on_read_q) {
|
||||
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
|
||||
control->on_read_q = 0;
|
||||
}
|
||||
TAILQ_REMOVE(&asoc->strmin[strmat].uno_inqueue, ctl, next_instrm);
|
||||
ctl->on_strm_q = 0;
|
||||
if (ctl->data) {
|
||||
sctp_m_freem(ctl->data);
|
||||
ctl->data = NULL;
|
||||
TAILQ_REMOVE(&asoc->strmin[strmat].uno_inqueue, control, next_instrm);
|
||||
control->on_strm_q = 0;
|
||||
if (control->data) {
|
||||
sctp_m_freem(control->data);
|
||||
control->data = NULL;
|
||||
}
|
||||
sctp_free_remote_addr(ctl->whoFrom);
|
||||
sctp_free_remote_addr(control->whoFrom);
|
||||
/* Now its reasm? */
|
||||
TAILQ_FOREACH_SAFE(chk, &ctl->reasm, sctp_next, nchk) {
|
||||
TAILQ_FOREACH_SAFE(chk, &control->reasm, sctp_next, nchk) {
|
||||
cnt++;
|
||||
SCTP_CALC_TSN_TO_GAP(gap, chk->rec.data.tsn, asoc->mapping_array_base_tsn);
|
||||
asoc->size_on_reasm_queue = sctp_sbspace_sub(asoc->size_on_reasm_queue, chk->send_size);
|
||||
KASSERT(chk->send_size > 0, ("chunk has zero length"));
|
||||
if (asoc->size_on_reasm_queue >= chk->send_size) {
|
||||
asoc->size_on_reasm_queue -= chk->send_size;
|
||||
} else {
|
||||
#ifdef INVARIANTS
|
||||
panic("size_on_reasm_queue = %u smaller than chunk length %u", asoc->size_on_reasm_queue, chk->send_size);
|
||||
#else
|
||||
asoc->size_on_reasm_queue = 0;
|
||||
#endif
|
||||
}
|
||||
sctp_ucount_decr(asoc->cnt_on_reasm_queue);
|
||||
SCTP_UNSET_TSN_PRESENT(asoc->mapping_array, gap);
|
||||
TAILQ_REMOVE(&ctl->reasm, chk, sctp_next);
|
||||
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
|
||||
if (chk->data) {
|
||||
sctp_m_freem(chk->data);
|
||||
chk->data = NULL;
|
||||
}
|
||||
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
|
||||
}
|
||||
sctp_free_a_readq(stcb, ctl);
|
||||
sctp_free_a_readq(stcb, control);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2754,9 +2754,9 @@ sctp_notify_assoc_change(uint16_t state, struct sctp_tcb *stcb,
|
||||
m_notify);
|
||||
if (control != NULL) {
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD,
|
||||
@ -3039,7 +3039,10 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1,
|
||||
@ -3139,7 +3142,10 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1, SCTP_READ_LOCK_NOT_HELD, so_locked);
|
||||
@ -3240,12 +3246,10 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
control->held_length = 0;
|
||||
control->length = 0;
|
||||
sb = &stcb->sctp_socket->so_rcv;
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
|
||||
sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBALLOC, SCTP_BUF_LEN(m_notify));
|
||||
@ -3254,7 +3258,6 @@ sctp_notify_partial_delivery_indication(struct sctp_tcb *stcb, uint32_t error,
|
||||
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_SB_LOGGING_ENABLE) {
|
||||
sctp_sblog(sb, control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
|
||||
}
|
||||
atomic_add_int(&control->length, SCTP_BUF_LEN(m_notify));
|
||||
control->end_added = 1;
|
||||
if (stcb->asoc.control_pdapi)
|
||||
TAILQ_INSERT_AFTER(&stcb->sctp_ep->read_queue, stcb->asoc.control_pdapi, control, next);
|
||||
@ -3349,8 +3352,8 @@ sctp_notify_shutdown_event(struct sctp_tcb *stcb)
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
@ -3456,8 +3459,8 @@ sctp_notify_stream_reset_add(struct sctp_tcb *stcb, uint16_t numberin, uint16_t
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
@ -3506,8 +3509,8 @@ sctp_notify_stream_reset_tsn(struct sctp_tcb *stcb, uint32_t sending_tsn, uint32
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
@ -3571,8 +3574,8 @@ sctp_notify_stream_reset(struct sctp_tcb *stcb,
|
||||
sctp_m_freem(m_notify);
|
||||
return;
|
||||
}
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
@ -3627,9 +3630,9 @@ sctp_notify_remote_error(struct sctp_tcb *stcb, uint16_t error, struct sctp_erro
|
||||
m_notify);
|
||||
if (control != NULL) {
|
||||
control->length = SCTP_BUF_LEN(m_notify);
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
/* not that we need this */
|
||||
control->tail_mbuf = m_notify;
|
||||
control->spec_flags = M_NOTIFICATION;
|
||||
sctp_add_to_readq(stcb->sctp_ep, stcb,
|
||||
control,
|
||||
&stcb->sctp_socket->so_rcv, 1,
|
||||
|
Loading…
Reference in New Issue
Block a user