summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_timer.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-04-14 09:44:09 +0000
committerrrs <rrs@FreeBSD.org>2007-04-14 09:44:09 +0000
commitfb6f6fd9a183da8573afa302e42cdf7684785a7d (patch)
tree083a217af386adf4fcec65b47183061eed4b0685 /sys/netinet/sctp_timer.c
parent571c5243e40d0546bb093ffb58ebf6e6476cfaba (diff)
downloadFreeBSD-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.c96
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;
OpenPOWER on IntegriCloud