diff options
author | rrs <rrs@FreeBSD.org> | 2007-04-14 09:44:09 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-04-14 09:44:09 +0000 |
commit | fb6f6fd9a183da8573afa302e42cdf7684785a7d (patch) | |
tree | 083a217af386adf4fcec65b47183061eed4b0685 /sys/netinet/sctp_timer.c | |
parent | 571c5243e40d0546bb093ffb58ebf6e6476cfaba (diff) | |
download | FreeBSD-src-fb6f6fd9a183da8573afa302e42cdf7684785a7d.zip FreeBSD-src-fb6f6fd9a183da8573afa302e42cdf7684785a7d.tar.gz |
- fix source address selection when picking an acceptable address
- name change of prefered -> preferred
- CMT fast recover code added.
- Comment fixes in CMT.
- We were not giving a reason of cant_start_asoc per socket api
if we failed to get init/or/cookie to bring up an assoc. Change
so we don't just give a generic "comm lost" but look at actual
states of dying assoc.
- change "crc32" arguments to "crc32c" to silence strict/noisy
compiler warnings when crc32() is also declared
- A few minor tweaks to get the portable stuff truely portable
for sctp6_usrreq.c :-D
- one-2-one style vrf match problem.
- window recovery would leave chks marked for retran
during window probes on the sent queue. This would then
cause an out-of-order problem and assure that the flight
size "problem" would occur.
- Solves a flight size logging issue that caused rwnd
overruns, flight size off as well as false retransmissions.g
- Macroize the up and down of flight size.
- Fix a ECNE bug in its counting.
- The strict_sacks options was causing aborts when window probing
was active, fix to make strict sacks a bit smarter about what
the next unsent TSN is.
- Fixes a one-2-one wakeup bug found by Martin Kulas.
- If-defed out form, Andre's copy routines pending his
commit of at least m_last().. need to adjust for 6.2 as
well.. since m_last won't exist.
Reviewed by: gnn
Diffstat (limited to 'sys/netinet/sctp_timer.c')
-rw-r--r-- | sys/netinet/sctp_timer.c | 96 |
1 files changed, 54 insertions, 42 deletions
diff --git a/sys/netinet/sctp_timer.c b/sys/netinet/sctp_timer.c index 05865a7..57ad30d 100644 --- a/sys/netinet/sctp_timer.c +++ b/sys/netinet/sctp_timer.c @@ -460,9 +460,9 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, struct sctp_nets *lnets; struct timeval now, min_wait, tv; int cur_rtt; - int orig_rwnd, audit_tf, num_mk, fir; + int audit_tf, num_mk, fir; unsigned int cnt_mk; - uint32_t orig_flight; + uint32_t orig_flight, orig_tf; uint32_t tsnlast, tsnfirst; /* @@ -524,8 +524,9 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, * Our rwnd will be incorrect here since we are not adding back the * cnt * mbuf but we will fix that down below. */ - orig_rwnd = stcb->asoc.peers_rwnd; orig_flight = net->flight_size; + orig_tf = stcb->asoc.total_flight; + net->fast_retran_ip = 0; /* Now on to each chunk */ num_mk = cnt_mk = 0; @@ -617,7 +618,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, } continue; } - if (chk->sent != SCTP_DATAGRAM_RESEND) { + if (chk->sent < SCTP_DATAGRAM_RESEND) { sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt); num_mk++; if (fir == 0) { @@ -630,33 +631,27 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, 0, SCTP_FR_T3_MARKED); #endif - } - if (stcb->asoc.total_flight_count > 0) - stcb->asoc.total_flight_count--; - if (chk->rec.data.chunk_was_revoked) { - /* deflate the cwnd */ - chk->whoTo->cwnd -= chk->book_size; - chk->rec.data.chunk_was_revoked = 0; + if (chk->rec.data.chunk_was_revoked) { + /* deflate the cwnd */ + chk->whoTo->cwnd -= chk->book_size; + chk->rec.data.chunk_was_revoked = 0; + } + net->marked_retrans++; + stcb->asoc.marked_retrans++; +#ifdef SCTP_FLIGHT_LOGGING + sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN_RSND_TO, + chk->whoTo->flight_size, + chk->book_size, + (uintptr_t) chk->whoTo, + chk->rec.data.TSN_seq); +#endif + sctp_flight_size_decrease(chk); + sctp_total_flight_decrease(stcb, chk); + stcb->asoc.peers_rwnd += chk->send_size; + stcb->asoc.peers_rwnd += sctp_peer_chunk_oh; } chk->sent = SCTP_DATAGRAM_RESEND; SCTP_STAT_INCR(sctps_markedretrans); - net->marked_retrans++; - stcb->asoc.marked_retrans++; -#ifdef SCTP_FLIGHT_LOGGING - sctp_misc_ints(SCTP_FLIGHT_LOG_DOWN, - chk->whoTo->flight_size, - chk->book_size, - (uintptr_t) stcb, - chk->rec.data.TSN_seq); -#endif - - if (net->flight_size >= chk->book_size) - net->flight_size -= chk->book_size; - else - net->flight_size = 0; - - stcb->asoc.peers_rwnd += chk->send_size; - stcb->asoc.peers_rwnd += sctp_peer_chunk_oh; /* reset the TSN for striking and other FR stuff */ chk->rec.data.doing_fast_retransmit = 0; @@ -686,18 +681,13 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, cnt_mk++; } } + if ((orig_flight - net->flight_size) != (orig_tf - stcb->asoc.total_flight)) { + /* we did not subtract the same things? */ + audit_tf = 1; + } #if defined(SCTP_FR_LOGGING) || defined(SCTP_EARLYFR_LOGGING) sctp_log_fr(tsnfirst, tsnlast, num_mk, SCTP_FR_T3_TIMEOUT); #endif - - if (stcb->asoc.total_flight >= (orig_flight - net->flight_size)) { - stcb->asoc.total_flight -= (orig_flight - net->flight_size); - } else { - stcb->asoc.total_flight = 0; - stcb->asoc.total_flight_count = 0; - audit_tf = 1; - } - #ifdef SCTP_DEBUG if (sctp_debug_on & SCTP_DEBUG_TIMER1) { if (num_mk) { @@ -766,12 +756,12 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb, sctp_misc_ints(SCTP_FLIGHT_LOG_UP, chk->whoTo->flight_size, chk->book_size, - (uintptr_t) stcb, + (uintptr_t) chk->whoTo, chk->rec.data.TSN_seq); #endif - stcb->asoc.total_flight += chk->book_size; - chk->whoTo->flight_size += chk->book_size; - stcb->asoc.total_flight_count++; + + sctp_flight_size_increase(chk); + sctp_total_flight_increase(stcb, chk); } } } @@ -865,7 +855,29 @@ sctp_t3rxt_timer(struct sctp_inpcb *inp, } else { win_probe = 0; } - alt = sctp_find_alternate_net(stcb, net, 0); + + if (sctp_cmt_on_off) { + /* + * CMT: Using RTX_SSTHRESH policy for CMT. If CMT is being + * used, then pick dest with largest ssthresh for any + * retransmission. + */ + alt = net; + alt = sctp_find_alternate_net(stcb, alt, 1); + /* + * CUCv2: If a different dest is picked for the + * retransmission, then new (rtx-)pseudo_cumack needs to be + * tracked for orig dest. Let CUCv2 track new (rtx-) + * pseudo-cumack always. + */ + net->find_pseudo_cumack = 1; + net->find_rtx_pseudo_cumack = 1; + + } else { /* CMT is OFF */ + + alt = sctp_find_alternate_net(stcb, net, 0); + } + sctp_mark_all_for_resend(stcb, net, alt, win_probe, &num_mk); /* FR Loss recovery just ended with the T3. */ stcb->asoc.fast_retran_loss_recovery = 0; |