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.
14 // A Dialer contains options for connecting to an address.
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.
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
24 // The default is no timeout.
26 // When using TCP and dialing a host name with multiple IP
27 // addresses, the timeout may be divided between them.
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.
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.
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.
46 // DualStack enables RFC 6555-compliant "Happy Eyeballs"
47 // dialing when the network is "tcp" and the host in the
48 // address parameter resolves to both IPv4 and IPv6 addresses.
49 // This allows a client to tolerate networks where one address
50 // family is silently broken.
53 // FallbackDelay specifies the length of time to wait before
54 // spawning a fallback connection, when DualStack is enabled.
55 // If zero, a default delay of 300ms is used.
56 FallbackDelay time
.Duration
58 // KeepAlive specifies the keep-alive period for an active
59 // network connection.
60 // If zero, keep-alives are not enabled. Network protocols
61 // that do not support keep-alives ignore this field.
62 KeepAlive time
.Duration
64 // Resolver optionally specifies an alternate resolver to use.
67 // Cancel is an optional channel whose closure indicates that
68 // the dial should be canceled. Not all types of dials support
71 // Deprecated: Use DialContext instead.
72 Cancel
<-chan struct{}
75 func minNonzeroTime(a
, b time
.Time
) time
.Time
{
79 if b
.IsZero() || a
.Before(b
) {
85 // deadline returns the earliest of:
88 // - the context's deadline
89 // Or zero, if none of Timeout, Deadline, or context's deadline is set.
90 func (d
*Dialer
) deadline(ctx context
.Context
, now time
.Time
) (earliest time
.Time
) {
91 if d
.Timeout
!= 0 { // including negative, for historical reasons
92 earliest
= now
.Add(d
.Timeout
)
94 if d
, ok
:= ctx
.Deadline(); ok
{
95 earliest
= minNonzeroTime(earliest
, d
)
97 return minNonzeroTime(earliest
, d
.Deadline
)
100 func (d
*Dialer
) resolver() *Resolver
{
101 if d
.Resolver
!= nil {
104 return DefaultResolver
107 // partialDeadline returns the deadline to use for a single address,
108 // when multiple addresses are pending.
109 func partialDeadline(now
, deadline time
.Time
, addrsRemaining
int) (time
.Time
, error
) {
110 if deadline
.IsZero() {
113 timeRemaining
:= deadline
.Sub(now
)
114 if timeRemaining
<= 0 {
115 return time
.Time
{}, poll
.ErrTimeout
117 // Tentatively allocate equal time to each remaining address.
118 timeout
:= timeRemaining
/ time
.Duration(addrsRemaining
)
119 // If the time per address is too short, steal from the end of the list.
120 const saneMinimum
= 2 * time
.Second
121 if timeout
< saneMinimum
{
122 if timeRemaining
< saneMinimum
{
123 timeout
= timeRemaining
125 timeout
= saneMinimum
128 return now
.Add(timeout
), nil
131 func (d
*Dialer
) fallbackDelay() time
.Duration
{
132 if d
.FallbackDelay
> 0 {
133 return d
.FallbackDelay
135 return 300 * time
.Millisecond
139 func parseNetwork(ctx context
.Context
, network
string, needsProto
bool) (afnet
string, proto
int, err error
) {
140 i
:= last(network
, ':')
141 if i
< 0 { // no colon
143 case "tcp", "tcp4", "tcp6":
144 case "udp", "udp4", "udp6":
145 case "ip", "ip4", "ip6":
147 return "", 0, UnknownNetworkError(network
)
149 case "unix", "unixgram", "unixpacket":
151 return "", 0, UnknownNetworkError(network
)
153 return network
, 0, nil
157 case "ip", "ip4", "ip6":
158 protostr
:= network
[i
+1:]
159 proto
, i
, ok
:= dtoi(protostr
)
160 if !ok || i
!= len(protostr
) {
161 proto
, err
= lookupProtocol(ctx
, protostr
)
166 return afnet
, proto
, nil
168 return "", 0, UnknownNetworkError(network
)
171 // resolveAddrList resolves addr using hint and returns a list of
172 // addresses. The result contains at least one address when error is
174 func (r
*Resolver
) resolveAddrList(ctx context
.Context
, op
, network
, addr
string, hint Addr
) (addrList
, error
) {
175 afnet
, _
, err
:= parseNetwork(ctx
, network
, true)
179 if op
== "dial" && addr
== "" {
180 return nil, errMissingAddress
183 case "unix", "unixgram", "unixpacket":
184 addr
, err
:= ResolveUnixAddr(afnet
, addr
)
188 if op
== "dial" && hint
!= nil && addr
.Network() != hint
.Network() {
189 return nil, &AddrError
{Err
: "mismatched local address type", Addr
: hint
.String()}
191 return addrList
{addr
}, nil
193 addrs
, err
:= r
.internetAddrList(ctx
, afnet
, addr
)
194 if err
!= nil || op
!= "dial" || hint
== nil {
203 switch hint
:= hint
.(type) {
206 wildcard
= tcp
.isWildcard()
209 wildcard
= udp
.isWildcard()
212 wildcard
= ip
.isWildcard()
215 for _
, addr
:= range addrs
{
216 if addr
.Network() != hint
.Network() {
217 return nil, &AddrError
{Err
: "mismatched local address type", Addr
: hint
.String()}
219 switch addr
:= addr
.(type) {
221 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(tcp
.IP
) {
224 naddrs
= append(naddrs
, addr
)
226 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(udp
.IP
) {
229 naddrs
= append(naddrs
, addr
)
231 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(ip
.IP
) {
234 naddrs
= append(naddrs
, addr
)
237 if len(naddrs
) == 0 {
238 return nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: hint
.String()}
243 // Dial connects to the address on the named network.
245 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
246 // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
247 // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
250 // For TCP and UDP networks, the address has the form "host:port".
251 // The host must be a literal IP address, or a host name that can be
252 // resolved to IP addresses.
253 // The port must be a literal port number or a service name.
254 // If the host is a literal IPv6 address it must be enclosed in square
255 // brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80".
256 // The zone specifies the scope of the literal IPv6 address as defined
258 // The functions JoinHostPort and SplitHostPort manipulate a pair of
259 // host and port in this form.
260 // When using TCP, and the host resolves to multiple IP addresses,
261 // Dial will try each IP address in order until one succeeds.
264 // Dial("tcp", "golang.org:http")
265 // Dial("tcp", "192.0.2.1:http")
266 // Dial("tcp", "198.51.100.1:80")
267 // Dial("udp", "[2001:db8::1]:domain")
268 // Dial("udp", "[fe80::1%lo0]:53")
269 // Dial("tcp", ":80")
271 // For IP networks, the network must be "ip", "ip4" or "ip6" followed
272 // by a colon and a literal protocol number or a protocol name, and
273 // the address has the form "host". The host must be a literal IP
274 // address or a literal IPv6 address with zone.
275 // It depends on each operating system how the operating system
276 // behaves with a non-well known protocol number such as "0" or "255".
279 // Dial("ip4:1", "192.0.2.1")
280 // Dial("ip6:ipv6-icmp", "2001:db8::1")
281 // Dial("ip6:58", "fe80::1%lo0")
283 // For TCP, UDP and IP networks, if the host is empty or a literal
284 // unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for
285 // TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is
288 // For Unix networks, the address must be a file system path.
289 func Dial(network
, address
string) (Conn
, error
) {
291 return d
.Dial(network
, address
)
294 // DialTimeout acts like Dial but takes a timeout.
296 // The timeout includes name resolution, if required.
297 // When using TCP, and the host in the address parameter resolves to
298 // multiple IP addresses, the timeout is spread over each consecutive
299 // dial, such that each is given an appropriate fraction of the time
302 // See func Dial for a description of the network and address
304 func DialTimeout(network
, address
string, timeout time
.Duration
) (Conn
, error
) {
305 d
:= Dialer
{Timeout
: timeout
}
306 return d
.Dial(network
, address
)
309 // dialParam contains a Dial's parameters and configuration.
310 type dialParam
struct {
312 network
, address
string
315 // Dial connects to the address on the named network.
317 // See func Dial for a description of the network and address
319 func (d
*Dialer
) Dial(network
, address
string) (Conn
, error
) {
320 return d
.DialContext(context
.Background(), network
, address
)
323 // DialContext connects to the address on the named network using
324 // the provided context.
326 // The provided Context must be non-nil. If the context expires before
327 // the connection is complete, an error is returned. Once successfully
328 // connected, any expiration of the context will not affect the
331 // When using TCP, and the host in the address parameter resolves to multiple
332 // network addresses, any dial timeout (from d.Timeout or ctx) is spread
333 // over each consecutive dial, such that each is given an appropriate
334 // fraction of the time to connect.
335 // For example, if a host has 4 IP addresses and the timeout is 1 minute,
336 // the connect to each single address will be given 15 seconds to complete
337 // before trying the next one.
339 // See func Dial for a description of the network and address
341 func (d
*Dialer
) DialContext(ctx context
.Context
, network
, address
string) (Conn
, error
) {
345 deadline
:= d
.deadline(ctx
, time
.Now())
346 if !deadline
.IsZero() {
347 if d
, ok
:= ctx
.Deadline(); !ok || deadline
.Before(d
) {
348 subCtx
, cancel
:= context
.WithDeadline(ctx
, deadline
)
353 if oldCancel
:= d
.Cancel
; oldCancel
!= nil {
354 subCtx
, cancel
:= context
.WithCancel(ctx
)
360 case <-subCtx
.Done():
366 // Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups.
368 if trace
, _
:= ctx
.Value(nettrace
.TraceKey
{}).(*nettrace
.Trace
); trace
!= nil {
370 shadow
.ConnectStart
= nil
371 shadow
.ConnectDone
= nil
372 resolveCtx
= context
.WithValue(resolveCtx
, nettrace
.TraceKey
{}, &shadow
)
375 addrs
, err
:= d
.resolver().resolveAddrList(resolveCtx
, "dial", network
, address
, d
.LocalAddr
)
377 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
386 var primaries
, fallbacks addrList
387 if d
.DualStack
&& network
== "tcp" {
388 primaries
, fallbacks
= addrs
.partition(isIPv4
)
394 if len(fallbacks
) > 0 {
395 c
, err
= dialParallel(ctx
, dp
, primaries
, fallbacks
)
397 c
, err
= dialSerial(ctx
, dp
, primaries
)
403 if tc
, ok
:= c
.(*TCPConn
); ok
&& d
.KeepAlive
> 0 {
404 setKeepAlive(tc
.fd
, true)
405 setKeepAlivePeriod(tc
.fd
, d
.KeepAlive
)
406 testHookSetKeepAlive()
411 // dialParallel races two copies of dialSerial, giving the first a
412 // head start. It returns the first established connection and
413 // closes the others. Otherwise it returns an error from the first
415 func dialParallel(ctx context
.Context
, dp
*dialParam
, primaries
, fallbacks addrList
) (Conn
, error
) {
416 if len(fallbacks
) == 0 {
417 return dialSerial(ctx
, dp
, primaries
)
420 returned
:= make(chan struct{})
421 defer close(returned
)
423 type dialResult
struct {
429 results
:= make(chan dialResult
) // unbuffered
431 startRacer
:= func(ctx context
.Context
, primary
bool) {
436 c
, err
:= dialSerial(ctx
, dp
, ras
)
438 case results
<- dialResult
{Conn
: c
, error
: err
, primary
: primary
, done
: true}:
446 var primary
, fallback dialResult
448 // Start the main racer.
449 primaryCtx
, primaryCancel
:= context
.WithCancel(ctx
)
450 defer primaryCancel()
451 go startRacer(primaryCtx
, true)
453 // Start the timer for the fallback racer.
454 fallbackTimer
:= time
.NewTimer(dp
.fallbackDelay())
455 defer fallbackTimer
.Stop()
459 case <-fallbackTimer
.C
:
460 fallbackCtx
, fallbackCancel
:= context
.WithCancel(ctx
)
461 defer fallbackCancel()
462 go startRacer(fallbackCtx
, false)
464 case res
:= <-results
:
465 if res
.error
== nil {
473 if primary
.done
&& fallback
.done
{
474 return nil, primary
.error
476 if res
.primary
&& fallbackTimer
.Stop() {
477 // If we were able to stop the timer, that means it
478 // was running (hadn't yet started the fallback), but
479 // we just got an error on the primary path, so start
480 // the fallback immediately (in 0 nanoseconds).
481 fallbackTimer
.Reset(0)
487 // dialSerial connects to a list of addresses in sequence, returning
488 // either the first successful connection, or the first error.
489 func dialSerial(ctx context
.Context
, dp
*dialParam
, ras addrList
) (Conn
, error
) {
490 var firstErr error
// The error from the first address is most relevant.
492 for i
, ra
:= range ras
{
495 return nil, &OpError
{Op
: "dial", Net
: dp
.network
, Source
: dp
.LocalAddr
, Addr
: ra
, Err
: mapErr(ctx
.Err())}
499 deadline
, _
:= ctx
.Deadline()
500 partialDeadline
, err
:= partialDeadline(time
.Now(), deadline
, len(ras
)-i
)
504 firstErr
= &OpError
{Op
: "dial", Net
: dp
.network
, Source
: dp
.LocalAddr
, Addr
: ra
, Err
: err
}
509 if partialDeadline
.Before(deadline
) {
510 var cancel context
.CancelFunc
511 dialCtx
, cancel
= context
.WithDeadline(ctx
, partialDeadline
)
515 c
, err
:= dialSingle(dialCtx
, dp
, ra
)
525 firstErr
= &OpError
{Op
: "dial", Net
: dp
.network
, Source
: nil, Addr
: nil, Err
: errMissingAddress
}
530 // dialSingle attempts to establish and returns a single connection to
531 // the destination address.
532 func dialSingle(ctx context
.Context
, dp
*dialParam
, ra Addr
) (c Conn
, err error
) {
533 trace
, _
:= ctx
.Value(nettrace
.TraceKey
{}).(*nettrace
.Trace
)
536 if trace
.ConnectStart
!= nil {
537 trace
.ConnectStart(dp
.network
, raStr
)
539 if trace
.ConnectDone
!= nil {
540 defer func() { trace
.ConnectDone(dp
.network
, raStr
, err
) }()
544 switch ra
:= ra
.(type) {
546 la
, _
:= la
.(*TCPAddr
)
547 c
, err
= dialTCP(ctx
, dp
.network
, la
, ra
)
549 la
, _
:= la
.(*UDPAddr
)
550 c
, err
= dialUDP(ctx
, dp
.network
, la
, ra
)
552 la
, _
:= la
.(*IPAddr
)
553 c
, err
= dialIP(ctx
, dp
.network
, la
, ra
)
555 la
, _
:= la
.(*UnixAddr
)
556 c
, err
= dialUnix(ctx
, dp
.network
, la
, ra
)
558 return nil, &OpError
{Op
: "dial", Net
: dp
.network
, Source
: la
, Addr
: ra
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: dp
.address
}}
561 return nil, &OpError
{Op
: "dial", Net
: dp
.network
, Source
: la
, Addr
: ra
, Err
: err
} // c is non-nil interface containing nil pointer
566 // Listen announces on the local network address.
568 // The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
570 // For TCP networks, if the host in the address parameter is empty or
571 // a literal unspecified IP address, Listen listens on all available
572 // unicast and anycast IP addresses of the local system.
573 // To only use IPv4, use network "tcp4".
574 // The address can use a host name, but this is not recommended,
575 // because it will create a listener for at most one of the host's IP
577 // If the port in the address parameter is empty or "0", as in
578 // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
579 // The Addr method of Listener can be used to discover the chosen
582 // See func Dial for a description of the network and address
584 func Listen(network
, address
string) (Listener
, error
) {
585 addrs
, err
:= DefaultResolver
.resolveAddrList(context
.Background(), "listen", network
, address
, nil)
587 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
590 switch la
:= addrs
.first(isIPv4
).(type) {
592 l
, err
= ListenTCP(network
, la
)
594 l
, err
= ListenUnix(network
, la
)
596 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: la
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: address
}}
599 return nil, err
// l is non-nil interface containing nil pointer
604 // ListenPacket announces on the local network address.
606 // The network must be "udp", "udp4", "udp6", "unixgram", or an IP
607 // transport. The IP transports are "ip", "ip4", or "ip6" followed by
608 // a colon and a literal protocol number or a protocol name, as in
609 // "ip:1" or "ip:icmp".
611 // For UDP and IP networks, if the host in the address parameter is
612 // empty or a literal unspecified IP address, ListenPacket listens on
613 // all available IP addresses of the local system except multicast IP
615 // To only use IPv4, use network "udp4" or "ip4:proto".
616 // The address can use a host name, but this is not recommended,
617 // because it will create a listener for at most one of the host's IP
619 // If the port in the address parameter is empty or "0", as in
620 // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
621 // The LocalAddr method of PacketConn can be used to discover the
624 // See func Dial for a description of the network and address
626 func ListenPacket(network
, address
string) (PacketConn
, error
) {
627 addrs
, err
:= DefaultResolver
.resolveAddrList(context
.Background(), "listen", network
, address
, nil)
629 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
632 switch la
:= addrs
.first(isIPv4
).(type) {
634 l
, err
= ListenUDP(network
, la
)
636 l
, err
= ListenIP(network
, la
)
638 l
, err
= ListenUnixgram(network
, la
)
640 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: la
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: address
}}
643 return nil, err
// l is non-nil interface containing nil pointer