1 // socket.go -- Socket handling.
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.
7 // Low-level socket interface.
8 // Only for implementing net package.
9 // DO NOT USE DIRECTLY.
15 // For testing: clients can set this flag to force
16 // creation of IPv6 sockets to return EAFNOSUPPORT.
17 var SocketDisableIPv6
bool
19 type Sockaddr
interface {
20 sockaddr() (ptr
*RawSockaddrAny
, len Socklen_t
, err error
) // lowercase; only we can define Sockaddrs
23 type RawSockaddrAny
struct {
28 const SizeofSockaddrAny
= 0x6c
30 type SockaddrInet4
struct {
36 func (sa
*SockaddrInet4
) sockaddr() (*RawSockaddrAny
, Socklen_t
, error
) {
37 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
40 sa
.raw
.Family
= AF_INET
42 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
))
43 p
[0] = byte(sa
.Port
>> 8)
45 for i
:= 0; i
< len(sa
.Addr
); i
++ {
46 sa
.raw
.Addr
[i
] = sa
.Addr
[i
]
48 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), n
, nil
51 type SockaddrInet6
struct {
58 func (sa
*SockaddrInet6
) sockaddr() (*RawSockaddrAny
, Socklen_t
, error
) {
59 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
62 sa
.raw
.Family
= AF_INET6
64 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
))
65 p
[0] = byte(sa
.Port
>> 8)
67 sa
.raw
.Scope_id
= sa
.ZoneId
68 for i
:= 0; i
< len(sa
.Addr
); i
++ {
69 sa
.raw
.Addr
[i
] = sa
.Addr
[i
]
71 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), n
, nil
74 type SockaddrUnix
struct {
79 func (sa
*SockaddrUnix
) sockaddr() (*RawSockaddrAny
, Socklen_t
, error
) {
82 if n
>= len(sa
.raw
.Path
) {
85 sa
.raw
.Family
= AF_UNIX
87 for i
:= 0; i
< n
; i
++ {
88 sa
.raw
.Path
[i
] = int8(name
[i
])
90 // length is family (uint16), name, NUL.
93 sl
+= Socklen_t(n
) + 1
95 sl
= sa
.raw
.adjustAbstract(sl
)
97 // length is family (uint16), name, NUL.
98 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), sl
, nil
101 func anyToSockaddr(rsa
*RawSockaddrAny
) (Sockaddr
, error
) {
102 switch rsa
.Addr
.Family
{
104 pp
:= (*RawSockaddrUnix
)(unsafe
.Pointer(rsa
))
105 sa
:= new(SockaddrUnix
)
106 n
, err
:= pp
.getLen()
110 bytes
:= (*[len(pp
.Path
)]byte)(unsafe
.Pointer(&pp
.Path
[0]))
111 sa
.Name
= string(bytes
[0:n
])
115 pp
:= (*RawSockaddrInet4
)(unsafe
.Pointer(rsa
))
116 sa
:= new(SockaddrInet4
)
117 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
118 sa
.Port
= int(p
[0])<<8 + int(p
[1])
119 for i
:= 0; i
< len(sa
.Addr
); i
++ {
120 sa
.Addr
[i
] = pp
.Addr
[i
]
125 pp
:= (*RawSockaddrInet6
)(unsafe
.Pointer(rsa
))
126 sa
:= new(SockaddrInet6
)
127 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
128 sa
.Port
= int(p
[0])<<8 + int(p
[1])
129 for i
:= 0; i
< len(sa
.Addr
); i
++ {
130 sa
.Addr
[i
] = pp
.Addr
[i
]
134 return anyToSockaddrOS(rsa
)
137 //sys accept(fd int, sa *RawSockaddrAny, len *Socklen_t) (nfd int, err error)
138 //accept(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
140 func Accept(fd
int) (nfd
int, sa Sockaddr
, err error
) {
141 var rsa RawSockaddrAny
142 var len Socklen_t
= SizeofSockaddrAny
143 nfd
, err
= accept(fd
, &rsa
, &len)
147 sa
, err
= anyToSockaddr(&rsa
)
155 //sysnb getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
156 //getsockname(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
158 func Getsockname(fd
int) (sa Sockaddr
, err error
) {
159 var rsa RawSockaddrAny
160 var len Socklen_t
= SizeofSockaddrAny
161 if err
= getsockname(fd
, &rsa
, &len); err
!= nil {
164 return anyToSockaddr(&rsa
)
167 //sysnb getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
168 //getpeername(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
170 func Getpeername(fd
int) (sa Sockaddr
, err error
) {
171 var rsa RawSockaddrAny
172 var len Socklen_t
= SizeofSockaddrAny
173 if err
= getpeername(fd
, &rsa
, &len); err
!= nil {
176 return anyToSockaddr(&rsa
)
179 func Bind(fd
int, sa Sockaddr
) (err error
) {
180 ptr
, n
, err
:= sa
.sockaddr()
184 return bind(fd
, ptr
, n
)
187 func Connect(fd
int, sa Sockaddr
) (err error
) {
188 ptr
, n
, err
:= sa
.sockaddr()
192 return connect(fd
, ptr
, n
)
195 func Socket(domain
, typ
, proto
int) (fd
int, err error
) {
196 if domain
== AF_INET6
&& SocketDisableIPv6
{
197 return -1, EAFNOSUPPORT
199 fd
, err
= socket(domain
, typ
, proto
)
203 func Socketpair(domain
, typ
, proto
int) (fd
[2]int, err error
) {
205 err
= socketpair(domain
, typ
, proto
, &fdx
)
213 func GetsockoptByte(fd
, level
, opt
int) (value
byte, err error
) {
215 vallen
:= Socklen_t(1)
216 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), &vallen
)
220 func GetsockoptInt(fd
, level
, opt
int) (value
int, err error
) {
222 vallen
:= Socklen_t(4)
223 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), &vallen
)
227 func GetsockoptInet4Addr(fd
, level
, opt
int) (value
[4]byte, err error
) {
228 vallen
:= Socklen_t(4)
229 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
[0]), &vallen
)
233 func GetsockoptIPMreq(fd
, level
, opt
int) (*IPMreq
, error
) {
235 vallen
:= Socklen_t(SizeofIPMreq
)
236 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
240 func GetsockoptIPMreqn(fd
, level
, opt
int) (*IPMreqn
, error
) {
242 vallen
:= Socklen_t(SizeofIPMreqn
)
243 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
247 func GetsockoptIPv6Mreq(fd
, level
, opt
int) (*IPv6Mreq
, error
) {
249 vallen
:= Socklen_t(SizeofIPv6Mreq
)
250 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
254 func GetsockoptICMPv6Filter(fd
, level
, opt
int) (*ICMPv6Filter
, error
) {
255 var value ICMPv6Filter
256 vallen
:= Socklen_t(SizeofICMPv6Filter
)
257 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
261 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen Socklen_t) (err error)
262 //setsockopt(s _C_int, level _C_int, optname _C_int, val *byte, vallen Socklen_t) _C_int
264 func SetsockoptByte(fd
, level
, opt
int, value
byte) (err error
) {
266 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), 1)
269 func SetsockoptInt(fd
, level
, opt
int, value
int) (err error
) {
271 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), 4)
274 func SetsockoptInet4Addr(fd
, level
, opt
int, value
[4]byte) (err error
) {
275 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
[0]), 4)
278 func SetsockoptTimeval(fd
, level
, opt
int, tv
*Timeval
) (err error
) {
279 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(tv
), Socklen_t(unsafe
.Sizeof(*tv
)))
282 func SetsockoptICMPv6Filter(fd
, level
, opt
int, filter
*ICMPv6Filter
) error
{
283 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(filter
), SizeofICMPv6Filter
)
291 func SetsockoptLinger(fd
, level
, opt
int, l
*Linger
) (err error
) {
292 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(l
), Socklen_t(unsafe
.Sizeof(*l
)))
295 func SetsockoptIPMreq(fd
, level
, opt
int, mreq
*IPMreq
) (err error
) {
296 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
299 func SetsockoptIPMreqn(fd
, level
, opt
int, mreq
*IPMreqn
) (err error
) {
300 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
303 func SetsockoptIPv6Mreq(fd
, level
, opt
int, mreq
*IPv6Mreq
) (err error
) {
304 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
307 func SetsockoptString(fd
, level
, opt
int, s
string) (err error
) {
308 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&[]byte(s
)[0]), Socklen_t(len(s
)))
311 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
312 //recvfrom(fd _C_int, buf *byte, len Size_t, flags _C_int, from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t
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 {
320 if rsa
.Addr
.Family
!= AF_UNSPEC
{
321 from
, err
= anyToSockaddr(&rsa
)
326 func Sendto(fd
int, p
[]byte, flags
int, to Sockaddr
) (err error
) {
327 ptr
, n
, err
:= to
.sockaddr()
331 return sendto(fd
, p
, flags
, ptr
, n
)
334 func Recvmsg(fd
int, p
, oob
[]byte, flags
int) (n
, oobn
int, recvflags
int, from Sockaddr
, err error
) {
336 var rsa RawSockaddrAny
337 msg
.Name
= (*byte)(unsafe
.Pointer(&rsa
))
338 msg
.Namelen
= uint32(SizeofSockaddrAny
)
341 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
346 // receive at least one normal byte
351 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
352 msg
.SetControllen(len(oob
))
356 if n
, err
= recvmsg(fd
, &msg
, flags
); err
!= nil {
359 oobn
= int(msg
.Controllen
)
360 recvflags
= int(msg
.Flags
)
361 // source address is only specified if the socket is unconnected
362 if rsa
.Addr
.Family
!= AF_UNSPEC
{
363 from
, err
= anyToSockaddr(&rsa
)
368 func Sendmsg(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (err error
) {
369 _
, err
= SendmsgN(fd
, p
, oob
, to
, flags
)
373 func SendmsgN(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (n
int, err error
) {
374 var ptr
*RawSockaddrAny
378 ptr
, salen
, err
= to
.sockaddr()
384 msg
.Name
= (*byte)(unsafe
.Pointer(ptr
))
385 msg
.Namelen
= uint32(salen
)
388 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
393 // send at least one normal byte
398 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
399 msg
.SetControllen(len(oob
))
403 if n
, err
= sendmsg(fd
, &msg
, flags
); err
!= nil {
406 if len(oob
) > 0 && len(p
) == 0 {
412 //sys Listen(fd int, n int) (err error)
413 //listen(fd _C_int, n _C_int) _C_int
415 //sys Shutdown(fd int, how int) (err error)
416 //shutdown(fd _C_int, how _C_int) _C_int
418 func (iov
*Iovec
) SetLen(length
int) {
419 iov
.Len
= Iovec_len_t(length
)
422 func (msghdr
*Msghdr
) SetControllen(length
int) {
423 msghdr
.Controllen
= Msghdr_controllen_t(length
)
426 func (cmsg
*Cmsghdr
) SetLen(length
int) {
427 cmsg
.Len
= Cmsghdr_len_t(length
)