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