1434 TCP_INIT_CWND setsockopt doesn't work on passive connections.
authorDan McDonald <danmcd@nexenta.com>
Fri, 02 Sep 2011 16:41:08 -0700
changeset 13445 4dad26dd1fb9
parent 13444 c1ed50709bff
child 13446 f342d051b376
1434 TCP_INIT_CWND setsockopt doesn't work on passive connections. Reviewed by: Jason King <[email protected]> Reviewed by: Dan Kruchinin <[email protected]> Approved by: Eric Schrock <[email protected]>
usr/src/uts/common/inet/tcp/tcp_opt_data.c
--- a/usr/src/uts/common/inet/tcp/tcp_opt_data.c	Tue Aug 30 15:16:15 2011 -0700
+++ b/usr/src/uts/common/inet/tcp/tcp_opt_data.c	Fri Sep 02 16:41:08 2011 -0700
@@ -694,19 +694,29 @@
 			 * privilege to set the initial cwnd to be larger
 			 * than allowed by RFC 3390.
 			 */
-			if (val <= MIN(4, MAX(2, 4380 / tcp->tcp_mss))) {
-				tcp->tcp_init_cwnd = val;
-				break;
+			if (val > MIN(4, MAX(2, 4380 / tcp->tcp_mss))) {
+				if ((reterr = secpolicy_ip_config(cr, B_TRUE))
+				    != 0) {
+					*outlenp = 0;
+					return (reterr);
+				}
+				if (val > tcp_max_init_cwnd) {
+					*outlenp = 0;
+					return (EINVAL);
+				}
 			}
-			if ((reterr = secpolicy_ip_config(cr, B_TRUE)) != 0) {
-				*outlenp = 0;
-				return (reterr);
+
+			tcp->tcp_init_cwnd = val;
+
+			/*
+			 * If the socket is connected, AND no outbound data
+			 * has been sent, reset the actual cwnd values.
+			 */
+			if (tcp->tcp_state == TCPS_ESTABLISHED &&
+			    tcp->tcp_iss == tcp->tcp_snxt - 1) {
+				tcp->tcp_cwnd =
+				    MIN(tcp->tcp_rwnd, val * tcp->tcp_mss);
 			}
-			if (val > tcp_max_init_cwnd) {
-				*outlenp = 0;
-				return (EINVAL);
-			}
-			tcp->tcp_init_cwnd = val;
 			break;
 
 		/*