summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctp_indata.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2011-03-08 11:58:25 +0000
committerrrs <rrs@FreeBSD.org>2011-03-08 11:58:25 +0000
commit1188e1f085e1f0d4b8ae9fe06955b2602b3db10e (patch)
tree58b9da37b248f4b570b6759db99b2fc405f9a00c /sys/netinet/sctp_indata.c
parent4d0733e0f8bd37f600ca86b0f1323a24ed9c7fae (diff)
downloadFreeBSD-src-1188e1f085e1f0d4b8ae9fe06955b2602b3db10e.zip
FreeBSD-src-1188e1f085e1f0d4b8ae9fe06955b2602b3db10e.tar.gz
Tunes and fixes the new DC-CC to seem to hit the
right mix. Still may need some tweaks but it appears to almost not give away too much to an RFC2581 flow, but can really minimize the amount of buffers used in the net. MFC after: 3 months
Diffstat (limited to 'sys/netinet/sctp_indata.c')
-rw-r--r--sys/netinet/sctp_indata.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index 1ec465e..6ea4669 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -2817,7 +2817,7 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
int *num_frs,
uint32_t * biggest_newly_acked_tsn,
uint32_t * this_sack_lowest_newack,
- int *ecn_seg_sums)
+ int *ecn_seg_sums, int *rto_ok)
{
struct sctp_tmit_chunk *tp1;
unsigned int theTSN;
@@ -2956,13 +2956,19 @@ sctp_process_segment_range(struct sctp_tcb *stcb, struct sctp_tmit_chunk **p_tp1
* update RTO too ?
*/
if (tp1->do_rtt) {
- tp1->whoTo->RTO =
- sctp_calculate_rto(stcb,
- &stcb->asoc,
- tp1->whoTo,
- &tp1->sent_rcv_time,
- sctp_align_safe_nocopy,
- SCTP_DETERMINE_LL_OK);
+ if (*rto_ok) {
+ tp1->whoTo->RTO =
+ sctp_calculate_rto(stcb,
+ &stcb->asoc,
+ tp1->whoTo,
+ &tp1->sent_rcv_time,
+ sctp_align_safe_nocopy,
+ SCTP_RTT_FROM_DATA);
+ *rto_ok = 0;
+ }
+ if (tp1->whoTo->rto_needed == 0) {
+ tp1->whoTo->rto_needed = 1;
+ }
tp1->do_rtt = 0;
}
}
@@ -3033,7 +3039,8 @@ static int
sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct sctp_association *asoc,
uint32_t last_tsn, uint32_t * biggest_tsn_acked,
uint32_t * biggest_newly_acked_tsn, uint32_t * this_sack_lowest_newack,
- int num_seg, int num_nr_seg, int *ecn_seg_sums)
+ int num_seg, int num_nr_seg, int *ecn_seg_sums,
+ int *rto_ok)
{
struct sctp_gap_ack_block *frag, block;
struct sctp_tmit_chunk *tp1;
@@ -3079,7 +3086,7 @@ sctp_handle_segments(struct mbuf *m, int *offset, struct sctp_tcb *stcb, struct
}
if (sctp_process_segment_range(stcb, &tp1, last_tsn, frag_strt, frag_end,
non_revocable, &num_frs, biggest_newly_acked_tsn,
- this_sack_lowest_newack, ecn_seg_sums)) {
+ this_sack_lowest_newack, ecn_seg_sums, rto_ok)) {
chunk_freed = 1;
}
prev_frag_end = frag_end;
@@ -3579,6 +3586,9 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
* this guy had a RTO calculation pending on
* it, cancel it
*/
+ if (tp1->whoTo->rto_needed == 0) {
+ tp1->whoTo->rto_needed = 1;
+ }
tp1->do_rtt = 0;
}
if (alt != tp1->whoTo) {
@@ -3775,6 +3785,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
int win_probe_recovery = 0;
int win_probe_recovered = 0;
int j, done_once = 0;
+ int rto_ok = 1;
if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_SACK_ARRIVALS_ENABLE) {
sctp_misc_ints(SCTP_SACK_LOG_EXPRESS, cumack,
@@ -3916,16 +3927,23 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
/* update RTO too? */
if (tp1->do_rtt) {
- tp1->whoTo->RTO =
- /*
- * sa_ignore
- * NO_NULL_CHK
- */
- sctp_calculate_rto(stcb,
- asoc, tp1->whoTo,
- &tp1->sent_rcv_time,
- sctp_align_safe_nocopy,
- SCTP_DETERMINE_LL_OK);
+ if (rto_ok) {
+ tp1->whoTo->RTO =
+ /*
+ * sa_ignore
+ * NO_NULL_CH
+ * K
+ */
+ sctp_calculate_rto(stcb,
+ asoc, tp1->whoTo,
+ &tp1->sent_rcv_time,
+ sctp_align_safe_nocopy,
+ SCTP_RTT_FROM_DATA);
+ rto_ok = 0;
+ }
+ if (tp1->whoTo->rto_needed == 0) {
+ tp1->whoTo->rto_needed = 1;
+ }
tp1->do_rtt = 0;
}
}
@@ -4280,6 +4298,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
struct sctp_nets *net = NULL;
int ecn_seg_sums = 0;
int done_once;
+ int rto_ok = 1;
uint8_t reneged_all = 0;
uint8_t cmt_dac_flag;
@@ -4526,12 +4545,18 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
/* update RTO too? */
if (tp1->do_rtt) {
- tp1->whoTo->RTO =
- sctp_calculate_rto(stcb,
- asoc, tp1->whoTo,
- &tp1->sent_rcv_time,
- sctp_align_safe_nocopy,
- SCTP_DETERMINE_LL_OK);
+ if (rto_ok) {
+ tp1->whoTo->RTO =
+ sctp_calculate_rto(stcb,
+ asoc, tp1->whoTo,
+ &tp1->sent_rcv_time,
+ sctp_align_safe_nocopy,
+ SCTP_RTT_FROM_DATA);
+ rto_ok = 0;
+ }
+ if (tp1->whoTo->rto_needed == 0) {
+ tp1->whoTo->rto_needed = 1;
+ }
tp1->do_rtt = 0;
}
}
@@ -4606,7 +4631,8 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
*/
if (sctp_handle_segments(m, &offset_seg, stcb, asoc, last_tsn, &biggest_tsn_acked,
&biggest_tsn_newly_acked, &this_sack_lowest_newack,
- num_seg, num_nr_seg, &ecn_seg_sums)) {
+ num_seg, num_nr_seg, &ecn_seg_sums,
+ &rto_ok)) {
wake_him++;
}
if (SCTP_BASE_SYSCTL(sctp_strict_sacks)) {
OpenPOWER on IntegriCloud