...

Source file src/syscall/net_nacl.go

     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