Print this page
DLPX-43064 include high-resolution round-trip times in connstat (EP-652)
DLPX-42721 Create inline function for TCP RTO calculation


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright 2016 Joyent, Inc.

  25  */
  26 
  27 #include <sys/types.h>
  28 #include <sys/stream.h>
  29 #define _SUN_TPI_VERSION 2
  30 #include <sys/tihdr.h>
  31 #include <sys/socket.h>
  32 #include <sys/xti_xtiopt.h>
  33 #include <sys/xti_inet.h>
  34 #include <sys/policy.h>
  35 
  36 #include <inet/common.h>
  37 #include <netinet/ip6.h>
  38 #include <inet/ip.h>
  39 
  40 #include <netinet/in.h>
  41 #include <netinet/tcp.h>
  42 #include <inet/optcom.h>
  43 #include <inet/proto_set.h>
  44 #include <inet/tcp_impl.h>


 957                                 tcp->tcp_ka_rinterval = 0;
 958                         }
 959                         break;
 960                 case TCP_CORK:
 961                         if (!checkonly) {
 962                                 /*
 963                                  * if tcp->tcp_cork was set and is now
 964                                  * being unset, we have to make sure that
 965                                  * the remaining data gets sent out. Also
 966                                  * unset tcp->tcp_cork so that tcp_wput_data()
 967                                  * can send data even if it is less than mss
 968                                  */
 969                                 if (tcp->tcp_cork && onoff == 0 &&
 970                                     tcp->tcp_unsent > 0) {
 971                                         tcp->tcp_cork = B_FALSE;
 972                                         tcp_wput_data(tcp, NULL, B_FALSE);
 973                                 }
 974                                 tcp->tcp_cork = onoff;
 975                         }
 976                         break;
 977                 case TCP_RTO_INITIAL: {
 978                         clock_t rto;
 979 
 980                         if (checkonly || val == 0)
 981                                 break;
 982 
 983                         /*
 984                          * Sanity checks
 985                          *
 986                          * The initial RTO should be bounded by the minimum
 987                          * and maximum RTO.  And it should also be smaller
 988                          * than the connect attempt abort timeout.  Otherwise,
 989                          * the connection won't be aborted in a period
 990                          * reasonably close to that timeout.
 991                          */
 992                         if (val < tcp->tcp_rto_min || val > tcp->tcp_rto_max ||
 993                             val > tcp->tcp_second_ctimer_threshold ||
 994                             val < tcps->tcps_rexmit_interval_initial_low ||
 995                             val > tcps->tcps_rexmit_interval_initial_high) {
 996                                 *outlenp = 0;
 997                                 return (EINVAL);
 998                         }
 999                         tcp->tcp_rto_initial = val;
1000 
1001                         /*
1002                          * If TCP has not sent anything, need to re-calculate
1003                          * tcp_rto.  Otherwise, this option change does not
1004                          * really affect anything.
1005                          */
1006                         if (tcp->tcp_state >= TCPS_SYN_SENT)
1007                                 break;
1008 
1009                         tcp->tcp_rtt_sa = tcp->tcp_rto_initial << 2;
1010                         tcp->tcp_rtt_sd = tcp->tcp_rto_initial >> 1;
1011                         rto = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
1012                             tcps->tcps_rexmit_interval_extra +
1013                             (tcp->tcp_rtt_sa >> 5) +
1014                             tcps->tcps_conn_grace_period;
1015                         TCP_SET_RTO(tcp, rto);
1016                         break;
1017                 }
1018                 case TCP_RTO_MIN:
1019                         if (checkonly || val == 0)
1020                                 break;
1021 
1022                         if (val < tcps->tcps_rexmit_interval_min_low ||
1023                             val > tcps->tcps_rexmit_interval_min_high ||
1024                             val > tcp->tcp_rto_max) {
1025                                 *outlenp = 0;
1026                                 return (EINVAL);
1027                         }
1028                         tcp->tcp_rto_min = val;
1029                         if (tcp->tcp_rto < val)
1030                                 tcp->tcp_rto = val;
1031                         break;
1032                 case TCP_RTO_MAX:
1033                         if (checkonly || val == 0)
1034                                 break;
1035 
1036                         /*
1037                          * Sanity checks




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  23  * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved.
  24  * Copyright 2016 Joyent, Inc.
  25  * Copyright (c) 2016 by Delphix. All rights reserved.
  26  */
  27 
  28 #include <sys/types.h>
  29 #include <sys/stream.h>
  30 #define _SUN_TPI_VERSION 2
  31 #include <sys/tihdr.h>
  32 #include <sys/socket.h>
  33 #include <sys/xti_xtiopt.h>
  34 #include <sys/xti_inet.h>
  35 #include <sys/policy.h>
  36 
  37 #include <inet/common.h>
  38 #include <netinet/ip6.h>
  39 #include <inet/ip.h>
  40 
  41 #include <netinet/in.h>
  42 #include <netinet/tcp.h>
  43 #include <inet/optcom.h>
  44 #include <inet/proto_set.h>
  45 #include <inet/tcp_impl.h>


 958                                 tcp->tcp_ka_rinterval = 0;
 959                         }
 960                         break;
 961                 case TCP_CORK:
 962                         if (!checkonly) {
 963                                 /*
 964                                  * if tcp->tcp_cork was set and is now
 965                                  * being unset, we have to make sure that
 966                                  * the remaining data gets sent out. Also
 967                                  * unset tcp->tcp_cork so that tcp_wput_data()
 968                                  * can send data even if it is less than mss
 969                                  */
 970                                 if (tcp->tcp_cork && onoff == 0 &&
 971                                     tcp->tcp_unsent > 0) {
 972                                         tcp->tcp_cork = B_FALSE;
 973                                         tcp_wput_data(tcp, NULL, B_FALSE);
 974                                 }
 975                                 tcp->tcp_cork = onoff;
 976                         }
 977                         break;
 978                 case TCP_RTO_INITIAL:


 979                         if (checkonly || val == 0)
 980                                 break;
 981 
 982                         /*
 983                          * Sanity checks
 984                          *
 985                          * The initial RTO should be bounded by the minimum
 986                          * and maximum RTO.  And it should also be smaller
 987                          * than the connect attempt abort timeout.  Otherwise,
 988                          * the connection won't be aborted in a period
 989                          * reasonably close to that timeout.
 990                          */
 991                         if (val < tcp->tcp_rto_min || val > tcp->tcp_rto_max ||
 992                             val > tcp->tcp_second_ctimer_threshold ||
 993                             val < tcps->tcps_rexmit_interval_initial_low ||
 994                             val > tcps->tcps_rexmit_interval_initial_high) {
 995                                 *outlenp = 0;
 996                                 return (EINVAL);
 997                         }
 998                         tcp->tcp_rto_initial = val;
 999 
1000                         /*
1001                          * If TCP has not sent anything, need to re-calculate
1002                          * tcp_rto.  Otherwise, this option change does not
1003                          * really affect anything.
1004                          */
1005                         if (tcp->tcp_state >= TCPS_SYN_SENT)
1006                                 break;
1007 
1008                         tcp->tcp_rtt_sa = MSEC2NSEC(tcp->tcp_rto_initial) << 2;
1009                         tcp->tcp_rtt_sd = MSEC2NSEC(tcp->tcp_rto_initial) >> 1;
1010                         tcp->tcp_rto = tcp_calculate_rto(tcp, tcps);




1011                         break;

1012                 case TCP_RTO_MIN:
1013                         if (checkonly || val == 0)
1014                                 break;
1015 
1016                         if (val < tcps->tcps_rexmit_interval_min_low ||
1017                             val > tcps->tcps_rexmit_interval_min_high ||
1018                             val > tcp->tcp_rto_max) {
1019                                 *outlenp = 0;
1020                                 return (EINVAL);
1021                         }
1022                         tcp->tcp_rto_min = val;
1023                         if (tcp->tcp_rto < val)
1024                                 tcp->tcp_rto = val;
1025                         break;
1026                 case TCP_RTO_MAX:
1027                         if (checkonly || val == 0)
1028                                 break;
1029 
1030                         /*
1031                          * Sanity checks