Print this page
11546 Track TCP round-trip time in nanoseconds
Portions contributed by: Cody Peter Mello <cody.mello@joyent.com>
Portions contributed by: Brandon Baker <bbaker@delphix.com>
Reviewed by: Jason King <jason.king@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>


   4  * The contents of this file are subject to the terms of the
   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  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/stream.h>
  28 #define _SUN_TPI_VERSION 2
  29 #include <sys/tihdr.h>
  30 #include <sys/socket.h>
  31 #include <sys/xti_xtiopt.h>
  32 #include <sys/xti_inet.h>
  33 #include <sys/policy.h>
  34 
  35 #include <inet/common.h>
  36 #include <netinet/ip6.h>
  37 #include <inet/ip.h>
  38 
  39 #include <netinet/in.h>
  40 #include <netinet/tcp.h>
  41 #include <inet/optcom.h>
  42 #include <inet/proto_set.h>
  43 #include <inet/tcp_impl.h>


 852                                 tcp->tcp_ka_rinterval = 0;
 853                         }
 854                         break;
 855                 case TCP_CORK:
 856                         if (!checkonly) {
 857                                 /*
 858                                  * if tcp->tcp_cork was set and is now
 859                                  * being unset, we have to make sure that
 860                                  * the remaining data gets sent out. Also
 861                                  * unset tcp->tcp_cork so that tcp_wput_data()
 862                                  * can send data even if it is less than mss
 863                                  */
 864                                 if (tcp->tcp_cork && onoff == 0 &&
 865                                     tcp->tcp_unsent > 0) {
 866                                         tcp->tcp_cork = B_FALSE;
 867                                         tcp_wput_data(tcp, NULL, B_FALSE);
 868                                 }
 869                                 tcp->tcp_cork = onoff;
 870                         }
 871                         break;
 872                 case TCP_RTO_INITIAL: {
 873                         clock_t rto;
 874 
 875                         if (checkonly || val == 0)
 876                                 break;
 877 
 878                         /*
 879                          * Sanity checks
 880                          *
 881                          * The initial RTO should be bounded by the minimum
 882                          * and maximum RTO.  And it should also be smaller
 883                          * than the connect attempt abort timeout.  Otherwise,
 884                          * the connection won't be aborted in a period
 885                          * reasonably close to that timeout.
 886                          */
 887                         if (val < tcp->tcp_rto_min || val > tcp->tcp_rto_max ||
 888                             val > tcp->tcp_second_ctimer_threshold ||
 889                             val < tcps->tcps_rexmit_interval_initial_low ||
 890                             val > tcps->tcps_rexmit_interval_initial_high) {
 891                                 *outlenp = 0;
 892                                 return (EINVAL);
 893                         }
 894                         tcp->tcp_rto_initial = val;
 895 
 896                         /*
 897                          * If TCP has not sent anything, need to re-calculate
 898                          * tcp_rto.  Otherwise, this option change does not
 899                          * really affect anything.
 900                          */
 901                         if (tcp->tcp_state >= TCPS_SYN_SENT)
 902                                 break;
 903 
 904                         tcp->tcp_rtt_sa = tcp->tcp_rto_initial << 2;
 905                         tcp->tcp_rtt_sd = tcp->tcp_rto_initial >> 1;
 906                         rto = (tcp->tcp_rtt_sa >> 3) + tcp->tcp_rtt_sd +
 907                             tcps->tcps_rexmit_interval_extra +
 908                             (tcp->tcp_rtt_sa >> 5) +
 909                             tcps->tcps_conn_grace_period;
 910                         TCP_SET_RTO(tcp, rto);
 911                         break;
 912                 }
 913                 case TCP_RTO_MIN:
 914                         if (checkonly || val == 0)
 915                                 break;
 916 
 917                         if (val < tcps->tcps_rexmit_interval_min_low ||
 918                             val > tcps->tcps_rexmit_interval_min_high ||
 919                             val > tcp->tcp_rto_max) {
 920                                 *outlenp = 0;
 921                                 return (EINVAL);
 922                         }
 923                         tcp->tcp_rto_min = val;
 924                         if (tcp->tcp_rto < val)
 925                                 tcp->tcp_rto = val;
 926                         break;
 927                 case TCP_RTO_MAX:
 928                         if (checkonly || val == 0)
 929                                 break;
 930 
 931                         /*
 932                          * Sanity checks




   4  * The contents of this file are subject to the terms of the
   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>


 854                                 tcp->tcp_ka_rinterval = 0;
 855                         }
 856                         break;
 857                 case TCP_CORK:
 858                         if (!checkonly) {
 859                                 /*
 860                                  * if tcp->tcp_cork was set and is now
 861                                  * being unset, we have to make sure that
 862                                  * the remaining data gets sent out. Also
 863                                  * unset tcp->tcp_cork so that tcp_wput_data()
 864                                  * can send data even if it is less than mss
 865                                  */
 866                                 if (tcp->tcp_cork && onoff == 0 &&
 867                                     tcp->tcp_unsent > 0) {
 868                                         tcp->tcp_cork = B_FALSE;
 869                                         tcp_wput_data(tcp, NULL, B_FALSE);
 870                                 }
 871                                 tcp->tcp_cork = onoff;
 872                         }
 873                         break;
 874                 case TCP_RTO_INITIAL:


 875                         if (checkonly || val == 0)
 876                                 break;
 877 
 878                         /*
 879                          * Sanity checks
 880                          *
 881                          * The initial RTO should be bounded by the minimum
 882                          * and maximum RTO.  And it should also be smaller
 883                          * than the connect attempt abort timeout.  Otherwise,
 884                          * the connection won't be aborted in a period
 885                          * reasonably close to that timeout.
 886                          */
 887                         if (val < tcp->tcp_rto_min || val > tcp->tcp_rto_max ||
 888                             val > tcp->tcp_second_ctimer_threshold ||
 889                             val < tcps->tcps_rexmit_interval_initial_low ||
 890                             val > tcps->tcps_rexmit_interval_initial_high) {
 891                                 *outlenp = 0;
 892                                 return (EINVAL);
 893                         }
 894                         tcp->tcp_rto_initial = val;
 895 
 896                         /*
 897                          * If TCP has not sent anything, need to re-calculate
 898                          * tcp_rto.  Otherwise, this option change does not
 899                          * really affect anything.
 900                          */
 901                         if (tcp->tcp_state >= TCPS_SYN_SENT)
 902                                 break;
 903 
 904                         tcp->tcp_rtt_sa = MSEC2NSEC(tcp->tcp_rto_initial) << 2;
 905                         tcp->tcp_rtt_sd = MSEC2NSEC(tcp->tcp_rto_initial) >> 1;
 906                         tcp->tcp_rto = tcp_calculate_rto(tcp, tcps,
 907                             tcps->tcps_conn_grace_period);



 908                         break;

 909                 case TCP_RTO_MIN:
 910                         if (checkonly || val == 0)
 911                                 break;
 912 
 913                         if (val < tcps->tcps_rexmit_interval_min_low ||
 914                             val > tcps->tcps_rexmit_interval_min_high ||
 915                             val > tcp->tcp_rto_max) {
 916                                 *outlenp = 0;
 917                                 return (EINVAL);
 918                         }
 919                         tcp->tcp_rto_min = val;
 920                         if (tcp->tcp_rto < val)
 921                                 tcp->tcp_rto = val;
 922                         break;
 923                 case TCP_RTO_MAX:
 924                         if (checkonly || val == 0)
 925                                 break;
 926 
 927                         /*
 928                          * Sanity checks