github.com/karrick/go@v0.0.0-20170817181416-d5b0ec858b37/src/syscall/net_nacl.go (about)

     1  // Copyright 2013 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // A simulated network for use within NaCl.
     6  // The simulation is not particularly tied to NaCl,
     7  // but other systems have real networks.
     8  
     9  // All int64 times are UnixNanos.
    10  
    11  package syscall
    12  
    13  import (
    14  	"sync"
    15  	"sync/atomic"
    16  )
    17  
    18  // Interface to timers implemented in package runtime.
    19  // Must be in sync with ../runtime/runtime.h:/^struct.Timer$
    20  // Really for use by package time, but we cannot import time here.
    21  
    22  type runtimeTimer struct {
    23  	i      int
    24  	when   int64
    25  	period int64
    26  	f      func(interface{}, uintptr) // NOTE: must not be closure
    27  	arg    interface{}
    28  	seq    uintptr
    29  }
    30  
    31  func startTimer(*runtimeTimer)
    32  func stopTimer(*runtimeTimer) bool
    33  
    34  type timer struct {
    35  	expired bool
    36  	q       *queue
    37  	r       runtimeTimer
    38  }
    39  
    40  func (t *timer) start(q *queue, deadline int64) {
    41  	if deadline == 0 {
    42  		return
    43  	}
    44  	t.q = q
    45  	t.r.when = deadline
    46  	t.r.f = timerExpired
    47  	t.r.arg = t
    48  	startTimer(&t.r)
    49  }
    50  
    51  func (t *timer) stop() {
    52  	stopTimer(&t.r)
    53  }
    54  
    55  func (t *timer) reset(q *queue, deadline int64) {
    56  	if t.r.f != nil {
    57  		t.stop()
    58  	}
    59  	if deadline == 0 {
    60  		return
    61  	}
    62  	if t.r.f == nil {
    63  		t.q = q
    64  		t.r.f = timerExpired
    65  		t.r.arg = t
    66  	}
    67  	t.r.when = deadline
    68  	startTimer(&t.r)
    69  }
    70  
    71  func timerExpired(i interface{}, seq uintptr) {
    72  	t := i.(*timer)
    73  	go func() {
    74  		t.q.Lock()
    75  		defer t.q.Unlock()
    76  		t.expired = true
    77  		t.q.canRead.Broadcast()
    78  		t.q.canWrite.Broadcast()
    79  	}()
    80  }
    81  
    82  // Network constants and data structures. These match the traditional values.
    83  
    84  const (
    85  	AF_UNSPEC = iota
    86  	AF_UNIX
    87  	AF_INET
    88  	AF_INET6
    89  )
    90  
    91  const (
    92  	SHUT_RD = iota
    93  	SHUT_WR
    94  	SHUT_RDWR
    95  )
    96  
    97  const (
    98  	SOCK_STREAM = 1 + iota
    99  	SOCK_DGRAM
   100  	SOCK_RAW
   101  	SOCK_SEQPACKET
   102  )
   103  
   104  const (
   105  	IPPROTO_IP   = 0
   106  	IPPROTO_IPV4 = 4
   107  	IPPROTO_IPV6 = 0x29
   108  	IPPROTO_TCP  = 6
   109  	IPPROTO_UDP  = 0x11
   110  )
   111  
   112  // Misc constants expected by package net but not supported.
   113  const (
   114  	_ = iota
   115  	SOL_SOCKET
   116  	SO_TYPE
   117  	NET_RT_IFLIST
   118  	IFNAMSIZ
   119  	IFF_UP
   120  	IFF_BROADCAST
   121  	IFF_LOOPBACK
   122  	IFF_POINTOPOINT
   123  	IFF_MULTICAST
   124  	IPV6_V6ONLY
   125  	SOMAXCONN
   126  	F_DUPFD_CLOEXEC
   127  	SO_BROADCAST
   128  	SO_REUSEADDR
   129  	SO_REUSEPORT
   130  	SO_RCVBUF
   131  	SO_SNDBUF
   132  	SO_KEEPALIVE
   133  	SO_LINGER
   134  	SO_ERROR
   135  	IP_PORTRANGE
   136  	IP_PORTRANGE_DEFAULT
   137  	IP_PORTRANGE_LOW
   138  	IP_PORTRANGE_HIGH
   139  	IP_MULTICAST_IF
   140  	IP_MULTICAST_LOOP
   141  	IP_ADD_MEMBERSHIP
   142  	IPV6_PORTRANGE
   143  	IPV6_PORTRANGE_DEFAULT
   144  	IPV6_PORTRANGE_LOW
   145  	IPV6_PORTRANGE_HIGH
   146  	IPV6_MULTICAST_IF
   147  	IPV6_MULTICAST_LOOP
   148  	IPV6_JOIN_GROUP
   149  	TCP_NODELAY
   150  	TCP_KEEPINTVL
   151  	TCP_KEEPIDLE
   152  
   153  	SYS_FCNTL = 500 // unsupported
   154  )
   155  
   156  var SocketDisableIPv6 bool
   157  
   158  // A Sockaddr is one of the SockaddrXxx structs.
   159  type Sockaddr interface {
   160  	// copy returns a copy of the underlying data.
   161  	copy() Sockaddr
   162  
   163  	// key returns the value of the underlying data,
   164  	// for comparison as a map key.
   165  	key() interface{}
   166  }
   167  
   168  type SockaddrInet4 struct {
   169  	Port int
   170  	Addr [4]byte
   171  }
   172  
   173  func (sa *SockaddrInet4) copy() Sockaddr {
   174  	sa1 := *sa
   175  	return &sa1
   176  }
   177  
   178  func (sa *SockaddrInet4) key() interface{} { return *sa }
   179  
   180  func isIPv4Localhost(sa Sockaddr) bool {
   181  	sa4, ok := sa.(*SockaddrInet4)
   182  	return ok && sa4.Addr == [4]byte{127, 0, 0, 1}
   183  }
   184  
   185  type SockaddrInet6 struct {
   186  	Port   int
   187  	ZoneId uint32
   188  	Addr   [16]byte
   189  }
   190  
   191  func (sa *SockaddrInet6) copy() Sockaddr {
   192  	sa1 := *sa
   193  	return &sa1
   194  }
   195  
   196  func (sa *SockaddrInet6) key() interface{} { return *sa }
   197  
   198  type SockaddrUnix struct {
   199  	Name string
   200  }
   201  
   202  func (sa *SockaddrUnix) copy() Sockaddr {
   203  	sa1 := *sa
   204  	return &sa1
   205  }
   206  
   207  func (sa *SockaddrUnix) key() interface{} { return *sa }
   208  
   209  type SockaddrDatalink struct {
   210  	Len    uint8
   211  	Family uint8
   212  	Index  uint16
   213  	Type   uint8
   214  	Nlen   uint8
   215  	Alen   uint8
   216  	Slen   uint8
   217  	Data   [12]int8
   218  }
   219  
   220  func (sa *SockaddrDatalink) copy() Sockaddr {
   221  	sa1 := *sa
   222  	return &sa1
   223  }
   224  
   225  func (sa *SockaddrDatalink) key() interface{} { return *sa }
   226  
   227  // RoutingMessage represents a routing message.
   228  type RoutingMessage interface {
   229  	unimplemented()
   230  }
   231  
   232  type IPMreq struct {
   233  	Multiaddr [4]byte /* in_addr */
   234  	Interface [4]byte /* in_addr */
   235  }
   236  
   237  type IPv6Mreq struct {
   238  	Multiaddr [16]byte /* in6_addr */
   239  	Interface uint32
   240  }
   241  
   242  type Linger struct {
   243  	Onoff  int32
   244  	Linger int32
   245  }
   246  
   247  type ICMPv6Filter struct {
   248  	Filt [8]uint32
   249  }
   250  
   251  // A queue is the bookkeeping for a synchronized buffered queue.
   252  // We do not use channels because we need to be able to handle
   253  // writes after and during close, and because a chan byte would
   254  // require too many send and receive operations in real use.
   255  type queue struct {
   256  	sync.Mutex
   257  	canRead  sync.Cond
   258  	canWrite sync.Cond
   259  	rtimer   *timer // non-nil if in read
   260  	wtimer   *timer // non-nil if in write
   261  	r        int    // total read index
   262  	w        int    // total write index
   263  	m        int    // index mask
   264  	closed   bool
   265  }
   266  
   267  func (q *queue) init(size int) {
   268  	if size&(size-1) != 0 {
   269  		panic("invalid queue size - must be power of two")
   270  	}
   271  	q.canRead.L = &q.Mutex
   272  	q.canWrite.L = &q.Mutex
   273  	q.m = size - 1
   274  }
   275  
   276  func past(deadline int64) bool {
   277  	sec, nsec := now()
   278  	return deadline > 0 && deadline < sec*1e9+int64(nsec)
   279  }
   280  
   281  func (q *queue) waitRead(n int, deadline int64) (int, error) {
   282  	if past(deadline) {
   283  		return 0, EAGAIN
   284  	}
   285  	var t timer
   286  	t.start(q, deadline)
   287  	q.rtimer = &t
   288  	for q.w-q.r == 0 && !q.closed && !t.expired {
   289  		q.canRead.Wait()
   290  	}
   291  	q.rtimer = nil
   292  	t.stop()
   293  	m := q.w - q.r
   294  	if m == 0 && t.expired {
   295  		return 0, EAGAIN
   296  	}
   297  	if m > n {
   298  		m = n
   299  		q.canRead.Signal() // wake up next reader too
   300  	}
   301  	q.canWrite.Signal()
   302  	return m, nil
   303  }
   304  
   305  func (q *queue) waitWrite(n int, deadline int64) (int, error) {
   306  	if past(deadline) {
   307  		return 0, EAGAIN
   308  	}
   309  	var t timer
   310  	t.start(q, deadline)
   311  	q.wtimer = &t
   312  	for q.w-q.r > q.m && !q.closed && !t.expired {
   313  		q.canWrite.Wait()
   314  	}
   315  	q.wtimer = nil
   316  	t.stop()
   317  	m := q.m + 1 - (q.w - q.r)
   318  	if m == 0 && t.expired {
   319  		return 0, EAGAIN
   320  	}
   321  	if m == 0 {
   322  		return 0, EAGAIN
   323  	}
   324  	if m > n {
   325  		m = n
   326  		q.canWrite.Signal() // wake up next writer too
   327  	}
   328  	q.canRead.Signal()
   329  	return m, nil
   330  }
   331  
   332  func (q *queue) close() {
   333  	q.Lock()
   334  	defer q.Unlock()
   335  	q.closed = true
   336  	q.canRead.Broadcast()
   337  	q.canWrite.Broadcast()
   338  }
   339  
   340  // A byteq is a byte queue.
   341  type byteq struct {
   342  	queue
   343  	data []byte
   344  }
   345  
   346  func newByteq() *byteq {
   347  	q := &byteq{
   348  		data: make([]byte, 4096),
   349  	}
   350  	q.init(len(q.data))
   351  	return q
   352  }
   353  
   354  func (q *byteq) read(b []byte, deadline int64) (int, error) {
   355  	q.Lock()
   356  	defer q.Unlock()
   357  	n, err := q.waitRead(len(b), deadline)
   358  	if err != nil {
   359  		return 0, err
   360  	}
   361  	b = b[:n]
   362  	for len(b) > 0 {
   363  		m := copy(b, q.data[q.r&q.m:])
   364  		q.r += m
   365  		b = b[m:]
   366  	}
   367  	return n, nil
   368  }
   369  
   370  func (q *byteq) write(b []byte, deadline int64) (n int, err error) {
   371  	q.Lock()
   372  	defer q.Unlock()
   373  	for n < len(b) {
   374  		nn, err := q.waitWrite(len(b[n:]), deadline)
   375  		if err != nil {
   376  			return n, err
   377  		}
   378  		bb := b[n : n+nn]
   379  		n += nn
   380  		for len(bb) > 0 {
   381  			m := copy(q.data[q.w&q.m:], bb)
   382  			q.w += m
   383  			bb = bb[m:]
   384  		}
   385  	}
   386  	return n, nil
   387  }
   388  
   389  // A msgq is a queue of messages.
   390  type msgq struct {
   391  	queue
   392  	data []interface{}
   393  }
   394  
   395  func newMsgq() *msgq {
   396  	q := &msgq{
   397  		data: make([]interface{}, 32),
   398  	}
   399  	q.init(len(q.data))
   400  	return q
   401  }
   402  
   403  func (q *msgq) read(deadline int64) (interface{}, error) {
   404  	q.Lock()
   405  	defer q.Unlock()
   406  	n, err := q.waitRead(1, deadline)
   407  	if err != nil {
   408  		return nil, err
   409  	}
   410  	if n == 0 {
   411  		return nil, nil
   412  	}
   413  	m := q.data[q.r&q.m]
   414  	q.r++
   415  	return m, nil
   416  }
   417  
   418  func (q *msgq) write(m interface{}, deadline int64) error {
   419  	q.Lock()
   420  	defer q.Unlock()
   421  	_, err := q.waitWrite(1, deadline)
   422  	if err != nil {
   423  		return err
   424  	}
   425  	q.data[q.w&q.m] = m
   426  	q.w++
   427  	return nil
   428  }
   429  
   430  // An addr is a sequence of bytes uniquely identifying a network address.
   431  // It is not human-readable.
   432  type addr string
   433  
   434  // A conn is one side of a stream-based network connection.
   435  // That is, a stream-based network connection is a pair of cross-connected conns.
   436  type conn struct {
   437  	rd     *byteq
   438  	wr     *byteq
   439  	local  addr
   440  	remote addr
   441  }
   442  
   443  // A pktconn is one side of a packet-based network connection.
   444  // That is, a packet-based network connection is a pair of cross-connected pktconns.
   445  type pktconn struct {
   446  	rd     *msgq
   447  	wr     *msgq
   448  	local  addr
   449  	remote addr
   450  }
   451  
   452  // A listener accepts incoming stream-based network connections.
   453  type listener struct {
   454  	rd    *msgq
   455  	local addr
   456  }
   457  
   458  // A netFile is an open network file.
   459  type netFile struct {
   460  	defaultFileImpl
   461  	proto      *netproto
   462  	sotype     int
   463  	listener   *msgq
   464  	packet     *msgq
   465  	rd         *byteq
   466  	wr         *byteq
   467  	rddeadline int64
   468  	wrdeadline int64
   469  	addr       Sockaddr
   470  	raddr      Sockaddr
   471  }
   472  
   473  // A netAddr is a network address in the global listener map.
   474  // All the fields must have defined == operations.
   475  type netAddr struct {
   476  	proto  *netproto
   477  	sotype int
   478  	addr   interface{}
   479  }
   480  
   481  // net records the state of the network.
   482  // It maps a network address to the listener on that address.
   483  var net = struct {
   484  	sync.Mutex
   485  	listener map[netAddr]*netFile
   486  }{
   487  	listener: make(map[netAddr]*netFile),
   488  }
   489  
   490  // TODO(rsc): Some day, do a better job with port allocation.
   491  // For playground programs, incrementing is fine.
   492  var nextport = 2
   493  
   494  // A netproto contains protocol-specific functionality
   495  // (one for AF_INET, one for AF_INET6 and so on).
   496  // It is a struct instead of an interface because the
   497  // implementation needs no state, and I expect to
   498  // add some data fields at some point.
   499  type netproto struct {
   500  	bind func(*netFile, Sockaddr) error
   501  }
   502  
   503  var netprotoAF_INET = &netproto{
   504  	bind: func(f *netFile, sa Sockaddr) error {
   505  		if sa == nil {
   506  			f.addr = &SockaddrInet4{
   507  				Port: nextport,
   508  				Addr: [4]byte{127, 0, 0, 1},
   509  			}
   510  			nextport++
   511  			return nil
   512  		}
   513  		addr, ok := sa.(*SockaddrInet4)
   514  		if !ok {
   515  			return EINVAL
   516  		}
   517  		addr = addr.copy().(*SockaddrInet4)
   518  		if addr.Port == 0 {
   519  			addr.Port = nextport
   520  			nextport++
   521  		}
   522  		f.addr = addr
   523  		return nil
   524  	},
   525  }
   526  
   527  var netprotos = map[int]*netproto{
   528  	AF_INET: netprotoAF_INET,
   529  }
   530  
   531  // These functions implement the usual BSD socket operations.
   532  
   533  func (f *netFile) bind(sa Sockaddr) error {
   534  	if f.addr != nil {
   535  		return EISCONN
   536  	}
   537  	if err := f.proto.bind(f, sa); err != nil {
   538  		return err
   539  	}
   540  	if f.sotype == SOCK_DGRAM {
   541  		_, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}]
   542  		if ok {
   543  			f.addr = nil
   544  			return EADDRINUSE
   545  		}
   546  		net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f
   547  		f.packet = newMsgq()
   548  	}
   549  	return nil
   550  }
   551  
   552  func (f *netFile) listen(backlog int) error {
   553  	net.Lock()
   554  	defer net.Unlock()
   555  	if f.listener != nil {
   556  		return EINVAL
   557  	}
   558  	old, ok := net.listener[netAddr{f.proto, f.sotype, f.addr.key()}]
   559  	if ok && !old.listenerClosed() {
   560  		return EADDRINUSE
   561  	}
   562  	net.listener[netAddr{f.proto, f.sotype, f.addr.key()}] = f
   563  	f.listener = newMsgq()
   564  	return nil
   565  }
   566  
   567  func (f *netFile) accept() (fd int, sa Sockaddr, err error) {
   568  	msg, err := f.listener.read(f.readDeadline())
   569  	if err != nil {
   570  		return -1, nil, err
   571  	}
   572  	newf, ok := msg.(*netFile)
   573  	if !ok {
   574  		// must be eof
   575  		return -1, nil, EAGAIN
   576  	}
   577  	return newFD(newf), newf.raddr.copy(), nil
   578  }
   579  
   580  func (f *netFile) connect(sa Sockaddr) error {
   581  	if past(f.writeDeadline()) {
   582  		return EAGAIN
   583  	}
   584  	if f.addr == nil {
   585  		if err := f.bind(nil); err != nil {
   586  			return err
   587  		}
   588  	}
   589  	net.Lock()
   590  	if sa == nil {
   591  		net.Unlock()
   592  		return EINVAL
   593  	}
   594  	sa = sa.copy()
   595  	if f.raddr != nil {
   596  		net.Unlock()
   597  		return EISCONN
   598  	}
   599  	if f.sotype == SOCK_DGRAM {
   600  		net.Unlock()
   601  		f.raddr = sa
   602  		return nil
   603  	}
   604  	if f.listener != nil {
   605  		net.Unlock()
   606  		return EISCONN
   607  	}
   608  	l, ok := net.listener[netAddr{f.proto, f.sotype, sa.key()}]
   609  	if !ok {
   610  		// If we're dialing 127.0.0.1 but found nothing, try
   611  		// 0.0.0.0 also. (Issue 20611)
   612  		if isIPv4Localhost(sa) {
   613  			sa = &SockaddrInet4{Port: sa.(*SockaddrInet4).Port}
   614  			l, ok = net.listener[netAddr{f.proto, f.sotype, sa.key()}]
   615  		}
   616  	}
   617  	if !ok || l.listenerClosed() {
   618  		net.Unlock()
   619  		return ECONNREFUSED
   620  	}
   621  	f.raddr = sa
   622  	f.rd = newByteq()
   623  	f.wr = newByteq()
   624  	newf := &netFile{
   625  		proto:  f.proto,
   626  		sotype: f.sotype,
   627  		addr:   f.raddr,
   628  		raddr:  f.addr,
   629  		rd:     f.wr,
   630  		wr:     f.rd,
   631  	}
   632  	net.Unlock()
   633  	l.listener.write(newf, f.writeDeadline())
   634  	return nil
   635  }
   636  
   637  func (f *netFile) read(b []byte) (int, error) {
   638  	if f.rd == nil {
   639  		if f.raddr != nil {
   640  			n, _, err := f.recvfrom(b, 0)
   641  			return n, err
   642  		}
   643  		return 0, ENOTCONN
   644  	}
   645  	return f.rd.read(b, f.readDeadline())
   646  }
   647  
   648  func (f *netFile) write(b []byte) (int, error) {
   649  	if f.wr == nil {
   650  		if f.raddr != nil {
   651  			err := f.sendto(b, 0, f.raddr)
   652  			var n int
   653  			if err == nil {
   654  				n = len(b)
   655  			}
   656  			return n, err
   657  		}
   658  		return 0, ENOTCONN
   659  	}
   660  	return f.wr.write(b, f.writeDeadline())
   661  }
   662  
   663  type pktmsg struct {
   664  	buf  []byte
   665  	addr Sockaddr
   666  }
   667  
   668  func (f *netFile) recvfrom(p []byte, flags int) (n int, from Sockaddr, err error) {
   669  	if f.sotype != SOCK_DGRAM {
   670  		return 0, nil, EINVAL
   671  	}
   672  	if f.packet == nil {
   673  		return 0, nil, ENOTCONN
   674  	}
   675  	msg1, err := f.packet.read(f.readDeadline())
   676  	if err != nil {
   677  		return 0, nil, err
   678  	}
   679  	msg, ok := msg1.(*pktmsg)
   680  	if !ok {
   681  		return 0, nil, EAGAIN
   682  	}
   683  	return copy(p, msg.buf), msg.addr, nil
   684  }
   685  
   686  func (f *netFile) sendto(p []byte, flags int, to Sockaddr) error {
   687  	if f.sotype != SOCK_DGRAM {
   688  		return EINVAL
   689  	}
   690  	if f.packet == nil {
   691  		if err := f.bind(nil); err != nil {
   692  			return err
   693  		}
   694  	}
   695  	net.Lock()
   696  	if to == nil {
   697  		net.Unlock()
   698  		return EINVAL
   699  	}
   700  	to = to.copy()
   701  	l, ok := net.listener[netAddr{f.proto, f.sotype, to.key()}]
   702  	if !ok || l.packet == nil {
   703  		net.Unlock()
   704  		return ECONNREFUSED
   705  	}
   706  	net.Unlock()
   707  	msg := &pktmsg{
   708  		buf:  make([]byte, len(p)),
   709  		addr: f.addr,
   710  	}
   711  	copy(msg.buf, p)
   712  	l.packet.write(msg, f.writeDeadline())
   713  	return nil
   714  }
   715  
   716  func (f *netFile) listenerClosed() bool {
   717  	f.listener.Lock()
   718  	defer f.listener.Unlock()
   719  	return f.listener.closed
   720  }
   721  
   722  func (f *netFile) close() error {
   723  	if f.listener != nil {
   724  		f.listener.close()
   725  	}
   726  	if f.packet != nil {
   727  		f.packet.close()
   728  	}
   729  	if f.rd != nil {
   730  		f.rd.close()
   731  	}
   732  	if f.wr != nil {
   733  		f.wr.close()
   734  	}
   735  	return nil
   736  }
   737  
   738  func fdToNetFile(fd int) (*netFile, error) {
   739  	f, err := fdToFile(fd)
   740  	if err != nil {
   741  		return nil, err
   742  	}
   743  	impl := f.impl
   744  	netf, ok := impl.(*netFile)
   745  	if !ok {
   746  		return nil, EINVAL
   747  	}
   748  	return netf, nil
   749  }
   750  
   751  func Socket(proto, sotype, unused int) (fd int, err error) {
   752  	p := netprotos[proto]
   753  	if p == nil {
   754  		return -1, EPROTONOSUPPORT
   755  	}
   756  	if sotype != SOCK_STREAM && sotype != SOCK_DGRAM {
   757  		return -1, ESOCKTNOSUPPORT
   758  	}
   759  	f := &netFile{
   760  		proto:  p,
   761  		sotype: sotype,
   762  	}
   763  	return newFD(f), nil
   764  }
   765  
   766  func Bind(fd int, sa Sockaddr) error {
   767  	f, err := fdToNetFile(fd)
   768  	if err != nil {
   769  		return err
   770  	}
   771  	return f.bind(sa)
   772  }
   773  
   774  func StopIO(fd int) error {
   775  	f, err := fdToNetFile(fd)
   776  	if err != nil {
   777  		return err
   778  	}
   779  	f.close()
   780  	return nil
   781  }
   782  
   783  func Listen(fd int, backlog int) error {
   784  	f, err := fdToNetFile(fd)
   785  	if err != nil {
   786  		return err
   787  	}
   788  	return f.listen(backlog)
   789  }
   790  
   791  func Accept(fd int) (newfd int, sa Sockaddr, err error) {
   792  	f, err := fdToNetFile(fd)
   793  	if err != nil {
   794  		return 0, nil, err
   795  	}
   796  	return f.accept()
   797  }
   798  
   799  func Getsockname(fd int) (sa Sockaddr, err error) {
   800  	f, err := fdToNetFile(fd)
   801  	if err != nil {
   802  		return nil, err
   803  	}
   804  	if f.addr == nil {
   805  		return nil, ENOTCONN
   806  	}
   807  	return f.addr.copy(), nil
   808  }
   809  
   810  func Getpeername(fd int) (sa Sockaddr, err error) {
   811  	f, err := fdToNetFile(fd)
   812  	if err != nil {
   813  		return nil, err
   814  	}
   815  	if f.raddr == nil {
   816  		return nil, ENOTCONN
   817  	}
   818  	return f.raddr.copy(), nil
   819  }
   820  
   821  func Connect(fd int, sa Sockaddr) error {
   822  	f, err := fdToNetFile(fd)
   823  	if err != nil {
   824  		return err
   825  	}
   826  	return f.connect(sa)
   827  }
   828  
   829  func Recvfrom(fd int, p []byte, flags int) (n int, from Sockaddr, err error) {
   830  	f, err := fdToNetFile(fd)
   831  	if err != nil {
   832  		return 0, nil, err
   833  	}
   834  	return f.recvfrom(p, flags)
   835  }
   836  
   837  func Sendto(fd int, p []byte, flags int, to Sockaddr) error {
   838  	f, err := fdToNetFile(fd)
   839  	if err != nil {
   840  		return err
   841  	}
   842  	return f.sendto(p, flags, to)
   843  }
   844  
   845  func Recvmsg(fd int, p, oob []byte, flags int) (n, oobn, recvflags int, from Sockaddr, err error) {
   846  	f, err := fdToNetFile(fd)
   847  	if err != nil {
   848  		return
   849  	}
   850  	n, from, err = f.recvfrom(p, flags)
   851  	return
   852  }
   853  
   854  func Sendmsg(fd int, p, oob []byte, to Sockaddr, flags int) error {
   855  	_, err := SendmsgN(fd, p, oob, to, flags)
   856  	return err
   857  }
   858  
   859  func SendmsgN(fd int, p, oob []byte, to Sockaddr, flags int) (n int, err error) {
   860  	f, err := fdToNetFile(fd)
   861  	if err != nil {
   862  		return 0, err
   863  	}
   864  	switch f.sotype {
   865  	case SOCK_STREAM:
   866  		n, err = f.write(p)
   867  	case SOCK_DGRAM:
   868  		n = len(p)
   869  		err = f.sendto(p, flags, to)
   870  	}
   871  	if err != nil {
   872  		return 0, err
   873  	}
   874  	return n, nil
   875  }
   876  
   877  func GetsockoptInt(fd, level, opt int) (value int, err error) {
   878  	f, err := fdToNetFile(fd)
   879  	if err != nil {
   880  		return 0, err
   881  	}
   882  	switch {
   883  	case level == SOL_SOCKET && opt == SO_TYPE:
   884  		return f.sotype, nil
   885  	}
   886  	return 0, ENOTSUP
   887  }
   888  
   889  func SetsockoptInt(fd, level, opt int, value int) error {
   890  	return nil
   891  }
   892  
   893  func SetsockoptByte(fd, level, opt int, value byte) error {
   894  	_, err := fdToNetFile(fd)
   895  	if err != nil {
   896  		return err
   897  	}
   898  	return ENOTSUP
   899  }
   900  
   901  func SetsockoptLinger(fd, level, opt int, l *Linger) error {
   902  	return nil
   903  }
   904  
   905  func SetReadDeadline(fd int, t int64) error {
   906  	f, err := fdToNetFile(fd)
   907  	if err != nil {
   908  		return err
   909  	}
   910  	atomic.StoreInt64(&f.rddeadline, t)
   911  	if bq := f.rd; bq != nil {
   912  		bq.Lock()
   913  		if timer := bq.rtimer; timer != nil {
   914  			timer.reset(&bq.queue, t)
   915  		}
   916  		bq.Unlock()
   917  	}
   918  	return nil
   919  }
   920  
   921  func (f *netFile) readDeadline() int64 {
   922  	return atomic.LoadInt64(&f.rddeadline)
   923  }
   924  
   925  func SetWriteDeadline(fd int, t int64) error {
   926  	f, err := fdToNetFile(fd)
   927  	if err != nil {
   928  		return err
   929  	}
   930  	atomic.StoreInt64(&f.wrdeadline, t)
   931  	if bq := f.wr; bq != nil {
   932  		bq.Lock()
   933  		if timer := bq.wtimer; timer != nil {
   934  			timer.reset(&bq.queue, t)
   935  		}
   936  		bq.Unlock()
   937  	}
   938  	return nil
   939  }
   940  
   941  func (f *netFile) writeDeadline() int64 {
   942  	return atomic.LoadInt64(&f.wrdeadline)
   943  }
   944  
   945  func Shutdown(fd int, how int) error {
   946  	f, err := fdToNetFile(fd)
   947  	if err != nil {
   948  		return err
   949  	}
   950  	switch how {
   951  	case SHUT_RD:
   952  		f.rd.close()
   953  	case SHUT_WR:
   954  		f.wr.close()
   955  	case SHUT_RDWR:
   956  		f.rd.close()
   957  		f.wr.close()
   958  	}
   959  	return nil
   960  }
   961  
   962  func SetsockoptICMPv6Filter(fd, level, opt int, filter *ICMPv6Filter) error { panic("SetsockoptICMPv") }
   963  func SetsockoptIPMreq(fd, level, opt int, mreq *IPMreq) error               { panic("SetsockoptIPMreq") }
   964  func SetsockoptIPv6Mreq(fd, level, opt int, mreq *IPv6Mreq) error           { panic("SetsockoptIPv") }
   965  func SetsockoptInet4Addr(fd, level, opt int, value [4]byte) error           { panic("SetsockoptInet") }
   966  func SetsockoptString(fd, level, opt int, s string) error                   { panic("SetsockoptString") }
   967  func SetsockoptTimeval(fd, level, opt int, tv *Timeval) error               { panic("SetsockoptTimeval") }
   968  func Socketpair(domain, typ, proto int) (fd [2]int, err error)              { panic("Socketpair") }
   969  
   970  func SetNonblock(fd int, nonblocking bool) error { return nil }