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 sd := &sysDialer{network: network, address: raddr.String()}
212 c, err := sd.dialUDP(context.Background(), laddr, raddr)
213 if err != nil {
214 return nil, &OpError{Op: "dial", Net: network, Source: laddr.opAddr(), Addr: raddr.opAddr(), Err: err}
215 }
216 return c, nil
217 }
218
219
220
221
222
223
224
225
226
227
228 func ListenUDP(network string, laddr *UDPAddr) (*UDPConn, error) {
229 switch network {
230 case "udp", "udp4", "udp6":
231 default:
232 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: UnknownNetworkError(network)}
233 }
234 if laddr == nil {
235 laddr = &UDPAddr{}
236 }
237 sl := &sysListener{network: network, address: laddr.String()}
238 c, err := sl.listenUDP(context.Background(), laddr)
239 if err != nil {
240 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: laddr.opAddr(), Err: err}
241 }
242 return c, nil
243 }
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262 func ListenMulticastUDP(network string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
263 switch network {
264 case "udp", "udp4", "udp6":
265 default:
266 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: UnknownNetworkError(network)}
267 }
268 if gaddr == nil || gaddr.IP == nil {
269 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: errMissingAddress}
270 }
271 sl := &sysListener{network: network, address: gaddr.String()}
272 c, err := sl.listenMulticastUDP(context.Background(), ifi, gaddr)
273 if err != nil {
274 return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: gaddr.opAddr(), Err: err}
275 }
276 return c, nil
277 }
278
View as plain text