OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [udpsock_posix.go] - Blame information for rev 848

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 The Go Authors.  All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// +build darwin freebsd linux netbsd openbsd windows
6
 
7
// UDP sockets
8
 
9
package net
10
 
11
import (
12
        "errors"
13
        "os"
14
        "syscall"
15
        "time"
16
)
17
 
18
var ErrWriteToConnected = errors.New("use of WriteTo with pre-connected UDP")
19
 
20
func sockaddrToUDP(sa syscall.Sockaddr) Addr {
21
        switch sa := sa.(type) {
22
        case *syscall.SockaddrInet4:
23
                return &UDPAddr{sa.Addr[0:], sa.Port}
24
        case *syscall.SockaddrInet6:
25
                return &UDPAddr{sa.Addr[0:], sa.Port}
26
        }
27
        return nil
28
}
29
 
30
func (a *UDPAddr) family() int {
31
        if a == nil || len(a.IP) <= IPv4len {
32
                return syscall.AF_INET
33
        }
34
        if a.IP.To4() != nil {
35
                return syscall.AF_INET
36
        }
37
        return syscall.AF_INET6
38
}
39
 
40
func (a *UDPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
41
        return ipToSockaddr(family, a.IP, a.Port)
42
}
43
 
44
func (a *UDPAddr) toAddr() sockaddr {
45
        if a == nil { // nil *UDPAddr
46
                return nil // nil interface
47
        }
48
        return a
49
}
50
 
51
// UDPConn is the implementation of the Conn and PacketConn
52
// interfaces for UDP network connections.
53
type UDPConn struct {
54
        fd *netFD
55
}
56
 
57
func newUDPConn(fd *netFD) *UDPConn { return &UDPConn{fd} }
58
 
59
func (c *UDPConn) ok() bool { return c != nil && c.fd != nil }
60
 
61
// Implementation of the Conn interface - see Conn for documentation.
62
 
63
// Read implements the Conn Read method.
64
func (c *UDPConn) Read(b []byte) (int, error) {
65
        if !c.ok() {
66
                return 0, os.EINVAL
67
        }
68
        return c.fd.Read(b)
69
}
70
 
71
// Write implements the Conn Write method.
72
func (c *UDPConn) Write(b []byte) (int, error) {
73
        if !c.ok() {
74
                return 0, os.EINVAL
75
        }
76
        return c.fd.Write(b)
77
}
78
 
79
// Close closes the UDP connection.
80
func (c *UDPConn) Close() error {
81
        if !c.ok() {
82
                return os.EINVAL
83
        }
84
        err := c.fd.Close()
85
        c.fd = nil
86
        return err
87
}
88
 
89
// LocalAddr returns the local network address.
90
func (c *UDPConn) LocalAddr() Addr {
91
        if !c.ok() {
92
                return nil
93
        }
94
        return c.fd.laddr
95
}
96
 
97
// RemoteAddr returns the remote network address, a *UDPAddr.
98
func (c *UDPConn) RemoteAddr() Addr {
99
        if !c.ok() {
100
                return nil
101
        }
102
        return c.fd.raddr
103
}
104
 
105
// SetDeadline implements the Conn SetDeadline method.
106
func (c *UDPConn) SetDeadline(t time.Time) error {
107
        if !c.ok() {
108
                return os.EINVAL
109
        }
110
        return setDeadline(c.fd, t)
111
}
112
 
113
// SetReadDeadline implements the Conn SetReadDeadline method.
114
func (c *UDPConn) SetReadDeadline(t time.Time) error {
115
        if !c.ok() {
116
                return os.EINVAL
117
        }
118
        return setReadDeadline(c.fd, t)
119
}
120
 
121
// SetWriteDeadline implements the Conn SetWriteDeadline method.
122
func (c *UDPConn) SetWriteDeadline(t time.Time) error {
123
        if !c.ok() {
124
                return os.EINVAL
125
        }
126
        return setWriteDeadline(c.fd, t)
127
}
128
 
129
// SetReadBuffer sets the size of the operating system's
130
// receive buffer associated with the connection.
131
func (c *UDPConn) SetReadBuffer(bytes int) error {
132
        if !c.ok() {
133
                return os.EINVAL
134
        }
135
        return setReadBuffer(c.fd, bytes)
136
}
137
 
138
// SetWriteBuffer sets the size of the operating system's
139
// transmit buffer associated with the connection.
140
func (c *UDPConn) SetWriteBuffer(bytes int) error {
141
        if !c.ok() {
142
                return os.EINVAL
143
        }
144
        return setWriteBuffer(c.fd, bytes)
145
}
146
 
147
// UDP-specific methods.
148
 
149
// ReadFromUDP reads a UDP packet from c, copying the payload into b.
150
// It returns the number of bytes copied into b and the return address
151
// that was on the packet.
152
//
153
// ReadFromUDP can be made to time out and return an error with Timeout() == true
154
// after a fixed time limit; see SetDeadline and SetReadDeadline.
155
func (c *UDPConn) ReadFromUDP(b []byte) (n int, addr *UDPAddr, err error) {
156
        if !c.ok() {
157
                return 0, nil, os.EINVAL
158
        }
159
        n, sa, err := c.fd.ReadFrom(b)
160
        switch sa := sa.(type) {
161
        case *syscall.SockaddrInet4:
162
                addr = &UDPAddr{sa.Addr[0:], sa.Port}
163
        case *syscall.SockaddrInet6:
164
                addr = &UDPAddr{sa.Addr[0:], sa.Port}
165
        }
166
        return
167
}
168
 
169
// ReadFrom implements the PacketConn ReadFrom method.
170
func (c *UDPConn) ReadFrom(b []byte) (int, Addr, error) {
171
        if !c.ok() {
172
                return 0, nil, os.EINVAL
173
        }
174
        n, uaddr, err := c.ReadFromUDP(b)
175
        return n, uaddr.toAddr(), err
176
}
177
 
178
// WriteToUDP writes a UDP packet to addr via c, copying the payload from b.
179
//
180
// WriteToUDP can be made to time out and return
181
// an error with Timeout() == true after a fixed time limit;
182
// see SetDeadline and SetWriteDeadline.
183
// On packet-oriented connections, write timeouts are rare.
184
func (c *UDPConn) WriteToUDP(b []byte, addr *UDPAddr) (int, error) {
185
        if !c.ok() {
186
                return 0, os.EINVAL
187
        }
188
        if c.fd.isConnected {
189
                return 0, &OpError{"write", c.fd.net, addr, ErrWriteToConnected}
190
        }
191
        sa, err := addr.sockaddr(c.fd.family)
192
        if err != nil {
193
                return 0, &OpError{"write", c.fd.net, addr, err}
194
        }
195
        return c.fd.WriteTo(b, sa)
196
}
197
 
198
// WriteTo implements the PacketConn WriteTo method.
199
func (c *UDPConn) WriteTo(b []byte, addr Addr) (int, error) {
200
        if !c.ok() {
201
                return 0, os.EINVAL
202
        }
203
        a, ok := addr.(*UDPAddr)
204
        if !ok {
205
                return 0, &OpError{"write", c.fd.net, addr, os.EINVAL}
206
        }
207
        return c.WriteToUDP(b, a)
208
}
209
 
210
// File returns a copy of the underlying os.File, set to blocking mode.
211
// It is the caller's responsibility to close f when finished.
212
// Closing c does not affect f, and closing f does not affect c.
213
func (c *UDPConn) File() (f *os.File, err error) { return c.fd.dup() }
214
 
215
// DialUDP connects to the remote address raddr on the network net,
216
// which must be "udp", "udp4", or "udp6".  If laddr is not nil, it is used
217
// as the local address for the connection.
218
func DialUDP(net string, laddr, raddr *UDPAddr) (*UDPConn, error) {
219
        switch net {
220
        case "udp", "udp4", "udp6":
221
        default:
222
                return nil, UnknownNetworkError(net)
223
        }
224
        if raddr == nil {
225
                return nil, &OpError{"dial", net, nil, errMissingAddress}
226
        }
227
        fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_DGRAM, 0, "dial", sockaddrToUDP)
228
        if err != nil {
229
                return nil, err
230
        }
231
        return newUDPConn(fd), nil
232
}
233
 
234
// ListenUDP listens for incoming UDP packets addressed to the
235
// local address laddr.  The returned connection c's ReadFrom
236
// and WriteTo methods can be used to receive and send UDP
237
// packets with per-packet addressing.
238
func ListenUDP(net string, laddr *UDPAddr) (*UDPConn, error) {
239
        switch net {
240
        case "udp", "udp4", "udp6":
241
        default:
242
                return nil, UnknownNetworkError(net)
243
        }
244
        if laddr == nil {
245
                return nil, &OpError{"listen", net, nil, errMissingAddress}
246
        }
247
        fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
248
        if err != nil {
249
                return nil, err
250
        }
251
        return newUDPConn(fd), nil
252
}
253
 
254
// ListenMulticastUDP listens for incoming multicast UDP packets
255
// addressed to the group address gaddr on ifi, which specifies
256
// the interface to join.  ListenMulticastUDP uses default
257
// multicast interface if ifi is nil.
258
func ListenMulticastUDP(net string, ifi *Interface, gaddr *UDPAddr) (*UDPConn, error) {
259
        switch net {
260
        case "udp", "udp4", "udp6":
261
        default:
262
                return nil, UnknownNetworkError(net)
263
        }
264
        if gaddr == nil || gaddr.IP == nil {
265
                return nil, &OpError{"listenmulticastudp", "udp", nil, errMissingAddress}
266
        }
267
        fd, err := internetSocket(net, gaddr.toAddr(), nil, syscall.SOCK_DGRAM, 0, "listen", sockaddrToUDP)
268
        if err != nil {
269
                return nil, err
270
        }
271
        c := newUDPConn(fd)
272
        ip4 := gaddr.IP.To4()
273
        if ip4 != nil {
274
                err := listenIPv4MulticastUDP(c, ifi, ip4)
275
                if err != nil {
276
                        c.Close()
277
                        return nil, err
278
                }
279
        } else {
280
                err := listenIPv6MulticastUDP(c, ifi, gaddr.IP)
281
                if err != nil {
282
                        c.Close()
283
                        return nil, err
284
                }
285
        }
286
        return c, nil
287
}
288
 
289
func listenIPv4MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
290
        if ifi != nil {
291
                err := setIPv4MulticastInterface(c.fd, ifi)
292
                if err != nil {
293
                        return err
294
                }
295
        }
296
        err := setIPv4MulticastLoopback(c.fd, false)
297
        if err != nil {
298
                return err
299
        }
300
        err = joinIPv4GroupUDP(c, ifi, ip)
301
        if err != nil {
302
                return err
303
        }
304
        return nil
305
}
306
 
307
func listenIPv6MulticastUDP(c *UDPConn, ifi *Interface, ip IP) error {
308
        if ifi != nil {
309
                err := setIPv6MulticastInterface(c.fd, ifi)
310
                if err != nil {
311
                        return err
312
                }
313
        }
314
        err := setIPv6MulticastLoopback(c.fd, false)
315
        if err != nil {
316
                return err
317
        }
318
        err = joinIPv6GroupUDP(c, ifi, ip)
319
        if err != nil {
320
                return err
321
        }
322
        return nil
323
}
324
 
325
func joinIPv4GroupUDP(c *UDPConn, ifi *Interface, ip IP) error {
326
        err := joinIPv4Group(c.fd, ifi, ip)
327
        if err != nil {
328
                return &OpError{"joinipv4group", c.fd.net, &IPAddr{ip}, err}
329
        }
330
        return nil
331
}
332
 
333
func leaveIPv4GroupUDP(c *UDPConn, ifi *Interface, ip IP) error {
334
        err := leaveIPv4Group(c.fd, ifi, ip)
335
        if err != nil {
336
                return &OpError{"leaveipv4group", c.fd.net, &IPAddr{ip}, err}
337
        }
338
        return nil
339
}
340
 
341
func joinIPv6GroupUDP(c *UDPConn, ifi *Interface, ip IP) error {
342
        err := joinIPv6Group(c.fd, ifi, ip)
343
        if err != nil {
344
                return &OpError{"joinipv6group", c.fd.net, &IPAddr{ip}, err}
345
        }
346
        return nil
347
}
348
 
349
func leaveIPv6GroupUDP(c *UDPConn, ifi *Interface, ip IP) error {
350
        err := leaveIPv6Group(c.fd, ifi, ip)
351
        if err != nil {
352
                return &OpError{"leaveipv6group", c.fd.net, &IPAddr{ip}, err}
353
        }
354
        return nil
355
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.