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
)
96 // Check again after adjustAbstract adjusts the length.
97 // This is testing whether the +1 for NUL puts us out of range.
98 if sl
-2 > Socklen_t(len(sa
.raw
.Path
)) {
102 // length is family (uint16), name, NUL.
103 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), sl
, nil
106 func anyToSockaddr(rsa
*RawSockaddrAny
) (Sockaddr
, error
) {
107 switch rsa
.Addr
.Family
{
109 pp
:= (*RawSockaddrUnix
)(unsafe
.Pointer(rsa
))
110 sa
:= new(SockaddrUnix
)
111 n
, err
:= pp
.getLen()
115 bytes
:= (*[len(pp
.Path
)]byte)(unsafe
.Pointer(&pp
.Path
[0]))
116 sa
.Name
= string(bytes
[0:n
])
120 pp
:= (*RawSockaddrInet4
)(unsafe
.Pointer(rsa
))
121 sa
:= new(SockaddrInet4
)
122 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
123 sa
.Port
= int(p
[0])<<8 + int(p
[1])
124 for i
:= 0; i
< len(sa
.Addr
); i
++ {
125 sa
.Addr
[i
] = pp
.Addr
[i
]
130 pp
:= (*RawSockaddrInet6
)(unsafe
.Pointer(rsa
))
131 sa
:= new(SockaddrInet6
)
132 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
133 sa
.Port
= int(p
[0])<<8 + int(p
[1])
134 for i
:= 0; i
< len(sa
.Addr
); i
++ {
135 sa
.Addr
[i
] = pp
.Addr
[i
]
139 return anyToSockaddrOS(rsa
)
142 //sys accept(fd int, sa *RawSockaddrAny, len *Socklen_t) (nfd int, err error)
143 //accept(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
145 func Accept(fd
int) (nfd
int, sa Sockaddr
, err error
) {
146 var rsa RawSockaddrAny
147 var len Socklen_t
= SizeofSockaddrAny
148 nfd
, err
= accept(fd
, &rsa
, &len)
152 sa
, err
= anyToSockaddr(&rsa
)
160 //sysnb getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
161 //getsockname(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
163 func Getsockname(fd
int) (sa Sockaddr
, err error
) {
164 var rsa RawSockaddrAny
165 var len Socklen_t
= SizeofSockaddrAny
166 if err
= getsockname(fd
, &rsa
, &len); err
!= nil {
169 return anyToSockaddr(&rsa
)
172 //sysnb getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
173 //getpeername(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
175 func Getpeername(fd
int) (sa Sockaddr
, err error
) {
176 var rsa RawSockaddrAny
177 var len Socklen_t
= SizeofSockaddrAny
178 if err
= getpeername(fd
, &rsa
, &len); err
!= nil {
181 return anyToSockaddr(&rsa
)
184 func Bind(fd
int, sa Sockaddr
) (err error
) {
185 ptr
, n
, err
:= sa
.sockaddr()
189 return bind(fd
, ptr
, n
)
192 func Connect(fd
int, sa Sockaddr
) (err error
) {
193 ptr
, n
, err
:= sa
.sockaddr()
197 return connect(fd
, ptr
, n
)
200 func Socket(domain
, typ
, proto
int) (fd
int, err error
) {
201 if domain
== AF_INET6
&& SocketDisableIPv6
{
202 return -1, EAFNOSUPPORT
204 fd
, err
= socket(domain
, typ
, proto
)
208 func Socketpair(domain
, typ
, proto
int) (fd
[2]int, err error
) {
210 err
= socketpair(domain
, typ
, proto
, &fdx
)
218 func GetsockoptByte(fd
, level
, opt
int) (value
byte, err error
) {
220 vallen
:= Socklen_t(1)
221 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), &vallen
)
225 func GetsockoptInt(fd
, level
, opt
int) (value
int, err error
) {
227 vallen
:= Socklen_t(4)
228 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), &vallen
)
232 func GetsockoptInet4Addr(fd
, level
, opt
int) (value
[4]byte, err error
) {
233 vallen
:= Socklen_t(4)
234 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
[0]), &vallen
)
238 func GetsockoptIPMreq(fd
, level
, opt
int) (*IPMreq
, error
) {
240 vallen
:= Socklen_t(SizeofIPMreq
)
241 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
245 func GetsockoptIPMreqn(fd
, level
, opt
int) (*IPMreqn
, error
) {
247 vallen
:= Socklen_t(SizeofIPMreqn
)
248 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
252 func GetsockoptIPv6Mreq(fd
, level
, opt
int) (*IPv6Mreq
, error
) {
254 vallen
:= Socklen_t(SizeofIPv6Mreq
)
255 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
259 func GetsockoptICMPv6Filter(fd
, level
, opt
int) (*ICMPv6Filter
, error
) {
260 var value ICMPv6Filter
261 vallen
:= Socklen_t(SizeofICMPv6Filter
)
262 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
266 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen Socklen_t) (err error)
267 //setsockopt(s _C_int, level _C_int, optname _C_int, val *byte, vallen Socklen_t) _C_int
269 func SetsockoptByte(fd
, level
, opt
int, value
byte) (err error
) {
271 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), 1)
274 func SetsockoptInt(fd
, level
, opt
int, value
int) (err error
) {
276 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), 4)
279 func SetsockoptInet4Addr(fd
, level
, opt
int, value
[4]byte) (err error
) {
280 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
[0]), 4)
283 func SetsockoptTimeval(fd
, level
, opt
int, tv
*Timeval
) (err error
) {
284 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(tv
), Socklen_t(unsafe
.Sizeof(*tv
)))
287 func SetsockoptICMPv6Filter(fd
, level
, opt
int, filter
*ICMPv6Filter
) error
{
288 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(filter
), SizeofICMPv6Filter
)
296 func SetsockoptLinger(fd
, level
, opt
int, l
*Linger
) (err error
) {
297 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(l
), Socklen_t(unsafe
.Sizeof(*l
)))
300 func SetsockoptIPMreq(fd
, level
, opt
int, mreq
*IPMreq
) (err error
) {
301 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
304 func SetsockoptIPMreqn(fd
, level
, opt
int, mreq
*IPMreqn
) (err error
) {
305 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
308 func SetsockoptIPv6Mreq(fd
, level
, opt
int, mreq
*IPv6Mreq
) (err error
) {
309 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
312 func SetsockoptString(fd
, level
, opt
int, s
string) (err error
) {
313 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&[]byte(s
)[0]), Socklen_t(len(s
)))
316 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
317 //recvfrom(fd _C_int, buf *byte, len Size_t, flags _C_int, from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t
319 func Recvfrom(fd
int, p
[]byte, flags
int) (n
int, from Sockaddr
, err error
) {
320 var rsa RawSockaddrAny
321 var len Socklen_t
= SizeofSockaddrAny
322 if n
, err
= recvfrom(fd
, p
, flags
, &rsa
, &len); err
!= nil {
325 if rsa
.Addr
.Family
!= AF_UNSPEC
{
326 from
, err
= anyToSockaddr(&rsa
)
331 func Sendto(fd
int, p
[]byte, flags
int, to Sockaddr
) (err error
) {
332 ptr
, n
, err
:= to
.sockaddr()
336 return sendto(fd
, p
, flags
, ptr
, n
)
339 func Recvmsg(fd
int, p
, oob
[]byte, flags
int) (n
, oobn
int, recvflags
int, from Sockaddr
, err error
) {
341 var rsa RawSockaddrAny
342 msg
.Name
= (*byte)(unsafe
.Pointer(&rsa
))
343 msg
.Namelen
= uint32(SizeofSockaddrAny
)
346 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
352 sockType
, err
= GetsockoptInt(fd
, SOL_SOCKET
, SO_TYPE
)
356 // receive at least one normal byte
357 if sockType
!= SOCK_DGRAM
&& len(p
) == 0 {
361 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
362 msg
.SetControllen(len(oob
))
366 if n
, err
= recvmsg(fd
, &msg
, flags
); err
!= nil {
369 oobn
= int(msg
.Controllen
)
370 recvflags
= int(msg
.Flags
)
371 // source address is only specified if the socket is unconnected
372 if rsa
.Addr
.Family
!= AF_UNSPEC
{
373 from
, err
= anyToSockaddr(&rsa
)
378 func Sendmsg(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (err error
) {
379 _
, err
= SendmsgN(fd
, p
, oob
, to
, flags
)
383 func SendmsgN(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (n
int, err error
) {
384 var ptr
*RawSockaddrAny
388 ptr
, salen
, err
= to
.sockaddr()
394 msg
.Name
= (*byte)(unsafe
.Pointer(ptr
))
395 msg
.Namelen
= uint32(salen
)
398 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
404 sockType
, err
= GetsockoptInt(fd
, SOL_SOCKET
, SO_TYPE
)
408 // send at least one normal byte
409 if sockType
!= SOCK_DGRAM
&& len(p
) == 0 {
413 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
414 msg
.SetControllen(len(oob
))
418 if n
, err
= sendmsg(fd
, &msg
, flags
); err
!= nil {
421 if len(oob
) > 0 && len(p
) == 0 {
427 //sys Listen(fd int, n int) (err error)
428 //listen(fd _C_int, n _C_int) _C_int
430 //sys Shutdown(fd int, how int) (err error)
431 //shutdown(fd _C_int, how _C_int) _C_int
433 func (iov
*Iovec
) SetLen(length
int) {
434 iov
.Len
= Iovec_len_t(length
)
437 func (msghdr
*Msghdr
) SetControllen(length
int) {
438 msghdr
.Controllen
= Msghdr_controllen_t(length
)
441 func (cmsg
*Cmsghdr
) SetLen(length
int) {
442 cmsg
.Len
= Cmsghdr_len_t(length
)