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
This commit is contained in:
Michael Tuexen 2012-11-05 20:55:17 +00:00
parent 7f90ab1c09
commit f3b05218ea
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242627
4 changed files with 71 additions and 91 deletions

View File

@ -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);

View File

@ -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 @@ sctp_move_to_outqueue(struct sctp_tcb *stcb,
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 @@ sctp_lower_sosend(struct socket *so,
}
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);

View File

@ -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;
};

View File

@ -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;
}
} /* End tailq_foreach */
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;
}
}
SCTP_TCB_SEND_UNLOCK(stcb);
}
if (do_wakeup_routine) {