summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2012-11-05 20:55:17 +0000
committertuexen <tuexen@FreeBSD.org>2012-11-05 20:55:17 +0000
commitf1eb961773e4618810cc75dcd1b47aae2e786795 (patch)
tree326841d3a775ee9a3bdb9edd374c7f6a09e68e3b /sys
parent07e3d575da067a9d735ea8bbbb37023970e9f97c (diff)
downloadFreeBSD-src-f1eb961773e4618810cc75dcd1b47aae2e786795.zip
FreeBSD-src-f1eb961773e4618810cc75dcd1b47aae2e786795.tar.gz
Move from early SSN assignment to late SSN assignment.
This doesn't change functionality, but makes upcoming change much easier. Developed with rrs@ at the IETF 85. MFC after: 1 week
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/sctp_input.c6
-rw-r--r--sys/netinet/sctp_output.c27
-rw-r--r--sys/netinet/sctp_structs.h3
-rw-r--r--sys/netinet/sctputil.c126
4 files changed, 71 insertions, 91 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 3be64b1..2371ecb 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -1942,7 +1942,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_NOT_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].stream_no = i;
- stcb->asoc.strmout[i].next_sequence_sent = 0;
+ stcb->asoc.strmout[i].next_sequence_send = 0;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
}
/* process the INIT-ACK info (my info) */
@@ -3489,7 +3489,7 @@ sctp_reset_out_streams(struct sctp_tcb *stcb, int number_entries, uint16_t * lis
if (number_entries == 0) {
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
- stcb->asoc.strmout[i].next_sequence_sent = 0;
+ stcb->asoc.strmout[i].next_sequence_send = 0;
}
} else if (number_entries) {
for (i = 0; i < number_entries; i++) {
@@ -3500,7 +3500,7 @@ sctp_reset_out_streams(struct sctp_tcb *stcb, int number_entries, uint16_t * lis
/* no such stream */
continue;
}
- stcb->asoc.strmout[temp].next_sequence_sent = 0;
+ stcb->asoc.strmout[temp].next_sequence_send = 0;
}
}
sctp_ulp_notify(SCTP_NOTIFY_STR_RESET_SEND, stcb, number_entries, (void *)list, SCTP_SO_NOT_LOCKED);
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index 63be5ee..cc97fd1 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -3513,7 +3513,7 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er
stcb->asoc.pre_open_streams = stcb->asoc.streamoutcnt;
}
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
- stcb->asoc.strmout[i].next_sequence_sent = 0;
+ stcb->asoc.strmout[i].next_sequence_send = 0;
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
@@ -6194,7 +6194,6 @@ sctp_msg_append(struct sctp_tcb *stcb,
sp->timetolive = srcv->sinfo_timetolive;
sp->ppid = srcv->sinfo_ppid;
sp->context = srcv->sinfo_context;
- sp->strseq = 0;
if (sp->sinfo_flags & SCTP_ADDR_OVER) {
sp->net = net;
atomic_add_int(&sp->net->ref_count, 1);
@@ -6235,10 +6234,6 @@ sctp_msg_append(struct sctp_tcb *stcb,
sctp_snd_sb_alloc(stcb, sp->length);
atomic_add_int(&stcb->asoc.stream_queue_cnt, 1);
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
- if ((srcv->sinfo_flags & SCTP_UNORDERED) == 0) {
- sp->strseq = strm->next_sequence_sent;
- strm->next_sequence_sent++;
- }
stcb->asoc.ss_functions.sctp_ss_add_to_stream(stcb, &stcb->asoc, strm, sp, 1);
m = NULL;
if (hold_stcb_lock == 0) {
@@ -7379,7 +7374,10 @@ dont_do_it:
chk->asoc = &stcb->asoc;
chk->pad_inplace = 0;
chk->no_fr_allowed = 0;
- chk->rec.data.stream_seq = sp->strseq;
+ chk->rec.data.stream_seq = strq->next_sequence_send;
+ if (rcv_flags & SCTP_DATA_LAST_FRAG) {
+ strq->next_sequence_send++;
+ }
chk->rec.data.stream_number = sp->stream;
chk->rec.data.payloadtype = sp->ppid;
chk->rec.data.context = sp->context;
@@ -11794,7 +11792,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
stcb->asoc.ss_functions.sctp_ss_clear(stcb, &stcb->asoc, 0, 1);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
- stcb->asoc.strmout[i].next_sequence_sent = oldstream[i].next_sequence_sent;
+ stcb->asoc.strmout[i].next_sequence_send = oldstream[i].next_sequence_send;
stcb->asoc.strmout[i].last_msg_incomplete = oldstream[i].last_msg_incomplete;
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], &oldstream[i]);
@@ -11814,7 +11812,7 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb,
/* now the new streams */
stcb->asoc.ss_functions.sctp_ss_init(stcb, &stcb->asoc, 1);
for (i = stcb->asoc.streamoutcnt; i < (stcb->asoc.streamoutcnt + adding_o); i++) {
- stcb->asoc.strmout[i].next_sequence_sent = 0x0;
+ stcb->asoc.strmout[i].next_sequence_send = 0x0;
TAILQ_INIT(&stcb->asoc.strmout[i].outqueue);
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
@@ -11971,7 +11969,6 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
sp->timetolive = srcv->sinfo_timetolive;
sp->ppid = srcv->sinfo_ppid;
sp->context = srcv->sinfo_context;
- sp->strseq = 0;
(void)SCTP_GETTIME_TIMEVAL(&sp->ts);
sp->stream = srcv->sinfo_stream;
@@ -12724,15 +12721,7 @@ skip_preblock:
}
sctp_snd_sb_alloc(stcb, sp->length);
atomic_add_int(&asoc->stream_queue_cnt, 1);
- if ((srcv->sinfo_flags & SCTP_UNORDERED) == 0) {
- sp->strseq = strm->next_sequence_sent;
- if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_AT_SEND_2_SCTP) {
- sctp_misc_ints(SCTP_STRMOUT_LOG_ASSIGN,
- (uintptr_t) stcb, sp->length,
- (uint32_t) ((srcv->sinfo_stream << 16) | sp->strseq), 0);
- }
- strm->next_sequence_sent++;
- } else {
+ if (srcv->sinfo_flags & SCTP_UNORDERED) {
SCTP_STAT_INCR(sctps_sends_with_unord);
}
TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
diff --git a/sys/netinet/sctp_structs.h b/sys/netinet/sctp_structs.h
index b344e91..d899ee5 100644
--- a/sys/netinet/sctp_structs.h
+++ b/sys/netinet/sctp_structs.h
@@ -517,7 +517,6 @@ struct sctp_stream_queue_pending {
uint32_t context;
uint16_t sinfo_flags;
uint16_t stream;
- uint16_t strseq;
uint16_t act_flags;
uint16_t auth_keyid;
uint8_t holds_key_ref;
@@ -590,7 +589,7 @@ struct sctp_stream_out {
struct sctp_streamhead outqueue;
union scheduling_parameters ss_params;
uint16_t stream_no;
- uint16_t next_sequence_sent; /* next one I expect to send out */
+ uint16_t next_sequence_send; /* next one I expect to send out */
uint8_t last_msg_incomplete;
};
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 77c6788..1c2dcae 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -1052,7 +1052,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
* that were dropped must be notified to the upper layer as
* failed to send.
*/
- asoc->strmout[i].next_sequence_sent = 0x0;
+ asoc->strmout[i].next_sequence_send = 0x0;
TAILQ_INIT(&asoc->strmout[i].outqueue);
asoc->strmout[i].stream_no = i;
asoc->strmout[i].last_msg_incomplete = 0;
@@ -2973,7 +2973,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
/* not exactly what the user sent in, but should be close :) */
bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
ssf->ssf_info.sinfo_stream = sp->stream;
- ssf->ssf_info.sinfo_ssn = sp->strseq;
+ ssf->ssf_info.sinfo_ssn = 0;
if (sp->some_taken) {
ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG;
} else {
@@ -4774,77 +4774,69 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
* Still no eom found. That means there is stuff left on the
* stream out queue.. yuck.
*/
- strq = &stcb->asoc.strmout[stream];
SCTP_TCB_SEND_LOCK(stcb);
- TAILQ_FOREACH(sp, &strq->outqueue, next) {
- /* FIXME: Shouldn't this be a serial number check? */
- if (sp->strseq > seq) {
- break;
- }
- /* Check if its our SEQ */
- if (sp->strseq == seq) {
- sp->discard_rest = 1;
- /*
- * We may need to put a chunk on the queue
- * that holds the TSN that would have been
- * sent with the LAST bit.
- */
+ strq = &stcb->asoc.strmout[stream];
+ sp = TAILQ_FIRST(&strq->outqueue);
+ if (sp != NULL) {
+ sp->discard_rest = 1;
+ /*
+ * We may need to put a chunk on the queue that
+ * holds the TSN that would have been sent with the
+ * LAST bit.
+ */
+ if (chk == NULL) {
+ /* Yep, we have to */
+ sctp_alloc_a_chunk(stcb, chk);
if (chk == NULL) {
- /* Yep, we have to */
- sctp_alloc_a_chunk(stcb, chk);
- if (chk == NULL) {
- /*
- * we are hosed. All we can
- * do is nothing.. which
- * will cause an abort if
- * the peer is paying
- * attention.
- */
- goto oh_well;
- }
- memset(chk, 0, sizeof(*chk));
- chk->rec.data.rcv_flags = SCTP_DATA_LAST_FRAG;
- chk->sent = SCTP_FORWARD_TSN_SKIP;
- chk->asoc = &stcb->asoc;
- chk->rec.data.stream_seq = sp->strseq;
- chk->rec.data.stream_number = sp->stream;
- chk->rec.data.payloadtype = sp->ppid;
- chk->rec.data.context = sp->context;
- chk->flags = sp->act_flags;
- if (sp->net)
- chk->whoTo = sp->net;
- else
- chk->whoTo = stcb->asoc.primary_destination;
- atomic_add_int(&chk->whoTo->ref_count, 1);
- chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
- stcb->asoc.pr_sctp_cnt++;
- chk->pr_sctp_on = 1;
- TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
- stcb->asoc.sent_queue_cnt++;
- stcb->asoc.pr_sctp_cnt++;
- } else {
- chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
- }
- oh_well:
- if (sp->data) {
/*
- * Pull any data to free up the SB
- * and allow sender to "add more"
- * while we will throw away :-)
+ * we are hosed. All we can do is
+ * nothing.. which will cause an
+ * abort if the peer is paying
+ * attention.
*/
- sctp_free_spbufspace(stcb, &stcb->asoc,
- sp);
- ret_sz += sp->length;
- do_wakeup_routine = 1;
- sp->some_taken = 1;
- sctp_m_freem(sp->data);
- sp->data = NULL;
- sp->tail_mbuf = NULL;
- sp->length = 0;
+ goto oh_well;
}
- break;
+ memset(chk, 0, sizeof(*chk));
+ chk->rec.data.rcv_flags = SCTP_DATA_LAST_FRAG;
+ chk->sent = SCTP_FORWARD_TSN_SKIP;
+ chk->asoc = &stcb->asoc;
+ chk->rec.data.stream_seq = strq->next_sequence_send;
+ chk->rec.data.stream_number = sp->stream;
+ chk->rec.data.payloadtype = sp->ppid;
+ chk->rec.data.context = sp->context;
+ chk->flags = sp->act_flags;
+ if (sp->net)
+ chk->whoTo = sp->net;
+ else
+ chk->whoTo = stcb->asoc.primary_destination;
+ atomic_add_int(&chk->whoTo->ref_count, 1);
+ chk->rec.data.TSN_seq = atomic_fetchadd_int(&stcb->asoc.sending_seq, 1);
+ stcb->asoc.pr_sctp_cnt++;
+ chk->pr_sctp_on = 1;
+ TAILQ_INSERT_TAIL(&stcb->asoc.sent_queue, chk, sctp_next);
+ stcb->asoc.sent_queue_cnt++;
+ stcb->asoc.pr_sctp_cnt++;
+ } else {
+ chk->rec.data.rcv_flags |= SCTP_DATA_LAST_FRAG;
+ }
+ strq->next_sequence_send++;
+ oh_well:
+ if (sp->data) {
+ /*
+ * Pull any data to free up the SB and allow
+ * sender to "add more" while we will throw
+ * away :-)
+ */
+ sctp_free_spbufspace(stcb, &stcb->asoc, sp);
+ ret_sz += sp->length;
+ do_wakeup_routine = 1;
+ sp->some_taken = 1;
+ sctp_m_freem(sp->data);
+ sp->data = NULL;
+ sp->tail_mbuf = NULL;
+ sp->length = 0;
}
- } /* End tailq_foreach */
+ }
SCTP_TCB_SEND_UNLOCK(stcb);
}
if (do_wakeup_routine) {
OpenPOWER on IntegriCloud