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.
13 // A Dialer contains options for connecting to an address.
15 // The zero value for each field is equivalent to dialing
16 // without that option. Dialing with the zero value of Dialer
17 // is therefore equivalent to just calling the Dial function.
19 // Timeout is the maximum amount of time a dial will wait for
20 // a connect to complete. If Deadline is also set, it may fail
23 // The default is no timeout.
25 // When dialing a name with multiple IP addresses, the timeout
26 // may be divided between them.
28 // With or without a timeout, the operating system may impose
29 // its own earlier timeout. For instance, TCP timeouts are
30 // often around 3 minutes.
33 // Deadline is the absolute point in time after which dials
34 // will fail. If Timeout is set, it may fail earlier.
35 // Zero means no deadline, or dependent on the operating system
36 // as with the Timeout option.
39 // LocalAddr is the local address to use when dialing an
40 // address. The address must be of a compatible type for the
41 // network being dialed.
42 // If nil, a local address is automatically chosen.
45 // DualStack enables RFC 6555-compliant "Happy Eyeballs" dialing
46 // when the network is "tcp" and the destination is a host name
47 // with both IPv4 and IPv6 addresses. This allows a client to
48 // tolerate networks where one address family is silently broken.
51 // FallbackDelay specifies the length of time to wait before
52 // spawning a fallback connection, when DualStack is enabled.
53 // If zero, a default delay of 300ms is used.
54 FallbackDelay time
.Duration
56 // KeepAlive specifies the keep-alive period for an active
57 // network connection.
58 // If zero, keep-alives are not enabled. Network protocols
59 // that do not support keep-alives ignore this field.
60 KeepAlive time
.Duration
62 // Resolver optionally specifies an alternate resolver to use.
65 // Cancel is an optional channel whose closure indicates that
66 // the dial should be canceled. Not all types of dials support
69 // Deprecated: Use DialContext instead.
70 Cancel
<-chan struct{}
73 func minNonzeroTime(a
, b time
.Time
) time
.Time
{
77 if b
.IsZero() || a
.Before(b
) {
83 // deadline returns the earliest of:
86 // - the context's deadline
87 // Or zero, if none of Timeout, Deadline, or context's deadline is set.
88 func (d
*Dialer
) deadline(ctx context
.Context
, now time
.Time
) (earliest time
.Time
) {
89 if d
.Timeout
!= 0 { // including negative, for historical reasons
90 earliest
= now
.Add(d
.Timeout
)
92 if d
, ok
:= ctx
.Deadline(); ok
{
93 earliest
= minNonzeroTime(earliest
, d
)
95 return minNonzeroTime(earliest
, d
.Deadline
)
98 func (d
*Dialer
) resolver() *Resolver
{
99 if d
.Resolver
!= nil {
102 return DefaultResolver
105 // partialDeadline returns the deadline to use for a single address,
106 // when multiple addresses are pending.
107 func partialDeadline(now
, deadline time
.Time
, addrsRemaining
int) (time
.Time
, error
) {
108 if deadline
.IsZero() {
111 timeRemaining
:= deadline
.Sub(now
)
112 if timeRemaining
<= 0 {
113 return time
.Time
{}, errTimeout
115 // Tentatively allocate equal time to each remaining address.
116 timeout
:= timeRemaining
/ time
.Duration(addrsRemaining
)
117 // If the time per address is too short, steal from the end of the list.
118 const saneMinimum
= 2 * time
.Second
119 if timeout
< saneMinimum
{
120 if timeRemaining
< saneMinimum
{
121 timeout
= timeRemaining
123 timeout
= saneMinimum
126 return now
.Add(timeout
), nil
129 func (d
*Dialer
) fallbackDelay() time
.Duration
{
130 if d
.FallbackDelay
> 0 {
131 return d
.FallbackDelay
133 return 300 * time
.Millisecond
137 func parseNetwork(ctx context
.Context
, net
string) (afnet
string, proto
int, err error
) {
139 if i
< 0 { // no colon
141 case "tcp", "tcp4", "tcp6":
142 case "udp", "udp4", "udp6":
143 case "ip", "ip4", "ip6":
144 case "unix", "unixgram", "unixpacket":
146 return "", 0, UnknownNetworkError(net
)
152 case "ip", "ip4", "ip6":
153 protostr
:= net
[i
+1:]
154 proto
, i
, ok
:= dtoi(protostr
)
155 if !ok || i
!= len(protostr
) {
156 proto
, err
= lookupProtocol(ctx
, protostr
)
161 return afnet
, proto
, nil
163 return "", 0, UnknownNetworkError(net
)
166 // resolveAddrList resolves addr using hint and returns a list of
167 // addresses. The result contains at least one address when error is
169 func (r
*Resolver
) resolveAddrList(ctx context
.Context
, op
, network
, addr
string, hint Addr
) (addrList
, error
) {
170 afnet
, _
, err
:= parseNetwork(ctx
, network
)
174 if op
== "dial" && addr
== "" {
175 return nil, errMissingAddress
178 case "unix", "unixgram", "unixpacket":
179 addr
, err
:= ResolveUnixAddr(afnet
, addr
)
183 if op
== "dial" && hint
!= nil && addr
.Network() != hint
.Network() {
184 return nil, &AddrError
{Err
: "mismatched local address type", Addr
: hint
.String()}
186 return addrList
{addr
}, nil
188 addrs
, err
:= r
.internetAddrList(ctx
, afnet
, addr
)
189 if err
!= nil || op
!= "dial" || hint
== nil {
198 switch hint
:= hint
.(type) {
201 wildcard
= tcp
.isWildcard()
204 wildcard
= udp
.isWildcard()
207 wildcard
= ip
.isWildcard()
210 for _
, addr
:= range addrs
{
211 if addr
.Network() != hint
.Network() {
212 return nil, &AddrError
{Err
: "mismatched local address type", Addr
: hint
.String()}
214 switch addr
:= addr
.(type) {
216 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(tcp
.IP
) {
219 naddrs
= append(naddrs
, addr
)
221 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(udp
.IP
) {
224 naddrs
= append(naddrs
, addr
)
226 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(ip
.IP
) {
229 naddrs
= append(naddrs
, addr
)
232 if len(naddrs
) == 0 {
233 return nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: hint
.String()}
238 // Dial connects to the address on the named network.
240 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
241 // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
242 // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
245 // For TCP and UDP networks, addresses have the form host:port.
246 // If host is a literal IPv6 address it must be enclosed
247 // in square brackets as in "[::1]:80" or "[ipv6-host%zone]:80".
248 // The functions JoinHostPort and SplitHostPort manipulate addresses
250 // If the host is empty, as in ":80", the local system is assumed.
253 // Dial("tcp", "192.0.2.1:80")
254 // Dial("tcp", "golang.org:http")
255 // Dial("tcp", "[2001:db8::1]:http")
256 // Dial("tcp", "[fe80::1%lo0]:80")
257 // Dial("tcp", ":80")
259 // For IP networks, the network must be "ip", "ip4" or "ip6" followed
260 // by a colon and a protocol number or name and the addr must be a
261 // literal IP address.
264 // Dial("ip4:1", "192.0.2.1")
265 // Dial("ip6:ipv6-icmp", "2001:db8::1")
267 // For Unix networks, the address must be a file system path.
269 // If the host is resolved to multiple addresses,
270 // Dial will try each address in order until one succeeds.
271 func Dial(network
, address
string) (Conn
, error
) {
273 return d
.Dial(network
, address
)
276 // DialTimeout acts like Dial but takes a timeout.
277 // The timeout includes name resolution, if required.
278 func DialTimeout(network
, address
string, timeout time
.Duration
) (Conn
, error
) {
279 d
:= Dialer
{Timeout
: timeout
}
280 return d
.Dial(network
, address
)
283 // dialParam contains a Dial's parameters and configuration.
284 type dialParam
struct {
286 network
, address
string
289 // Dial connects to the address on the named network.
291 // See func Dial for a description of the network and address
293 func (d
*Dialer
) Dial(network
, address
string) (Conn
, error
) {
294 return d
.DialContext(context
.Background(), network
, address
)
297 // DialContext connects to the address on the named network using
298 // the provided context.
300 // The provided Context must be non-nil. If the context expires before
301 // the connection is complete, an error is returned. Once successfully
302 // connected, any expiration of the context will not affect the
305 // When using TCP, and the host in the address parameter resolves to multiple
306 // network addresses, any dial timeout (from d.Timeout or ctx) is spread
307 // over each consecutive dial, such that each is given an appropriate
308 // fraction of the time to connect.
309 // For example, if a host has 4 IP addresses and the timeout is 1 minute,
310 // the connect to each single address will be given 15 seconds to complete
311 // before trying the next one.
313 // See func Dial for a description of the network and address
315 func (d
*Dialer
) DialContext(ctx context
.Context
, network
, address
string) (Conn
, error
) {
319 deadline
:= d
.deadline(ctx
, time
.Now())
320 if !deadline
.IsZero() {
321 if d
, ok
:= ctx
.Deadline(); !ok || deadline
.Before(d
) {
322 subCtx
, cancel
:= context
.WithDeadline(ctx
, deadline
)
327 if oldCancel
:= d
.Cancel
; oldCancel
!= nil {
328 subCtx
, cancel
:= context
.WithCancel(ctx
)
334 case <-subCtx
.Done():
340 // Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups.
342 if trace
, _
:= ctx
.Value(nettrace
.TraceKey
{}).(*nettrace
.Trace
); trace
!= nil {
344 shadow
.ConnectStart
= nil
345 shadow
.ConnectDone
= nil
346 resolveCtx
= context
.WithValue(resolveCtx
, nettrace
.TraceKey
{}, &shadow
)
349 addrs
, err
:= d
.resolver().resolveAddrList(resolveCtx
, "dial", network
, address
, d
.LocalAddr
)
351 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
360 var primaries
, fallbacks addrList
361 if d
.DualStack
&& network
== "tcp" {
362 primaries
, fallbacks
= addrs
.partition(isIPv4
)
368 if len(fallbacks
) > 0 {
369 c
, err
= dialParallel(ctx
, dp
, primaries
, fallbacks
)
371 c
, err
= dialSerial(ctx
, dp
, primaries
)
377 if tc
, ok
:= c
.(*TCPConn
); ok
&& d
.KeepAlive
> 0 {
378 setKeepAlive(tc
.fd
, true)
379 setKeepAlivePeriod(tc
.fd
, d
.KeepAlive
)
380 testHookSetKeepAlive()
385 // dialParallel races two copies of dialSerial, giving the first a
386 // head start. It returns the first established connection and
387 // closes the others. Otherwise it returns an error from the first
389 func dialParallel(ctx context
.Context
, dp
*dialParam
, primaries
, fallbacks addrList
) (Conn
, error
) {
390 if len(fallbacks
) == 0 {
391 return dialSerial(ctx
, dp
, primaries
)
394 returned
:= make(chan struct{})
395 defer close(returned
)
397 type dialResult
struct {
403 results
:= make(chan dialResult
) // unbuffered
405 startRacer
:= func(ctx context
.Context
, primary
bool) {
410 c
, err
:= dialSerial(ctx
, dp
, ras
)
412 case results
<- dialResult
{Conn
: c
, error
: err
, primary
: primary
, done
: true}:
420 var primary
, fallback dialResult
422 // Start the main racer.
423 primaryCtx
, primaryCancel
:= context
.WithCancel(ctx
)
424 defer primaryCancel()
425 go startRacer(primaryCtx
, true)
427 // Start the timer for the fallback racer.
428 fallbackTimer
:= time
.NewTimer(dp
.fallbackDelay())
429 defer fallbackTimer
.Stop()
433 case <-fallbackTimer
.C
:
434 fallbackCtx
, fallbackCancel
:= context
.WithCancel(ctx
)
435 defer fallbackCancel()
436 go startRacer(fallbackCtx
, false)
438 case res
:= <-results
:
439 if res
.error
== nil {
447 if primary
.done
&& fallback
.done
{
448 return nil, primary
.error
450 if res
.primary
&& fallbackTimer
.Stop() {
451 // If we were able to stop the timer, that means it
452 // was running (hadn't yet started the fallback), but
453 // we just got an error on the primary path, so start
454 // the fallback immediately (in 0 nanoseconds).
455 fallbackTimer
.Reset(0)
461 // dialSerial connects to a list of addresses in sequence, returning
462 // either the first successful connection, or the first error.
463 func dialSerial(ctx context
.Context
, dp
*dialParam
, ras addrList
) (Conn
, error
) {
464 var firstErr error
// The error from the first address is most relevant.
466 for i
, ra
:= range ras
{
469 return nil, &OpError
{Op
: "dial", Net
: dp
.network
, Source
: dp
.LocalAddr
, Addr
: ra
, Err
: mapErr(ctx
.Err())}
473 deadline
, _
:= ctx
.Deadline()
474 partialDeadline
, err
:= partialDeadline(time
.Now(), deadline
, len(ras
)-i
)
478 firstErr
= &OpError
{Op
: "dial", Net
: dp
.network
, Source
: dp
.LocalAddr
, Addr
: ra
, Err
: err
}
483 if partialDeadline
.Before(deadline
) {
484 var cancel context
.CancelFunc
485 dialCtx
, cancel
= context
.WithDeadline(ctx
, partialDeadline
)
489 c
, err
:= dialSingle(dialCtx
, dp
, ra
)
499 firstErr
= &OpError
{Op
: "dial", Net
: dp
.network
, Source
: nil, Addr
: nil, Err
: errMissingAddress
}
504 // dialSingle attempts to establish and returns a single connection to
505 // the destination address.
506 func dialSingle(ctx context
.Context
, dp
*dialParam
, ra Addr
) (c Conn
, err error
) {
507 trace
, _
:= ctx
.Value(nettrace
.TraceKey
{}).(*nettrace
.Trace
)
510 if trace
.ConnectStart
!= nil {
511 trace
.ConnectStart(dp
.network
, raStr
)
513 if trace
.ConnectDone
!= nil {
514 defer func() { trace
.ConnectDone(dp
.network
, raStr
, err
) }()
518 switch ra
:= ra
.(type) {
520 la
, _
:= la
.(*TCPAddr
)
521 c
, err
= dialTCP(ctx
, dp
.network
, la
, ra
)
523 la
, _
:= la
.(*UDPAddr
)
524 c
, err
= dialUDP(ctx
, dp
.network
, la
, ra
)
526 la
, _
:= la
.(*IPAddr
)
527 c
, err
= dialIP(ctx
, dp
.network
, la
, ra
)
529 la
, _
:= la
.(*UnixAddr
)
530 c
, err
= dialUnix(ctx
, dp
.network
, la
, ra
)
532 return nil, &OpError
{Op
: "dial", Net
: dp
.network
, Source
: la
, Addr
: ra
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: dp
.address
}}
535 return nil, &OpError
{Op
: "dial", Net
: dp
.network
, Source
: la
, Addr
: ra
, Err
: err
} // c is non-nil interface containing nil pointer
540 // Listen announces on the local network address laddr.
541 // The network net must be a stream-oriented network: "tcp", "tcp4",
542 // "tcp6", "unix" or "unixpacket".
543 // For TCP and UDP, the syntax of laddr is "host:port", like "127.0.0.1:8080".
544 // If host is omitted, as in ":8080", Listen listens on all available interfaces
545 // instead of just the interface with the given host address.
546 // See Dial for more details about address syntax.
548 // Listening on a hostname is not recommended because this creates a socket
549 // for at most one of its IP addresses.
550 func Listen(net
, laddr
string) (Listener
, error
) {
551 addrs
, err
:= DefaultResolver
.resolveAddrList(context
.Background(), "listen", net
, laddr
, nil)
553 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: nil, Err
: err
}
556 switch la
:= addrs
.first(isIPv4
).(type) {
558 l
, err
= ListenTCP(net
, la
)
560 l
, err
= ListenUnix(net
, la
)
562 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: la
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: laddr
}}
565 return nil, err
// l is non-nil interface containing nil pointer
570 // ListenPacket announces on the local network address laddr.
571 // The network net must be a packet-oriented network: "udp", "udp4",
572 // "udp6", "ip", "ip4", "ip6" or "unixgram".
573 // For TCP and UDP, the syntax of laddr is "host:port", like "127.0.0.1:8080".
574 // If host is omitted, as in ":8080", ListenPacket listens on all available interfaces
575 // instead of just the interface with the given host address.
576 // See Dial for the syntax of laddr.
578 // Listening on a hostname is not recommended because this creates a socket
579 // for at most one of its IP addresses.
580 func ListenPacket(net
, laddr
string) (PacketConn
, error
) {
581 addrs
, err
:= DefaultResolver
.resolveAddrList(context
.Background(), "listen", net
, laddr
, nil)
583 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: nil, Err
: err
}
586 switch la
:= addrs
.first(isIPv4
).(type) {
588 l
, err
= ListenUDP(net
, la
)
590 l
, err
= ListenIP(net
, la
)
592 l
, err
= ListenUnixgram(net
, la
)
594 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: la
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: laddr
}}
597 return nil, err
// l is non-nil interface containing nil pointer