Help us shape the future of Go! Take the 2026 Go Developer Survey

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  	var laddrTCP, raddrTCP *TCPAddr
   611  	if laddr.IsValid() {
   612  		laddrTCP = TCPAddrFromAddrPort(laddr)
   613  	}
   614  	if raddr.IsValid() {
   615  		raddrTCP = TCPAddrFromAddrPort(raddr)
   616  	}
   617  	return dialTCP(ctx, d, network, laddrTCP, raddrTCP)
   618  }
   619  
   620  // DialUDP acts like Dial for UDP networks using the provided context.
   621  //
   622  // The provided Context must be non-nil. If the context expires before
   623  // the connection is complete, an error is returned. Once successfully
   624  // connected, any expiration of the context will not affect the
   625  // connection.
   626  //
   627  // The network must be a UDP network name; see func Dial for details.
   628  func (d *Dialer) DialUDP(ctx context.Context, network string, laddr netip.AddrPort, raddr netip.AddrPort) (*UDPConn, error) {
   629  	ctx, cancel := d.dialCtx(ctx)
   630  	defer cancel()
   631  	var laddrUDP, raddrUDP *UDPAddr
   632  	if laddr.IsValid() {
   633  		laddrUDP = UDPAddrFromAddrPort(laddr)
   634  	}
   635  	if raddr.IsValid() {
   636  		raddrUDP = UDPAddrFromAddrPort(raddr)
   637  	}
   638  	return dialUDP(ctx, d, network, laddrUDP, raddrUDP)
   639  }
   640  
   641  // DialIP acts like Dial for IP 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 an IP network name; see func Dial for details.
   649  func (d *Dialer) DialIP(ctx context.Context, network string, laddr netip.Addr, raddr netip.Addr) (*IPConn, error) {
   650  	ctx, cancel := d.dialCtx(ctx)
   651  	defer cancel()
   652  	var laddrIP, raddrIP *IPAddr
   653  	if laddr.IsValid() {
   654  		laddrIP = ipAddrFromAddr(laddr)
   655  	}
   656  	if raddr.IsValid() {
   657  		raddrIP = ipAddrFromAddr(raddr)
   658  	}
   659  	return dialIP(ctx, d, network, laddrIP, raddrIP)
   660  }
   661  
   662  // DialUnix acts like Dial for Unix networks using the provided context.
   663  //
   664  // The provided Context must be non-nil. If the context expires before
   665  // the connection is complete, an error is returned. Once successfully
   666  // connected, any expiration of the context will not affect the
   667  // connection.
   668  //
   669  // The network must be a Unix network name; see func Dial for details.
   670  func (d *Dialer) DialUnix(ctx context.Context, network string, laddr *UnixAddr, raddr *UnixAddr) (*UnixConn, error) {
   671  	ctx, cancel := d.dialCtx(ctx)
   672  	defer cancel()
   673  	return dialUnix(ctx, d, network, laddr, raddr)
   674  }
   675  
   676  // dialParallel races two copies of dialSerial, giving the first a
   677  // head start. It returns the first established connection and
   678  // closes the others. Otherwise it returns an error from the first
   679  // primary address.
   680  func (sd *sysDialer) dialParallel(ctx context.Context, primaries, fallbacks addrList) (Conn, error) {
   681  	if len(fallbacks) == 0 {
   682  		return sd.dialSerial(ctx, primaries)
   683  	}
   684  
   685  	returned := make(chan struct{})
   686  	defer close(returned)
   687  
   688  	type dialResult struct {
   689  		Conn
   690  		error   error
   691  		primary bool
   692  		done    bool
   693  	}
   694  	results := make(chan dialResult) // unbuffered
   695  
   696  	startRacer := func(ctx context.Context, primary bool) {
   697  		ras := primaries
   698  		if !primary {
   699  			ras = fallbacks
   700  		}
   701  		c, err := sd.dialSerial(ctx, ras)
   702  		select {
   703  		case results <- dialResult{Conn: c, error: err, primary: primary, done: true}:
   704  		case <-returned:
   705  			if c != nil {
   706  				c.Close()
   707  			}
   708  		}
   709  	}
   710  
   711  	var primary, fallback dialResult
   712  
   713  	// Start the main racer.
   714  	primaryCtx, primaryCancel := context.WithCancel(ctx)
   715  	defer primaryCancel()
   716  	go startRacer(primaryCtx, true)
   717  
   718  	// Start the timer for the fallback racer.
   719  	fallbackTimer := time.NewTimer(sd.fallbackDelay())
   720  	defer fallbackTimer.Stop()
   721  
   722  	for {
   723  		select {
   724  		case <-fallbackTimer.C:
   725  			fallbackCtx, fallbackCancel := context.WithCancel(ctx)
   726  			defer fallbackCancel()
   727  			go startRacer(fallbackCtx, false)
   728  
   729  		case res := <-results:
   730  			if res.error == nil {
   731  				return res.Conn, nil
   732  			}
   733  			if res.primary {
   734  				primary = res
   735  			} else {
   736  				fallback = res
   737  			}
   738  			if primary.done && fallback.done {
   739  				return nil, primary.error
   740  			}
   741  			if res.primary && fallbackTimer.Stop() {
   742  				// If we were able to stop the timer, that means it
   743  				// was running (hadn't yet started the fallback), but
   744  				// we just got an error on the primary path, so start
   745  				// the fallback immediately (in 0 nanoseconds).
   746  				fallbackTimer.Reset(0)
   747  			}
   748  		}
   749  	}
   750  }
   751  
   752  // dialSerial connects to a list of addresses in sequence, returning
   753  // either the first successful connection, or the first error.
   754  func (sd *sysDialer) dialSerial(ctx context.Context, ras addrList) (Conn, error) {
   755  	var firstErr error // The error from the first address is most relevant.
   756  
   757  	for i, ra := range ras {
   758  		select {
   759  		case <-ctx.Done():
   760  			return nil, &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: mapErr(ctx.Err())}
   761  		default:
   762  		}
   763  
   764  		dialCtx := ctx
   765  		if deadline, hasDeadline := ctx.Deadline(); hasDeadline {
   766  			partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i)
   767  			if err != nil {
   768  				// Ran out of time.
   769  				if firstErr == nil {
   770  					firstErr = &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: err}
   771  				}
   772  				break
   773  			}
   774  			if partialDeadline.Before(deadline) {
   775  				var cancel context.CancelFunc
   776  				dialCtx, cancel = context.WithDeadline(ctx, partialDeadline)
   777  				defer cancel()
   778  			}
   779  		}
   780  
   781  		c, err := sd.dialSingle(dialCtx, ra)
   782  		if err == nil {
   783  			return c, nil
   784  		}
   785  		if firstErr == nil {
   786  			firstErr = err
   787  		}
   788  	}
   789  
   790  	if firstErr == nil {
   791  		firstErr = &OpError{Op: "dial", Net: sd.network, Source: nil, Addr: nil, Err: errMissingAddress}
   792  	}
   793  	return nil, firstErr
   794  }
   795  
   796  // dialSingle attempts to establish and returns a single connection to
   797  // the destination address.
   798  func (sd *sysDialer) dialSingle(ctx context.Context, ra Addr) (c Conn, err error) {
   799  	trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace)
   800  	if trace != nil {
   801  		raStr := ra.String()
   802  		if trace.ConnectStart != nil {
   803  			trace.ConnectStart(sd.network, raStr)
   804  		}
   805  		if trace.ConnectDone != nil {
   806  			defer func() { trace.ConnectDone(sd.network, raStr, err) }()
   807  		}
   808  	}
   809  	la := sd.LocalAddr
   810  	switch ra := ra.(type) {
   811  	case *TCPAddr:
   812  		la, _ := la.(*TCPAddr)
   813  		if sd.MultipathTCP() {
   814  			c, err = sd.dialMPTCP(ctx, la, ra)
   815  		} else {
   816  			c, err = sd.dialTCP(ctx, la, ra)
   817  		}
   818  	case *UDPAddr:
   819  		la, _ := la.(*UDPAddr)
   820  		c, err = sd.dialUDP(ctx, la, ra)
   821  	case *IPAddr:
   822  		la, _ := la.(*IPAddr)
   823  		c, err = sd.dialIP(ctx, la, ra)
   824  	case *UnixAddr:
   825  		la, _ := la.(*UnixAddr)
   826  		c, err = sd.dialUnix(ctx, la, ra)
   827  	default:
   828  		return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: sd.address}}
   829  	}
   830  	if err != nil {
   831  		return nil, &OpError{Op: "dial", Net: sd.network, Source: la, Addr: ra, Err: err} // c is non-nil interface containing nil pointer
   832  	}
   833  	return c, nil
   834  }
   835  
   836  // ListenConfig contains options for listening to an address.
   837  type ListenConfig struct {
   838  	// If Control is not nil, it is called after creating the network
   839  	// connection but before binding it to the operating system.
   840  	//
   841  	// Network and address parameters passed to Control function are not
   842  	// necessarily the ones passed to Listen. Calling Listen with TCP networks
   843  	// will cause the Control function to be called with "tcp4" or "tcp6",
   844  	// UDP networks become "udp4" or "udp6", IP networks become "ip4" or "ip6",
   845  	// and other known networks are passed as-is.
   846  	Control func(network, address string, c syscall.RawConn) error
   847  
   848  	// KeepAlive specifies the keep-alive period for network
   849  	// connections accepted by this listener.
   850  	//
   851  	// KeepAlive is ignored if KeepAliveConfig.Enable is true.
   852  	//
   853  	// If zero, keep-alive are enabled if supported by the protocol
   854  	// and operating system. Network protocols or operating systems
   855  	// that do not support keep-alive ignore this field.
   856  	// If negative, keep-alive are disabled.
   857  	KeepAlive time.Duration
   858  
   859  	// KeepAliveConfig specifies the keep-alive probe configuration
   860  	// for an active network connection, when supported by the
   861  	// protocol and operating system.
   862  	//
   863  	// If KeepAliveConfig.Enable is true, keep-alive probes are enabled.
   864  	// If KeepAliveConfig.Enable is false and KeepAlive is negative,
   865  	// keep-alive probes are disabled.
   866  	KeepAliveConfig KeepAliveConfig
   867  
   868  	// If mptcpStatus is set to a value allowing Multipath TCP (MPTCP) to be
   869  	// used, any call to Listen with "tcp(4|6)" as network will use MPTCP if
   870  	// supported by the operating system.
   871  	mptcpStatus mptcpStatusListen
   872  }
   873  
   874  // MultipathTCP reports whether MPTCP will be used.
   875  //
   876  // This method doesn't check if MPTCP is supported by the operating
   877  // system or not.
   878  func (lc *ListenConfig) MultipathTCP() bool {
   879  	return lc.mptcpStatus.get()
   880  }
   881  
   882  // SetMultipathTCP directs the [Listen] method to use, or not use, MPTCP,
   883  // if supported by the operating system. This method overrides the
   884  // system default and the GODEBUG=multipathtcp=... setting if any.
   885  //
   886  // If MPTCP is not available on the host or not supported by the client,
   887  // the Listen method will fall back to TCP.
   888  func (lc *ListenConfig) SetMultipathTCP(use bool) {
   889  	lc.mptcpStatus.set(use)
   890  }
   891  
   892  // Listen announces on the local network address.
   893  //
   894  // See func Listen for a description of the network and address
   895  // parameters.
   896  //
   897  // The ctx argument is used while resolving the address on which to listen;
   898  // it does not affect the returned Listener.
   899  func (lc *ListenConfig) Listen(ctx context.Context, network, address string) (Listener, error) {
   900  	addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
   901  	if err != nil {
   902  		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
   903  	}
   904  	sl := &sysListener{
   905  		ListenConfig: *lc,
   906  		network:      network,
   907  		address:      address,
   908  	}
   909  	var l Listener
   910  	la := addrs.first(isIPv4)
   911  	switch la := la.(type) {
   912  	case *TCPAddr:
   913  		if sl.MultipathTCP() {
   914  			l, err = sl.listenMPTCP(ctx, la)
   915  		} else {
   916  			l, err = sl.listenTCP(ctx, la)
   917  		}
   918  	case *UnixAddr:
   919  		l, err = sl.listenUnix(ctx, la)
   920  	default:
   921  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
   922  	}
   923  	if err != nil {
   924  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // l is non-nil interface containing nil pointer
   925  	}
   926  	return l, nil
   927  }
   928  
   929  // ListenPacket announces on the local network address.
   930  //
   931  // See func ListenPacket for a description of the network and address
   932  // parameters.
   933  //
   934  // The ctx argument is used while resolving the address on which to listen;
   935  // it does not affect the returned PacketConn.
   936  func (lc *ListenConfig) ListenPacket(ctx context.Context, network, address string) (PacketConn, error) {
   937  	addrs, err := DefaultResolver.resolveAddrList(ctx, "listen", network, address, nil)
   938  	if err != nil {
   939  		return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err}
   940  	}
   941  	sl := &sysListener{
   942  		ListenConfig: *lc,
   943  		network:      network,
   944  		address:      address,
   945  	}
   946  	var c PacketConn
   947  	la := addrs.first(isIPv4)
   948  	switch la := la.(type) {
   949  	case *UDPAddr:
   950  		c, err = sl.listenUDP(ctx, la)
   951  	case *IPAddr:
   952  		c, err = sl.listenIP(ctx, la)
   953  	case *UnixAddr:
   954  		c, err = sl.listenUnixgram(ctx, la)
   955  	default:
   956  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}}
   957  	}
   958  	if err != nil {
   959  		return nil, &OpError{Op: "listen", Net: sl.network, Source: nil, Addr: la, Err: err} // c is non-nil interface containing nil pointer
   960  	}
   961  	return c, nil
   962  }
   963  
   964  // sysListener contains a Listen's parameters and configuration.
   965  type sysListener struct {
   966  	ListenConfig
   967  	network, address string
   968  }
   969  
   970  // Listen announces on the local network address.
   971  //
   972  // The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
   973  //
   974  // For TCP networks, if the host in the address parameter is empty or
   975  // a literal unspecified IP address, Listen listens on all available
   976  // unicast and anycast IP addresses of the local system.
   977  // To only use IPv4, use network "tcp4".
   978  // The address can use a host name, but this is not recommended,
   979  // because it will create a listener for at most one of the host's IP
   980  // addresses.
   981  // If the port in the address parameter is empty or "0", as in
   982  // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
   983  // The [Addr] method of [Listener] can be used to discover the chosen
   984  // port.
   985  //
   986  // See func [Dial] for a description of the network and address
   987  // parameters.
   988  //
   989  // Listen uses context.Background internally; to specify the context, use
   990  // [ListenConfig.Listen].
   991  func Listen(network, address string) (Listener, error) {
   992  	var lc ListenConfig
   993  	return lc.Listen(context.Background(), network, address)
   994  }
   995  
   996  // ListenPacket announces on the local network address.
   997  //
   998  // The network must be "udp", "udp4", "udp6", "unixgram", or an IP
   999  // transport. The IP transports are "ip", "ip4", or "ip6" followed by
  1000  // a colon and a literal protocol number or a protocol name, as in
  1001  // "ip:1" or "ip:icmp".
  1002  //
  1003  // For UDP and IP networks, if the host in the address parameter is
  1004  // empty or a literal unspecified IP address, ListenPacket listens on
  1005  // all available IP addresses of the local system except multicast IP
  1006  // addresses.
  1007  // To only use IPv4, use network "udp4" or "ip4:proto".
  1008  // The address can use a host name, but this is not recommended,
  1009  // because it will create a listener for at most one of the host's IP
  1010  // addresses.
  1011  // If the port in the address parameter is empty or "0", as in
  1012  // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
  1013  // The LocalAddr method of [PacketConn] can be used to discover the
  1014  // chosen port.
  1015  //
  1016  // See func [Dial] for a description of the network and address
  1017  // parameters.
  1018  //
  1019  // ListenPacket uses context.Background internally; to specify the context, use
  1020  // [ListenConfig.ListenPacket].
  1021  func ListenPacket(network, address string) (PacketConn, error) {
  1022  	var lc ListenConfig
  1023  	return lc.ListenPacket(context.Background(), network, address)
  1024  }
  1025  

View as plain text