Fix the PR-SCTP behaviour.

This is done by rrs@.

MFC after:	3 days
This commit is contained in:
Michael Tuexen 2016-07-17 13:14:51 +00:00
parent 1cecacfe73
commit 8e1b295f09
4 changed files with 20 additions and 7 deletions

View File

@ -345,6 +345,7 @@ __FBSDID("$FreeBSD$");
#define SCTP_RTT_FROM_NON_DATA 0
#define SCTP_RTT_FROM_DATA 1
#define PR_SCTP_UNORDERED_FLAG 0x0001
/* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */
#define SCTP_FIRST_MBUF_RESV 68

View File

@ -397,7 +397,7 @@ struct sctp_strseq {
struct sctp_strseq_mid {
uint16_t stream;
uint16_t reserved;
uint16_t flags;
uint32_t msg_id;
};

View File

@ -5283,10 +5283,11 @@ sctp_kick_prsctp_reorder_queue(struct sctp_tcb *stcb,
}
}
static void
sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
struct sctp_association *asoc,
uint16_t stream, uint32_t seq)
uint16_t stream, uint32_t seq, int ordered, int old)
{
struct sctp_queued_to_read *control;
struct sctp_stream_in *strm;
@ -5301,7 +5302,7 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
* queue.
*/
strm = &asoc->strmin[stream];
control = find_reasm_entry(strm, (uint32_t) seq, 0, 0);
control = find_reasm_entry(strm, (uint32_t) seq, ordered, old);
if (control == NULL) {
/* Not found */
return;
@ -5433,6 +5434,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
unsigned int num_str;
uint32_t sequence;
uint16_t stream;
uint16_t ordered, flags;
int old;
struct sctp_strseq *stseq, strseqbuf;
struct sctp_strseq_mid *stseq_m, strseqbuf_m;
@ -5458,6 +5460,12 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
}
stream = ntohs(stseq_m->stream);
sequence = ntohl(stseq_m->msg_id);
flags = ntohs(stseq_m->flags);
if (flags & PR_SCTP_UNORDERED_FLAG) {
ordered = 0;
} else {
ordered = 1;
}
} else {
stseq = (struct sctp_strseq *)sctp_m_getptr(m, offset,
sizeof(struct sctp_strseq),
@ -5468,6 +5476,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
}
stream = ntohs(stseq->stream);
sequence = (uint32_t) ntohs(stseq->sequence);
ordered = 1;
}
/* Convert */
@ -5493,7 +5502,7 @@ sctp_handle_forward_tsn(struct sctp_tcb *stcb,
asoc->fragmented_delivery_inprogress = 0;
}
strm = &asoc->strmin[stream];
sctp_flush_reassm_for_str_seq(stcb, asoc, stream, sequence);
sctp_flush_reassm_for_str_seq(stcb, asoc, stream, sequence, ordered, old);
TAILQ_FOREACH(ctl, &stcb->sctp_ep->read_queue, next) {
if ((ctl->sinfo_stream == stream) &&
(ctl->sinfo_ssn == sequence)) {

View File

@ -10383,7 +10383,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
/* no more to look at */
break;
}
if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
if ((at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) && old) {
/* We don't report these */
continue;
}
@ -10504,7 +10504,7 @@ send_forward_tsn(struct sctp_tcb *stcb,
tp1 = TAILQ_NEXT(at, sctp_next);
if (tp1 == NULL)
break;
if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED) {
if (old && (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)) {
/* We don't report these */
i--;
at = tp1;
@ -10519,8 +10519,11 @@ send_forward_tsn(struct sctp_tcb *stcb,
strseq++;
} else {
strseq_m->stream = ntohs(at->rec.data.stream_number);
strseq_m->reserved = ntohs(0);
strseq_m->msg_id = ntohl(at->rec.data.stream_seq);
if (at->rec.data.rcv_flags & SCTP_DATA_UNORDERED)
strseq_m->flags = ntohs(PR_SCTP_UNORDERED_FLAG);
else
strseq_m->flags = 0;
strseq_m++;
}
at = tp1;