summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2016-04-27 18:58:47 +0000
committertuexen <tuexen@FreeBSD.org>2016-04-27 18:58:47 +0000
commitbe1074b698ad7656bf4897bd3b2ad223df8b14bc (patch)
tree18719f8bb6508cbee1476af048c9afde0f5e1607 /sys/netinet
parent9e4bb0297ca054e482d94668c3aa02b479b223bd (diff)
downloadFreeBSD-src-be1074b698ad7656bf4897bd3b2ad223df8b14bc.zip
FreeBSD-src-be1074b698ad7656bf4897bd3b2ad223df8b14bc.tar.gz
Don't use the control argument after calling sctp_add_to_readq().
This breaks the userland stack. There should be no functional change for the FreeBSD kernel stack. While there, use consistent variable nameing.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_indata.c55
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,
OpenPOWER on IntegriCloud