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