tcp_keepalive_unix.go raw

   1  //go:build unix
   2  
   3  /*
   4   * Copyright 2023 gRPC authors.
   5   *
   6   * Licensed under the Apache License, Version 2.0 (the "License");
   7   * you may not use this file except in compliance with the License.
   8   * You may obtain a copy of the License at
   9   *
  10   *     http://www.apache.org/licenses/LICENSE-2.0
  11   *
  12   * Unless required by applicable law or agreed to in writing, software
  13   * distributed under the License is distributed on an "AS IS" BASIS,
  14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15   * See the License for the specific language governing permissions and
  16   * limitations under the License.
  17   *
  18   */
  19  
  20  package internal
  21  
  22  import (
  23  	"net"
  24  	"syscall"
  25  	"time"
  26  
  27  	"golang.org/x/sys/unix"
  28  )
  29  
  30  // NetDialerWithTCPKeepalive returns a net.Dialer that enables TCP keepalives on
  31  // the underlying connection with OS default values for keepalive parameters.
  32  //
  33  // TODO: Once https://github.com/golang/go/issues/62254 lands, and the
  34  // appropriate Go version becomes less than our least supported Go version, we
  35  // should look into using the new API to make things more straightforward.
  36  func NetDialerWithTCPKeepalive() *net.Dialer {
  37  	return &net.Dialer{
  38  		// Setting a negative value here prevents the Go stdlib from overriding
  39  		// the values of TCP keepalive time and interval. It also prevents the
  40  		// Go stdlib from enabling TCP keepalives by default.
  41  		KeepAlive: time.Duration(-1),
  42  		// This method is called after the underlying network socket is created,
  43  		// but before dialing the socket (or calling its connect() method). The
  44  		// combination of unconditionally enabling TCP keepalives here, and
  45  		// disabling the overriding of TCP keepalive parameters by setting the
  46  		// KeepAlive field to a negative value above, results in OS defaults for
  47  		// the TCP keepalive interval and time parameters.
  48  		Control: func(_, _ string, c syscall.RawConn) error {
  49  			return c.Control(func(fd uintptr) {
  50  				unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1)
  51  			})
  52  		},
  53  	}
  54  }
  55