diff options
author | tuexen <tuexen@FreeBSD.org> | 2010-12-22 17:59:38 +0000 |
---|---|---|
committer | tuexen <tuexen@FreeBSD.org> | 2010-12-22 17:59:38 +0000 |
commit | c17bd2abe06cae94dd7c76d82b5484b79b746af2 (patch) | |
tree | 80303e0e707760d51274d8c8dfdfdf5f3083faab /sys/netinet/sctp_indata.c | |
parent | aa42d9f67fb8820598ba9b01c9f9de9a6525eba1 (diff) | |
download | FreeBSD-src-c17bd2abe06cae94dd7c76d82b5484b79b746af2.zip FreeBSD-src-c17bd2abe06cae94dd7c76d82b5484b79b746af2.tar.gz |
Improve plausibility check in sctp_handle_sack().
Allow cmt_on_off to support values 0 (no CMT), 1 (CMT), and 2 (CMT/RP).
MFC after: 3 months.
Diffstat (limited to 'sys/netinet/sctp_indata.c')
-rw-r--r-- | sys/netinet/sctp_indata.c | 50 |
1 files changed, 21 insertions, 29 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c index 3300c97..b518a5c 100644 --- a/sys/netinet/sctp_indata.c +++ b/sys/netinet/sctp_indata.c @@ -2476,7 +2476,7 @@ sctp_sack_check(struct sctp_tcb *stcb, int was_a_gap, int *abort_flag) (stcb->asoc.data_pkts_seen >= stcb->asoc.sack_freq) /* hit limit of pkts */ ) { - if ((stcb->asoc.sctp_cmt_on_off == 1) && + if ((stcb->asoc.sctp_cmt_on_off > 0) && (SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) && (stcb->asoc.send_sack == 0) && (stcb->asoc.numduptsns == 0) && @@ -3242,7 +3242,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, } /* CMT DAC algo: finding out if SACK is a mixed SACK */ - if ((asoc->sctp_cmt_on_off == 1) && + if ((asoc->sctp_cmt_on_off > 0) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) { TAILQ_FOREACH(net, &asoc->nets, sctp_next) { if (net->saw_newack) @@ -3353,7 +3353,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, if (tp1->sent < SCTP_DATAGRAM_RESEND) { tp1->sent++; } - if ((asoc->sctp_cmt_on_off == 1) && + if ((asoc->sctp_cmt_on_off > 0) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) { /* * CMT DAC algorithm: If SACK flag is set to @@ -3419,7 +3419,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, tp1->sent++; } strike_flag = 1; - if ((asoc->sctp_cmt_on_off == 1) && + if ((asoc->sctp_cmt_on_off > 0) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) { /* * CMT DAC algorithm: If @@ -3480,7 +3480,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, if (tp1->sent < SCTP_DATAGRAM_RESEND) { tp1->sent++; } - if ((asoc->sctp_cmt_on_off == 1) && + if ((asoc->sctp_cmt_on_off > 0) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac)) { /* * CMT DAC algorithm: If SACK flag is set to @@ -3560,7 +3560,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc, SCTP_STAT_INCR(sctps_sendmultfastretrans); } sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); - if (asoc->sctp_cmt_on_off == 1) { + if (asoc->sctp_cmt_on_off > 0) { /* * CMT: Using RTX_SSTHRESH policy for CMT. * If CMT is being used, then pick dest with @@ -4776,7 +4776,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, /*******************************************/ /* cancel ALL T3-send timer if accum moved */ /*******************************************/ - if (asoc->sctp_cmt_on_off == 1) { + if (asoc->sctp_cmt_on_off > 0) { TAILQ_FOREACH(net, &asoc->nets, sctp_next) { if (net->new_pseudo_cumack) sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, @@ -4797,10 +4797,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, /********************************************/ asoc->last_acked_seq = cum_ack; - tp1 = TAILQ_FIRST(&asoc->sent_queue); - if (tp1 == NULL) - goto done_with_it; - do { + TAILQ_FOREACH_SAFE(tp1, &asoc->sent_queue, sctp_next, tp2) { if (compare_with_wrap(tp1->rec.data.TSN_seq, cum_ack, MAX_TSN)) { break; @@ -4810,26 +4807,17 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, printf("Warning, tp1->sent == %d and its now acked?\n", tp1->sent); } - tp2 = TAILQ_NEXT(tp1, sctp_next); TAILQ_REMOVE(&asoc->sent_queue, tp1, sctp_next); if (tp1->pr_sctp_on) { if (asoc->pr_sctp_cnt != 0) asoc->pr_sctp_cnt--; } - if (TAILQ_EMPTY(&asoc->sent_queue) && - (asoc->total_flight > 0)) { -#ifdef INVARIANTS - panic("Warning flight size is postive and should be 0"); -#else - SCTP_PRINTF("Warning flight size incorrect should be 0 is %d\n", - asoc->total_flight); -#endif - asoc->total_flight = 0; - } + asoc->sent_queue_cnt--; if (tp1->data) { /* sa_ignore NO_NULL_CHK */ sctp_free_bufspace(stcb, asoc, tp1, 1); sctp_m_freem(tp1->data); + tp1->data = NULL; if (asoc->peer_supports_prsctp && PR_SCTP_BUF_ENABLED(tp1->flags)) { asoc->sent_queue_cnt_removeable--; } @@ -4842,14 +4830,18 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, 0, SCTP_LOG_FREE_SENT); } - tp1->data = NULL; - asoc->sent_queue_cnt--; sctp_free_a_chunk(stcb, tp1); wake_him++; - tp1 = tp2; - } while (tp1 != NULL); - -done_with_it: + } + if (TAILQ_EMPTY(&asoc->sent_queue) && (asoc->total_flight > 0)) { +#ifdef INVARIANTS + panic("Warning flight size is postive and should be 0"); +#else + SCTP_PRINTF("Warning flight size incorrect should be 0 is %d\n", + asoc->total_flight); +#endif + asoc->total_flight = 0; + } /* sa_ignore NO_NULL_CHK */ if ((wake_him) && (stcb->sctp_socket)) { #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) @@ -5077,7 +5069,7 @@ done_with_it: * to be done. Setting this_sack_lowest_newack to the cum_ack will * automatically ensure that. */ - if ((asoc->sctp_cmt_on_off == 1) && + if ((asoc->sctp_cmt_on_off > 0) && SCTP_BASE_SYSCTL(sctp_cmt_use_dac) && (cmt_dac_flag == 0)) { this_sack_lowest_newack = cum_ack; |