~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/net/iprawsock_posix.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
 
5
5
// +build darwin freebsd linux netbsd openbsd windows
6
6
 
7
 
// (Raw) IP sockets
8
 
 
9
7
package net
10
8
 
11
9
import (
12
 
        "os"
13
10
        "syscall"
14
11
        "time"
15
12
)
17
14
func sockaddrToIP(sa syscall.Sockaddr) Addr {
18
15
        switch sa := sa.(type) {
19
16
        case *syscall.SockaddrInet4:
20
 
                return &IPAddr{sa.Addr[0:]}
 
17
                return &IPAddr{IP: sa.Addr[0:]}
21
18
        case *syscall.SockaddrInet6:
22
 
                return &IPAddr{sa.Addr[0:]}
 
19
                return &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
23
20
        }
24
21
        return nil
25
22
}
42
39
}
43
40
 
44
41
func (a *IPAddr) sockaddr(family int) (syscall.Sockaddr, error) {
45
 
        return ipToSockaddr(family, a.IP, 0)
 
42
        return ipToSockaddr(family, a.IP, 0, a.Zone)
46
43
}
47
44
 
48
45
func (a *IPAddr) toAddr() sockaddr {
52
49
        return a
53
50
}
54
51
 
55
 
// IPConn is the implementation of the Conn and PacketConn
56
 
// interfaces for IP network connections.
 
52
// IPConn is the implementation of the Conn and PacketConn interfaces
 
53
// for IP network connections.
57
54
type IPConn struct {
58
 
        fd *netFD
59
 
}
60
 
 
61
 
func newIPConn(fd *netFD) *IPConn { return &IPConn{fd} }
62
 
 
63
 
func (c *IPConn) ok() bool { return c != nil && c.fd != nil }
64
 
 
65
 
// Implementation of the Conn interface - see Conn for documentation.
66
 
 
67
 
// Read implements the Conn Read method.
68
 
func (c *IPConn) Read(b []byte) (int, error) {
69
 
        n, _, err := c.ReadFrom(b)
70
 
        return n, err
71
 
}
72
 
 
73
 
// Write implements the Conn Write method.
74
 
func (c *IPConn) Write(b []byte) (int, error) {
75
 
        if !c.ok() {
76
 
                return 0, syscall.EINVAL
77
 
        }
78
 
        return c.fd.Write(b)
79
 
}
80
 
 
81
 
// Close closes the IP connection.
82
 
func (c *IPConn) Close() error {
83
 
        if !c.ok() {
84
 
                return syscall.EINVAL
85
 
        }
86
 
        return c.fd.Close()
87
 
}
88
 
 
89
 
// LocalAddr returns the local network address.
90
 
func (c *IPConn) 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 *IPAddr.
98
 
func (c *IPConn) 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 *IPConn) SetDeadline(t time.Time) error {
107
 
        if !c.ok() {
108
 
                return syscall.EINVAL
109
 
        }
110
 
        return setDeadline(c.fd, t)
111
 
}
112
 
 
113
 
// SetReadDeadline implements the Conn SetReadDeadline method.
114
 
func (c *IPConn) SetReadDeadline(t time.Time) error {
115
 
        if !c.ok() {
116
 
                return syscall.EINVAL
117
 
        }
118
 
        return setReadDeadline(c.fd, t)
119
 
}
120
 
 
121
 
// SetWriteDeadline implements the Conn SetWriteDeadline method.
122
 
func (c *IPConn) SetWriteDeadline(t time.Time) error {
123
 
        if !c.ok() {
124
 
                return syscall.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 *IPConn) SetReadBuffer(bytes int) error {
132
 
        if !c.ok() {
133
 
                return syscall.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 *IPConn) SetWriteBuffer(bytes int) error {
141
 
        if !c.ok() {
142
 
                return syscall.EINVAL
143
 
        }
144
 
        return setWriteBuffer(c.fd, bytes)
145
 
}
146
 
 
147
 
// IP-specific methods.
148
 
 
149
 
// ReadFromIP reads a IP packet from c, copying the payload into b.
 
55
        conn
 
56
}
 
57
 
 
58
func newIPConn(fd *netFD) *IPConn { return &IPConn{conn{fd}} }
 
59
 
 
60
// ReadFromIP reads an IP packet from c, copying the payload into b.
150
61
// It returns the number of bytes copied into b and the return address
151
62
// that was on the packet.
152
63
//
163
74
        n, sa, err := c.fd.ReadFrom(b)
164
75
        switch sa := sa.(type) {
165
76
        case *syscall.SockaddrInet4:
166
 
                addr = &IPAddr{sa.Addr[0:]}
 
77
                addr = &IPAddr{IP: sa.Addr[0:]}
167
78
                if len(b) >= IPv4len { // discard ipv4 header
168
79
                        hsize := (int(b[0]) & 0xf) * 4
169
80
                        copy(b, b[hsize:])
170
81
                        n -= hsize
171
82
                }
172
83
        case *syscall.SockaddrInet6:
173
 
                addr = &IPAddr{sa.Addr[0:]}
 
84
                addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
174
85
        }
175
86
        return n, addr, err
176
87
}
180
91
        if !c.ok() {
181
92
                return 0, nil, syscall.EINVAL
182
93
        }
183
 
        n, uaddr, err := c.ReadFromIP(b)
184
 
        return n, uaddr.toAddr(), err
185
 
}
186
 
 
187
 
// WriteToIP writes a IP packet to addr via c, copying the payload from b.
 
94
        n, addr, err := c.ReadFromIP(b)
 
95
        return n, addr.toAddr(), err
 
96
}
 
97
 
 
98
// ReadMsgIP reads a packet from c, copying the payload into b and the
 
99
// associated out-of-band data into oob.  It returns the number of
 
100
// bytes copied into b, the number of bytes copied into oob, the flags
 
101
// that were set on the packet and the source address of the packet.
 
102
func (c *IPConn) ReadMsgIP(b, oob []byte) (n, oobn, flags int, addr *IPAddr, err error) {
 
103
        if !c.ok() {
 
104
                return 0, 0, 0, nil, syscall.EINVAL
 
105
        }
 
106
        var sa syscall.Sockaddr
 
107
        n, oobn, flags, sa, err = c.fd.ReadMsg(b, oob)
 
108
        switch sa := sa.(type) {
 
109
        case *syscall.SockaddrInet4:
 
110
                addr = &IPAddr{IP: sa.Addr[0:]}
 
111
        case *syscall.SockaddrInet6:
 
112
                addr = &IPAddr{IP: sa.Addr[0:], Zone: zoneToString(int(sa.ZoneId))}
 
113
        }
 
114
        return
 
115
}
 
116
 
 
117
// WriteToIP writes an IP packet to addr via c, copying the payload
 
118
// from b.
188
119
//
189
 
// WriteToIP can be made to time out and return
190
 
// an error with Timeout() == true after a fixed time limit;
191
 
// see SetDeadline and SetWriteDeadline.
192
 
// On packet-oriented connections, write timeouts are rare.
 
120
// WriteToIP can be made to time out and return an error with
 
121
// Timeout() == true after a fixed time limit; see SetDeadline and
 
122
// SetWriteDeadline.  On packet-oriented connections, write timeouts
 
123
// are rare.
193
124
func (c *IPConn) WriteToIP(b []byte, addr *IPAddr) (int, error) {
194
125
        if !c.ok() {
195
126
                return 0, syscall.EINVAL
213
144
        return c.WriteToIP(b, a)
214
145
}
215
146
 
216
 
// DialIP connects to the remote address raddr on the network protocol netProto,
217
 
// which must be "ip", "ip4", or "ip6" followed by a colon and a protocol number or name.
 
147
// WriteMsgIP writes a packet to addr via c, copying the payload from
 
148
// b and the associated out-of-band data from oob.  It returns the
 
149
// number of payload and out-of-band bytes written.
 
150
func (c *IPConn) WriteMsgIP(b, oob []byte, addr *IPAddr) (n, oobn int, err error) {
 
151
        if !c.ok() {
 
152
                return 0, 0, syscall.EINVAL
 
153
        }
 
154
        sa, err := addr.sockaddr(c.fd.family)
 
155
        if err != nil {
 
156
                return 0, 0, &OpError{"write", c.fd.net, addr, err}
 
157
        }
 
158
        return c.fd.WriteMsg(b, oob, sa)
 
159
}
 
160
 
 
161
// DialIP connects to the remote address raddr on the network protocol
 
162
// netProto, which must be "ip", "ip4", or "ip6" followed by a colon
 
163
// and a protocol number or name.
218
164
func DialIP(netProto string, laddr, raddr *IPAddr) (*IPConn, error) {
219
 
        net, proto, err := parseDialNetwork(netProto)
 
165
        return dialIP(netProto, laddr, raddr, noDeadline)
 
166
}
 
167
 
 
168
func dialIP(netProto string, laddr, raddr *IPAddr, deadline time.Time) (*IPConn, error) {
 
169
        net, proto, err := parseNetwork(netProto)
220
170
        if err != nil {
221
171
                return nil, err
222
172
        }
223
173
        switch net {
224
174
        case "ip", "ip4", "ip6":
225
175
        default:
226
 
                return nil, UnknownNetworkError(net)
 
176
                return nil, UnknownNetworkError(netProto)
227
177
        }
228
178
        if raddr == nil {
229
179
                return nil, &OpError{"dial", netProto, nil, errMissingAddress}
230
180
        }
231
 
        fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
 
181
        fd, err := internetSocket(net, laddr.toAddr(), raddr.toAddr(), deadline, syscall.SOCK_RAW, proto, "dial", sockaddrToIP)
232
182
        if err != nil {
233
183
                return nil, err
234
184
        }
235
185
        return newIPConn(fd), nil
236
186
}
237
187
 
238
 
// ListenIP listens for incoming IP packets addressed to the
239
 
// local address laddr.  The returned connection c's ReadFrom
240
 
// and WriteTo methods can be used to receive and send IP
241
 
// packets with per-packet addressing.
 
188
// ListenIP listens for incoming IP packets addressed to the local
 
189
// address laddr.  The returned connection's ReadFrom and WriteTo
 
190
// methods can be used to receive and send IP packets with per-packet
 
191
// addressing.
242
192
func ListenIP(netProto string, laddr *IPAddr) (*IPConn, error) {
243
 
        net, proto, err := parseDialNetwork(netProto)
 
193
        net, proto, err := parseNetwork(netProto)
244
194
        if err != nil {
245
195
                return nil, err
246
196
        }
247
197
        switch net {
248
198
        case "ip", "ip4", "ip6":
249
199
        default:
250
 
                return nil, UnknownNetworkError(net)
 
200
                return nil, UnknownNetworkError(netProto)
251
201
        }
252
 
        fd, err := internetSocket(net, laddr.toAddr(), nil, syscall.SOCK_RAW, proto, "listen", sockaddrToIP)
 
202
        fd, err := internetSocket(net, laddr.toAddr(), nil, noDeadline, syscall.SOCK_RAW, proto, "listen", sockaddrToIP)
253
203
        if err != nil {
254
204
                return nil, err
255
205
        }
256
206
        return newIPConn(fd), nil
257
207
}
258
 
 
259
 
// File returns a copy of the underlying os.File, set to blocking mode.
260
 
// It is the caller's responsibility to close f when finished.
261
 
// Closing c does not affect f, and closing f does not affect c.
262
 
func (c *IPConn) File() (f *os.File, err error) { return c.fd.dup() }