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