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