Source file
src/net/udpsock.go
1
2
3
4
5 package net
6
7 import (
8 "context"
9 "internal/itoa"
10 "net/netip"
11 "syscall"
12 )
13
14
15
16
17
18
19
20
21
22
23
24 type UDPAddr struct {
25 IP IP
26 Port int
27 Zone string
28 }
29
30
31
32
33
34
35 func (a *UDPAddr) AddrPort() netip.AddrPort {
36 if a == nil {
37 return netip.AddrPort{}
38 }
39 na, _ := netip.AddrFromSlice(a.IP)
40 na = na.WithZone(a.Zone)
41 return netip.AddrPortFrom(na, uint16(a.Port))
42 }
43
44
45 func (a *UDPAddr) Network() string { return "udp" }
46
47 func (a *UDPAddr) String() string {
48 if a == nil {
49 return "<nil>"
50 }
51 ip := ipEmptyString(a.IP)
52 if a.Zone != "" {
53 return JoinHostPort(ip+"%"+a.Zone, itoa.Itoa(a.Port))
54 }
55 return JoinHostPort(ip, itoa.Itoa(a.Port))
56 }
57
58 func (a *UDPAddr) isWildcard() bool {
59 if a == nil || a.IP == nil {
60 return true
61 }
62 return a.IP.IsUnspecified()
63 }
64
65 func (a *UDPAddr) opAddr() Addr {
66 if a == nil {
67 return nil
68 }
69 return a
70 }
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87 func ResolveUDPAddr(network, address string) (*UDPAddr, error) {
88 switch network {
89 case "udp", "udp4", "udp6":
90 case "":
91 network = "udp"
92 default:
93 return nil, UnknownNetworkError(network)
94 }
95 addrs, err := DefaultResolver.internetAddrList(context.Background(), network, address)
96 if err != nil {
97 return nil, err
98 }
99 return addrs.forResolve(network, address).(*UDPAddr), nil
100 }
101
102
103
104
105 func UDPAddrFromAddrPort(addr netip.AddrPort) *UDPAddr {
106 return &UDPAddr{
107 IP: addr.Addr().AsSlice(),
108 Zone: addr.Addr().Zone(),
109 Port: int(addr.Port()),
110 }
111 }
112
113
114 type addrPortUDPAddr struct {
115 netip.AddrPort
116 }
117
118 func (addrPortUDPAddr) Network() string { return "udp" }
119
120
121
122 type UDPConn struct {
123 conn
124 }
125
126
127
128 func (c *UDPConn) SyscallConn() (syscall.RawConn, error) {
129 if !c.ok() {
130 return nil, syscall.EINVAL
131 }
132 return newRawConn(c.fd), nil
133 }
134
135
136 func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
137
138
139
140
141 return c.readFromUDP(b, &UDPAddr{})
142 }
143
144
145 func (c *UDPConn) readFromUDP(b []byte, addr *UDPAddr) (int, *UDPAddr, error) {
146 if !c.ok() {
147 return 0, nil, syscall.EINVAL
148 }
149 n, addr, err := c.readFrom(b, addr)
150 if err != nil {
151 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
152 }
153 return n, addr, err
154 }
155
156
157 func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
158 n, addr, err := c.readFromUDP(b, &UDPAddr{})
159 if addr == nil {
160
161 return n, nil, err
162 }
163 return n, addr, err
164 }
165
166
167
168
169
170
171 func (c *UDPConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) {
172 if !c.ok() {
173 return 0, netip.AddrPort{}, syscall.EINVAL
174 }
175 n, addr, err = c.readFromAddrPort(b)
176 if err != nil {
177 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
178 }
179 return n, addr, err
180 }
181
182
183
184
185
186
187
188
189 func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
190 var ap netip.AddrPort
191 n, oobn, flags, ap, err = c.ReadMsgUDPAddrPort(b, oob)
192 if ap.IsValid() {
193 addr = UDPAddrFromAddrPort(ap)
194 }
195 return
196 }
197
198
199 func (c *UDPConn) ReadMsgUDPAddrPort(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
200 if !c.ok() {
201 return 0, 0, 0, netip.AddrPort{}, syscall.EINVAL
202 }
203 n, oobn, flags, addr, err = c.readMsg(b, oob)
204 if err != nil {
205 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
206 }
207 return
208 }
209
210
211 func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
212 if !c.ok() {
213 return 0, syscall.EINVAL
214 }
215 n, err := c.writeTo(b, addr)
216 if err != nil {
217 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
218 }
219 return n, err
220 }
221
222
223 func (c *UDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) {
224 if !c.ok() {
225 return 0, syscall.EINVAL
226 }
227 n, err := c.writeToAddrPort(b, addr)
228 if err != nil {
229 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addrPortUDPAddr{addr}, Err: err}
230 }
231 return n, err
232 }
233
234
235 func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
236 if !c.ok() {
237 return 0, syscall.EINVAL
238 }
239 a, ok := addr.(*UDPAddr)
240 if !ok {
241 return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
242 }
243 n, err := c.writeTo(b, a)
244 if err != nil {
245 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
246 }
247 return n, err
248 }
249
250
251
252
253
254
255
256
257
258 func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
259 if !c.ok() {
260 return 0, 0, syscall.EINVAL
261 }
262 n, oobn, err = c.writeMsg(b, oob, addr)
263 if err != nil {
264 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
265 }
266 return
267 }
268
269
270 func (c *UDPConn) WriteMsgUDPAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn int, err error) {
271 if !c.ok() {
272 return 0, 0, syscall.EINVAL
273 }
274 n, oobn, err = c.writeMsgAddrPort(b, oob, addr)
275 if err != nil {
276 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addrPortUDPAddr{addr}, Err: err}
277 }
278 return
279 }
280
281 func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }
282
283
284
285
286
287
288
289
290 func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error) {
291 switch network {
292 case "udp", "udp4", "udp6":
293 default:
294 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
295 }
296 if raddr == nil {
297 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
298 }
299 sd := &sysDialer{network: network, address: raddr.String()}
300 c, err := sd.dialUDP(context.Background(), laddr, raddr)
301 if err != nil {
302 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
303 }
304 return c, nil
305 }
306
307
308
309
310
311
312
313
314
315
316 func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
317 switch network {
318 case "udp", "udp4", "udp6":
319 default:
320 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
321 }
322 if laddr == nil {
323 laddr = &UDPAddr{}
324 }
325 sl := &sysListener{network: network, address: laddr.String()}
326 c, err := sl.listenUDP(context.Background(), laddr)
327 if err != nil {
328 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
329 }
330 return c, nil
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353 func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
354 switch network {
355 case "udp", "udp4", "udp6":
356 default:
357 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
358 }
359 if gaddr == nil || gaddr.IP == nil {
360 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
361 }
362 sl := &sysListener{network: network, address: gaddr.String()}
363 c, err := sl.listenMulticastUDP(context.Background(), ifi, gaddr)
364 if err != nil {
365 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: err}
366 }
367 return c, nil
368 }
369
View as plain text