Source file
src/net/udpsock.go
Documentation: net
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "syscall"
10 )
11
12
13
14
15
16
17
18
19
20
21
22 type UDPAddr struct {
23 IP IP
24 Port int
25 Zone string
26 }
27
28
29 func (a *UDPAddr) Network() string { return "udp" }
30
31 func (a *UDPAddr) String() string {
32 if a == nil {
33 return "<nil>"
34 }
35 ip := ipEmptyString(a.IP)
36 if a.Zone != "" {
37 return JoinHostPort(ip+"%"+a.Zone, itoa(a.Port))
38 }
39 return JoinHostPort(ip, itoa(a.Port))
40 }
41
42 func (a *UDPAddr) isWildcard() bool {
43 if a == nil || a.IP == nil {
44 return true
45 }
46 return a.IP.IsUnspecified()
47 }
48
49 func (a *UDPAddr) opAddr() Addr {
50 if a == nil {
51 return nil
52 }
53 return a
54 }
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71 func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
72 switch network {
73 case "udp", "udp4", "udp6":
74 case "":
75 network = "udp"
76 default:
77 return nil, UnknownNetworkError(network)
78 }
79 addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
80 if err != nil {
81 return nil, err
82 }
83 return addrs.forResolve(network, address).(*UDPAddr), nil
84 }
85
86
87
88 type UDPConn struct {
89 conn
90 }
91
92
93
94 func (c *UDPConn) SyscallConn() (syscall.RawConn, error) {
95 if !c.ok() {
96 return nil, syscall.EINVAL
97 }
98 return newRawConn(c.fd)
99 }
100
101
102 func (c *UDPConn) ReadFromUDP(b []byte) (int, *UDPAddr, error) {
103 if !c.ok() {
104 return 0, nil, syscall.EINVAL
105 }
106 n, addr, err := c.readFrom(b)
107 if err != nil {
108 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
109 }
110 return n, addr, err
111 }
112
113
114 func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
115 if !c.ok() {
116 return 0, nil, syscall.EINVAL
117 }
118 n, addr, err := c.readFrom(b)
119 if err != nil {
120 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
121 }
122 if addr == nil {
123 return n, nil, err
124 }
125 return n, addr, err
126 }
127
128
129
130
131
132
133
134
135 func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
136 if !c.ok() {
137 return 0, 0, 0, nil, syscall.EINVAL
138 }
139 n, oobn, flags, addr, err = c.readMsg(b, oob)
140 if err != nil {
141 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
142 }
143 return
144 }
145
146
147 func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
148 if !c.ok() {
149 return 0, syscall.EINVAL
150 }
151 n, err := c.writeTo(b, addr)
152 if err != nil {
153 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
154 }
155 return n, err
156 }
157
158
159 func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
160 if !c.ok() {
161 return 0, syscall.EINVAL
162 }
163 a, ok := addr.(*UDPAddr)
164 if !ok {
165 return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
166 }
167 n, err := c.writeTo(b, a)
168 if err != nil {
169 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
170 }
171 return n, err
172 }
173
174
175
176
177
178
179
180
181
182 func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
183 if !c.ok() {
184 return 0, 0, syscall.EINVAL
185 }
186 n, oobn, err = c.writeMsg(b, oob, addr)
187 if err != nil {
188 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
189 }
190 return
191 }
192
193 func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }
194
195
196
197
198
199
200
201
202 func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error) {
203 switch network {
204 case "udp", "udp4", "udp6":
205 default:
206 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
207 }
208 if raddr == nil {
209 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
210 }
211 c, err := dialUDP(context.Background(), network, laddr, raddr)
212 if err != nil {
213 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
214 }
215 return c, nil
216 }
217
218
219
220
221
222
223
224
225
226
227 func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
228 switch network {
229 case "udp", "udp4", "udp6":
230 default:
231 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
232 }
233 if laddr == nil {
234 laddr = &UDPAddr{}
235 }
236 c, err := listenUDP(context.Background(), network, laddr)
237 if err != nil {
238 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
239 }
240 return c, nil
241 }
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260 func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
261 switch network {
262 case "udp", "udp4", "udp6":
263 default:
264 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
265 }
266 if gaddr == nil || gaddr.IP == nil {
267 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
268 }
269 c, err := listenMulticastUDP(context.Background(), network, ifi, gaddr)
270 if err != nil {
271 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: err}
272 }
273 return c, nil
274 }
275
View as plain text