github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/syscall/socket.go (about)

     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 = 0x6c
    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) {
    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 := Socklen_t(2)
    92  	if n > 0 {
    93  		sl += Socklen_t(n) + 1
    94  	}
    95  	sl = sa.raw.adjustAbstract(sl)
    96  
    97  	// length is family (uint16), name, NUL.
    98  	return (*RawSockaddrAny)(unsafe.Pointer(&sa.raw)), sl, nil
    99  }
   100  
   101  func anyToSockaddr(rsa *RawSockaddrAny) (Sockaddr, error) {
   102  	switch rsa.Addr.Family {
   103  	case AF_UNIX:
   104  		pp := (*RawSockaddrUnix)(unsafe.Pointer(rsa))
   105  		sa := new(SockaddrUnix)
   106  		n, err := pp.getLen()
   107  		if err != nil {
   108  			return nil, err
   109  		}
   110  		bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))
   111  		sa.Name = string(bytes[0:n])
   112  		return sa, nil
   113  
   114  	case AF_INET:
   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]
   121  		}
   122  		return sa, nil
   123  
   124  	case AF_INET6:
   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]
   131  		}
   132  		return sa, nil
   133  	}
   134  	return anyToSockaddrOS(rsa)
   135  }
   136  
   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
   139  
   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)
   144  	if err != nil {
   145  		return
   146  	}
   147  	sa, err = anyToSockaddr(&rsa)
   148  	if err != nil {
   149  		Close(nfd)
   150  		nfd = 0
   151  	}
   152  	return
   153  }
   154  
   155  //sysnb	getsockname(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
   156  //getsockname(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
   157  
   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 {
   162  		return
   163  	}
   164  	return anyToSockaddr(&rsa)
   165  }
   166  
   167  //sysnb getpeername(fd int, sa *RawSockaddrAny, len *Socklen_t) (err error)
   168  //getpeername(fd _C_int, sa *RawSockaddrAny, len *Socklen_t) _C_int
   169  
   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 {
   174  		return
   175  	}
   176  	return anyToSockaddr(&rsa)
   177  }
   178  
   179  func Bind(fd int, sa Sockaddr) (err error) {
   180  	ptr, n, err := sa.sockaddr()
   181  	if err != nil {
   182  		return err
   183  	}
   184  	return bind(fd, ptr, n)
   185  }
   186  
   187  func Connect(fd int, sa Sockaddr) (err error) {
   188  	ptr, n, err := sa.sockaddr()
   189  	if err != nil {
   190  		return err
   191  	}
   192  	return connect(fd, ptr, n)
   193  }
   194  
   195  func Socket(domain, typ, proto int) (fd int, err error) {
   196  	if domain == AF_INET6 && SocketDisableIPv6 {
   197  		return -1, EAFNOSUPPORT
   198  	}
   199  	fd, err = socket(domain, typ, proto)
   200  	return
   201  }
   202  
   203  func Socketpair(domain, typ, proto int) (fd [2]int, err error) {
   204  	var fdx [2]_C_int
   205  	err = socketpair(domain, typ, proto, &fdx)
   206  	if err == nil {
   207  		fd[0] = int(fdx[0])
   208  		fd[1] = int(fdx[1])
   209  	}
   210  	return
   211  }
   212  
   213  func GetsockoptByte(fd, level, opt int) (value byte, err error) {
   214  	var n byte
   215  	vallen := Socklen_t(1)
   216  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
   217  	return n, err
   218  }
   219  
   220  func GetsockoptInt(fd, level, opt int) (value int, err error) {
   221  	var n int32
   222  	vallen := Socklen_t(4)
   223  	err = getsockopt(fd, level, opt, unsafe.Pointer(&n), &vallen)
   224  	return int(n), err
   225  }
   226  
   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)
   230  	return value, err
   231  }
   232  
   233  func GetsockoptIPMreq(fd, level, opt int) (*IPMreq, error) {
   234  	var value IPMreq
   235  	vallen := Socklen_t(SizeofIPMreq)
   236  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
   237  	return &value, err
   238  }
   239  
   240  func GetsockoptIPMreqn(fd, level, opt int) (*IPMreqn, error) {
   241  	var value IPMreqn
   242  	vallen := Socklen_t(SizeofIPMreqn)
   243  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
   244  	return &value, err
   245  }
   246  
   247  func GetsockoptIPv6Mreq(fd, level, opt int) (*IPv6Mreq, error) {
   248  	var value IPv6Mreq
   249  	vallen := Socklen_t(SizeofIPv6Mreq)
   250  	err := getsockopt(fd, level, opt, unsafe.Pointer(&value), &vallen)
   251  	return &value, err
   252  }
   253  
   254  //sys	setsockopt(s int, level int, name int, val unsafe.Pointer, vallen Socklen_t) (err error)
   255  //setsockopt(s _C_int, level _C_int, optname _C_int, val *byte, vallen Socklen_t) _C_int
   256  
   257  func SetsockoptByte(fd, level, opt int, value byte) (err error) {
   258  	var n = byte(value)
   259  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 1)
   260  }
   261  
   262  func SetsockoptInt(fd, level, opt int, value int) (err error) {
   263  	var n = int32(value)
   264  	return setsockopt(fd, level, opt, unsafe.Pointer(&n), 4)
   265  }
   266  
   267  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) (err error) {
   268  	return setsockopt(fd, level, opt, unsafe.Pointer(&value[0]), 4)
   269  }
   270  
   271  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) (err error) {
   272  	return setsockopt(fd, level, opt, unsafe.Pointer(tv), Socklen_t(unsafe.Sizeof(*tv)))
   273  }
   274  
   275  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error {
   276  	return setsockopt(fd, level, opt, unsafe.Pointer(filter), SizeofICMPv6Filter)
   277  }
   278  
   279  type Linger struct {
   280  	Onoff  int32
   281  	Linger int32
   282  }
   283  
   284  func SetsockoptLinger(fd, level, opt int, l *Linger) (err error) {
   285  	return setsockopt(fd, level, opt, unsafe.Pointer(l), Socklen_t(unsafe.Sizeof(*l)))
   286  }
   287  
   288  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) (err error) {
   289  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), Socklen_t(unsafe.Sizeof(*mreq)))
   290  }
   291  
   292  func SetsockoptIPMreqn(fd, level, opt int, mreq *IPMreqn) (err error) {
   293  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), Socklen_t(unsafe.Sizeof(*mreq)))
   294  }
   295  
   296  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) (err error) {
   297  	return setsockopt(fd, level, opt, unsafe.Pointer(mreq), Socklen_t(unsafe.Sizeof(*mreq)))
   298  }
   299  
   300  func SetsockoptString(fd, level, opt int, s string) (err error) {
   301  	return setsockopt(fd, level, opt, unsafe.Pointer(&[]byte(s)[0]), Socklen_t(len(s)))
   302  }
   303  
   304  //sys	recvfrom(fd int, p []byte, flags int, from *RawSockaddrAny, fromlen *Socklen_t) (n int, err error)
   305  //recvfrom(fd _C_int, buf *byte, len Size_t, flags _C_int, from *RawSockaddrAny, fromlen *Socklen_t) Ssize_t
   306  
   307  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
   308  	var rsa RawSockaddrAny
   309  	var len Socklen_t = SizeofSockaddrAny
   310  	if n, err = recvfrom(fd, p, flags, &rsa, &len); err != nil {
   311  		return
   312  	}
   313  	if rsa.Addr.Family != AF_UNSPEC {
   314  		from, err = anyToSockaddr(&rsa)
   315  	}
   316  	return
   317  }
   318  
   319  func Sendto(fd int, p []byte, flags int, to Sockaddr) (err error) {
   320  	ptr, n, err := to.sockaddr()
   321  	if err != nil {
   322  		return err
   323  	}
   324  	return sendto(fd, p, flags, ptr, n)
   325  }
   326  
   327  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn int, recvflags int, from Sockaddr, err error) {
   328  	var msg Msghdr
   329  	var rsa RawSockaddrAny
   330  	msg.Name = (*byte)(unsafe.Pointer(&rsa))
   331  	msg.Namelen = uint32(SizeofSockaddrAny)
   332  	var iov Iovec
   333  	if len(p) > 0 {
   334  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
   335  		iov.SetLen(len(p))
   336  	}
   337  	var dummy byte
   338  	if len(oob) > 0 {
   339  		// receive at least one normal byte
   340  		if len(p) == 0 {
   341  			iov.Base = &dummy
   342  			iov.SetLen(1)
   343  		}
   344  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
   345  		msg.SetControllen(len(oob))
   346  	}
   347  	msg.Iov = &iov
   348  	msg.Iovlen = 1
   349  	if n, err = recvmsg(fd, &msg, flags); err != nil {
   350  		return
   351  	}
   352  	oobn = int(msg.Controllen)
   353  	recvflags = int(msg.Flags)
   354  	// source address is only specified if the socket is unconnected
   355  	if rsa.Addr.Family != AF_UNSPEC {
   356  		from, err = anyToSockaddr(&rsa)
   357  	}
   358  	return
   359  }
   360  
   361  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) (err error) {
   362  	_, err = SendmsgN(fd, p, oob, to, flags)
   363  	return
   364  }
   365  
   366  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
   367  	var ptr *RawSockaddrAny
   368  	var salen Socklen_t
   369  	if to != nil {
   370  		var err error
   371  		ptr, salen, err = to.sockaddr()
   372  		if err != nil {
   373  			return 0, err
   374  		}
   375  	}
   376  	var msg Msghdr
   377  	msg.Name = (*byte)(unsafe.Pointer(ptr))
   378  	msg.Namelen = uint32(salen)
   379  	var iov Iovec
   380  	if len(p) > 0 {
   381  		iov.Base = (*byte)(unsafe.Pointer(&p[0]))
   382  		iov.SetLen(len(p))
   383  	}
   384  	var dummy byte
   385  	if len(oob) > 0 {
   386  		// send at least one normal byte
   387  		if len(p) == 0 {
   388  			iov.Base = &dummy
   389  			iov.SetLen(1)
   390  		}
   391  		msg.Control = (*byte)(unsafe.Pointer(&oob[0]))
   392  		msg.SetControllen(len(oob))
   393  	}
   394  	msg.Iov = &iov
   395  	msg.Iovlen = 1
   396  	if n, err = sendmsg(fd, &msg, flags); err != nil {
   397  		return 0, err
   398  	}
   399  	if len(oob) > 0 && len(p) == 0 {
   400  		n = 0
   401  	}
   402  	return n, nil
   403  }
   404  
   405  //sys	Listen(fd int, n int) (err error)
   406  //listen(fd _C_int, n _C_int) _C_int
   407  
   408  //sys	Shutdown(fd int, how int) (err error)
   409  //shutdown(fd _C_int, how _C_int) _C_int
   410  
   411  func (iov *Iovec) SetLen(length int) {
   412  	iov.Len = Iovec_len_t(length)
   413  }
   414  
   415  func (msghdr *Msghdr) SetControllen(length int) {
   416  	msghdr.Controllen = Msghdr_controllen_t(length)
   417  }
   418  
   419  func (cmsg *Cmsghdr) SetLen(length int) {
   420  	cmsg.Len = Cmsghdr_len_t(length)
   421  }