summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/sctp_output.c')
-rw-r--r--sys/netinet/sctp_output.c74
1 files changed, 54 insertions, 20 deletions
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 8593ee6..4ebd0b4 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -8620,13 +8620,12 @@ re_look:
sp->some_taken = 1;
}
} else {
- to_move = sctp_can_we_split_this(stcb, length, goal_mtu,
- frag_point, eeor_mode);
+ to_move = sctp_can_we_split_this(stcb, length, goal_mtu, frag_point, eeor_mode);
if (to_move) {
/*-
- * We use a snapshot of length in case it
- * is expanding during the compare.
- */
+ * We use a snapshot of length in case it
+ * is expanding during the compare.
+ */
uint32_t llen;
llen = length;
@@ -8634,9 +8633,9 @@ re_look:
to_move = llen;
if (send_lock_up == 0) {
/*-
- * We are taking all of an incomplete msg
- * thus we need a send lock.
- */
+ * We are taking all of an incomplete msg
+ * thus we need a send lock.
+ */
SCTP_TCB_SEND_LOCK(stcb);
send_lock_up = 1;
if (sp->msg_is_complete) {
@@ -8836,8 +8835,7 @@ dont_do_it:
goto out_of;
}
sctp_snd_sb_alloc(stcb, sizeof(struct sctp_data_chunk));
- chk->book_size = chk->send_size = (to_move +
- sizeof(struct sctp_data_chunk));
+ chk->book_size = chk->send_size = (to_move + sizeof(struct sctp_data_chunk));
chk->book_size_scale = 0;
chk->sent = SCTP_DATAGRAM_UNSENT;
@@ -13339,13 +13337,49 @@ sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *chk,
return;
}
+static void
+sctp_add_a_stream(struct sctp_tmit_chunk *chk,
+ uint32_t seq,
+ uint16_t adding)
+{
+ int len, old_len;
+ struct sctp_chunkhdr *ch;
+ struct sctp_stream_reset_add_strm *addstr;
+
+ ch = mtod(chk->data, struct sctp_chunkhdr *);
+ old_len = len = SCTP_SIZE32(ntohs(ch->chunk_length));
+
+ /* get to new offset for the param. */
+ addstr = (struct sctp_stream_reset_add_strm *)((caddr_t)ch + len);
+ /* now how long will this param be? */
+ len = sizeof(struct sctp_stream_reset_add_strm);
+
+ /* Fill it out. */
+ addstr->ph.param_type = htons(SCTP_STR_RESET_ADD_STREAMS);
+ addstr->ph.param_length = htons(len);
+ addstr->request_seq = htonl(seq);
+ addstr->number_of_streams = htons(adding);
+ addstr->reserved = 0;
+
+ /* now fix the chunk length */
+ ch->chunk_length = htons(len + old_len);
+ chk->send_size = len + old_len;
+ chk->book_size = SCTP_SIZE32(chk->send_size);
+ chk->book_size_scale = 0;
+ SCTP_BUF_LEN(chk->data) = SCTP_SIZE32(chk->send_size);
+ return;
+}
int
sctp_send_str_reset_req(struct sctp_tcb *stcb,
int number_entries, uint16_t * list,
- uint8_t send_out_req, uint32_t resp_seq,
+ uint8_t send_out_req,
+ uint32_t resp_seq,
uint8_t send_in_req,
- uint8_t send_tsn_req)
+ uint8_t send_tsn_req,
+ uint8_t add_stream,
+ uint16_t adding
+)
{
struct sctp_association *asoc;
@@ -13361,7 +13395,8 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EBUSY);
return (EBUSY);
}
- if ((send_out_req == 0) && (send_in_req == 0) && (send_tsn_req == 0)) {
+ if ((send_out_req == 0) && (send_in_req == 0) && (send_tsn_req == 0) &&
+ (add_stream == 0)) {
/* nothing to do */
SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTP_OUTPUT, EINVAL);
return (EINVAL);
@@ -13412,6 +13447,11 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
seq++;
asoc->stream_reset_outstanding++;
}
+ if (add_stream) {
+ sctp_add_a_stream(chk, seq, adding);
+ seq++;
+ asoc->stream_reset_outstanding++;
+ }
if (send_in_req) {
sctp_add_stream_reset_in(chk, number_entries, list, seq);
asoc->stream_reset_outstanding++;
@@ -14432,7 +14472,7 @@ sctp_lower_sosend(struct socket *so,
if (tmp_str != NULL) {
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
asoc->strmout = tmp_str;
- asoc->streamoutcnt = asoc->pre_open_streams;
+ asoc->strm_realoutsize = asoc->streamoutcnt = asoc->pre_open_streams;
} else {
asoc->pre_open_streams = asoc->streamoutcnt;
}
@@ -15016,9 +15056,6 @@ skip_preblock:
(stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk)));
if (net->flight_size > net->cwnd) {
queue_only = 1;
- SCTP_STAT_INCR(sctps_send_burst_avoid);
- } else if (net->flight_size > net->cwnd) {
- queue_only = 1;
SCTP_STAT_INCR(sctps_send_cwnd_avoid);
} else {
queue_only = 0;
@@ -15293,9 +15330,6 @@ skip_out_eof:
(stcb->asoc.stream_queue_cnt * sizeof(struct sctp_data_chunk)));
if (net->flight_size > net->cwnd) {
queue_only = 1;
- SCTP_STAT_INCR(sctps_send_burst_avoid);
- } else if (net->flight_size > net->cwnd) {
- queue_only = 1;
SCTP_STAT_INCR(sctps_send_cwnd_avoid);
} else {
queue_only = 0;
OpenPOWER on IntegriCloud