OSDN Git Service

syscall: Fix handling of Unix domain @ addresses.
[pf3gnuchains/gcc-fork.git] / libgo / go / syscall / socket.go
1 // socket.go -- Socket handling.
2
3 // Copyright 2009 The Go Authors. All rights reserved.
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file.
6
7 // Low-level socket interface.
8 // Only for implementing net package.
9 // DO NOT USE DIRECTLY.
10
11 package syscall
12
13 import "unsafe"
14
15 // For testing: clients can set this flag to force
16 // creation of IPv6 sockets to return EAFNOSUPPORT.
17 var SocketDisableIPv6 bool
18
19 type Sockaddr interface {
20         sockaddr() (ptr *RawSockaddrAny, len Socklen_t, err error) // lowercase; only we can define Sockaddrs
21 }
22
23 type RawSockaddrAny struct {
24         Addr RawSockaddr
25         Pad  [96]int8
26 }
27
28 const SizeofSockaddrAny = 0x1c
29
30 type SockaddrInet4 struct {
31         Port int
32         Addr [4]byte
33         raw  RawSockaddrInet4
34 }
35
36 func (sa *SockaddrInet4) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
37         if sa.Port < 0 || sa.Port > 0xFFFF {
38                 return nil, 0, EINVAL
39         }
40         sa.raw.Family = AF_INET
41         n := sa.raw.setLen()
42         p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
43         p[0] = byte(sa.Port >> 8)
44         p[1] = byte(sa.Port)
45         for i := 0; i < len(sa.Addr); i++ {
46                 sa.raw.Addr[i] = sa.Addr[i]
47         }
48         return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), n, nil
49 }
50
51 type SockaddrInet6 struct {
52         Port   int
53         ZoneId uint32
54         Addr   [16]byte
55         raw    RawSockaddrInet6
56 }
57
58 func (sa *SockaddrInet6) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
59         if sa.Port < 0 || sa.Port > 0xFFFF {
60                 return nil, 0, EINVAL
61         }
62         sa.raw.Family = AF_INET6
63         n := sa.raw.setLen()
64         p := (*[2]byte)(unsafe.Pointer(&sa.raw.Port))
65         p[0] = byte(sa.Port >> 8)
66         p[1] = byte(sa.Port)
67         sa.raw.Scope_id = sa.ZoneId
68         for i := 0; i < len(sa.Addr); i++ {
69                 sa.raw.Addr[i] = sa.Addr[i]
70         }
71         return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), n, nil
72 }
73
74 type SockaddrUnix struct {
75         Name string
76         raw  RawSockaddrUnix
77 }
78
79 func (sa *SockaddrUnix) sockaddr() (*RawSockaddrAny, Socklen_t, error) {
80         name := sa.Name
81         n := len(name)
82         if n >= len(sa.raw.Path) || n == 0 {
83                 return nil, 0, EINVAL
84         }
85         sa.raw.Family = AF_UNIX
86         sa.raw.setLen(n)
87         for i := 0; i < n; i++ {
88                 sa.raw.Path[i] = int8(name[i])
89         }
90         // length is family (uint16), name, NUL.
91         sl := 2 + Socklen_t(n) + 1
92         if sa.raw.Path[0] == '@' {
93                 sa.raw.Path[0] = 0
94                 // Don't count trailing NUL for abstract address.
95                 sl--
96         }
97
98         // length is family (uint16), name, NUL.
99         return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), sl, nil
100 }
101
102 func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
103         switch rsa.Addr.Family {
104         case AF_UNIX:
105                 pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
106                 sa := new(SockaddrUnix)
107                 n, err := pp.getLen()
108                 if err != nil {
109                         return nil, err
110                 }
111                 bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))
112                 sa.Name = string(bytes[0:n])
113                 return sa, nil
114
115         case AF_INET:
116                 pp := (*RawSockaddrInet4)(unsafe.Pointer(rsa))
117                 sa := new(SockaddrInet4)
118                 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
119                 sa.Port = int(p[0])<<8 + int(p[1])
120                 for i := 0; i < len(sa.Addr); i++ {
121                         sa.Addr[i] = pp.Addr[i]
122                 }
123                 return sa, nil
124
125         case AF_INET6:
126                 pp := (*RawSockaddrInet6)(unsafe.Pointer(rsa))
127                 sa := new(SockaddrInet6)
128                 p := (*[2]byte)(unsafe.Pointer(&pp.Port))
129                 sa.Port = int(p[0])<<8 + int(p[1])
130                 for i := 0; i < len(sa.Addr); i++ {
131                         sa.Addr[i] = pp.Addr[i]
132                 }
133                 return sa, nil
134         }
135         return anyToSockaddrOS(rsa)
136 }
137
138 //sys   accept(fd int, sa *RawSockaddrAny, len *Socklen_t) (nfd int, err error)
139 //accept(fd int, sa *RawSockaddrAny, len *Socklen_t) int
140
141 func Accept(fd int) (nfd int, sa Sockaddr, err error) {
142         var rsa RawSockaddrAny
143         var len Socklen_t = SizeofSockaddrAny
144         nfd, err = accept(fd, &rsa, &len)
145         if err != nil {
146                 return
147         }
148         sa, err = anyToSockaddr(&rsa)
149         if err != nil {
150                 Close(nfd)
151                 nfd = 0
152         }
153         return
154 }
155
156 //sysnb getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
157 //getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) int
158
159 func Getsockname(fd int) (sa Sockaddr, err error) {
160         var rsa RawSockaddrAny
161         var len Socklen_t = SizeofSockaddrAny
162         if err = getsockname(fd, &rsa, &len); err != nil {
163                 return
164         }
165         return anyToSockaddr(&rsa)
166 }
167
168 //sysnb getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
169 //getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) int
170
171 func Getpeername(fd int) (sa Sockaddr, err error) {
172         var rsa RawSockaddrAny
173         var len Socklen_t = SizeofSockaddrAny
174         if err = getpeername(fd, &rsa, &len); err != nil {
175                 return
176         }
177         return anyToSockaddr(&rsa)
178 }
179
180 //sys   bind(fd int, sa *RawSockaddrAny, len Socklen_t) (err error)
181 //bind(fd int, sa *RawSockaddrAny, len Socklen_t) int
182
183 func Bind(fd int, sa Sockaddr) (err error) {
184         ptr, n, err := sa.sockaddr()
185         if err != nil {
186                 return err
187         }
188         return bind(fd, ptr, n)
189 }
190
191 //sys   connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) (err error)
192 //connect(s int, addr *RawSockaddrAny, addrlen Socklen_t) int
193
194 func Connect(fd int, sa Sockaddr) (err error) {
195         ptr, n, err := sa.sockaddr()
196         if err != nil {
197                 return err
198         }
199         return connect(fd, ptr, n)
200 }
201
202 //sysnb socket(domain int, typ int, proto int) (fd int, err error)
203 //socket(domain int, typ int, protocol int) int
204
205 func Socket(domain, typ, proto int) (fd int, err error) {
206         if domain == AF_INET6 && SocketDisableIPv6 {
207                 return -1, EAFNOSUPPORT
208         }
209         fd, err = socket(domain, typ, proto)
210         return
211 }
212
213 //sysnb socketpair(domain int, typ int, proto int, fd *[2]int) (err error)
214 //socketpair(domain int, typ int, protocol int, fd *[2]int) int
215
216 func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
217         err = socketpair(domain, typ, proto, &fd)
218         return
219 }
220
221 //sys   getsockopt(s int, level int, name int, val uintptr, vallen *Socklen_t) (err error)
222 //getsockopt(s int, level int, name int, val *byte, vallen *Socklen_t) int
223
224 func GetsockoptByte(fd, level, opt int) (value byte, err error) {
225         var n byte
226         vallen := Socklen_t(1)
227         err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&n)), &vallen)
228         return n, err
229 }
230
231 func GetsockoptInt(fd, level, opt int) (value int, err error) {
232         var n int32
233         vallen := Socklen_t(4)
234         err = getsockopt(fd, level, opt, (uintptr)(unsafe.Pointer(&n)), &vallen)
235         return int(n), err
236 }
237
238 func GetsockoptInet4Addr(fd, level, opt int) (value [4]byte, err error) {
239         vallen := Socklen_t(4)
240         err = getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value[0])), &vallen)
241         return value, err
242 }
243
244 func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
245         var value IPMreq
246         vallen := Socklen_t(SizeofIPMreq)
247         err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
248         return &value, err
249 }
250
251 func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
252         var value IPMreqn
253         vallen := Socklen_t(SizeofIPMreqn)
254         err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
255         return &value, err
256 }
257
258 func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
259         var value IPv6Mreq
260         vallen := Socklen_t(SizeofIPv6Mreq)
261         err := getsockopt(fd, level, opt, uintptr(unsafe.Pointer(&value)), &vallen)
262         return &value, err
263 }
264
265 //sys   setsockopt(s int, level int, name int, val *byte, vallen Socklen_t) (err error)
266 //setsockopt(s int, level int, optname int, val *byte, vallen Socklen_t) int
267
268 func SetsockoptByte(fd, level, opt int, value byte) (err error) {
269         var n = byte(value)
270         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 1)
271 }
272
273 func SetsockoptInt(fd, level, opt int, value int) (err error) {
274         var n = int32(value)
275         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&n)), 4)
276 }
277
278 func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
279         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&value[0])), 4)
280 }
281
282 func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
283         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(tv)), Socklen_t(unsafe.Sizeof(*tv)))
284 }
285
286 type Linger struct {
287         Onoff  int32
288         Linger int32
289 }
290
291 func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
292         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(l)), Socklen_t(unsafe.Sizeof(*l)))
293 }
294
295 func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
296         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
297 }
298
299 func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
300         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
301 }
302
303 func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
304         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(mreq)), Socklen_t(unsafe.Sizeof(*mreq)))
305 }
306
307 func SetsockoptString(fd, level, opt int, s string) (err error) {
308         return setsockopt(fd, level, opt, (*byte)(unsafe.Pointer(&[]byte(s)[0])), Socklen_t(len(s)))
309 }
310
311 //sys   recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
312 //recvfrom(fd int, buf *byte, len Size_t, flags int, from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t
313
314 func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
315         var rsa RawSockaddrAny
316         var len Socklen_t = SizeofSockaddrAny
317         if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
318                 return
319         }
320         from, err = anyToSockaddr(&rsa)
321         return
322 }
323
324 //sys   sendto(s int, buf []byte, flags int, to *RawSockaddrAny, tolen Socklen_t) (err error)
325 //sendto(s int, buf *byte, len Size_t, flags int, to *RawSockaddrAny, tolen Socklen_t) Ssize_t
326
327 func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
328         ptr, n, err := to.sockaddr()
329         if err != nil {
330                 return err
331         }
332         return sendto(fd, p, flags, ptr, n)
333 }
334
335 //sys   recvmsg(s int, msg *Msghdr, flags int) (n int, err error)
336 //recvmsg(s int, msg *Msghdr, flags int) Ssize_t
337
338 func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
339         var msg Msghdr
340         var rsa RawSockaddrAny
341         msg.Name = (*byte)(unsafe.Pointer(&rsa))
342         msg.Namelen = uint32(SizeofSockaddrAny)
343         var iov Iovec
344         if len(p) > 0 {
345                 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
346                 iov.SetLen(len(p))
347         }
348         var dummy byte
349         if len(oob) > 0 {
350                 // receive at least one normal byte
351                 if len(p) == 0 {
352                         iov.Base = &dummy
353                         iov.SetLen(1)
354                 }
355                 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
356                 msg.SetControllen(len(oob))
357         }
358         msg.Iov = &iov
359         msg.Iovlen = 1
360         if n, err = recvmsg(fd, &msg, flags); err != nil {
361                 return
362         }
363         oobn = int(msg.Controllen)
364         recvflags = int(msg.Flags)
365         // source address is only specified if the socket is unconnected
366         if rsa.Addr.Family != AF_UNSPEC {
367                 from, err = anyToSockaddr(&rsa)
368         }
369         return
370 }
371
372 //sys   sendmsg(s int, msg *Msghdr, flags int) (err error)
373 //sendmsg(s int, msg *Msghdr, flags int) Ssize_t
374
375 func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
376         var ptr *RawSockaddrAny
377         var salen Socklen_t
378         if to != nil {
379                 var err error
380                 ptr, salen, err = to.sockaddr()
381                 if err != nil {
382                         return err
383                 }
384         }
385         var msg Msghdr
386         msg.Name = (*byte)(unsafe.Pointer(ptr))
387         msg.Namelen = uint32(salen)
388         var iov Iovec
389         if len(p) > 0 {
390                 iov.Base = (*byte)(unsafe.Pointer(&p[0]))
391                 iov.SetLen(len(p))
392         }
393         var dummy byte
394         if len(oob) > 0 {
395                 // send at least one normal byte
396                 if len(p) == 0 {
397                         iov.Base = &dummy
398                         iov.SetLen(1)
399                 }
400                 msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
401                 msg.SetControllen(len(oob))
402         }
403         msg.Iov = &iov
404         msg.Iovlen = 1
405         if err = sendmsg(fd, &msg, flags); err != nil {
406                 return
407         }
408         return
409 }
410
411 //sys   Listen(fd int, n int) (err error)
412 //listen(fd int, n int) int
413
414 //sys   Shutdown(fd int, how int) (err error)
415 //shutdown(fd int, how int) int
416
417 func (iov *Iovec) SetLen(length int) {
418         iov.Len = Iovec_len_t(length)
419 }
420
421 func (msghdr *Msghdr) SetControllen(length int) {
422         msghdr.Controllen = Msghdr_controllen_t(length)
423 }
424
425 func (cmsg *Cmsghdr) SetLen(length int) {
426         cmsg.Len = Cmsghdr_len_t(length)
427 }