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

View as plain text