summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2016-01-17 12:15:41 +0000
committertuexen <tuexen@FreeBSD.org>2016-01-17 12:15:41 +0000
commit70ab0ed557e2bfba1ee7f7e04ef56422a59c1d78 (patch)
treec1c63fbc506f1285a8adfdf574e9cda2d4f0b203 /sys/netinet
parent08b1ba6353e118296055ace26ff500a2fc2eda57 (diff)
downloadFreeBSD-src-70ab0ed557e2bfba1ee7f7e04ef56422a59c1d78.zip
FreeBSD-src-70ab0ed557e2bfba1ee7f7e04ef56422a59c1d78.tar.gz
MFC r291904:
Fix the allocation of outgoing streams: * When processing a cookie, use the number of streams announced in the INIT-ACK. * When sending an INIT-ACK for an existing association, use the value from the association, not from the end-point.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/sctp_input.c1
-rw-r--r--sys/netinet/sctp_output.c6
-rw-r--r--sys/netinet/sctp_pcb.c3
-rw-r--r--sys/netinet/sctp_pcb.h2
-rw-r--r--sys/netinet/sctp_usrreq.c3
-rw-r--r--sys/netinet/sctputil.c4
-rw-r--r--sys/netinet/sctputil.h2
7 files changed, 13 insertions, 8 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index b008f45..993179b 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -2103,6 +2103,7 @@ sctp_process_cookie_new(struct mbuf *m, int iphlen, int offset,
*/
stcb = sctp_aloc_assoc(inp, init_src, &error,
ntohl(initack_cp->init.initiate_tag), vrf_id,
+ ntohs(initack_cp->init.num_outbound_streams),
(struct thread *)NULL
);
if (stcb == NULL) {
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 3df52f7..f61de95 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3652,6 +3652,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
#endif
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
+ stcb->asoc.strmout[i].state = SCTP_STREAM_OPENING;
stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], NULL);
}
}
@@ -5841,10 +5842,10 @@ do_a_abort:
his_limit = ntohs(init_chk->init.num_inbound_streams);
/* choose what I want */
if (asoc != NULL) {
- if (asoc->streamoutcnt > inp->sctp_ep.pre_open_stream_count) {
+ if (asoc->streamoutcnt > asoc->pre_open_streams) {
i_want = asoc->streamoutcnt;
} else {
- i_want = inp->sctp_ep.pre_open_stream_count;
+ i_want = asoc->pre_open_streams;
}
} else {
i_want = inp->sctp_ep.pre_open_stream_count;
@@ -12617,6 +12618,7 @@ sctp_lower_sosend(struct socket *so,
}
#endif
stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id,
+ inp->sctp_ep.pre_open_stream_count,
p
);
if (stcb == NULL) {
diff --git a/sys/netinet/sctp_pcb.c b/sys/netinet/sctp_pcb.c
index 0715dd60..303a944 100644
--- a/sys/netinet/sctp_pcb.c
+++ b/sys/netinet/sctp_pcb.c
@@ -4164,6 +4164,7 @@ try_again:
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
int *error, uint32_t override_tag, uint32_t vrf_id,
+ uint16_t o_streams,
struct thread *p
)
{
@@ -4322,7 +4323,7 @@ sctp_aloc_assoc(struct sctp_inpcb *inp, struct sockaddr *firstaddr,
/* setup back pointer's */
stcb->sctp_ep = inp;
stcb->sctp_socket = inp->sctp_socket;
- if ((err = sctp_init_asoc(inp, stcb, override_tag, vrf_id))) {
+ if ((err = sctp_init_asoc(inp, stcb, override_tag, vrf_id, o_streams))) {
/* failed */
SCTP_TCB_LOCK_DESTROY(stcb);
SCTP_TCB_SEND_LOCK_DESTROY(stcb);
diff --git a/sys/netinet/sctp_pcb.h b/sys/netinet/sctp_pcb.h
index f5ede2a..ff6ccc5 100644
--- a/sys/netinet/sctp_pcb.h
+++ b/sys/netinet/sctp_pcb.h
@@ -584,7 +584,7 @@ void sctp_inpcb_free(struct sctp_inpcb *, int, int);
struct sctp_tcb *
sctp_aloc_assoc(struct sctp_inpcb *, struct sockaddr *,
- int *, uint32_t, uint32_t, struct thread *);
+ int *, uint32_t, uint32_t, uint16_t, struct thread *);
int sctp_free_assoc(struct sctp_inpcb *, struct sctp_tcb *, int, int);
diff --git a/sys/netinet/sctp_usrreq.c b/sys/netinet/sctp_usrreq.c
index eafa2c9..60deff0 100644
--- a/sys/netinet/sctp_usrreq.c
+++ b/sys/netinet/sctp_usrreq.c
@@ -1501,6 +1501,7 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
/* We are GOOD to go */
stcb = sctp_aloc_assoc(inp, sa, &error, 0, vrf_id,
+ inp->sctp_ep.pre_open_stream_count,
(struct thread *)p
);
if (stcb == NULL) {
@@ -6929,7 +6930,7 @@ sctp_connect(struct socket *so, struct sockaddr *addr, struct thread *p)
}
vrf_id = inp->def_vrf_id;
/* We are GOOD to go */
- stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, p);
+ stcb = sctp_aloc_assoc(inp, addr, &error, 0, vrf_id, inp->sctp_ep.pre_open_stream_count, p);
if (stcb == NULL) {
/* Gak! no memory */
goto out_now;
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 8d8f375..f2e9457 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -938,7 +938,7 @@ sctp_map_assoc_state(int kernel_state)
int
sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
- uint32_t override_tag, uint32_t vrf_id)
+ uint32_t override_tag, uint32_t vrf_id, uint16_t o_strms)
{
struct sctp_association *asoc;
@@ -1100,7 +1100,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
* that we request by default.
*/
asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams =
- inp->sctp_ep.pre_open_stream_count;
+ o_strms;
SCTP_MALLOC(asoc->strmout, struct sctp_stream_out *,
asoc->streamoutcnt * sizeof(struct sctp_stream_out),
SCTP_M_STRMO);
diff --git a/sys/netinet/sctputil.h b/sys/netinet/sctputil.h
index 82de736..354d40e 100644
--- a/sys/netinet/sctputil.h
+++ b/sys/netinet/sctputil.h
@@ -83,7 +83,7 @@ uint32_t sctp_select_initial_TSN(struct sctp_pcb *);
uint32_t sctp_select_a_tag(struct sctp_inpcb *, uint16_t lport, uint16_t rport, int);
-int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t);
+int sctp_init_asoc(struct sctp_inpcb *, struct sctp_tcb *, uint32_t, uint32_t, uint16_t);
void sctp_fill_random_store(struct sctp_pcb *);
OpenPOWER on IntegriCloud