...
Run Format

Source file src/syscall/net_nacl.go

Documentation: syscall

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

View as plain text