Source file src/net/dial.go

     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package net
     6  
     7  import (
     8  	"context"
     9  	"internal/bytealg"
    10  	"internal/godebug"
    11  	"internal/nettrace"
    12  	"syscall"
    13  	"time"
    14  )
    15  
    16  const (
    17  	// defaultTCPKeepAliveIdle is a default constant value for TCP_KEEPIDLE.
    18  	// See go.dev/issue/31510 for details.
    19  	defaultTCPKeepAliveIdle = 15 * time.Second
    20  
    21  	// defaultTCPKeepAliveInterval is a default constant value for TCP_KEEPINTVL.
    22  	// It is the same as defaultTCPKeepAliveIdle, see go.dev/issue/31510 for details.
    23  	defaultTCPKeepAliveInterval = 15 * time.Second
    24  
    25  	// defaultTCPKeepAliveCount is a default constant value for TCP_KEEPCNT.
    26  	defaultTCPKeepAliveCount = 9
    27  
    28  	// For the moment, MultiPath TCP is used by default with listeners, if
    29  	// available, but not with dialers.
    30  	// See go.dev/issue/56539
    31  	defaultMPTCPEnabledListen = true
    32  	defaultMPTCPEnabledDial   = false
    33  )
    34  
    35  // The type of service offered
    36  //
    37  //	0 == MPTCP disabled
    38  //	1 == MPTCP enabled
    39  //	2 == MPTCP enabled on listeners only
    40  //	3 == MPTCP enabled on dialers only
    41  var multipathtcp = godebug.New("multipathtcp")
    42  
    43  // mptcpStatusDial is a tristate for Multipath TCP on clients,
    44  // see go.dev/issue/56539
    45  type mptcpStatusDial uint8
    46  
    47  const (
    48  	// The value 0 is the system default, linked to defaultMPTCPEnabledDial
    49  	mptcpUseDefaultDial mptcpStatusDial = iota
    50  	mptcpEnabledDial
    51  	mptcpDisabledDial
    52  )
    53  
    54  func (m *mptcpStatusDial) get() bool {
    55  	switch *m {
    56  	case mptcpEnabledDial:
    57  		return true
    58  	case mptcpDisabledDial:
    59  		return false
    60  	}
    61  
    62  	// If MPTCP is forced via GODEBUG=multipathtcp=1
    63  	if multipathtcp.Value() == "1" || multipathtcp.Value() == "3" {
    64  		multipathtcp.IncNonDefault()
    65  
    66  		return true
    67  	}
    68  
    69  	return defaultMPTCPEnabledDial
    70  }
    71  
    72  func (m *mptcpStatusDial) set(use bool) {
    73  	if use {
    74  		*m = mptcpEnabledDial
    75  	} else {
    76  		*m = mptcpDisabledDial
    77  	}
    78  }
    79  
    80  // mptcpStatusListen is a tristate for Multipath TCP on servers,
    81  // see go.dev/issue/56539
    82  type mptcpStatusListen uint8
    83  
    84  const (
    85  	// The value 0 is the system default, linked to defaultMPTCPEnabledListen
    86  	mptcpUseDefaultListen mptcpStatusListen = iota
    87  	mptcpEnabledListen
    88  	mptcpDisabledListen
    89  )
    90  
    91  func (m *mptcpStatusListen) get() bool {
    92  	switch *m {
    93  	case mptcpEnabledListen:
    94  		return true
    95  	case mptcpDisabledListen:
    96  		return false
    97  	}
    98  
    99  	// If MPTCP is disabled via GODEBUG=multipathtcp=0 or only
   100  	// enabled on dialers, but not on listeners.
   101  	if multipathtcp.Value() == "0" || multipathtcp.Value() == "3" {
   102  		multipathtcp.IncNonDefault()
   103  
   104  		return false
   105  	}
   106  
   107  	return defaultMPTCPEnabledListen
   108  }
   109  
   110  func (m *mptcpStatusListen) set(use bool) {
   111  	if use {
   112  		*m = mptcpEnabledListen
   113  	} else {
   114  		*m = mptcpDisabledListen
   115  	}
   116  }
   117  
   118  // A Dialer contains options for connecting to an address.
   119  //
   120  // The zero value for each field is equivalent to dialing
   121  // without that option. Dialing with the zero value of Dialer
   122  // is therefore equivalent to just calling the [Dial] function.
   123  //
   124  // It is safe to call Dialer's methods concurrently.
   125  type Dialer struct {
   126  	// Timeout is the maximum amount of time a dial will wait for
   127  	// a connect to complete. If Deadline is also set, it may fail
   128  	// earlier.
   129  	//
   130  	// The default is no timeout.
   131  	//
   132  	// When using TCP and dialing a host name with multiple IP
   133  	// addresses, the timeout may be divided between them.
   134  	//
   135  	// With or without a timeout, the operating system may impose
   136  	// its own earlier timeout. For instance, TCP timeouts are
   137  	// often around 3 minutes.
   138  	Timeout time.Duration
   139  
   140  	// Deadline is the absolute point in time after which dials
   141  	// will fail. If Timeout is set, it may fail earlier.
   142  	// Zero means no deadline, or dependent on the operating system
   143  	// as with the Timeout option.
   144  	Deadline time.Time
   145  
   146  	// LocalAddr is the local address to use when dialing an
   147  	// address. The address must be of a compatible type for the
   148  	// network being dialed.
   149  	// If nil, a local address is automatically chosen.
   150  	LocalAddr Addr
   151  
   152  	// DualStack previously enabled RFC 6555 Fast Fallback
   153  	// support, also known as "Happy Eyeballs", in which IPv4 is
   154  	// tried soon if IPv6 appears to be misconfigured and
   155  	// hanging.
   156  	//
   157  	// Deprecated: Fast Fallback is enabled by default. To
   158  	// disable, set FallbackDelay to a negative value.
   159  	DualStack bool
   160  
   161  	// FallbackDelay specifies the length of time to wait before
   162  	// spawning a RFC 6555 Fast Fallback connection. That is, this
   163  	// is the amount of time to wait for IPv6 to succeed before
   164  	// assuming that IPv6 is misconfigured and falling back to
   165  	// IPv4.
   166  	//
   167  	// If zero, a default delay of 300ms is used.
   168  	// A negative value disables Fast Fallback support.
   169  	FallbackDelay time.Duration
   170  
   171  	// KeepAlive specifies the interval between keep-alive
   172  	// probes for an active network connection.
   173  	//
   174  	// KeepAlive is ignored if KeepAliveConfig.Enable is true.
   175  	//
   176  	// If zero, keep-alive probes are sent with a default value
   177  	// (currently 15 seconds), if supported by the protocol and operating
   178  	// system. Network protocols or operating systems that do
   179  	// not support keep-alive ignore this field.
   180  	// If negative, keep-alive probes are disabled.
   181  	KeepAlive time.Duration
   182  
   183  	// KeepAliveConfig specifies the keep-alive probe configuration
   184  	// for an active network connection, when supported by the
   185  	// protocol and operating system.
   186  	//
   187  	// If KeepAliveConfig.Enable is true, keep-alive probes are enabled.
   188  	// If KeepAliveConfig.Enable is false and KeepAlive is negative,
   189  	// keep-alive probes are disabled.
   190  	KeepAliveConfig KeepAliveConfig
   191  
   192  	// Resolver optionally specifies an alternate resolver to use.
   193  	Resolver *Resolver
   194  
   195  	// Cancel is an optional channel whose closure indicates that
   196  	// the dial should be canceled. Not all types of dials support
   197  	// cancellation.
   198  	//
   199  	// Deprecated: Use DialContext instead.
   200  	Cancel <-chan struct{}
   201  
   202  	// If Control is not nil, it is called after creating the network
   203  	// connection but before actually dialing.
   204  	//
   205  	// Network and address parameters passed to Control function are not
   206  	// necessarily the ones passed to Dial. Calling Dial with TCP networks
   207  	// will cause the Control function to be called with "tcp4" or "tcp6",
   208  	// UDP networks become "udp4" or "udp6", IP networks become "ip4" or "ip6",
   209  	// and other known networks are passed as-is.
   210  	//
   211  	// Control is ignored if ControlContext is not nil.
   212  	Control func(network, address string, c syscall.RawConn) error
   213  
   214  	// If ControlContext is not nil, it is called after creating the network
   215  	// connection but before actually dialing.
   216  	//
   217  	// Network and address parameters passed to ControlContext function are not
   218  	// necessarily the ones passed to Dial. Calling Dial with TCP networks
   219  	// will cause the ControlContext function to be called with "tcp4" or "tcp6",
   220  	// UDP networks become "udp4" or "udp6", IP networks become "ip4" or "ip6",
   221  	// and other known networks are passed as-is.
   222  	//
   223  	// If ControlContext is not nil, Control is ignored.
   224  	ControlContext func(ctx context.Context, network, address string, c syscall.RawConn) error
   225  
   226  	// If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
   227  	// used, any call to Dial with "tcp(4|6)" as network will use MPTCP if
   228  	// supported by the operating system.
   229  	mptcpStatus mptcpStatusDial
   230  }
   231  
   232  func (d *Dialer) dualStack() bool { return d.FallbackDelay >= 0 }
   233  
   234  func minNonzeroTime(a, b time.Time) time.Time {
   235  	if a.IsZero() {
   236  		return b
   237  	}
   238  	if b.IsZero() || a.Before(b) {
   239  		return a
   240  	}
   241  	return b
   242  }
   243  
   244  // deadline returns the earliest of:
   245  //   - now+Timeout
   246  //   - d.Deadline
   247  //   - the context's deadline
   248  //
   249  // Or zero, if none of Timeout, Deadline, or context's deadline is set.
   250  func (d *Dialer) deadline(ctx context.Context, now time.Time) (earliest time.Time) {
   251  	if d.Timeout != 0 { // including negative, for historical reasons
   252  		earliest = now.Add(d.Timeout)
   253  	}
   254  	if d, ok := ctx.Deadline(); ok {
   255  		earliest = minNonzeroTime(earliest, d)
   256  	}
   257  	return minNonzeroTime(earliest, d.Deadline)
   258  }
   259  
   260  func (d *Dialer) resolver() *Resolver {
   261  	if d.Resolver != nil {
   262  		return d.Resolver
   263  	}
   264  	return DefaultResolver
   265  }
   266  
   267  // partialDeadline returns the deadline to use for a single address,
   268  // when multiple addresses are pending.
   269  func partialDeadline(now, deadline time.Time, addrsRemaining int) (time.Time, error) {
   270  	if deadline.IsZero() {
   271  		return deadline, nil
   272  	}
   273  	timeRemaining := deadline.Sub(now)
   274  	if timeRemaining <= 0 {
   275  		return time.Time{}, errTimeout
   276  	}
   277  	// Tentatively allocate equal time to each remaining address.
   278  	timeout := timeRemaining / time.Duration(addrsRemaining)
   279  	// If the time per address is too short, steal from the end of the list.
   280  	const saneMinimum = 2 * time.Second
   281  	if timeout < saneMinimum {
   282  		if timeRemaining < saneMinimum {
   283  			timeout = timeRemaining
   284  		} else {
   285  			timeout = saneMinimum
   286  		}
   287  	}
   288  	return now.Add(timeout), nil
   289  }
   290  
   291  func (d *Dialer) fallbackDelay() time.Duration {
   292  	if d.FallbackDelay > 0 {
   293  		return d.FallbackDelay
   294  	} else {
   295  		return 300 * time.Millisecond
   296  	}
   297  }
   298  
   299  func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet string, proto int, err error) {
   300  	i := bytealg.LastIndexByteString(network, ':')
   301  	if i < 0 { // no colon
   302  		switch network {
   303  		case "tcp", "tcp4", "tcp6":
   304  		case "udp", "udp4", "udp6":
   305  		case "ip", "ip4", "ip6":
   306  			if needsProto {
   307  				return "", 0, UnknownNetworkError(network)
   308  			}
   309  		case "unix", "unixgram", "unixpacket":
   310  		default:
   311  			return "", 0, UnknownNetworkError(network)
   312  		}
   313  		return network, 0, nil
   314  	}
   315  	afnet = network[:i]
   316  	switch afnet {
   317  	case "ip", "ip4", "ip6":
   318  		protostr := network[i+1:]
   319  		proto, i, ok := dtoi(protostr)
   320  		if !ok || i != len(protostr) {
   321  			proto, err = lookupProtocol(ctx, protostr)
   322  			if err != nil {
   323  				return "", 0, err
   324  			}
   325  		}
   326  		return afnet, proto, nil
   327  	}
   328  	return "", 0, UnknownNetworkError(network)
   329  }
   330  
   331  // resolveAddrList resolves addr using hint and returns a list of
   332  // addresses. The result contains at least one address when error is
   333  // nil.
   334  func (r *Resolver) resolveAddrList(ctx context.Context, op, network, addr string, hint Addr) (addrList, error) {
   335  	afnet, _, err := parseNetwork(ctx, network, true)
   336  	if err != nil {
   337  		return nil, err
   338  	}
   339  	if op == "dial" && addr == "" {
   340  		return nil, errMissingAddress
   341  	}
   342  	switch afnet {
   343  	case "unix", "unixgram", "unixpacket":
   344  		addr, err := ResolveUnixAddr(afnet, addr)
   345  		if err != nil {
   346  			return nil, err
   347  		}
   348  		if op == "dial" && hint != nil && addr.Network() != hint.Network() {
   349  			return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()}
   350  		}
   351  		return addrList{addr}, nil
   352  	}
   353  	addrs, err := r.internetAddrList(ctx, afnet, addr)
   354  	if err != nil || op != "dial" || hint == nil {
   355  		return addrs, err
   356  	}
   357  	var (
   358  		tcp      *TCPAddr
   359  		udp      *UDPAddr
   360  		ip       *IPAddr
   361  		wildcard bool
   362  	)
   363  	switch hint := hint.(type) {
   364  	case *TCPAddr:
   365  		tcp = hint
   366  		wildcard = tcp.isWildcard()
   367  	case *UDPAddr:
   368  		udp = hint
   369  		wildcard = udp.isWildcard()
   370  	case *IPAddr:
   371  		ip = hint
   372  		wildcard = ip.isWildcard()
   373  	}
   374  	naddrs := addrs[:0]
   375  	for _, addr := range addrs {
   376  		if addr.Network() != hint.Network() {
   377  			return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()}
   378  		}
   379  		switch addr := addr.(type) {
   380  		case *TCPAddr:
   381  			if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(tcp.IP) {
   382  				continue
   383  			}
   384  			naddrs = append(naddrs, addr)
   385  		case *UDPAddr:
   386  			if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(udp.IP) {
   387  				continue
   388  			}
   389  			naddrs = append(naddrs, addr)
   390  		case *IPAddr:
   391  			if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(ip.IP) {
   392  				continue
   393  			}
   394  			naddrs = append(naddrs, addr)
   395  		}
   396  	}
   397  	if len(naddrs) == 0 {
   398  		return nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: hint.String()}
   399  	}
   400  	return naddrs, nil
   401  }
   402  
   403  // MultipathTCP reports whether MPTCP will be used.
   404  //
   405  // This method doesn't check if MPTCP is supported by the operating
   406  // system or not.
   407  func (d *Dialer) MultipathTCP() bool {
   408  	return d.mptcpStatus.get()
   409  }
   410  
   411  // SetMultipathTCP directs the [Dial] methods to use, or not use, MPTCP,
   412  // if supported by the operating system. This method overrides the
   413  // system default and the GODEBUG=multipathtcp=... setting if any.
   414  //
   415  // If MPTCP is not available on the host or not supported by the server,
   416  // the Dial methods will fall back to TCP.
   417  func (d *Dialer) SetMultipathTCP(use bool) {
   418  	d.mptcpStatus.set(use)
   419  }
   420  
   421  // Dial connects to the address on the named network.
   422  //
   423  // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
   424  // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
   425  // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
   426  // "unixpacket".
   427  //
   428  // For TCP and UDP networks, the address has the form "host:port".
   429  // The host must be a literal IP address, or a host name that can be
   430  // resolved to IP addresses.
   431  // The port must be a literal port number or a service name.
   432  // If the host is a literal IPv6 address it must be enclosed in square
   433  // brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80".
   434  // The zone specifies the scope of the literal IPv6 address as defined
   435  // in RFC 4007.
   436  // The functions [JoinHostPort] and [SplitHostPort] manipulate a pair of
   437  // host and port in this form.
   438  // When using TCP, and the host resolves to multiple IP addresses,
   439  // Dial will try each IP address in order until one succeeds.
   440  //
   441  // Examples:
   442  //
   443  //	Dial("tcp", "golang.org:http")
   444  //	Dial("tcp", "192.0.2.1:http")
   445  //	Dial("tcp", "198.51.100.1:80")
   446  //	Dial("udp", "[2001:db8::1]:domain")
   447  //	Dial("udp", "[fe80::1%lo0]:53")
   448  //	Dial("tcp", ":80")
   449  //
   450  // For IP networks, the network must be "ip", "ip4" or "ip6" followed
   451  // by a colon and a literal protocol number or a protocol name, and
   452  // the address has the form "host". The host must be a literal IP
   453  // address or a literal IPv6 address with zone.
   454  // It depends on each operating system how the operating system
   455  // behaves with a non-well known protocol number such as "0" or "255".
   456  //
   457  // Examples:
   458  //
   459  //	Dial("ip4:1", "192.0.2.1")
   460  //	Dial("ip6:ipv6-icmp", "2001:db8::1")
   461  //	Dial("ip6:58", "fe80::1%lo0")
   462  //
   463  // For TCP, UDP and IP networks, if the host is empty or a literal
   464  // unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for
   465  // TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is
   466  // assumed.
   467  //
   468  // For Unix networks, the address must be a file system path.
   469  func Dial(network, address string) (Conn, error) {
   470  	var d Dialer
   471  	return d.Dial(network, address)
   472  }
   473  
   474  // DialTimeout acts like [Dial] but takes a timeout.
   475  //
   476  // The timeout includes name resolution, if required.
   477  // When using TCP, and the host in the address parameter resolves to
   478  // multiple IP addresses, the timeout is spread over each consecutive
   479  // dial, such that each is given an appropriate fraction of the time
   480  // to connect.
   481  //
   482  // See func Dial for a description of the network and address
   483  // parameters.
   484  func DialTimeout(network, address string, timeout time.Duration) (Conn, error) {
   485  	d := Dialer{Timeout: timeout}
   486  	return d.Dial(network, address)
   487  }
   488  
   489  // sysDialer contains a Dial's parameters and configuration.
   490  type sysDialer struct {
   491  	Dialer
   492  	network, address string
   493  	testHookDialTCP  func(ctx context.Context, net string, laddr, raddr *TCPAddr) (*TCPConn, error)
   494  }
   495  
   496  // Dial connects to the address on the named network.
   497  //
   498  // See func Dial for a description of the network and address
   499  // parameters.
   500  //
   501  // Dial uses [context.Background] internally; to specify the context, use
   502  // [Dialer.DialContext].
   503  func (d *Dialer) Dial(network, address string) (Conn, error) {
   504  	return d.DialContext(context.Background(), network, address)
   505  }
   506  
   507  // DialContext connects to the address on the named network using
   508  // the provided context.
   509  //
   510  // The provided Context must be non-nil. If the context expires before
   511  // the connection is complete, an error is returned. Once successfully
   512  // connected, any expiration of the context will not affect the
   513  // connection.
   514  //
   515  // When using TCP, and the host in the address parameter resolves to multiple
   516  // network addresses, any dial timeout (from d.Timeout or ctx) is spread
   517  // over each consecutive dial, such that each is given an appropriate
   518  // fraction of the time to connect.
   519  // For example, if a host has 4 IP addresses and the timeout is 1 minute,
   520  // the connect to each single address will be given 15 seconds to complete
   521  // before trying the next one.
   522  //
   523  // See func [Dial] for a description of the network and address
   524  // parameters.
   525  func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) {
   526  	if ctx == nil {
   527  		panic("nil context")
   528  	}
   529  	deadline := d.deadline(ctx, time.Now())
   530  	if !deadline.IsZero() {
   531  		testHookStepTime()
   532  		if d, ok := ctx.Deadline(); !ok || deadline.Before(d) {
   533  			subCtx, cancel := context.WithDeadline(ctx, deadline)
   534  			defer cancel()
   535  			ctx = subCtx
   536  		}
   537  	}
   538  	if oldCancel := d.Cancel; oldCancel != nil {
   539  		subCtx, cancel := context.WithCancel(ctx)
   540  		defer cancel()
   541  		go func() {
   542  			select {
   543  			case <-oldCancel:
   544  				cancel()
   545  			case <-subCtx.Done():
   546  			}
   547  		}()
   548  		ctx = subCtx
   549  	}
   550  
   551  	// Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups.
   552  	resolveCtx := ctx
   553  	if trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace); trace != nil {
   554  		shadow := *trace
   555  		shadow.ConnectStart = nil
   556  		shadow.ConnectDone = nil
   557  		resolveCtx = context.WithValue(resolveCtx, nettrace.TraceKey{}, &shadow)
   558  	}
   559  
   560  	addrs, err := d.resolver().resolveAddrList(resolveCtx, "dial", network, address, d.LocalAddr)
   561  	if err != nil {
   562  		return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err}
   563  	}
   564  
   565  	sd := &sysDialer{
   566  		Dialer:  *d,
   567  		network: network,
   568  		address: address,
   569  	}
   570  
   571  	var primaries, fallbacks addrList
   572  	if d.dualStack() && network == "tcp" {
   573  		primaries, fallbacks = addrs.partition(isIPv4)
   574  	} else {
   575  		primaries = addrs
   576  	}
   577  
   578  	return sd.dialParallel(ctx, primaries, fallbacks)
   579  }
   580  
   581  // dialParallel races two copies of dialSerial, giving the first a
   582  // head start. It returns the first established connection and
   583  // closes the others. Otherwise it returns an error from the first
   584  // primary address.
   585  func (sd *sysDialer) dialParallel(ctx context.Context, primaries, fallbacks addrList) (Conn, error) {
   586  	if len(fallbacks) == 0 {
   587  		return sd.dialSerial(ctx, primaries)
   588  	}
   589  
   590  	returned := make(chan struct{})
   591  	defer close(returned)
   592  
   593  	type dialResult struct {
   594  		Conn
   595  		error
   596  		primary bool
   597  		done    bool
   598  	}
   599  	results := make(chan dialResult) // unbuffered
   600  
   601  	startRacer := func(ctx context.Context, primary bool) {
   602  		ras := primaries
   603  		if !primary {
   604  			ras = fallbacks
   605  		}
   606  		c, err := sd.dialSerial(ctx, ras)
   607  		select {
   608  		case results <- dialResult{Conn: c, error: err, primary: primary, done: true}:
   609  		case <-returned:
   610  			if c != nil {
   611  				c.Close()
   612  			}
   613  		}
   614  	}
   615  
   616  	var primary, fallback dialResult
   617  
   618  	// Start the main racer.
   619  	primaryCtx, primaryCancel := context.WithCancel(ctx)
   620  	defer primaryCancel()
   621  	go startRacer(primaryCtx, true)
   622  
   623  	// Start the timer for the fallback racer.
   624  	fallbackTimer := time.NewTimer(sd.fallbackDelay())
   625  	defer fallbackTimer.Stop()
   626  
   627  	for {
   628  		select {
   629  		case <-fallbackTimer.C:
   630  			fallbackCtx, fallbackCancel := context.WithCancel(ctx)
   631  			defer fallbackCancel()
   632  			go startRacer(fallbackCtx, false)
   633  
   634  		case res := <-results:
   635  			if res.error == nil {
   636  				return res.Conn, nil
   637  			}
   638  			if res.primary {
   639  				primary = res
   640  			} else {
   641  				fallback = res
   642  			}
   643  			if primary.done && fallback.done {
   644  				return nil, primary.error
   645  			}
   646  			if res.primary && fallbackTimer.Stop() {
   647  				// If we were able to stop the timer, that means it
   648  				// was running (hadn't yet started the fallback), but
   649  				// we just got an error on the primary path, so start
   650  				// the fallback immediately (in 0 nanoseconds).
   651  				fallbackTimer.Reset(0)
   652  			}
   653  		}
   654  	}
   655  }
   656  
   657  // dialSerial connects to a list of addresses in sequence, returning
   658  // either the first successful connection, or the first error.
   659  func (sd *sysDialer) dialSerial(ctx context.Context, ras addrList) (Conn, error) {
   660  	var firstErr error // The error from the first address is most relevant.
   661  
   662  	for i, ra := range ras {
   663  		select {
   664  		case <-ctx.Done():
   665  			return nil, &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: mapErr(ctx.Err())}
   666  		default:
   667  		}
   668  
   669  		dialCtx := ctx
   670  		if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
   671  			partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i)
   672  			if err != nil {
   673  				// Ran out of time.
   674  				if firstErr == nil {
   675  					firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err}
   676  				}
   677  				break
   678  			}
   679  			if partialDeadline.Before(deadline) {
   680  				var cancel context.CancelFunc
   681  				dialCtx, cancel = context.WithDeadline(ctx, partialDeadline)
   682  				defer cancel()
   683  			}
   684  		}
   685  
   686  		c, err := sd.dialSingle(dialCtx, ra)
   687  		if err == nil {
   688  			return c, nil
   689  		}
   690  		if firstErr == nil {
   691  			firstErr = err
   692  		}
   693  	}
   694  
   695  	if firstErr == nil {
   696  		firstErr = &OpError{Op: "dial", Net: sd.network, Source: nil, Addr: nil, Err: errMissingAddress}
   697  	}
   698  	return nil, firstErr
   699  }
   700  
   701  // dialSingle attempts to establish and returns a single connection to
   702  // the destination address.
   703  func (sd *sysDialer) dialSingle(ctx context.Context, ra Addr) (c Conn, err error) {
   704  	trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace)
   705  	if trace != nil {
   706  		raStr := ra.String()
   707  		if trace.ConnectStart != nil {
   708  			trace.ConnectStart(sd.network, raStr)
   709  		}
   710  		if trace.ConnectDone != nil {
   711  			defer func() { trace.ConnectDone(sd.network, raStr, err) }()
   712  		}
   713  	}
   714  	la := sd.LocalAddr
   715  	switch ra := ra.(type) {
   716  	case *TCPAddr:
   717  		la, _ := la.(*TCPAddr)
   718  		if sd.MultipathTCP() {
   719  			c, err = sd.dialMPTCP(ctx, la, ra)
   720  		} else {
   721  			c, err = sd.dialTCP(ctx, la, ra)
   722  		}
   723  	case *UDPAddr:
   724  		la, _ := la.(*UDPAddr)
   725  		c, err = sd.dialUDP(ctx, la, ra)
   726  	case *IPAddr:
   727  		la, _ := la.(*IPAddr)
   728  		c, err = sd.dialIP(ctx, la, ra)
   729  	case *UnixAddr:
   730  		la, _ := la.(*UnixAddr)
   731  		c, err = sd.dialUnix(ctx, la, ra)
   732  	default:
   733  		return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: sd.address}}
   734  	}
   735  	if err != nil {
   736  		return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: err} // c is non-nil interface containing nil pointer
   737  	}
   738  	return c, nil
   739  }
   740  
   741  // ListenConfig contains options for listening to an address.
   742  type ListenConfig struct {
   743  	// If Control is not nil, it is called after creating the network
   744  	// connection but before binding it to the operating system.
   745  	//
   746  	// Network and address parameters passed to Control function are not
   747  	// necessarily the ones passed to Listen. Calling Listen with TCP networks
   748  	// will cause the Control function to be called with "tcp4" or "tcp6",
   749  	// UDP networks become "udp4" or "udp6", IP networks become "ip4" or "ip6",
   750  	// and other known networks are passed as-is.
   751  	Control func(network, address string, c syscall.RawConn) error
   752  
   753  	// KeepAlive specifies the keep-alive period for network
   754  	// connections accepted by this listener.
   755  	//
   756  	// KeepAlive is ignored if KeepAliveConfig.Enable is true.
   757  	//
   758  	// If zero, keep-alive are enabled if supported by the protocol
   759  	// and operating system. Network protocols or operating systems
   760  	// that do not support keep-alive ignore this field.
   761  	// If negative, keep-alive are disabled.
   762  	KeepAlive time.Duration
   763  
   764  	// KeepAliveConfig specifies the keep-alive probe configuration
   765  	// for an active network connection, when supported by the
   766  	// protocol and operating system.
   767  	//
   768  	// If KeepAliveConfig.Enable is true, keep-alive probes are enabled.
   769  	// If KeepAliveConfig.Enable is false and KeepAlive is negative,
   770  	// keep-alive probes are disabled.
   771  	KeepAliveConfig KeepAliveConfig
   772  
   773  	// If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
   774  	// used, any call to Listen with "tcp(4|6)" as network will use MPTCP if
   775  	// supported by the operating system.
   776  	mptcpStatus mptcpStatusListen
   777  }
   778  
   779  // MultipathTCP reports whether MPTCP will be used.
   780  //
   781  // This method doesn't check if MPTCP is supported by the operating
   782  // system or not.
   783  func (lc *ListenConfig) MultipathTCP() bool {
   784  	return lc.mptcpStatus.get()
   785  }
   786  
   787  // SetMultipathTCP directs the [Listen] method to use, or not use, MPTCP,
   788  // if supported by the operating system. This method overrides the
   789  // system default and the GODEBUG=multipathtcp=... setting if any.
   790  //
   791  // If MPTCP is not available on the host or not supported by the client,
   792  // the Listen method will fall back to TCP.
   793  func (lc *ListenConfig) SetMultipathTCP(use bool) {
   794  	lc.mptcpStatus.set(use)
   795  }
   796  
   797  // Listen announces on the local network address.
   798  //
   799  // See func Listen for a description of the network and address
   800  // parameters.
   801  //
   802  // The ctx argument is used while resolving the address on which to listen;
   803  // it does not affect the returned Listener.
   804  func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) {
   805  	addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
   806  	if err != nil {
   807  		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
   808  	}
   809  	sl := &sysListener{
   810  		ListenConfig: *lc,
   811  		network:      network,
   812  		address:      address,
   813  	}
   814  	var l Listener
   815  	la := addrs.first(isIPv4)
   816  	switch la := la.(type) {
   817  	case *TCPAddr:
   818  		if sl.MultipathTCP() {
   819  			l, err = sl.listenMPTCP(ctx, la)
   820  		} else {
   821  			l, err = sl.listenTCP(ctx, la)
   822  		}
   823  	case *UnixAddr:
   824  		l, err = sl.listenUnix(ctx, la)
   825  	default:
   826  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
   827  	}
   828  	if err != nil {
   829  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // l is non-nil interface containing nil pointer
   830  	}
   831  	return l, nil
   832  }
   833  
   834  // ListenPacket announces on the local network address.
   835  //
   836  // See func ListenPacket for a description of the network and address
   837  // parameters.
   838  //
   839  // The ctx argument is used while resolving the address on which to listen;
   840  // it does not affect the returned Listener.
   841  func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (PacketConn, error) {
   842  	addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
   843  	if err != nil {
   844  		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
   845  	}
   846  	sl := &sysListener{
   847  		ListenConfig: *lc,
   848  		network:      network,
   849  		address:      address,
   850  	}
   851  	var c PacketConn
   852  	la := addrs.first(isIPv4)
   853  	switch la := la.(type) {
   854  	case *UDPAddr:
   855  		c, err = sl.listenUDP(ctx, la)
   856  	case *IPAddr:
   857  		c, err = sl.listenIP(ctx, la)
   858  	case *UnixAddr:
   859  		c, err = sl.listenUnixgram(ctx, la)
   860  	default:
   861  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
   862  	}
   863  	if err != nil {
   864  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // c is non-nil interface containing nil pointer
   865  	}
   866  	return c, nil
   867  }
   868  
   869  // sysListener contains a Listen's parameters and configuration.
   870  type sysListener struct {
   871  	ListenConfig
   872  	network, address string
   873  }
   874  
   875  // Listen announces on the local network address.
   876  //
   877  // The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
   878  //
   879  // For TCP networks, if the host in the address parameter is empty or
   880  // a literal unspecified IP address, Listen listens on all available
   881  // unicast and anycast IP addresses of the local system.
   882  // To only use IPv4, use network "tcp4".
   883  // The address can use a host name, but this is not recommended,
   884  // because it will create a listener for at most one of the host's IP
   885  // addresses.
   886  // If the port in the address parameter is empty or "0", as in
   887  // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
   888  // The [Addr] method of [Listener] can be used to discover the chosen
   889  // port.
   890  //
   891  // See func [Dial] for a description of the network and address
   892  // parameters.
   893  //
   894  // Listen uses context.Background internally; to specify the context, use
   895  // [ListenConfig.Listen].
   896  func Listen(network, address string) (Listener, error) {
   897  	var lc ListenConfig
   898  	return lc.Listen(context.Background(), network, address)
   899  }
   900  
   901  // ListenPacket announces on the local network address.
   902  //
   903  // The network must be "udp", "udp4", "udp6", "unixgram", or an IP
   904  // transport. The IP transports are "ip", "ip4", or "ip6" followed by
   905  // a colon and a literal protocol number or a protocol name, as in
   906  // "ip:1" or "ip:icmp".
   907  //
   908  // For UDP and IP networks, if the host in the address parameter is
   909  // empty or a literal unspecified IP address, ListenPacket listens on
   910  // all available IP addresses of the local system except multicast IP
   911  // addresses.
   912  // To only use IPv4, use network "udp4" or "ip4:proto".
   913  // The address can use a host name, but this is not recommended,
   914  // because it will create a listener for at most one of the host's IP
   915  // addresses.
   916  // If the port in the address parameter is empty or "0", as in
   917  // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
   918  // The LocalAddr method of [PacketConn] can be used to discover the
   919  // chosen port.
   920  //
   921  // See func [Dial] for a description of the network and address
   922  // parameters.
   923  //
   924  // ListenPacket uses context.Background internally; to specify the context, use
   925  // [ListenConfig.ListenPacket].
   926  func ListenPacket(network, address string) (PacketConn, error) {
   927  	var lc ListenConfig
   928  	return lc.ListenPacket(context.Background(), network, address)
   929  }
   930  

View as plain text