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