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 type RawSockaddrAny
struct {
20 const SizeofSockaddrAny
= 0x1c;
22 // For testing: clients can set this flag to force
23 // creation of IPv6 sockets to return EAFNOSUPPORT.
24 var SocketDisableIPv6
bool
26 type Sockaddr
interface {
27 sockaddr() (ptr
*RawSockaddrAny
, len Socklen_t
, errno
int); // lowercase; only we can define Sockaddrs
30 type SockaddrInet4
struct {
36 type SockaddrInet6
struct {
42 type SockaddrUnix
struct {
52 func (sa
*SockaddrInet4
) sockaddr() (*RawSockaddrAny
, Socklen_t
, int) {
53 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
54 return nil, 0, EINVAL
;
56 sa
.raw
.Family
= AF_INET
;
58 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
));
59 p
[0] = byte(sa
.Port
>>8);
61 for i
:= 0; i
< len(sa
.Addr
); i
++ {
62 sa
.raw
.Addr
[i
] = sa
.Addr
[i
];
64 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), n
, 0;
67 func (sa
*SockaddrInet6
) sockaddr() (*RawSockaddrAny
, Socklen_t
, int) {
68 if sa
.Port
< 0 || sa
.Port
> 0xFFFF {
69 return nil, 0, EINVAL
;
71 sa
.raw
.Family
= AF_INET6
;
73 p
:= (*[2]byte)(unsafe
.Pointer(&sa
.raw
.Port
));
74 p
[0] = byte(sa
.Port
>>8);
76 for i
:= 0; i
< len(sa
.Addr
); i
++ {
77 sa
.raw
.Addr
[i
] = sa
.Addr
[i
];
79 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), n
, 0;
82 func (sa
*SockaddrUnix
) sockaddr() (*RawSockaddrAny
, Socklen_t
, int) {
85 if n
>= len(sa
.raw
.Path
) || n
== 0 {
86 return nil, 0, EINVAL
;
88 sa
.raw
.Family
= AF_UNIX
;
90 for i
:= 0; i
< n
; i
++ {
91 sa
.raw
.Path
[i
] = int8(name
[i
]);
93 if sa
.raw
.Path
[0] == '@' {
97 // length is family (uint16), name, NUL.
98 return (*RawSockaddrAny
)(unsafe
.Pointer(&sa
.raw
)), 2 + Socklen_t(n
) + 1, 0;
101 func anyToSockaddr(rsa
*RawSockaddrAny
) (Sockaddr
, int) {
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 nil, EAFNOSUPPORT
;
137 func libc_accept(fd
int, sa
*RawSockaddrAny
, len *Socklen_t
) int __asm__ ("accept");
138 func libc_bind(fd
int, sa
*RawSockaddrAny
, len Socklen_t
) int __asm__ ("bind");
139 func libc_connect(fd
int, sa
*RawSockaddrAny
, len Socklen_t
) int __asm__ ("connect");
140 func libc_socket(domain
, typ
, protocol
int) int __asm__ ("socket");
141 func libc_setsockopt(fd
, level
, optname
int, optval
*byte, optlen Socklen_t
) int __asm__ ("setsockopt");
142 func libc_listen(fd
, backlog
int) int __asm__ ("listen");
143 func libc_getsockopt(fd
, level
, optname
int, optval
*byte, optlen
*Socklen_t
) int __asm__ ("getsockopt");
144 func libc_getsockname(fd
int, sa
*RawSockaddrAny
, len *Socklen_t
) int __asm__ ("getsockname");
145 func libc_getpeername(fd
int, sa
*RawSockaddrAny
, len *Socklen_t
) int __asm__ ("getpeername");
146 func libc_recv(fd
int, buf
*byte, len Size_t
, flags
int) Ssize_t
__asm__ ("recv");
147 func libc_recvfrom(fd
int, buf
*byte, len Size_t
, flags
int,
148 from
*RawSockaddrAny
, fromlen
*Socklen_t
) Ssize_t
__asm__("recvfrom");
149 func libc_recvmsg(fd
int, msg
*Msghdr
, flags
int) Ssize_t
__asm__("recvmsg")
150 func libc_send(fd
int, buf
*byte, len Size_t
, flags
int) Ssize_t
__asm__("send");
151 func libc_sendto(fd
int, buf
*byte, len Size_t
, flags
int,
152 to
*RawSockaddrAny
, tolen Socklen_t
) Ssize_t
__asm__("sendto");
153 func libc_sendmsg(fd
int, msg
*Msghdr
, flags
int) Ssize_t
__asm__("sendmsg")
154 func libc_shutdown(fd
int, how
int) int __asm__ ("shutdown");
156 func Accept(fd
int) (nfd
int, sa Sockaddr
, errno
int) {
157 var rsa RawSockaddrAny
;
158 var len Socklen_t
= SizeofSockaddrAny
;
159 nfd
= libc_accept(fd
, &rsa
, &len);
164 sa
, errno
= anyToSockaddr(&rsa
);
172 func Bind(fd
int, sa Sockaddr
) (errno
int) {
173 ptr
, n
, err
:= sa
.sockaddr();
177 if libc_bind(fd
, ptr
, n
) < 0 {
183 func Connect(fd
int, sa Sockaddr
) (errno
int) {
184 ptr
, n
, err
:= sa
.sockaddr();
188 if libc_connect(fd
, ptr
, n
) < 0 {
194 func Socket(domain
, typ
, proto
int) (fd
, errno
int) {
195 if domain
== AF_INET6
&& SocketDisableIPv6
{
196 return -1, EAFNOSUPPORT
198 fd
= libc_socket(int(domain
), int(typ
), int(proto
));
205 func Listen(fd
int, n
int) (errno
int) {
206 r
:= libc_listen(int(fd
), int(n
));
207 if r
< 0 { errno
= GetErrno() }
211 func setsockopt(fd
, level
, opt
int, valueptr
uintptr, length Socklen_t
) (errno
int) {
212 r
:= libc_setsockopt(fd
, level
, opt
, (*byte)(unsafe
.Pointer(valueptr
)),
214 if r
< 0 { errno
= GetErrno() }
218 func SetsockoptInt(fd
, level
, opt
int, value
int) (errno
int) {
219 var n
= int32(value
);
220 return setsockopt(fd
, level
, opt
, uintptr(unsafe
.Pointer(&n
)), 4);
223 func SetsockoptTimeval(fd
, level
, opt
int, tv
*Timeval
) (errno
int) {
224 return setsockopt(fd
, level
, opt
, uintptr(unsafe
.Pointer(tv
)), Socklen_t(unsafe
.Sizeof(*tv
)));
227 func SetsockoptLinger(fd
, level
, opt
int, l
*Linger
) (errno
int) {
228 return setsockopt(fd
, level
, opt
, uintptr(unsafe
.Pointer(l
)), Socklen_t(unsafe
.Sizeof(*l
)));
231 func SetsockoptString(fd
, level
, opt
int, s
string) (errno
int) {
232 return setsockopt(fd
, level
, opt
, uintptr(unsafe
.Pointer(&[]byte(s
)[0])), Socklen_t(len(s
)))
235 func Getsockname(fd
int) (sa Sockaddr
, errno
int) {
236 var rsa RawSockaddrAny
;
237 var len Socklen_t
= SizeofSockaddrAny
;
238 if libc_getsockname(fd
, &rsa
, &len) != 0 {
242 return anyToSockaddr(&rsa
);
245 func Getpeername(fd
int) (sa Sockaddr
, errno
int) {
246 var rsa RawSockaddrAny
;
247 var len Socklen_t
= SizeofSockaddrAny
;
248 if libc_getpeername(fd
, &rsa
, &len) != 0 {
252 return anyToSockaddr(&rsa
);
255 func Recvfrom(fd
int, p
[]byte, flags
int) (n
int, from Sockaddr
, errno
int) {
256 var rsa RawSockaddrAny
;
257 var slen Socklen_t
= SizeofSockaddrAny
;
259 if len(p
) > 0 { _p0
= &p
[0]; }
260 r
:= libc_recvfrom(fd
, _p0
, Size_t(len(p
)), flags
, &rsa
, &slen
);
265 from
, errno
= anyToSockaddr(&rsa
);
270 func (iov
*Iovec
) SetLen(length
int) {
271 iov
.Len
= Iovec_len_t(length
)
274 func (msghdr
*Msghdr
) SetControllen(length
int) {
275 msghdr
.Controllen
= Msghdr_controllen_t(length
)
278 func Recvmsg(fd
int, p
, oob
[]byte, flags
int) (n
, oobn
int, recvflags
int, from Sockaddr
, errno
int) {
280 var rsa RawSockaddrAny
281 msg
.Name
= (*byte)(unsafe
.Pointer(&rsa
))
282 msg
.Namelen
= uint32(SizeofSockaddrAny
)
285 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
290 // receive at least one normal byte
295 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
296 msg
.SetControllen(len(oob
))
300 if n
, errno
= recvmsg(fd
, &msg
, flags
); errno
!= 0 {
303 oobn
= int(msg
.Controllen
)
304 recvflags
= int(msg
.Flags
)
305 // source address is only specified if the socket is unconnected
306 if rsa
.Addr
.Family
!= 0 {
307 from
, errno
= anyToSockaddr(&rsa
)
312 func recvmsg(s
int, msg
*Msghdr
, flags
int) (n
int, errno
int) {
313 r
:= libc_recvmsg(s
, msg
, flags
)
322 func Sendto(fd
int, p
[]byte, flags
int, to Sockaddr
) (errno
int) {
323 ptr
, n
, err
:= to
.sockaddr();
328 if len(p
) > 0 { _p0
= &p
[0]; }
329 r
:= libc_sendto(fd
, _p0
, Size_t(len(p
)), flags
, ptr
, n
);
330 if r
== -1 { errno
= GetErrno(); }
334 func Sendmsg(fd
int, p
, oob
[]byte, to Sockaddr
, flags
int) (errno
int) {
335 var ptr
*RawSockaddrAny
339 ptr
, nsock
, err
= to
.sockaddr()
345 msg
.Name
= (*byte)(unsafe
.Pointer(ptr
))
346 msg
.Namelen
= uint32(nsock
)
349 iov
.Base
= (*byte)(unsafe
.Pointer(&p
[0]))
354 // send at least one normal byte
359 msg
.Control
= (*byte)(unsafe
.Pointer(&oob
[0]))
360 msg
.SetControllen(len(oob
))
364 if errno
= sendmsg(fd
, &msg
, flags
); errno
!= 0 {
370 func sendmsg(s
int, msg
*Msghdr
, flags
int) (errno
int) {
371 if libc_sendmsg(s
, msg
, flags
) < 0 {
377 func Shutdown(fd
int, how
int) (errno
int) {
378 r
:= libc_shutdown(fd
, how
);
379 if r
< 0 { errno
= GetErrno() }
383 // FIXME: No getsockopt.