diff options
Diffstat (limited to 'sys/netinet')
-rw-r--r-- | sys/netinet/sctp_indata.c | 55 |
1 files changed, 30 insertions, 25 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 9c38855..a643358 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -812,11 +812,6 @@ restart: control->on_strm_q = 0; } } - if (control->on_read_q == 0) { - sctp_add_to_readq(stcb->sctp_ep, stcb, control, - &stcb->sctp_socket->so_rcv, control->end_added, - SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - } if (control->pdapi_started) { strm->pd_api_started = 0; control->pdapi_started = 0; @@ -825,6 +820,11 @@ restart: TAILQ_REMOVE(&strm->uno_inqueue, control, next_instrm); control->on_strm_q = 0; } + if (control->on_read_q == 0) { + sctp_add_to_readq(stcb->sctp_ep, stcb, control, + &stcb->sctp_socket->so_rcv, control->end_added, + SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); + } sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); if ((nc) && (nc->first_frag_seen)) { /* @@ -843,11 +843,11 @@ restart: } } if ((control->length > pd_point) && (strm->pd_api_started == 0)) { + strm->pd_api_started = 1; + control->pdapi_started = 1; sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, control->end_added, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); - strm->pd_api_started = 1; - control->pdapi_started = 1; sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); return (0); } else { @@ -1083,16 +1083,16 @@ done_un: TAILQ_REMOVE(&strm->inqueue, control, next_instrm); control->on_strm_q = 0; } + if (strm->pd_api_started && control->pdapi_started) { + control->pdapi_started = 0; + strm->pd_api_started = 0; + } if (control->on_read_q == 0) { sctp_add_to_readq(stcb->sctp_ep, stcb, control, &stcb->sctp_socket->so_rcv, control->end_added, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); } - if (strm->pd_api_started && control->pdapi_started) { - control->pdapi_started = 0; - strm->pd_api_started = 0; - } control = nctl; } } @@ -1113,6 +1113,8 @@ deliver_more: nctl = TAILQ_NEXT(control, next_instrm); if ((control->sinfo_ssn == next_to_del) && (control->first_frag_seen)) { + int done; + /* Ok we can deliver it onto the stream. */ if (control->end_added) { /* We are done with it afterwards */ @@ -1147,6 +1149,7 @@ deliver_more: goto out; } } + done = (control->end_added) && (control->last_frag_seen); if (control->on_read_q == 0) { sctp_add_to_readq(stcb->sctp_ep, stcb, control, @@ -1154,7 +1157,7 @@ deliver_more: SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); } strm->last_sequence_delivered = next_to_del; - if ((control->end_added) && (control->last_frag_seen)) { + if (done) { control = nctl; goto deliver_more; } else { @@ -1248,7 +1251,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, { uint32_t next_fsn; struct sctp_tmit_chunk *at, *nat; - int cnt_added, unordered; + int do_wakeup, unordered; /* * For old un-ordered data chunks. @@ -1457,7 +1460,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, * Ok lets see if we can suck any up into the control structure that * are in seq if it makes sense. */ - cnt_added = 0; + do_wakeup = 0; /* * If the first fragment has not been seen there is no sense in * looking. @@ -1474,7 +1477,9 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, next_fsn, control->fsn_included); TAILQ_REMOVE(&control->reasm, at, sctp_next); sctp_add_chk_to_control(control, strm, stcb, asoc, at); - cnt_added++; + if (control->on_read_q) { + do_wakeup = 1; + } next_fsn++; if (control->end_added && control->pdapi_started) { if (strm->pd_api_started) { @@ -1486,6 +1491,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, control, &stcb->sctp_socket->so_rcv, control->end_added, SCTP_READ_LOCK_NOT_HELD, SCTP_SO_NOT_LOCKED); + do_wakeup = 1; } break; } @@ -1494,7 +1500,7 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, } } } - if ((control->on_read_q) && (cnt_added > 0)) { + if (do_wakeup) { /* Need to wakeup the reader */ sctp_wakeup_the_read_socket(stcb->sctp_ep, stcb, SCTP_SO_NOT_LOCKED); } @@ -1503,29 +1509,28 @@ sctp_queue_data_for_reasm(struct sctp_tcb *stcb, struct sctp_association *asoc, static struct sctp_queued_to_read * find_reasm_entry(struct sctp_stream_in *strm, uint32_t msg_id, int ordered, int old) { - struct sctp_queued_to_read *reasm; + struct sctp_queued_to_read *control; if (ordered) { - TAILQ_FOREACH(reasm, &strm->inqueue, next_instrm) { - if (reasm->msg_id == msg_id) { + TAILQ_FOREACH(control, &strm->inqueue, next_instrm) { + if (control->msg_id == msg_id) { break; } } } else { if (old) { - reasm = TAILQ_FIRST(&strm->uno_inqueue); - return (reasm); + control = TAILQ_FIRST(&strm->uno_inqueue); + return (control); } - TAILQ_FOREACH(reasm, &strm->uno_inqueue, next_instrm) { - if (reasm->msg_id == msg_id) { + TAILQ_FOREACH(control, &strm->uno_inqueue, next_instrm) { + if (control->msg_id == msg_id) { break; } } } - return (reasm); + return (control); } - static int sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc, struct mbuf **m, int offset, int chk_length, |