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.
11 func parseDialNetwork(net
string) (afnet
string, proto
int, err error
) {
13 if i
< 0 { // no colon
15 case "tcp", "tcp4", "tcp6":
16 case "udp", "udp4", "udp6":
17 case "ip", "ip4", "ip6":
18 case "unix", "unixgram", "unixpacket":
20 return "", 0, UnknownNetworkError(net
)
26 case "ip", "ip4", "ip6":
28 proto
, i
, ok
:= dtoi(protostr
, 0)
29 if !ok || i
!= len(protostr
) {
30 proto
, err
= lookupProtocol(protostr
)
35 return afnet
, proto
, nil
37 return "", 0, UnknownNetworkError(net
)
40 func resolveNetAddr(op
, net
, addr
string, deadline time
.Time
) (afnet
string, a Addr
, err error
) {
41 afnet
, _
, err
= parseDialNetwork(net
)
43 return "", nil, &OpError
{op
, net
, nil, err
}
45 if op
== "dial" && addr
== "" {
46 return "", nil, &OpError
{op
, net
, nil, errMissingAddress
}
48 a
, err
= resolveAfnetAddr(afnet
, addr
, deadline
)
52 func resolveAfnetAddr(afnet
, addr
string, deadline time
.Time
) (Addr
, error
) {
57 case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6", "ip", "ip4", "ip6":
58 return resolveInternetAddr(afnet
, addr
, deadline
)
59 case "unix", "unixgram", "unixpacket":
60 return ResolveUnixAddr(afnet
, addr
)
65 // Dial connects to the address addr on the network net.
67 // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only),
68 // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4"
69 // (IPv4-only), "ip6" (IPv6-only), "unix" and "unixpacket".
71 // For TCP and UDP networks, addresses have the form host:port.
72 // If host is a literal IPv6 address, it must be enclosed
73 // in square brackets. The functions JoinHostPort and SplitHostPort
74 // manipulate addresses in this form.
77 // Dial("tcp", "12.34.56.78:80")
78 // Dial("tcp", "google.com:80")
79 // Dial("tcp", "[de:ad:be:ef::ca:fe]:80")
81 // For IP networks, net must be "ip", "ip4" or "ip6" followed
82 // by a colon and a protocol number or name.
85 // Dial("ip4:1", "127.0.0.1")
86 // Dial("ip6:ospf", "::1")
88 func Dial(net
, addr
string) (Conn
, error
) {
89 _
, addri
, err
:= resolveNetAddr("dial", net
, addr
, noDeadline
)
93 return dialAddr(net
, addr
, addri
, noDeadline
)
96 func dialAddr(net
, addr
string, addri Addr
, deadline time
.Time
) (c Conn
, err error
) {
97 switch ra
:= addri
.(type) {
99 c
, err
= dialTCP(net
, nil, ra
, deadline
)
101 c
, err
= dialUDP(net
, nil, ra
, deadline
)
103 c
, err
= dialIP(net
, nil, ra
, deadline
)
105 c
, err
= dialUnix(net
, nil, ra
, deadline
)
107 err
= &OpError
{"dial", net
+ " " + addr
, nil, UnknownNetworkError(net
)}
115 // DialTimeout acts like Dial but takes a timeout.
116 // The timeout includes name resolution, if required.
117 func DialTimeout(net
, addr
string, timeout time
.Duration
) (Conn
, error
) {
118 return dialTimeout(net
, addr
, timeout
)
121 // dialTimeoutRace is the old implementation of DialTimeout, still used
122 // on operating systems where the deadline hasn't been pushed down
123 // into the pollserver.
124 // TODO: fix this on plan9.
125 func dialTimeoutRace(net
, addr
string, timeout time
.Duration
) (Conn
, error
) {
126 t
:= time
.NewTimer(timeout
)
132 ch
:= make(chan pair
, 1)
133 resolvedAddr
:= make(chan Addr
, 1)
135 _
, addri
, err
:= resolveNetAddr("dial", net
, addr
, noDeadline
)
140 resolvedAddr
<- addri
// in case we need it for OpError
141 c
, err
:= dialAddr(net
, addr
, addri
, noDeadline
)
146 // Try to use the real Addr in our OpError, if we resolved it
147 // before the timeout. Otherwise we just use stringAddr.
150 case a
:= <-resolvedAddr
:
153 addri
= &stringAddr
{net
, addr
}
159 Err
: &timeoutError
{},
163 return p
.Conn
, p
.error
168 type stringAddr
struct {
172 func (a stringAddr
) Network() string { return a
.net
}
173 func (a stringAddr
) String() string { return a
.addr
}
175 // Listen announces on the local network address laddr.
176 // The network string net must be a stream-oriented network:
177 // "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
178 func Listen(net
, laddr
string) (Listener
, error
) {
179 afnet
, a
, err
:= resolveNetAddr("listen", net
, laddr
, noDeadline
)
184 case "tcp", "tcp4", "tcp6":
189 return ListenTCP(net
, la
)
190 case "unix", "unixpacket":
195 return ListenUnix(net
, la
)
197 return nil, UnknownNetworkError(net
)
200 // ListenPacket announces on the local network address laddr.
201 // The network string net must be a packet-oriented network:
202 // "udp", "udp4", "udp6", "ip", "ip4", "ip6" or "unixgram".
203 func ListenPacket(net
, laddr
string) (PacketConn
, error
) {
204 afnet
, a
, err
:= resolveNetAddr("listen", net
, laddr
, noDeadline
)
209 case "udp", "udp4", "udp6":
214 return ListenUDP(net
, la
)
215 case "ip", "ip4", "ip6":
220 return ListenIP(net
, la
)
226 return ListenUnixgram(net
, la
)
228 return nil, UnknownNetworkError(net
)