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