1 // Copyright 2009 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.
12 // BUG(mikio): On NaCl, Plan 9 and Windows, the ReadMsgUDP and
13 // WriteMsgUDP methods of UDPConn are not implemented.
15 // BUG(mikio): On Windows, the File method of UDPConn is not
18 // BUG(mikio): On NaCl, the ListenMulticastUDP function is not
21 // UDPAddr represents the address of a UDP end point.
25 Zone
string // IPv6 scoped addressing zone
28 // Network returns the address's network name, "udp".
29 func (a
*UDPAddr
) Network() string { return "udp" }
31 func (a
*UDPAddr
) String() string {
35 ip
:= ipEmptyString(a
.IP
)
37 return JoinHostPort(ip
+"%"+a
.Zone
, itoa(a
.Port
))
39 return JoinHostPort(ip
, itoa(a
.Port
))
42 func (a
*UDPAddr
) isWildcard() bool {
43 if a
== nil || a
.IP
== nil {
46 return a
.IP
.IsUnspecified()
49 func (a
*UDPAddr
) opAddr() Addr
{
56 // ResolveUDPAddr parses addr as a UDP address of the form "host:port"
57 // or "[ipv6-host%zone]:port" and resolves a pair of domain name and
58 // port name on the network net, which must be "udp", "udp4" or
59 // "udp6". A literal address or host name for IPv6 must be enclosed
60 // in square brackets, as in "[::1]:80", "[ipv6-host]:http" or
61 // "[ipv6-host%zone]:80".
63 // Resolving a hostname is not recommended because this returns at most
64 // one of its IP addresses.
65 func ResolveUDPAddr(net
, addr
string) (*UDPAddr
, error
) {
67 case "udp", "udp4", "udp6":
68 case "": // a hint wildcard for Go 1.0 undocumented behavior
71 return nil, UnknownNetworkError(net
)
73 addrs
, err
:= DefaultResolver
.internetAddrList(context
.Background(), net
, addr
)
77 return addrs
.first(isIPv4
).(*UDPAddr
), nil
80 // UDPConn is the implementation of the Conn and PacketConn interfaces
81 // for UDP network connections.
86 // ReadFromUDP reads a UDP packet from c, copying the payload into b.
87 // It returns the number of bytes copied into b and the return address
88 // that was on the packet.
90 // ReadFromUDP can be made to time out and return an error with
91 // Timeout() == true after a fixed time limit; see SetDeadline and
93 func (c
*UDPConn
) ReadFromUDP(b
[]byte) (int, *UDPAddr
, error
) {
95 return 0, nil, syscall
.EINVAL
97 n
, addr
, err
:= c
.readFrom(b
)
99 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
104 // ReadFrom implements the PacketConn ReadFrom method.
105 func (c
*UDPConn
) ReadFrom(b
[]byte) (int, Addr
, error
) {
107 return 0, nil, syscall
.EINVAL
109 n
, addr
, err
:= c
.readFrom(b
)
111 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
119 // ReadMsgUDP reads a packet from c, copying the payload into b and
120 // the associated out-of-band data into oob. It returns the number
121 // of bytes copied into b, the number of bytes copied into oob, the
122 // flags that were set on the packet and the source address of the
124 func (c
*UDPConn
) ReadMsgUDP(b
, oob
[]byte) (n
, oobn
, flags
int, addr
*UDPAddr
, err error
) {
126 return 0, 0, 0, nil, syscall
.EINVAL
128 n
, oobn
, flags
, addr
, err
= c
.readMsg(b
, oob
)
130 err
= &OpError
{Op
: "read", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: c
.fd
.raddr
, Err
: err
}
135 // WriteToUDP writes a UDP packet to addr via c, copying the payload
138 // WriteToUDP can be made to time out and return an error with
139 // Timeout() == true after a fixed time limit; see SetDeadline and
140 // SetWriteDeadline. On packet-oriented connections, write timeouts
142 func (c
*UDPConn
) WriteToUDP(b
[]byte, addr
*UDPAddr
) (int, error
) {
144 return 0, syscall
.EINVAL
146 n
, err
:= c
.writeTo(b
, addr
)
148 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
153 // WriteTo implements the PacketConn WriteTo method.
154 func (c
*UDPConn
) WriteTo(b
[]byte, addr Addr
) (int, error
) {
156 return 0, syscall
.EINVAL
158 a
, ok
:= addr
.(*UDPAddr
)
160 return 0, &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
, Err
: syscall
.EINVAL
}
162 n
, err
:= c
.writeTo(b
, a
)
164 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: a
.opAddr(), Err
: err
}
169 // WriteMsgUDP writes a packet to addr via c if c isn't connected, or
170 // to c's remote destination address if c is connected (in which case
171 // addr must be nil). The payload is copied from b and the associated
172 // out-of-band data is copied from oob. It returns the number of
173 // payload and out-of-band bytes written.
174 func (c
*UDPConn
) WriteMsgUDP(b
, oob
[]byte, addr
*UDPAddr
) (n
, oobn
int, err error
) {
176 return 0, 0, syscall
.EINVAL
178 n
, oobn
, err
= c
.writeMsg(b
, oob
, addr
)
180 err
= &OpError
{Op
: "write", Net
: c
.fd
.net
, Source
: c
.fd
.laddr
, Addr
: addr
.opAddr(), Err
: err
}
185 func newUDPConn(fd
*netFD
) *UDPConn
{ return &UDPConn
{conn
{fd
}} }
187 // DialUDP connects to the remote address raddr on the network net,
188 // which must be "udp", "udp4", or "udp6". If laddr is not nil, it is
189 // used as the local address for the connection.
190 func DialUDP(net
string, laddr
, raddr
*UDPAddr
) (*UDPConn
, error
) {
192 case "udp", "udp4", "udp6":
194 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: UnknownNetworkError(net
)}
197 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: nil, Err
: errMissingAddress
}
199 c
, err
:= dialUDP(context
.Background(), net
, laddr
, raddr
)
201 return nil, &OpError
{Op
: "dial", Net
: net
, Source
: laddr
.opAddr(), Addr
: raddr
.opAddr(), Err
: err
}
206 // ListenUDP listens for incoming UDP packets addressed to the local
207 // address laddr. Net must be "udp", "udp4", or "udp6". If laddr has
208 // a port of 0, ListenUDP will choose an available port.
209 // The LocalAddr method of the returned UDPConn can be used to
210 // discover the port. The returned connection's ReadFrom and WriteTo
211 // methods can be used to receive and send UDP packets with per-packet
213 func ListenUDP(net
string, laddr
*UDPAddr
) (*UDPConn
, error
) {
215 case "udp", "udp4", "udp6":
217 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: UnknownNetworkError(net
)}
222 c
, err
:= listenUDP(context
.Background(), net
, laddr
)
224 return nil, &OpError
{Op
: "listen", Net
: net
, Source
: nil, Addr
: laddr
.opAddr(), Err
: err
}
229 // ListenMulticastUDP listens for incoming multicast UDP packets
230 // addressed to the group address gaddr on the interface ifi.
231 // Network must be "udp", "udp4" or "udp6".
232 // ListenMulticastUDP uses the system-assigned multicast interface
233 // when ifi is nil, although this is not recommended because the
234 // assignment depends on platforms and sometimes it might require
235 // routing configuration.
237 // ListenMulticastUDP is just for convenience of simple, small
238 // applications. There are golang.org/x/net/ipv4 and
239 // golang.org/x/net/ipv6 packages for general purpose uses.
240 func ListenMulticastUDP(network
string, ifi
*Interface
, gaddr
*UDPAddr
) (*UDPConn
, error
) {
242 case "udp", "udp4", "udp6":
244 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: gaddr
.opAddr(), Err
: UnknownNetworkError(network
)}
246 if gaddr
== nil || gaddr
.IP
== nil {
247 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: gaddr
.opAddr(), Err
: errMissingAddress
}
249 c
, err
:= listenMulticastUDP(context
.Background(), network
, ifi
, gaddr
)
251 return nil, &OpError
{Op
: "listen", Net
: network
, Source
: nil, Addr
: gaddr
.opAddr(), Err
: err
}