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)
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 func (c *UDPConn) ReadFromUDPAddrPort(b []byte) (n int, addr netip.AddrPort, err error) {
168 if !c.ok() {
169 return 0, netip.AddrPort{}, syscall.EINVAL
170 }
171 n, addr, err = c.readFromAddrPort(b)
172 if err != nil {
173 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
174 }
175 return n, addr, err
176 }
177
178
179
180
181
182
183
184
185 func (c *UDPConn) ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *UDPAddr, err error) {
186 var ap netip.AddrPort
187 n, oobn, flags, ap, err = c.ReadMsgUDPAddrPort(b, oob)
188 if ap.IsValid() {
189 addr = UDPAddrFromAddrPort(ap)
190 }
191 return
192 }
193
194
195 func (c *UDPConn) ReadMsgUDPAddrPort(b, oob []byte) (n, oobn, flags int, addr netip.AddrPort, err error) {
196 if !c.ok() {
197 return 0, 0, 0, netip.AddrPort{}, syscall.EINVAL
198 }
199 n, oobn, flags, addr, err = c.readMsg(b, oob)
200 if err != nil {
201 err = &OpError{Op: "read", Net: c.fd.net, Source: c.fd.laddr, Addr: c.fd.raddr, Err: err}
202 }
203 return
204 }
205
206
207 func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
208 if !c.ok() {
209 return 0, syscall.EINVAL
210 }
211 n, err := c.writeTo(b, addr)
212 if err != nil {
213 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
214 }
215 return n, err
216 }
217
218
219 func (c *UDPConn) WriteToUDPAddrPort(b []byte, addr netip.AddrPort) (int, error) {
220 if !c.ok() {
221 return 0, syscall.EINVAL
222 }
223 n, err := c.writeToAddrPort(b, addr)
224 if err != nil {
225 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addrPortUDPAddr{addr}, Err: err}
226 }
227 return n, err
228 }
229
230
231 func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
232 if !c.ok() {
233 return 0, syscall.EINVAL
234 }
235 a, ok := addr.(*UDPAddr)
236 if !ok {
237 return 0, &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr, Err: syscall.EINVAL}
238 }
239 n, err := c.writeTo(b, a)
240 if err != nil {
241 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: a.opAddr(), Err: err}
242 }
243 return n, err
244 }
245
246
247
248
249
250
251
252
253
254 func (c *UDPConn) WriteMsgUDP(b, oob []byte, addr *UDPAddr) (n, oobn int, err error) {
255 if !c.ok() {
256 return 0, 0, syscall.EINVAL
257 }
258 n, oobn, err = c.writeMsg(b, oob, addr)
259 if err != nil {
260 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addr.opAddr(), Err: err}
261 }
262 return
263 }
264
265
266 func (c *UDPConn) WriteMsgUDPAddrPort(b, oob []byte, addr netip.AddrPort) (n, oobn int, err error) {
267 if !c.ok() {
268 return 0, 0, syscall.EINVAL
269 }
270 n, oobn, err = c.writeMsgAddrPort(b, oob, addr)
271 if err != nil {
272 err = &OpError{Op: "write", Net: c.fd.net, Source: c.fd.laddr, Addr: addrPortUDPAddr{addr}, Err: err}
273 }
274 return
275 }
276
277 func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{conn{fd}} }
278
279
280
281
282
283
284
285
286 func DialUDP(network string, laddr, raddr *UDPAddr) (*UDPConn, error) {
287 switch network {
288 case "udp", "udp4", "udp6":
289 default:
290 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: UnknownNetworkError(network)}
291 }
292 if raddr == nil {
293 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: nil, Err: errMissingAddress}
294 }
295 sd := &sysDialer{network: network, address: raddr.String()}
296 c, err := sd.dialUDP(context.Background(), laddr, raddr)
297 if err != nil {
298 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
299 }
300 return c, nil
301 }
302
303
304
305
306
307
308
309
310
311
312 func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
313 switch network {
314 case "udp", "udp4", "udp6":
315 default:
316 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
317 }
318 if laddr == nil {
319 laddr = &UDPAddr{}
320 }
321 sl := &sysListener{network: network, address: laddr.String()}
322 c, err := sl.listenUDP(context.Background(), laddr)
323 if err != nil {
324 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
325 }
326 return c, nil
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
350 switch network {
351 case "udp", "udp4", "udp6":
352 default:
353 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
354 }
355 if gaddr == nil || gaddr.IP == nil {
356 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
357 }
358 sl := &sysListener{network: network, address: gaddr.String()}
359 c, err := sl.listenMulticastUDP(context.Background(), ifi, gaddr)
360 if err != nil {
361 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: err}
362 }
363 return c, nil
364 }
365
View as plain text