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