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 // These functions are called from the internal/syscall/unix package.
16 // Use go:linkname to export them.
18 //go:linkname recvfromInet4
19 //go:linkname recvfromInet6
20 //go:linkname sendtoInet4
21 //go:linkname sendtoInet6
22 //go:linkname sendmsgNInet4
23 //go:linkname sendmsgNInet6
24 //go:linkname recvmsgInet4
25 //go:linkname recvmsgInet6
27 // For testing: clients can set this flag to force
28 // creation of IPv6 sockets to return EAFNOSUPPORT.
29 var SocketDisableIPv6
bool
31 type Sockaddr
interface {
32 sockaddr() (ptr
*RawSockaddrAny
, len Socklen_t
, err error
) // lowercase; only we can define Sockaddrs
35 type RawSockaddrAny
struct {
40 const SizeofSockaddrAny
= 0x6c
42 type SockaddrInet4
struct {
48 func (sa
*SockaddrInet4
) sockaddr() (*RawSockaddrAny
, Socklen_t
, error
) {
49 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
52 sa
.raw
.Family
= AF_INET
54 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
))
55 p
[0] = byte(sa
.Port
>> 8)
57 for i
:= 0; i
< len(sa
.Addr
); i
++ {
58 sa
.raw
.Addr
[i
] = sa
.Addr
[i
]
60 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), n
, nil
63 type SockaddrInet6
struct {
70 func (sa
*SockaddrInet6
) sockaddr() (*RawSockaddrAny
, Socklen_t
, error
) {
71 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
74 sa
.raw
.Family
= AF_INET6
76 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
))
77 p
[0] = byte(sa
.Port
>> 8)
79 sa
.raw
.Scope_id
= sa
.ZoneId
80 for i
:= 0; i
< len(sa
.Addr
); i
++ {
81 sa
.raw
.Addr
[i
] = sa
.Addr
[i
]
83 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), n
, nil
86 type SockaddrUnix
struct {
91 func (sa
*SockaddrUnix
) sockaddr() (*RawSockaddrAny
, Socklen_t
, error
) {
94 if n
> len(sa
.raw
.Path
) {
97 sa
.raw
.Family
= AF_UNIX
99 for i
:= 0; i
< n
; i
++ {
100 sa
.raw
.Path
[i
] = int8(name
[i
])
102 // length is family (uint16), name, NUL.
105 sl
+= Socklen_t(n
) + 1
107 sl
= sa
.raw
.adjustAbstract(sl
)
108 // Check again after adjustAbstract adjusts the length.
109 // This is testing whether the +1 for NUL puts us out of range.
110 if sl
-2 > Socklen_t(len(sa
.raw
.Path
)) {
111 return nil, 0, EINVAL
114 // length is family (uint16), name, NUL.
115 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), sl
, nil
118 func anyToSockaddr(rsa
*RawSockaddrAny
) (Sockaddr
, error
) {
119 switch rsa
.Addr
.Family
{
121 pp
:= (*RawSockaddrUnix
)(unsafe
.Pointer(rsa
))
122 sa
:= new(SockaddrUnix
)
123 n
, err
:= pp
.getLen()
127 bytes
:= (*[len(pp
.Path
)]byte)(unsafe
.Pointer(&pp
.Path
[0]))
128 sa
.Name
= string(bytes
[0:n
])
132 pp
:= (*RawSockaddrInet4
)(unsafe
.Pointer(rsa
))
133 sa
:= new(SockaddrInet4
)
134 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
135 sa
.Port
= int(p
[0])<<8 + int(p
[1])
136 for i
:= 0; i
< len(sa
.Addr
); i
++ {
137 sa
.Addr
[i
] = pp
.Addr
[i
]
142 pp
:= (*RawSockaddrInet6
)(unsafe
.Pointer(rsa
))
143 sa
:= new(SockaddrInet6
)
144 p
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
145 sa
.Port
= int(p
[0])<<8 + int(p
[1])
146 for i
:= 0; i
< len(sa
.Addr
); i
++ {
147 sa
.Addr
[i
] = pp
.Addr
[i
]
151 return anyToSockaddrOS(rsa
)
154 //sys accept(fd int, sa *RawSockaddrAny, len *Socklen_t) (nfd int, err error)
155 //accept(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
157 func Accept(fd
int) (nfd
int, sa Sockaddr
, err error
) {
158 var rsa RawSockaddrAny
159 var len Socklen_t
= SizeofSockaddrAny
160 nfd
, err
= accept(fd
, &rsa
, &len)
164 sa
, err
= anyToSockaddr(&rsa
)
172 //sysnb getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
173 //getsockname(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
175 func Getsockname(fd
int) (sa Sockaddr
, err error
) {
176 var rsa RawSockaddrAny
177 var len Socklen_t
= SizeofSockaddrAny
178 if err
= getsockname(fd
, &rsa
, &len); err
!= nil {
181 return anyToSockaddr(&rsa
)
184 //sysnb getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
185 //getpeername(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
187 func Getpeername(fd
int) (sa Sockaddr
, err error
) {
188 var rsa RawSockaddrAny
189 var len Socklen_t
= SizeofSockaddrAny
190 if err
= getpeername(fd
, &rsa
, &len); err
!= nil {
193 return anyToSockaddr(&rsa
)
196 func Bind(fd
int, sa Sockaddr
) (err error
) {
197 ptr
, n
, err
:= sa
.sockaddr()
201 return bind(fd
, ptr
, n
)
204 func Connect(fd
int, sa Sockaddr
) (err error
) {
205 ptr
, n
, err
:= sa
.sockaddr()
209 return connect(fd
, ptr
, n
)
212 func Socket(domain
, typ
, proto
int) (fd
int, err error
) {
213 if domain
== AF_INET6
&& SocketDisableIPv6
{
214 return -1, EAFNOSUPPORT
216 fd
, err
= socket(domain
, typ
, proto
)
220 func Socketpair(domain
, typ
, proto
int) (fd
[2]int, err error
) {
222 err
= socketpair(domain
, typ
, proto
, &fdx
)
230 func GetsockoptByte(fd
, level
, opt
int) (value
byte, err error
) {
232 vallen
:= Socklen_t(1)
233 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), &vallen
)
237 func GetsockoptInt(fd
, level
, opt
int) (value
int, err error
) {
239 vallen
:= Socklen_t(4)
240 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), &vallen
)
244 func GetsockoptInet4Addr(fd
, level
, opt
int) (value
[4]byte, err error
) {
245 vallen
:= Socklen_t(4)
246 err
= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
[0]), &vallen
)
250 func GetsockoptIPMreq(fd
, level
, opt
int) (*IPMreq
, error
) {
252 vallen
:= Socklen_t(SizeofIPMreq
)
253 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
257 func GetsockoptIPMreqn(fd
, level
, opt
int) (*IPMreqn
, error
) {
259 vallen
:= Socklen_t(SizeofIPMreqn
)
260 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
264 func GetsockoptIPv6Mreq(fd
, level
, opt
int) (*IPv6Mreq
, error
) {
266 vallen
:= Socklen_t(SizeofIPv6Mreq
)
267 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
271 func GetsockoptICMPv6Filter(fd
, level
, opt
int) (*ICMPv6Filter
, error
) {
272 var value ICMPv6Filter
273 vallen
:= Socklen_t(SizeofICMPv6Filter
)
274 err
:= getsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
), &vallen
)
278 //sys setsockopt(s int, level int, name int, val unsafe.Pointer, vallen Socklen_t) (err error)
279 //setsockopt(s _C_int, level _C_int, optname _C_int, val *byte, vallen Socklen_t) _C_int
281 func SetsockoptByte(fd
, level
, opt
int, value
byte) (err error
) {
283 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), 1)
286 func SetsockoptInt(fd
, level
, opt
int, value
int) (err error
) {
288 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&n
), 4)
291 func SetsockoptInet4Addr(fd
, level
, opt
int, value
[4]byte) (err error
) {
292 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(&value
[0]), 4)
295 func SetsockoptTimeval(fd
, level
, opt
int, tv
*Timeval
) (err error
) {
296 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(tv
), Socklen_t(unsafe
.Sizeof(*tv
)))
299 func SetsockoptICMPv6Filter(fd
, level
, opt
int, filter
*ICMPv6Filter
) error
{
300 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(filter
), SizeofICMPv6Filter
)
308 func SetsockoptLinger(fd
, level
, opt
int, l
*Linger
) (err error
) {
309 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(l
), Socklen_t(unsafe
.Sizeof(*l
)))
312 func SetsockoptIPMreq(fd
, level
, opt
int, mreq
*IPMreq
) (err error
) {
313 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
316 func SetsockoptIPMreqn(fd
, level
, opt
int, mreq
*IPMreqn
) (err error
) {
317 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
320 func SetsockoptIPv6Mreq(fd
, level
, opt
int, mreq
*IPv6Mreq
) (err error
) {
321 return setsockopt(fd
, level
, opt
, unsafe
.Pointer(mreq
), Socklen_t(unsafe
.Sizeof(*mreq
)))
324 func SetsockoptString(fd
, level
, opt
int, s
string) (err error
) {
327 p
= unsafe
.Pointer(&[]byte(s
)[0])
329 return setsockopt(fd
, level
, opt
, p
, Socklen_t(len(s
)))
332 //sys recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
333 //recvfrom(fd _C_int, buf *byte, len Size_t, flags _C_int, from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t
335 func Recvfrom(fd
int, p
[]byte, flags
int) (n
int, from Sockaddr
, err error
) {
336 var rsa RawSockaddrAny
337 var len Socklen_t
= SizeofSockaddrAny
338 if n
, err
= recvfrom(fd
, p
, flags
, &rsa
, &len); err
!= nil {
341 if rsa
.Addr
.Family
!= AF_UNSPEC
{
342 from
, err
= anyToSockaddr(&rsa
)
347 func recvfromInet4(fd
int, p
[]byte, flags
int, from
*SockaddrInet4
) (n
int, err error
) {
348 var rsa RawSockaddrAny
349 var socklen Socklen_t
= SizeofSockaddrAny
350 if n
, err
= recvfrom(fd
, p
, flags
, &rsa
, &socklen
); err
!= nil {
353 pp
:= (*RawSockaddrInet4
)(unsafe
.Pointer(&rsa
))
354 port
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
355 from
.Port
= int(port
[0])<<8 + int(port
[1])
360 func recvfromInet6(fd
int, p
[]byte, flags
int, from
*SockaddrInet6
) (n
int, err error
) {
361 var rsa RawSockaddrAny
362 var socklen Socklen_t
= SizeofSockaddrAny
363 if n
, err
= recvfrom(fd
, p
, flags
, &rsa
, &socklen
); err
!= nil {
366 pp
:= (*RawSockaddrInet6
)(unsafe
.Pointer(&rsa
))
367 port
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
368 from
.Port
= int(port
[0])<<8 + int(port
[1])
369 from
.ZoneId
= pp
.Scope_id
374 func recvmsgInet4(fd
int, p
, oob
[]byte, flags
int, from
*SockaddrInet4
) (n
, oobn
int, recvflags
int, err error
) {
375 var rsa RawSockaddrAny
376 n
, oobn
, recvflags
, err
= recvmsgRaw(fd
, p
, oob
, flags
, &rsa
)
380 pp
:= (*RawSockaddrInet4
)(unsafe
.Pointer(&rsa
))
381 port
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
382 from
.Port
= int(port
[0])<<8 + int(port
[1])
387 func recvmsgInet6(fd
int, p
, oob
[]byte, flags
int, from
*SockaddrInet6
) (n
, oobn
int, recvflags
int, err error
) {
388 var rsa RawSockaddrAny
389 n
, oobn
, recvflags
, err
= recvmsgRaw(fd
, p
, oob
, flags
, &rsa
)
393 pp
:= (*RawSockaddrInet6
)(unsafe
.Pointer(&rsa
))
394 port
:= (*[2]byte)(unsafe
.Pointer(&pp
.Port
))
395 from
.Port
= int(port
[0])<<8 + int(port
[1])
396 from
.ZoneId
= pp
.Scope_id
401 func Recvmsg(fd
int, p
, oob
[]byte, flags
int) (n
, oobn
int, recvflags
int, from Sockaddr
, err error
) {
402 var rsa RawSockaddrAny
403 n
, oobn
, recvflags
, err
= recvmsgRaw(fd
, p
, oob
, flags
, &rsa
)
404 // source address is only specified if the socket is unconnected
405 if rsa
.Addr
.Family
!= AF_UNSPEC
{
406 from
, err
= anyToSockaddr(&rsa
)
411 func Sendmsg(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (err error
) {
412 _
, err
= SendmsgN(fd
, p
, oob
, to
, flags
)
416 func SendmsgN(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (n
int, err error
) {
417 var ptr
*RawSockaddrAny
420 ptr
, salen
, err
= to
.sockaddr()
425 return sendmsgN(fd
, p
, oob
, ptr
, salen
, flags
)
428 func sendmsgNInet4(fd
int, p
, oob
[]byte, to
*SockaddrInet4
, flags
int) (n
int, err error
) {
429 ptr
, salen
, err
:= to
.sockaddr()
433 return sendmsgN(fd
, p
, oob
, ptr
, salen
, flags
)
436 func sendmsgNInet6(fd
int, p
, oob
[]byte, to
*SockaddrInet6
, flags
int) (n
int, err error
) {
437 ptr
, salen
, err
:= to
.sockaddr()
441 return sendmsgN(fd
, p
, oob
, ptr
, salen
, flags
)
444 func sendtoInet4(fd
int, p
[]byte, flags
int, to
*SockaddrInet4
) (err error
) {
445 ptr
, n
, err
:= to
.sockaddr()
449 return sendto(fd
, p
, flags
, ptr
, n
)
452 func sendtoInet6(fd
int, p
[]byte, flags
int, to
*SockaddrInet6
) (err error
) {
453 ptr
, n
, err
:= to
.sockaddr()
457 return sendto(fd
, p
, flags
, ptr
, n
)
460 func Sendto(fd
int, p
[]byte, flags
int, to Sockaddr
) (err error
) {
461 ptr
, n
, err
:= to
.sockaddr()
465 return sendto(fd
, p
, flags
, ptr
, n
)
468 func recvmsgRaw(fd
int, p
, oob
[]byte, flags
int, rsa
*RawSockaddrAny
) (n
, oobn
int, recvflags
int, err error
) {
470 msg
.Name
= (*byte)(unsafe
.Pointer(&rsa
))
471 msg
.Namelen
= uint32(SizeofSockaddrAny
)
474 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
480 sockType
, err
= GetsockoptInt(fd
, SOL_SOCKET
, SO_TYPE
)
484 // receive at least one normal byte
485 if sockType
!= SOCK_DGRAM
&& len(p
) == 0 {
489 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
490 msg
.SetControllen(len(oob
))
494 if n
, err
= recvmsg(fd
, &msg
, flags
); err
!= nil {
497 oobn
= int(msg
.Controllen
)
498 recvflags
= int(msg
.Flags
)
502 func sendmsgN(fd
int, p
, oob
[]byte, to
*RawSockaddrAny
, salen Socklen_t
, flags
int) (n
int, err error
) {
504 msg
.Name
= (*byte)(unsafe
.Pointer(to
))
505 msg
.Namelen
= uint32(salen
)
508 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
514 sockType
, err
= GetsockoptInt(fd
, SOL_SOCKET
, SO_TYPE
)
518 // send at least one normal byte
519 if sockType
!= SOCK_DGRAM
&& len(p
) == 0 {
523 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
524 msg
.SetControllen(len(oob
))
528 if n
, err
= sendmsg(fd
, &msg
, flags
); err
!= nil {
531 if len(oob
) > 0 && len(p
) == 0 {
537 //sys Listen(fd int, n int) (err error)
538 //listen(fd _C_int, n _C_int) _C_int
540 //sys Shutdown(fd int, how int) (err error)
541 //shutdown(fd _C_int, how _C_int) _C_int
543 func (iov
*Iovec
) SetLen(length
int) {
544 iov
.Len
= Iovec_len_t(length
)
547 func (msghdr
*Msghdr
) SetControllen(length
int) {
548 msghdr
.Controllen
= Msghdr_controllen_t(length
)
551 func (cmsg
*Cmsghdr
) SetLen(length
int) {
552 cmsg
.Len
= Cmsghdr_len_t(length
)