summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_indata.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2010-06-08 03:39:31 +0000
committerrrs <rrs@FreeBSD.org>2010-06-08 03:39:31 +0000
commit8bbbdc4764a3fb1583b5f25c105e7e73278c5f29 (patch)
tree3d5302792225a12b4b0d7b8c8e993b5e2a136516 /sys/netinet/sctp_indata.c
parent7aeb20c5a4418da6b46558df2d4d65bd8c1d3475 (diff)
downloadFreeBSD-src-8bbbdc4764a3fb1583b5f25c105e7e73278c5f29.zip
FreeBSD-src-8bbbdc4764a3fb1583b5f25c105e7e73278c5f29.tar.gz
2 Bugs:
1) Only use both mapping arrays when NR sack is off. This way we can hold off moving the cumack (not the best but workable) when NR-sack is on. 2) We must make sure to just return on the move of the bit to the NR array if the cum-ack as already went past the TSN. This prevents marking a bit behind the array and hitting the invariant code that panic's us. MFC after: 1 week
Diffstat (limited to 'sys/netinet/sctp_indata.c')
-rw-r--r--sys/netinet/sctp_indata.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 83ab59f..c04b25a 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -289,12 +289,20 @@ sctp_build_ctl_cchunk(struct sctp_inpcb *inp,
static void
sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
{
- uint32_t gap, i;
+ uint32_t gap, i, cumackp1;
int fnd = 0;
if (SCTP_BASE_SYSCTL(sctp_do_drain) == 0) {
return;
}
+ cumackp1 = asoc->cumulative_tsn + 1;
+ if (compare_with_wrap(cumackp1, tsn, MAX_TSN)) {
+ /*
+ * this tsn is behind the cum ack and thus we don't need to
+ * worry about it being moved from one to the other.
+ */
+ return;
+ }
SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
if (!SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap)) {
printf("gap:%x tsn:%x\n", gap, tsn);
@@ -2259,6 +2267,7 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
uint8_t val;
int slide_from, slide_end, lgap, distance;
uint32_t old_cumack, old_base, old_highest, highest_tsn;
+ int type;
asoc = &stcb->asoc;
at = 0;
@@ -2270,9 +2279,18 @@ sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
* We could probably improve this a small bit by calculating the
* offset of the current cum-ack as the starting point.
*/
+ if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) &&
+ stcb->asoc.peer_supports_nr_sack) {
+ type = SCTP_NR_SELECTIVE_ACK;
+ } else {
+ type = SCTP_SELECTIVE_ACK;
+ }
at = 0;
for (slide_from = 0; slide_from < stcb->asoc.mapping_array_size; slide_from++) {
- val = asoc->nr_mapping_array[slide_from] | asoc->mapping_array[slide_from];
+ if (type == SCTP_NR_SELECTIVE_ACK)
+ val = asoc->nr_mapping_array[slide_from];
+ else
+ val = asoc->nr_mapping_array[slide_from] | asoc->mapping_array[slide_from];
if (val == 0xff) {
at += 8;
} else {
OpenPOWER on IntegriCloud