svn commit: r301666 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Wed Jun 8 17:57:43 UTC 2016
Author: tuexen
Date: Wed Jun 8 17:57:42 2016
New Revision: 301666
URL: https://svnweb.freebsd.org/changeset/base/301666
Log:
Use a separate MID counter for ordered und unordered messages for each
outgoing stream.
Thanks to Jens Hoelscher for reporting the issue.
MFC after: 1 week
Modified:
head/sys/netinet/sctp_input.c
head/sys/netinet/sctp_output.c
head/sys/netinet/sctp_structs.h
head/sys/netinet/sctputil.c
Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c Wed Jun 8 17:51:21 2016 (r301665)
+++ head/sys/netinet/sctp_input.c Wed Jun 8 17:57:42 2016 (r301666)
@@ -1969,7 +1969,8 @@ sctp_process_cookie_existing(struct mbuf
asoc->strmout[i].abandoned_unsent[0] = 0;
#endif
stcb->asoc.strmout[i].stream_no = i;
- stcb->asoc.strmout[i].next_sequence_send = 0;
+ stcb->asoc.strmout[i].next_mid_ordered = 0;
+ stcb->asoc.strmout[i].next_mid_unordered = 0;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
}
/* process the INIT-ACK info (my info) */
@@ -3521,11 +3522,13 @@ sctp_reset_out_streams(struct sctp_tcb *
/* no such stream */
continue;
}
- stcb->asoc.strmout[temp].next_sequence_send = 0;
+ stcb->asoc.strmout[temp].next_mid_ordered = 0;
+ stcb->asoc.strmout[temp].next_mid_unordered = 0;
}
} else {
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
- stcb->asoc.strmout[i].next_sequence_send = 0;
+ stcb->asoc.strmout[i].next_mid_ordered = 0;
+ stcb->asoc.strmout[i].next_mid_unordered = 0;
}
}
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c Wed Jun 8 17:51:21 2016 (r301665)
+++ head/sys/netinet/sctp_output.c Wed Jun 8 17:57:42 2016 (r301666)
@@ -3643,7 +3643,8 @@ sctp_process_cmsgs_for_init(struct sctp_
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
stcb->asoc.strmout[i].chunks_on_queues = 0;
- stcb->asoc.strmout[i].next_sequence_send = 0;
+ stcb->asoc.strmout[i].next_mid_ordered = 0;
+ stcb->asoc.strmout[i].next_mid_unordered = 0;
#if defined(SCTP_DETAILED_STR_STATS)
for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) {
stcb->asoc.strmout[i].abandoned_sent[j] = 0;
@@ -6381,7 +6382,6 @@ sctp_msg_append(struct sctp_tcb *stcb,
sp->ppid = srcv->sinfo_ppid;
sp->context = srcv->sinfo_context;
sp->fsn = 0;
- sp->msg_id = atomic_fetchadd_int(&stcb->asoc.assoc_msg_id, 1);
if (sp->sinfo_flags & SCTP_ADDR_OVER) {
sp->net = net;
atomic_add_int(&sp->net->ref_count, 1);
@@ -7568,10 +7568,28 @@ dont_do_it:
chk->asoc = &stcb->asoc;
chk->pad_inplace = 0;
chk->no_fr_allowed = 0;
- chk->rec.data.stream_seq = strq->next_sequence_send;
- if ((rcv_flags & SCTP_DATA_LAST_FRAG) &&
- !(rcv_flags & SCTP_DATA_UNORDERED)) {
- strq->next_sequence_send++;
+ if (stcb->asoc.idata_supported == 0) {
+ if (rcv_flags & SCTP_DATA_UNORDERED) {
+ /* Just use 0. The receiver ignores the values. */
+ chk->rec.data.stream_seq = 0;
+ } else {
+ chk->rec.data.stream_seq = strq->next_mid_ordered;
+ if (rcv_flags & SCTP_DATA_LAST_FRAG) {
+ strq->next_mid_ordered++;
+ }
+ }
+ } else {
+ if (rcv_flags & SCTP_DATA_UNORDERED) {
+ chk->rec.data.stream_seq = strq->next_mid_unordered;
+ if (rcv_flags & SCTP_DATA_LAST_FRAG) {
+ strq->next_mid_unordered++;
+ }
+ } else {
+ chk->rec.data.stream_seq = strq->next_mid_ordered;
+ if (rcv_flags & SCTP_DATA_LAST_FRAG) {
+ strq->next_mid_ordered++;
+ }
+ }
}
chk->rec.data.stream_number = sp->stream;
chk->rec.data.payloadtype = sp->ppid;
@@ -7630,7 +7648,7 @@ dont_do_it:
dchkh->ch.chunk_flags = chk->rec.data.rcv_flags;
dchkh->dp.tsn = htonl(chk->rec.data.TSN_seq);
dchkh->dp.stream_id = htons((strq->stream_no & 0x0000ffff));
- dchkh->dp.stream_sequence = htons(chk->rec.data.stream_seq);
+ dchkh->dp.stream_sequence = htons((uint16_t) chk->rec.data.stream_seq);
dchkh->dp.protocol_id = chk->rec.data.payloadtype;
dchkh->ch.chunk_length = htons(chk->send_size);
} else {
@@ -7638,9 +7656,8 @@ dont_do_it:
ndchkh->ch.chunk_flags = chk->rec.data.rcv_flags;
ndchkh->dp.tsn = htonl(chk->rec.data.TSN_seq);
ndchkh->dp.stream_id = htons(strq->stream_no);
- /* WHAT DO WE DO HERE??? */
ndchkh->dp.reserved = htons(0);
- ndchkh->dp.msg_id = htonl(sp->msg_id);
+ ndchkh->dp.msg_id = htonl(chk->rec.data.stream_seq);
if (sp->fsn == 0)
ndchkh->dp.ppid_fsn.protocol_id = chk->rec.data.payloadtype;
else
@@ -12235,7 +12252,8 @@ sctp_send_str_reset_req(struct sctp_tcb
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
stcb->asoc.strmout[i].chunks_on_queues = oldstream[i].chunks_on_queues;
- stcb->asoc.strmout[i].next_sequence_send = oldstream[i].next_sequence_send;
+ stcb->asoc.strmout[i].next_mid_ordered = oldstream[i].next_mid_ordered;
+ stcb->asoc.strmout[i].next_mid_unordered = oldstream[i].next_mid_unordered;
stcb->asoc.strmout[i].last_msg_incomplete = oldstream[i].last_msg_incomplete;
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].state = oldstream[i].state;
@@ -12267,7 +12285,8 @@ sctp_send_str_reset_req(struct sctp_tcb
stcb->asoc.strmout[i].abandoned_sent[0] = 0;
stcb->asoc.strmout[i].abandoned_unsent[0] = 0;
#endif
- stcb->asoc.strmout[i].next_sequence_send = 0x0;
+ stcb->asoc.strmout[i].next_mid_ordered = 0;
+ stcb->asoc.strmout[i].next_mid_unordered = 0;
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], NULL);
@@ -12425,7 +12444,6 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
sp->ppid = srcv->sinfo_ppid;
sp->context = srcv->sinfo_context;
sp->fsn = 0;
- sp->msg_id = atomic_fetchadd_int(&stcb->asoc.assoc_msg_id, 1);
(void)SCTP_GETTIME_TIMEVAL(&sp->ts);
sp->stream = srcv->sinfo_stream;
Modified: head/sys/netinet/sctp_structs.h
==============================================================================
--- head/sys/netinet/sctp_structs.h Wed Jun 8 17:51:21 2016 (r301665)
+++ head/sys/netinet/sctp_structs.h Wed Jun 8 17:57:42 2016 (r301666)
@@ -522,7 +522,6 @@ struct sctp_stream_queue_pending {
TAILQ_ENTRY(sctp_stream_queue_pending) next;
TAILQ_ENTRY(sctp_stream_queue_pending) ss_next;
uint32_t fsn;
- uint32_t msg_id;
uint32_t length;
uint32_t timetolive;
uint32_t ppid;
@@ -619,7 +618,12 @@ struct sctp_stream_out {
uint32_t abandoned_unsent[1];
uint32_t abandoned_sent[1];
#endif
- uint32_t next_sequence_send; /* next one I expect to send out */
+ /*
+ * For associations using DATA chunks, the lower 16-bit of
+ * next_mid_ordered are used as the next SSN.
+ */
+ uint32_t next_mid_ordered;
+ uint32_t next_mid_unordered;
uint16_t stream_no;
uint8_t last_msg_incomplete;
uint8_t state;
@@ -893,7 +897,6 @@ struct sctp_association {
uint32_t stream_scheduling_module;
uint32_t vrf_id;
- uint32_t assoc_msg_id;
uint32_t cookie_preserve_req;
/* ASCONF next seq I am sending out, inits at init-tsn */
uint32_t asconf_seq_out;
Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c Wed Jun 8 17:51:21 2016 (r301665)
+++ head/sys/netinet/sctputil.c Wed Jun 8 17:57:42 2016 (r301666)
@@ -1123,7 +1123,8 @@ sctp_init_asoc(struct sctp_inpcb *inp, s
* that were dropped must be notified to the upper layer as
* failed to send.
*/
- asoc->strmout[i].next_sequence_send = 0x0;
+ asoc->strmout[i].next_mid_ordered = 0;
+ asoc->strmout[i].next_mid_unordered = 0;
TAILQ_INIT(&asoc->strmout[i].outqueue);
asoc->strmout[i].chunks_on_queues = 0;
#if defined(SCTP_DETAILED_STR_STATS)
@@ -4836,10 +4837,22 @@ sctp_release_pr_sctp_chunk(struct sctp_t
goto oh_well;
}
memset(chk, 0, sizeof(*chk));
- chk->rec.data.rcv_flags = SCTP_DATA_LAST_FRAG;
+ chk->rec.data.rcv_flags = 0;
chk->sent = SCTP_FORWARD_TSN_SKIP;
chk->asoc = &stcb->asoc;
- chk->rec.data.stream_seq = strq->next_sequence_send;
+ if (stcb->asoc.idata_supported == 0) {
+ if (sp->sinfo_flags & SCTP_UNORDERED) {
+ chk->rec.data.stream_seq = 0;
+ } else {
+ chk->rec.data.stream_seq = strq->next_mid_ordered;
+ }
+ } else {
+ if (sp->sinfo_flags & SCTP_UNORDERED) {
+ chk->rec.data.stream_seq = strq->next_mid_unordered;
+ } else {
+ chk->rec.data.stream_seq = strq->next_mid_ordered;
+ }
+ }
chk->rec.data.stream_number = sp->stream;
chk->rec.data.payloadtype = sp->ppid;
chk->rec.data.context = sp->context;
@@ -4850,10 +4863,19 @@ sctp_release_pr_sctp_chunk(struct sctp_t
TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
stcb->asoc.sent_queue_cnt++;
stcb->asoc.pr_sctp_cnt++;
+ }
+ chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
+ if (stcb->asoc.idata_supported == 0) {
+ if ((sp->sinfo_flags & SCTP_UNORDERED) == 0) {
+ strq->next_mid_ordered++;
+ }
} else {
- chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
+ if (sp->sinfo_flags & SCTP_UNORDERED) {
+ strq->next_mid_unordered++;
+ } else {
+ strq->next_mid_ordered++;
+ }
}
- strq->next_sequence_send++;
oh_well:
if (sp->data) {
/*
More information about the svn-src-head
mailing list