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

View as plain text