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 // defaultTCPKeepAlive is a default constant value for TCPKeepAlive times
15 // See golang.org/issue/31510
17 defaultTCPKeepAlive
= 15 * time
.Second
20 // A Dialer contains options for connecting to an address.
22 // The zero value for each field is equivalent to dialing
23 // without that option. Dialing with the zero value of Dialer
24 // is therefore equivalent to just calling the Dial function.
26 // It is safe to call Dialer's methods concurrently.
28 // Timeout is the maximum amount of time a dial will wait for
29 // a connect to complete. If Deadline is also set, it may fail
32 // The default is no timeout.
34 // When using TCP and dialing a host name with multiple IP
35 // addresses, the timeout may be divided between them.
37 // With or without a timeout, the operating system may impose
38 // its own earlier timeout. For instance, TCP timeouts are
39 // often around 3 minutes.
42 // Deadline is the absolute point in time after which dials
43 // will fail. If Timeout is set, it may fail earlier.
44 // Zero means no deadline, or dependent on the operating system
45 // as with the Timeout option.
48 // LocalAddr is the local address to use when dialing an
49 // address. The address must be of a compatible type for the
50 // network being dialed.
51 // If nil, a local address is automatically chosen.
54 // DualStack previously enabled RFC 6555 Fast Fallback
55 // support, also known as "Happy Eyeballs", in which IPv4 is
56 // tried soon if IPv6 appears to be misconfigured and
59 // Deprecated: Fast Fallback is enabled by default. To
60 // disable, set FallbackDelay to a negative value.
63 // FallbackDelay specifies the length of time to wait before
64 // spawning a RFC 6555 Fast Fallback connection. That is, this
65 // is the amount of time to wait for IPv6 to succeed before
66 // assuming that IPv6 is misconfigured and falling back to
69 // If zero, a default delay of 300ms is used.
70 // A negative value disables Fast Fallback support.
71 FallbackDelay time
.Duration
73 // KeepAlive specifies the interval between keep-alive
74 // probes for an active network connection.
75 // If zero, keep-alive probes are sent with a default value
76 // (currently 15 seconds), if supported by the protocol and operating
77 // system. Network protocols or operating systems that do
78 // not support keep-alives ignore this field.
79 // If negative, keep-alive probes are disabled.
80 KeepAlive time
.Duration
82 // Resolver optionally specifies an alternate resolver to use.
85 // Cancel is an optional channel whose closure indicates that
86 // the dial should be canceled. Not all types of dials support
89 // Deprecated: Use DialContext instead.
90 Cancel
<-chan struct{}
92 // If Control is not nil, it is called after creating the network
93 // connection but before actually dialing.
95 // Network and address parameters passed to Control method are not
96 // necessarily the ones passed to Dial. For example, passing "tcp" to Dial
97 // will cause the Control function to be called with "tcp4" or "tcp6".
98 Control
func(network
, address
string, c syscall
.RawConn
) error
101 func (d
*Dialer
) dualStack() bool { return d
.FallbackDelay
>= 0 }
103 func minNonzeroTime(a
, b time
.Time
) time
.Time
{
107 if b
.IsZero() || a
.Before(b
) {
113 // deadline returns the earliest of:
116 // - the context's deadline
117 // Or zero, if none of Timeout, Deadline, or context's deadline is set.
118 func (d
*Dialer
) deadline(ctx context
.Context
, now time
.Time
) (earliest time
.Time
) {
119 if d
.Timeout
!= 0 { // including negative, for historical reasons
120 earliest
= now
.Add(d
.Timeout
)
122 if d
, ok
:= ctx
.Deadline(); ok
{
123 earliest
= minNonzeroTime(earliest
, d
)
125 return minNonzeroTime(earliest
, d
.Deadline
)
128 func (d
*Dialer
) resolver() *Resolver
{
129 if d
.Resolver
!= nil {
132 return DefaultResolver
135 // partialDeadline returns the deadline to use for a single address,
136 // when multiple addresses are pending.
137 func partialDeadline(now
, deadline time
.Time
, addrsRemaining
int) (time
.Time
, error
) {
138 if deadline
.IsZero() {
141 timeRemaining
:= deadline
.Sub(now
)
142 if timeRemaining
<= 0 {
143 return time
.Time
{}, errTimeout
145 // Tentatively allocate equal time to each remaining address.
146 timeout
:= timeRemaining
/ time
.Duration(addrsRemaining
)
147 // If the time per address is too short, steal from the end of the list.
148 const saneMinimum
= 2 * time
.Second
149 if timeout
< saneMinimum
{
150 if timeRemaining
< saneMinimum
{
151 timeout
= timeRemaining
153 timeout
= saneMinimum
156 return now
.Add(timeout
), nil
159 func (d
*Dialer
) fallbackDelay() time
.Duration
{
160 if d
.FallbackDelay
> 0 {
161 return d
.FallbackDelay
163 return 300 * time
.Millisecond
167 func parseNetwork(ctx context
.Context
, network
string, needsProto
bool) (afnet
string, proto
int, err error
) {
168 i
:= last(network
, ':')
169 if i
< 0 { // no colon
171 case "tcp", "tcp4", "tcp6":
172 case "udp", "udp4", "udp6":
173 case "ip", "ip4", "ip6":
175 return "", 0, UnknownNetworkError(network
)
177 case "unix", "unixgram", "unixpacket":
179 return "", 0, UnknownNetworkError(network
)
181 return network
, 0, nil
185 case "ip", "ip4", "ip6":
186 protostr
:= network
[i
+1:]
187 proto
, i
, ok
:= dtoi(protostr
)
188 if !ok || i
!= len(protostr
) {
189 proto
, err
= lookupProtocol(ctx
, protostr
)
194 return afnet
, proto
, nil
196 return "", 0, UnknownNetworkError(network
)
199 // resolveAddrList resolves addr using hint and returns a list of
200 // addresses. The result contains at least one address when error is
202 func (r
*Resolver
) resolveAddrList(ctx context
.Context
, op
, network
, addr
string, hint Addr
) (addrList
, error
) {
203 afnet
, _
, err
:= parseNetwork(ctx
, network
, true)
207 if op
== "dial" && addr
== "" {
208 return nil, errMissingAddress
211 case "unix", "unixgram", "unixpacket":
212 addr
, err
:= ResolveUnixAddr(afnet
, addr
)
216 if op
== "dial" && hint
!= nil && addr
.Network() != hint
.Network() {
217 return nil, &AddrError
{Err
: "mismatched local address type", Addr
: hint
.String()}
219 return addrList
{addr
}, nil
221 addrs
, err
:= r
.internetAddrList(ctx
, afnet
, addr
)
222 if err
!= nil || op
!= "dial" || hint
== nil {
231 switch hint
:= hint
.(type) {
234 wildcard
= tcp
.isWildcard()
237 wildcard
= udp
.isWildcard()
240 wildcard
= ip
.isWildcard()
243 for _
, addr
:= range addrs
{
244 if addr
.Network() != hint
.Network() {
245 return nil, &AddrError
{Err
: "mismatched local address type", Addr
: hint
.String()}
247 switch addr
:= addr
.(type) {
249 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(tcp
.IP
) {
252 naddrs
= append(naddrs
, addr
)
254 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(udp
.IP
) {
257 naddrs
= append(naddrs
, addr
)
259 if !wildcard
&& !addr
.isWildcard() && !addr
.IP
.matchAddrFamily(ip
.IP
) {
262 naddrs
= append(naddrs
, addr
)
265 if len(naddrs
) == 0 {
266 return nil, &AddrError
{Err
: errNoSuitableAddress
.Error(), Addr
: hint
.String()}
271 // Dial connects to the address on the named network.
273 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
274 // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
275 // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and
278 // For TCP and UDP networks, the address has the form "host:port".
279 // The host must be a literal IP address, or a host name that can be
280 // resolved to IP addresses.
281 // The port must be a literal port number or a service name.
282 // If the host is a literal IPv6 address it must be enclosed in square
283 // brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80".
284 // The zone specifies the scope of the literal IPv6 address as defined
286 // The functions JoinHostPort and SplitHostPort manipulate a pair of
287 // host and port in this form.
288 // When using TCP, and the host resolves to multiple IP addresses,
289 // Dial will try each IP address in order until one succeeds.
292 // Dial("tcp", "golang.org:http")
293 // Dial("tcp", "192.0.2.1:http")
294 // Dial("tcp", "198.51.100.1:80")
295 // Dial("udp", "[2001:db8::1]:domain")
296 // Dial("udp", "[fe80::1%lo0]:53")
297 // Dial("tcp", ":80")
299 // For IP networks, the network must be "ip", "ip4" or "ip6" followed
300 // by a colon and a literal protocol number or a protocol name, and
301 // the address has the form "host". The host must be a literal IP
302 // address or a literal IPv6 address with zone.
303 // It depends on each operating system how the operating system
304 // behaves with a non-well known protocol number such as "0" or "255".
307 // Dial("ip4:1", "192.0.2.1")
308 // Dial("ip6:ipv6-icmp", "2001:db8::1")
309 // Dial("ip6:58", "fe80::1%lo0")
311 // For TCP, UDP and IP networks, if the host is empty or a literal
312 // unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for
313 // TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is
316 // For Unix networks, the address must be a file system path.
317 func Dial(network
, address
string) (Conn
, error
) {
319 return d
.Dial(network
, address
)
322 // DialTimeout acts like Dial but takes a timeout.
324 // The timeout includes name resolution, if required.
325 // When using TCP, and the host in the address parameter resolves to
326 // multiple IP addresses, the timeout is spread over each consecutive
327 // dial, such that each is given an appropriate fraction of the time
330 // See func Dial for a description of the network and address
332 func DialTimeout(network
, address
string, timeout time
.Duration
) (Conn
, error
) {
333 d
:= Dialer
{Timeout
: timeout
}
334 return d
.Dial(network
, address
)
337 // sysDialer contains a Dial's parameters and configuration.
338 type sysDialer
struct {
340 network
, address
string
343 // Dial connects to the address on the named network.
345 // See func Dial for a description of the network and address
348 // Dial uses context.Background internally; to specify the context, use
350 func (d
*Dialer
) Dial(network
, address
string) (Conn
, error
) {
351 return d
.DialContext(context
.Background(), network
, address
)
354 // DialContext connects to the address on the named network using
355 // the provided context.
357 // The provided Context must be non-nil. If the context expires before
358 // the connection is complete, an error is returned. Once successfully
359 // connected, any expiration of the context will not affect the
362 // When using TCP, and the host in the address parameter resolves to multiple
363 // network addresses, any dial timeout (from d.Timeout or ctx) is spread
364 // over each consecutive dial, such that each is given an appropriate
365 // fraction of the time to connect.
366 // For example, if a host has 4 IP addresses and the timeout is 1 minute,
367 // the connect to each single address will be given 15 seconds to complete
368 // before trying the next one.
370 // See func Dial for a description of the network and address
372 func (d
*Dialer
) DialContext(ctx context
.Context
, network
, address
string) (Conn
, error
) {
376 deadline
:= d
.deadline(ctx
, time
.Now())
377 if !deadline
.IsZero() {
378 if d
, ok
:= ctx
.Deadline(); !ok || deadline
.Before(d
) {
379 subCtx
, cancel
:= context
.WithDeadline(ctx
, deadline
)
384 if oldCancel
:= d
.Cancel
; oldCancel
!= nil {
385 subCtx
, cancel
:= context
.WithCancel(ctx
)
391 case <-subCtx
.Done():
397 // Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups.
399 if trace
, _
:= ctx
.Value(nettrace
.TraceKey
{}).(*nettrace
.Trace
); trace
!= nil {
401 shadow
.ConnectStart
= nil
402 shadow
.ConnectDone
= nil
403 resolveCtx
= context
.WithValue(resolveCtx
, nettrace
.TraceKey
{}, &shadow
)
406 addrs
, err
:= d
.resolver().resolveAddrList(resolveCtx
, "dial", network
, address
, d
.LocalAddr
)
408 return nil, &OpError
{Op
: "dial", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
417 var primaries
, fallbacks addrList
418 if d
.dualStack() && network
== "tcp" {
419 primaries
, fallbacks
= addrs
.partition(isIPv4
)
425 if len(fallbacks
) > 0 {
426 c
, err
= sd
.dialParallel(ctx
, primaries
, fallbacks
)
428 c
, err
= sd
.dialSerial(ctx
, primaries
)
434 if tc
, ok
:= c
.(*TCPConn
); ok
&& d
.KeepAlive
>= 0 {
435 setKeepAlive(tc
.fd
, true)
437 if d
.KeepAlive
== 0 {
438 ka
= defaultTCPKeepAlive
440 setKeepAlivePeriod(tc
.fd
, ka
)
441 testHookSetKeepAlive(ka
)
446 // dialParallel races two copies of dialSerial, giving the first a
447 // head start. It returns the first established connection and
448 // closes the others. Otherwise it returns an error from the first
450 func (sd
*sysDialer
) dialParallel(ctx context
.Context
, primaries
, fallbacks addrList
) (Conn
, error
) {
451 if len(fallbacks
) == 0 {
452 return sd
.dialSerial(ctx
, primaries
)
455 returned
:= make(chan struct{})
456 defer close(returned
)
458 type dialResult
struct {
464 results
:= make(chan dialResult
) // unbuffered
466 startRacer
:= func(ctx context
.Context
, primary
bool) {
471 c
, err
:= sd
.dialSerial(ctx
, ras
)
473 case results
<- dialResult
{Conn
: c
, error
: err
, primary
: primary
, done
: true}:
481 var primary
, fallback dialResult
483 // Start the main racer.
484 primaryCtx
, primaryCancel
:= context
.WithCancel(ctx
)
485 defer primaryCancel()
486 go startRacer(primaryCtx
, true)
488 // Start the timer for the fallback racer.
489 fallbackTimer
:= time
.NewTimer(sd
.fallbackDelay())
490 defer fallbackTimer
.Stop()
494 case <-fallbackTimer
.C
:
495 fallbackCtx
, fallbackCancel
:= context
.WithCancel(ctx
)
496 defer fallbackCancel()
497 go startRacer(fallbackCtx
, false)
499 case res
:= <-results
:
500 if res
.error
== nil {
508 if primary
.done
&& fallback
.done
{
509 return nil, primary
.error
511 if res
.primary
&& fallbackTimer
.Stop() {
512 // If we were able to stop the timer, that means it
513 // was running (hadn't yet started the fallback), but
514 // we just got an error on the primary path, so start
515 // the fallback immediately (in 0 nanoseconds).
516 fallbackTimer
.Reset(0)
522 // dialSerial connects to a list of addresses in sequence, returning
523 // either the first successful connection, or the first error.
524 func (sd
*sysDialer
) dialSerial(ctx context
.Context
, ras addrList
) (Conn
, error
) {
525 var firstErr error
// The error from the first address is most relevant.
527 for i
, ra
:= range ras
{
530 return nil, &OpError
{Op
: "dial", Net
: sd
.network
, Source
: sd
.LocalAddr
, Addr
: ra
, Err
: mapErr(ctx
.Err())}
535 if deadline
, hasDeadline
:= ctx
.Deadline(); hasDeadline
{
536 partialDeadline
, err
:= partialDeadline(time
.Now(), deadline
, len(ras
)-i
)
540 firstErr
= &OpError
{Op
: "dial", Net
: sd
.network
, Source
: sd
.LocalAddr
, Addr
: ra
, Err
: err
}
544 if partialDeadline
.Before(deadline
) {
545 var cancel context
.CancelFunc
546 dialCtx
, cancel
= context
.WithDeadline(ctx
, partialDeadline
)
551 c
, err
:= sd
.dialSingle(dialCtx
, ra
)
561 firstErr
= &OpError
{Op
: "dial", Net
: sd
.network
, Source
: nil, Addr
: nil, Err
: errMissingAddress
}
566 // dialSingle attempts to establish and returns a single connection to
567 // the destination address.
568 func (sd
*sysDialer
) dialSingle(ctx context
.Context
, ra Addr
) (c Conn
, err error
) {
569 trace
, _
:= ctx
.Value(nettrace
.TraceKey
{}).(*nettrace
.Trace
)
572 if trace
.ConnectStart
!= nil {
573 trace
.ConnectStart(sd
.network
, raStr
)
575 if trace
.ConnectDone
!= nil {
576 defer func() { trace
.ConnectDone(sd
.network
, raStr
, err
) }()
580 switch ra
:= ra
.(type) {
582 la
, _
:= la
.(*TCPAddr
)
583 c
, err
= sd
.dialTCP(ctx
, la
, ra
)
585 la
, _
:= la
.(*UDPAddr
)
586 c
, err
= sd
.dialUDP(ctx
, la
, ra
)
588 la
, _
:= la
.(*IPAddr
)
589 c
, err
= sd
.dialIP(ctx
, la
, ra
)
591 la
, _
:= la
.(*UnixAddr
)
592 c
, err
= sd
.dialUnix(ctx
, la
, ra
)
594 return nil, &OpError
{Op
: "dial", Net
: sd
.network
, Source
: la
, Addr
: ra
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: sd
.address
}}
597 return nil, &OpError
{Op
: "dial", Net
: sd
.network
, Source
: la
, Addr
: ra
, Err
: err
} // c is non-nil interface containing nil pointer
602 // ListenConfig contains options for listening to an address.
603 type ListenConfig
struct {
604 // If Control is not nil, it is called after creating the network
605 // connection but before binding it to the operating system.
607 // Network and address parameters passed to Control method are not
608 // necessarily the ones passed to Listen. For example, passing "tcp" to
609 // Listen will cause the Control function to be called with "tcp4" or "tcp6".
610 Control
func(network
, address
string, c syscall
.RawConn
) error
612 // KeepAlive specifies the keep-alive period for network
613 // connections accepted by this listener.
614 // If zero, keep-alives are enabled if supported by the protocol
615 // and operating system. Network protocols or operating systems
616 // that do not support keep-alives ignore this field.
617 // If negative, keep-alives are disabled.
618 KeepAlive time
.Duration
621 // Listen announces on the local network address.
623 // See func Listen for a description of the network and address
625 func (lc
*ListenConfig
) Listen(ctx context
.Context
, network
, address
string) (Listener
, error
) {
626 addrs
, err
:= DefaultResolver
.resolveAddrList(ctx
, "listen", network
, address
, nil)
628 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
636 la
:= addrs
.first(isIPv4
)
637 switch la
:= la
.(type) {
639 l
, err
= sl
.listenTCP(ctx
, la
)
641 l
, err
= sl
.listenUnix(ctx
, la
)
643 return nil, &OpError
{Op
: "listen", Net
: sl
.network
, Source
: nil, Addr
: la
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: address
}}
646 return nil, &OpError
{Op
: "listen", Net
: sl
.network
, Source
: nil, Addr
: la
, Err
: err
} // l is non-nil interface containing nil pointer
651 // ListenPacket announces on the local network address.
653 // See func ListenPacket for a description of the network and address
655 func (lc
*ListenConfig
) ListenPacket(ctx context
.Context
, network
, address
string) (PacketConn
, error
) {
656 addrs
, err
:= DefaultResolver
.resolveAddrList(ctx
, "listen", network
, address
, nil)
658 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: nil, Err
: err
}
666 la
:= addrs
.first(isIPv4
)
667 switch la
:= la
.(type) {
669 c
, err
= sl
.listenUDP(ctx
, la
)
671 c
, err
= sl
.listenIP(ctx
, la
)
673 c
, err
= sl
.listenUnixgram(ctx
, la
)
675 return nil, &OpError
{Op
: "listen", Net
: sl
.network
, Source
: nil, Addr
: la
, Err
: &AddrError
{Err
: "unexpected address type", Addr
: address
}}
678 return nil, &OpError
{Op
: "listen", Net
: sl
.network
, Source
: nil, Addr
: la
, Err
: err
} // c is non-nil interface containing nil pointer
683 // sysListener contains a Listen's parameters and configuration.
684 type sysListener
struct {
686 network
, address
string
689 // Listen announces on the local network address.
691 // The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
693 // For TCP networks, if the host in the address parameter is empty or
694 // a literal unspecified IP address, Listen listens on all available
695 // unicast and anycast IP addresses of the local system.
696 // To only use IPv4, use network "tcp4".
697 // The address can use a host name, but this is not recommended,
698 // because it will create a listener for at most one of the host's IP
700 // If the port in the address parameter is empty or "0", as in
701 // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
702 // The Addr method of Listener can be used to discover the chosen
705 // See func Dial for a description of the network and address
708 // Listen uses context.Background internally; to specify the context, use
709 // ListenConfig.Listen.
710 func Listen(network
, address
string) (Listener
, error
) {
712 return lc
.Listen(context
.Background(), network
, address
)
715 // ListenPacket announces on the local network address.
717 // The network must be "udp", "udp4", "udp6", "unixgram", or an IP
718 // transport. The IP transports are "ip", "ip4", or "ip6" followed by
719 // a colon and a literal protocol number or a protocol name, as in
720 // "ip:1" or "ip:icmp".
722 // For UDP and IP networks, if the host in the address parameter is
723 // empty or a literal unspecified IP address, ListenPacket listens on
724 // all available IP addresses of the local system except multicast IP
726 // To only use IPv4, use network "udp4" or "ip4:proto".
727 // The address can use a host name, but this is not recommended,
728 // because it will create a listener for at most one of the host's IP
730 // If the port in the address parameter is empty or "0", as in
731 // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen.
732 // The LocalAddr method of PacketConn can be used to discover the
735 // See func Dial for a description of the network and address
738 // ListenPacket uses context.Background internally; to specify the context, use
739 // ListenConfig.ListenPacket.
740 func ListenPacket(network
, address
string) (PacketConn
, error
) {
742 return lc
.ListenPacket(context
.Background(), network
, address
)