svn commit: r218186 - head/sys/netinet

Randall Stewart rrs at FreeBSD.org
Wed Feb 2 11:13:23 UTC 2011


Author: rrs
Date: Wed Feb  2 11:13:23 2011
New Revision: 218186
URL: http://svn.freebsd.org/changeset/base/218186

Log:
  1) Allow a chunk to track the cwnd it was at when sent.
  2) Add separate max-bursts for retransmit and hb. These
     are set to sysctlable values but not settable via the
     socket api. This makes sure we don't blast out HB's or
     fast-retransmits.
  3) Determine on the first data transmission on a net if
     its local-lan (by being under or over a RTT). This
     can later be used to think about different algorithms
     based on locallan vs big-i (experimental)
  4) The cwnd should NOT be allowed to grow when an ECNEcho
     is seen (TCP has this same bug). We fix this in SCTP
     so an ECNe being seen prevents an advance of cwnd.
  5) CWR's should not be sent multiple times to the
     same network, instead just updating the TSN being
     transmitted if needed.
  
  MFC after:	1 Month

Modified:
  head/sys/netinet/sctp_cc_functions.c
  head/sys/netinet/sctp_constants.h
  head/sys/netinet/sctp_indata.c
  head/sys/netinet/sctp_indata.h
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_structs.h
  head/sys/netinet/sctp_sysctl.c
  head/sys/netinet/sctp_sysctl.h
  head/sys/netinet/sctp_timer.c
  head/sys/netinet/sctputil.c
  head/sys/netinet/sctputil.h

Modified: head/sys/netinet/sctp_cc_functions.c
==============================================================================
--- head/sys/netinet/sctp_cc_functions.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_cc_functions.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -481,6 +481,7 @@ sctp_cwnd_update_after_timeout(struct sc
 	}
 }
 
+
 static void
 sctp_cwnd_update_after_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net,
     int in_window, int num_pkt_lost)

Modified: head/sys/netinet/sctp_constants.h
==============================================================================
--- head/sys/netinet/sctp_constants.h	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_constants.h	Wed Feb  2 11:13:23 2011	(r218186)
@@ -345,6 +345,16 @@ __FBSDID("$FreeBSD$");
 
 /* default max I can burst out after a fast retransmit, 0 disables it */
 #define SCTP_DEF_MAX_BURST 0
+#define SCTP_DEF_HBMAX_BURST 4
+#define SCTP_DEF_FRMAX_BURST 4
+
+/* RTO calculation flag to say if it
+ * is safe to determine local lan or not.
+ */
+#define SCTP_DETERMINE_LL_NOTOK 0
+#define SCTP_DETERMINE_LL_OK    1
+
+
 /* IP hdr (20/40) + 12+2+2 (enet) + sctp common 12 */
 #define SCTP_FIRST_MBUF_RESV 68
 /* Packet transmit states in the sent field */
@@ -947,6 +957,18 @@ __FBSDID("$FreeBSD$");
  */
 #define SCTP_TIME_WAIT 60
 
+/* How many micro seconds is the cutoff from
+ * local lan type rtt's
+ */
+ /*
+  * We allow 500us for the rtt and another 500us for the cookie processing
+  * since we measure this on the first rtt.
+  */
+#define SCTP_LOCAL_LAN_RTT 1100
+#define SCTP_LAN_UNKNOWN  0
+#define SCTP_LAN_LOCAL    1
+#define SCTP_LAN_INTERNET 2
+
 #define SCTP_SEND_BUFFER_SPLITTING 0x00000001
 #define SCTP_RECV_BUFFER_SPLITTING 0x00000002
 
@@ -994,6 +1016,7 @@ __FBSDID("$FreeBSD$");
 
 #if defined(_KERNEL)
 
+#define SCTP_GETTIME_TIMESPEC(x) (getnanouptime(x))
 #define SCTP_GETTIME_TIMEVAL(x)	(getmicrouptime(x))
 #define SCTP_GETPTIME_TIMEVAL(x)	(microuptime(x))
 #endif

Modified: head/sys/netinet/sctp_indata.c
==============================================================================
--- head/sys/netinet/sctp_indata.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_indata.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -2955,7 +2955,8 @@ sctp_process_segment_range(struct sctp_t
 								    &stcb->asoc,
 								    tp1->whoTo,
 								    &tp1->sent_rcv_time,
-								    sctp_align_safe_nocopy);
+								    sctp_align_safe_nocopy,
+								    SCTP_DETERMINE_LL_OK);
 								tp1->do_rtt = 0;
 							}
 						}
@@ -3751,7 +3752,7 @@ sctp_window_probe_recovery(struct sctp_t
 
 void
 sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
-    uint32_t rwnd, int *abort_now)
+    uint32_t rwnd, int *abort_now, int ecne_seen)
 {
 	struct sctp_nets *net;
 	struct sctp_association *asoc;
@@ -3902,7 +3903,8 @@ sctp_express_handle_sack(struct sctp_tcb
 							    sctp_calculate_rto(stcb,
 							    asoc, tp1->whoTo,
 							    &tp1->sent_rcv_time,
-							    sctp_align_safe_nocopy);
+							    sctp_align_safe_nocopy,
+							    SCTP_DETERMINE_LL_OK);
 							tp1->do_rtt = 0;
 						}
 					}
@@ -3994,7 +3996,7 @@ sctp_express_handle_sack(struct sctp_tcb
 	}
 
 	/* JRS - Use the congestion control given in the CC module */
-	if (asoc->last_acked_seq != cumack)
+	if ((asoc->last_acked_seq != cumack) && (ecne_seen == 0))
 		asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, 1, 0, 0);
 
 	asoc->last_acked_seq = cumack;
@@ -4240,7 +4242,7 @@ sctp_handle_sack(struct mbuf *m, int off
     struct sctp_tcb *stcb, struct sctp_nets *net_from,
     uint16_t num_seg, uint16_t num_nr_seg, uint16_t num_dup,
     int *abort_now, uint8_t flags,
-    uint32_t cum_ack, uint32_t rwnd)
+    uint32_t cum_ack, uint32_t rwnd, int ecne_seen)
 {
 	struct sctp_association *asoc;
 	struct sctp_tmit_chunk *tp1, *tp2;
@@ -4500,7 +4502,8 @@ sctp_handle_sack(struct mbuf *m, int off
 							    sctp_calculate_rto(stcb,
 							    asoc, tp1->whoTo,
 							    &tp1->sent_rcv_time,
-							    sctp_align_safe_nocopy);
+							    sctp_align_safe_nocopy,
+							    SCTP_DETERMINE_LL_OK);
 							tp1->do_rtt = 0;
 						}
 					}
@@ -4754,7 +4757,8 @@ sctp_handle_sack(struct mbuf *m, int off
 		asoc->saw_sack_with_nr_frags = 0;
 
 	/* JRS - Use the congestion control given in the CC module */
-	asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
+	if (ecne_seen == 0)
+		asoc->cc_functions.sctp_cwnd_update_after_sack(stcb, asoc, accum_moved, reneged_all, will_exit_fast_recovery);
 
 	if (TAILQ_EMPTY(&asoc->sent_queue)) {
 		/* nothing left in-flight */
@@ -5077,7 +5081,7 @@ sctp_update_acked(struct sctp_tcb *stcb,
 	a_rwnd = stcb->asoc.peers_rwnd + stcb->asoc.total_flight;
 
 	/* Now call the express sack handling */
-	sctp_express_handle_sack(stcb, cum_ack, a_rwnd, abort_flag);
+	sctp_express_handle_sack(stcb, cum_ack, a_rwnd, abort_flag, 0);
 }
 
 static void

Modified: head/sys/netinet/sctp_indata.h
==============================================================================
--- head/sys/netinet/sctp_indata.h	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_indata.h	Wed Feb  2 11:13:23 2011	(r218186)
@@ -93,14 +93,14 @@ sctp_calc_rwnd(struct sctp_tcb *stcb, st
 
 void
 sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
-    uint32_t rwnd, int *abort_now);
+    uint32_t rwnd, int *abort_now, int ecne_seen);
 
 void
 sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup,
     struct sctp_tcb *stcb, struct sctp_nets *net_from,
     uint16_t num_seg, uint16_t num_nr_seg, uint16_t num_dup,
     int *abort_now, uint8_t flags,
-    uint32_t cum_ack, uint32_t rwnd);
+    uint32_t cum_ack, uint32_t rwnd, int ecne_seen);
 
 /* draft-ietf-tsvwg-usctp */
 void

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_input.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -481,7 +481,8 @@ sctp_process_init_ack(struct mbuf *m, in
 	    asoc->primary_destination, SCTP_FROM_SCTP_INPUT + SCTP_LOC_4);
 
 	/* calculate the RTO */
-	net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy);
+	net->RTO = sctp_calculate_rto(stcb, asoc, net, &asoc->time_entered, sctp_align_safe_nocopy,
+	    SCTP_DETERMINE_LL_NOTOK);
 
 	retval = sctp_send_cookie_echo(m, offset, stcb, net);
 	if (retval < 0) {
@@ -625,7 +626,8 @@ sctp_handle_heartbeat_ack(struct sctp_he
 		    net, net->cwnd);
 	}
 	/* Now lets do a RTO with this */
-	r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy);
+	r_net->RTO = sctp_calculate_rto(stcb, &stcb->asoc, r_net, &tv, sctp_align_safe_nocopy,
+	    SCTP_DETERMINE_LL_OK);
 	/* Mobility adaptation */
 	if (req_prim) {
 		if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
@@ -1540,7 +1542,9 @@ sctp_process_cookie_existing(struct mbuf
 			 */
 			net->hb_responded = 1;
 			net->RTO = sctp_calculate_rto(stcb, asoc, net,
-			    &cookie->time_entered, sctp_align_unsafe_makecopy);
+			    &cookie->time_entered,
+			    sctp_align_unsafe_makecopy,
+			    SCTP_DETERMINE_LL_NOTOK);
 
 			if (stcb->asoc.sctp_autoclose_ticks &&
 			    (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_AUTOCLOSE))) {
@@ -2243,7 +2247,8 @@ sctp_process_cookie_new(struct mbuf *m, 
 	(void)SCTP_GETTIME_TIMEVAL(&stcb->asoc.time_entered);
 	if ((netp) && (*netp)) {
 		(*netp)->RTO = sctp_calculate_rto(stcb, asoc, *netp,
-		    &cookie->time_entered, sctp_align_unsafe_makecopy);
+		    &cookie->time_entered, sctp_align_unsafe_makecopy,
+		    SCTP_DETERMINE_LL_NOTOK);
 	}
 	/* respond with a COOKIE-ACK */
 	sctp_send_cookie_ack(stcb);
@@ -2831,7 +2836,8 @@ sctp_handle_cookie_ack(struct sctp_cooki
 		SCTP_STAT_INCR_GAUGE32(sctps_currestab);
 		if (asoc->overall_error_count == 0) {
 			net->RTO = sctp_calculate_rto(stcb, asoc, net,
-			    &asoc->time_entered, sctp_align_safe_nocopy);
+			    &asoc->time_entered, sctp_align_safe_nocopy,
+			    SCTP_DETERMINE_LL_NOTOK);
 		}
 		(void)SCTP_GETTIME_TIMEVAL(&asoc->time_entered);
 		sctp_ulp_notify(SCTP_NOTIFY_ASSOC_UP, stcb, 0, NULL, SCTP_SO_NOT_LOCKED);
@@ -2939,6 +2945,7 @@ sctp_handle_ecn_echo(struct sctp_ecne_ch
 	TAILQ_FOREACH(lchk, &stcb->asoc.sent_queue, sctp_next) {
 		if (lchk->rec.data.TSN_seq == tsn) {
 			net = lchk->whoTo;
+			net->ecn_prev_cwnd = lchk->rec.data.cwnd_at_send;
 			break;
 		}
 		if (SCTP_TSN_GT(lchk->rec.data.TSN_seq, tsn)) {
@@ -4196,6 +4203,7 @@ __attribute__((noinline))
 	uint32_t chk_length;
 	int ret;
 	int abort_no_unlock = 0;
+	int ecne_seen = 0;
 
 	/*
 	 * How big should this be, and should it be alloc'd? Lets try the
@@ -4691,13 +4699,13 @@ process_control_chunks:
 					 * with no missing segments to go
 					 * this way too.
 					 */
-					sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now);
+					sctp_express_handle_sack(stcb, cum_ack, a_rwnd, &abort_now, ecne_seen);
 				} else {
 					if (netp && *netp)
 						sctp_handle_sack(m, offset_seg, offset_dup,
 						    stcb, *netp,
 						    num_seg, 0, num_dup, &abort_now, flags,
-						    cum_ack, a_rwnd);
+						    cum_ack, a_rwnd, ecne_seen);
 				}
 				if (abort_now) {
 					/* ABORT signal from sack processing */
@@ -4780,13 +4788,13 @@ process_control_chunks:
 					 * too.
 					 */
 					sctp_express_handle_sack(stcb, cum_ack, a_rwnd,
-					    &abort_now);
+					    &abort_now, ecne_seen);
 				} else {
 					if (netp && *netp)
 						sctp_handle_sack(m, offset_seg, offset_dup,
 						    stcb, *netp,
 						    num_seg, num_nr_seg, num_dup, &abort_now, flags,
-						    cum_ack, a_rwnd);
+						    cum_ack, a_rwnd, ecne_seen);
 				}
 				if (abort_now) {
 					/* ABORT signal from sack processing */
@@ -5063,6 +5071,7 @@ process_control_chunks:
 				stcb->asoc.overall_error_count = 0;
 				sctp_handle_ecn_echo((struct sctp_ecne_chunk *)ch,
 				    stcb);
+				ecne_seen = 1;
 			}
 			break;
 		case SCTP_ECN_CWR:

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_output.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -6395,6 +6395,7 @@ sctp_clean_up_datalist(struct sctp_tcb *
 		}
 		/* record time */
 		data_list[i]->sent_rcv_time = net->last_sent_time;
+		data_list[i]->rec.data.cwnd_at_send = net->cwnd;
 		data_list[i]->rec.data.fast_retran_tsn = data_list[i]->rec.data.TSN_seq;
 		if (data_list[i]->whoTo == NULL) {
 			data_list[i]->whoTo = net;
@@ -9414,7 +9415,7 @@ sctp_chunk_output(struct sctp_inpcb *inp
 			    &now, &now_filled, frag_point, so_locked);
 			return;
 		}
-		if ((asoc->max_burst > 0) && (tot_frs > asoc->max_burst)) {
+		if ((asoc->fr_max_burst > 0) && (tot_frs >= asoc->fr_max_burst)) {
 			/* Hit FR burst limit */
 			return;
 		}
@@ -10962,6 +10963,27 @@ sctp_send_cwr(struct sctp_tcb *stcb, str
 	asoc = &stcb->asoc;
 	SCTP_TCB_LOCK_ASSERT(stcb);
 
+
+	TAILQ_FOREACH(chk, &asoc->control_send_queue, sctp_next) {
+		if ((chk->rec.chunk_id.id == SCTP_ECN_CWR) && (net == chk->whoTo)) {
+			/*
+			 * found a previous CWR queued to same destination
+			 * update it if needed
+			 */
+			uint32_t ctsn;
+
+			cwr = mtod(chk->data, struct sctp_cwr_chunk *);
+			ctsn = ntohl(cwr->tsn);
+			if (SCTP_TSN_GT(high_tsn, ctsn)) {
+				cwr->tsn = htonl(high_tsn);
+			}
+			if (override & SCTP_CWR_REDUCE_OVERRIDE) {
+				/* Make sure override is carried */
+				cwr->ch.chunk_flags |= SCTP_CWR_REDUCE_OVERRIDE;
+			}
+			return;
+		}
+	}
 	sctp_alloc_a_chunk(stcb, chk);
 	if (chk == NULL) {
 		return;

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_pcb.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -2516,6 +2516,8 @@ sctp_inpcb_alloc(struct socket *so, uint
 	m->sctp_sws_sender = SCTP_SWS_SENDER_DEF;
 	m->sctp_sws_receiver = SCTP_SWS_RECEIVER_DEF;
 	m->max_burst = SCTP_BASE_SYSCTL(sctp_max_burst_default);
+	m->fr_max_burst = SCTP_BASE_SYSCTL(sctp_fr_max_burst_default);
+
 	m->sctp_default_cc_module = SCTP_BASE_SYSCTL(sctp_default_cc_module);
 	m->sctp_default_ss_module = SCTP_BASE_SYSCTL(sctp_default_ss_module);
 	/* number of streams to pre-open on a association */

Modified: head/sys/netinet/sctp_pcb.h
==============================================================================
--- head/sys/netinet/sctp_pcb.h	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_pcb.h	Wed Feb  2 11:13:23 2011	(r218186)
@@ -318,6 +318,7 @@ struct sctp_pcb {
 	uint32_t adaptation_layer_indicator;
 	uint32_t store_at;
 	uint32_t max_burst;
+	uint32_t fr_max_burst;
 	char current_secret_number;
 	char last_secret_number;
 };

Modified: head/sys/netinet/sctp_structs.h
==============================================================================
--- head/sys/netinet/sctp_structs.h	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_structs.h	Wed Feb  2 11:13:23 2011	(r218186)
@@ -237,6 +237,8 @@ struct sctp_nets {
 	uint32_t flight_size;
 	uint32_t cwnd;		/* actual cwnd */
 	uint32_t prev_cwnd;	/* cwnd before any processing */
+	uint32_t ecn_prev_cwnd;	/* ECN prev cwnd at first ecn_echo seen in new
+				 * window */
 	uint32_t partial_bytes_acked;	/* in CA tracks when to incr a MTU */
 	uint32_t prev_rtt;
 	/* tracking variables to avoid the aloc/free in sack processing */
@@ -318,6 +320,7 @@ struct sctp_nets {
 	uint8_t window_probe;	/* Doing a window probe? */
 	uint8_t RTO_measured;	/* Have we done the first measure */
 	uint8_t last_hs_used;	/* index into the last HS table entry we used */
+	uint8_t lan_type;
 	/* JRS - struct used in HTCP algorithm */
 	struct htcp htcp_ca;
 };
@@ -329,8 +332,7 @@ struct sctp_data_chunkrec {
 	uint16_t stream_number;	/* the stream number of this guy */
 	uint32_t payloadtype;
 	uint32_t context;	/* from send */
-
-	uint8_t fwd_tsn_cnt;
+	uint32_t cwnd_at_send;
 	/*
 	 * part of the Highest sacked algorithm to be able to stroke counts
 	 * on ones that are FR'd.
@@ -342,6 +344,7 @@ struct sctp_data_chunkrec {
 				 * outbound holds sending flags for PR-SCTP. */
 	uint8_t state_flags;
 	uint8_t chunk_was_revoked;
+	uint8_t fwd_tsn_cnt;
 };
 
 TAILQ_HEAD(sctpchunk_listhead, sctp_tmit_chunk);
@@ -1052,8 +1055,10 @@ struct sctp_association {
 	 */
 	uint8_t send_sack;
 
-	/* max burst after fast retransmit completes */
+	/* max burst of new packets into the network */
 	uint32_t max_burst;
+	/* max burst of fast retransmit packets */
+	uint32_t fr_max_burst;
 
 	uint8_t sat_network;	/* RTT is in range of sat net or greater */
 	uint8_t sat_network_lockout;	/* lockout code */

Modified: head/sys/netinet/sctp_sysctl.c
==============================================================================
--- head/sys/netinet/sctp_sysctl.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_sysctl.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -59,6 +59,7 @@ sctp_init_sysctls()
 	SCTP_BASE_SYSCTL(sctp_strict_init) = SCTPCTL_STRICT_INIT_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_peer_chunk_oh) = SCTPCTL_PEER_CHKOH_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_max_burst_default) = SCTPCTL_MAXBURST_DEFAULT;
+	SCTP_BASE_SYSCTL(sctp_fr_max_burst_default) = SCTPCTL_FRMAXBURST_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue) = SCTPCTL_MAXCHUNKS_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_hashtblsize) = SCTPCTL_TCBHASHSIZE_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_pcbtblsize) = SCTPCTL_PCBHASHSIZE_DEFAULT;
@@ -576,6 +577,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_init), SCTPCTL_STRICT_INIT_MIN, SCTPCTL_STRICT_INIT_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_peer_chunk_oh), SCTPCTL_PEER_CHKOH_MIN, SCTPCTL_PEER_CHKOH_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_max_burst_default), SCTPCTL_MAXBURST_MIN, SCTPCTL_MAXBURST_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), SCTPCTL_FRMAXBURST_MIN, SCTPCTL_FRMAXBURST_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), SCTPCTL_MAXCHUNKS_MIN, SCTPCTL_MAXCHUNKS_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_hashtblsize), SCTPCTL_TCBHASHSIZE_MIN, SCTPCTL_TCBHASHSIZE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_pcbtblsize), SCTPCTL_PCBHASHSIZE_MIN, SCTPCTL_PCBHASHSIZE_MAX);
@@ -849,6 +851,10 @@ SYSCTL_PROC(_net_inet_sctp, OID_AUTO, ma
     &SCTP_BASE_SYSCTL(sctp_max_burst_default), 0, sysctl_sctp_check, "IU",
     SCTPCTL_MAXBURST_DESC);
 
+SYSCTL_PROC(_net_inet_sctp, OID_AUTO, fr_maxburst, CTLTYPE_UINT | CTLFLAG_RW,
+    &SCTP_BASE_SYSCTL(sctp_fr_max_burst_default), 0, sysctl_sctp_check, "IU",
+    SCTPCTL_FRMAXBURST_DESC);
+
 SYSCTL_PROC(_net_inet_sctp, OID_AUTO, maxchunks, CTLTYPE_UINT | CTLFLAG_RW,
     &SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue), 0, sysctl_sctp_check, "IU",
     SCTPCTL_MAXCHUNKS_DESC);

Modified: head/sys/netinet/sctp_sysctl.h
==============================================================================
--- head/sys/netinet/sctp_sysctl.h	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_sysctl.h	Wed Feb  2 11:13:23 2011	(r218186)
@@ -43,7 +43,7 @@ struct sctp_sysctl {
 	uint32_t sctp_auto_asconf;
 	uint32_t sctp_multiple_asconfs;
 	uint32_t sctp_ecn_enable;
-	uint32_t sctp_not_used;
+	uint32_t sctp_fr_max_burst_default;
 	uint32_t sctp_strict_sacks;
 #if !defined(SCTP_WITH_NO_CSUM)
 	uint32_t sctp_no_csum_on_loopback;
@@ -182,6 +182,13 @@ struct sctp_sysctl {
 #define SCTPCTL_MAXBURST_MAX		0xFFFFFFFF
 #define SCTPCTL_MAXBURST_DEFAULT	SCTP_DEF_MAX_BURST
 
+/* fr_maxburst: Default max burst for sctp endpoints when fast retransmitting */
+#define SCTPCTL_FRMAXBURST_DESC		"Default fr max burst for sctp endpoints"
+#define SCTPCTL_FRMAXBURST_MIN		0
+#define SCTPCTL_FRMAXBURST_MAX		0xFFFFFFFF
+#define SCTPCTL_FRMAXBURST_DEFAULT	SCTP_DEF_FRMAX_BURST
+
+
 /* maxchunks: Default max chunks on queue per asoc */
 #define SCTPCTL_MAXCHUNKS_DESC		"Default max chunks on queue per asoc"
 #define SCTPCTL_MAXCHUNKS_MIN		0
@@ -402,7 +409,7 @@ struct sctp_sysctl {
 #define SCTPCTL_HB_MAX_BURST_DESC	"Confirmation Heartbeat max burst"
 #define SCTPCTL_HB_MAX_BURST_MIN	1
 #define SCTPCTL_HB_MAX_BURST_MAX	0xFFFFFFFF
-#define SCTPCTL_HB_MAX_BURST_DEFAULT	SCTP_DEF_MAX_BURST
+#define SCTPCTL_HB_MAX_BURST_DEFAULT	SCTP_DEF_HBMAX_BURST
 
 /* abort_at_limit: When one-2-one hits qlimit abort */
 #define SCTPCTL_ABORT_AT_LIMIT_DESC	"When one-2-one hits qlimit abort"

Modified: head/sys/netinet/sctp_timer.c
==============================================================================
--- head/sys/netinet/sctp_timer.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctp_timer.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -1630,7 +1630,8 @@ sctp_heartbeat_timer(struct sctp_inpcb *
 				else if (ret == 0) {
 					break;
 				}
-				if (cnt_sent >= SCTP_BASE_SYSCTL(sctp_hb_maxburst))
+				if (SCTP_BASE_SYSCTL(sctp_hb_maxburst) &&
+				    (cnt_sent >= SCTP_BASE_SYSCTL(sctp_hb_maxburst)))
 					break;
 			}
 		}

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctputil.c	Wed Feb  2 11:13:23 2011	(r218186)
@@ -913,6 +913,7 @@ sctp_init_asoc(struct sctp_inpcb *m, str
 	/* init all variables to a known value. */
 	SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE);
 	asoc->max_burst = m->sctp_ep.max_burst;
+	asoc->fr_max_burst = m->sctp_ep.fr_max_burst;
 	asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
 	asoc->cookie_life = m->sctp_ep.def_cookie_life;
 	asoc->sctp_cmt_on_off = m->sctp_cmt_on_off;
@@ -2459,12 +2460,13 @@ sctp_mtu_size_reset(struct sctp_inpcb *i
  * given an association and starting time of the current RTT period return
  * RTO in number of msecs net should point to the current network
  */
+
 uint32_t
 sctp_calculate_rto(struct sctp_tcb *stcb,
     struct sctp_association *asoc,
     struct sctp_nets *net,
     struct timeval *told,
-    int safe)
+    int safe, int local_lan_determine)
 {
 	/*-
 	 * given an association and the starting time of the current RTT
@@ -2492,13 +2494,21 @@ sctp_calculate_rto(struct sctp_tcb *stcb
 	/************************/
 	/* get the current time */
 	(void)SCTP_GETTIME_TIMEVAL(&now);
-
 	/*
 	 * Record the real time of the last RTT for use in DC-CC.
 	 */
 	net->last_measured_rtt = now;
 	timevalsub(&net->last_measured_rtt, old);
 
+	/* Do we need to determine the lan type? */
+	if ((local_lan_determine == SCTP_DETERMINE_LL_OK) && (net->lan_type == SCTP_LAN_UNKNOWN)) {
+		if ((net->last_measured_rtt.tv_sec) ||
+		    (net->last_measured_rtt.tv_usec > SCTP_LOCAL_LAN_RTT)) {
+			net->lan_type = SCTP_LAN_INTERNET;
+		} else {
+			net->lan_type = SCTP_LAN_LOCAL;
+		}
+	}
 	/* compute the RTT value */
 	if ((u_long)now.tv_sec > (u_long)old->tv_sec) {
 		calc_time = ((u_long)now.tv_sec - (u_long)old->tv_sec) * 1000;

Modified: head/sys/netinet/sctputil.h
==============================================================================
--- head/sys/netinet/sctputil.h	Wed Feb  2 08:24:26 2011	(r218185)
+++ head/sys/netinet/sctputil.h	Wed Feb  2 11:13:23 2011	(r218186)
@@ -132,7 +132,7 @@ void
 
 uint32_t
 sctp_calculate_rto(struct sctp_tcb *, struct sctp_association *,
-    struct sctp_nets *, struct timeval *, int);
+    struct sctp_nets *, struct timeval *, int, int);
 
 uint32_t sctp_calculate_len(struct mbuf *);
 


More information about the svn-src-all mailing list