...

Source file src/net/net_fake.go

     1	// Copyright 2018 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	// Fake networking for js/wasm. It is intended to allow tests of other package to pass.
     6	
     7	// +build js,wasm
     8	
     9	package net
    10	
    11	import (
    12		"context"
    13		"internal/poll"
    14		"io"
    15		"os"
    16		"sync"
    17		"syscall"
    18		"time"
    19	)
    20	
    21	var listenersMu sync.Mutex
    22	var listeners = make(map[string]*netFD)
    23	
    24	var portCounterMu sync.Mutex
    25	var portCounter = 0
    26	
    27	func nextPort() int {
    28		portCounterMu.Lock()
    29		defer portCounterMu.Unlock()
    30		portCounter++
    31		return portCounter
    32	}
    33	
    34	// Network file descriptor.
    35	type netFD struct {
    36		r        *bufferedPipe
    37		w        *bufferedPipe
    38		incoming chan *netFD
    39	
    40		closedMu sync.Mutex
    41		closed   bool
    42	
    43		// immutable until Close
    44		listener bool
    45		family   int
    46		sotype   int
    47		net      string
    48		laddr    Addr
    49		raddr    Addr
    50	
    51		// unused
    52		pfd         poll.FD
    53		isConnected bool // handshake completed or use of association with peer
    54	}
    55	
    56	// socket returns a network file descriptor that is ready for
    57	// asynchronous I/O using the network poller.
    58	func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlFn func(string, string, syscall.RawConn) error) (*netFD, error) {
    59		fd := &netFD{family: family, sotype: sotype, net: net}
    60	
    61		if laddr != nil && raddr == nil { // listener
    62			l := laddr.(*TCPAddr)
    63			fd.laddr = &TCPAddr{
    64				IP:   l.IP,
    65				Port: nextPort(),
    66				Zone: l.Zone,
    67			}
    68			fd.listener = true
    69			fd.incoming = make(chan *netFD, 1024)
    70			listenersMu.Lock()
    71			listeners[fd.laddr.(*TCPAddr).String()] = fd
    72			listenersMu.Unlock()
    73			return fd, nil
    74		}
    75	
    76		fd.laddr = &TCPAddr{
    77			IP:   IPv4(127, 0, 0, 1),
    78			Port: nextPort(),
    79		}
    80		fd.raddr = raddr
    81		fd.r = newBufferedPipe(65536)
    82		fd.w = newBufferedPipe(65536)
    83	
    84		fd2 := &netFD{family: fd.family, sotype: sotype, net: net}
    85		fd2.laddr = fd.raddr
    86		fd2.raddr = fd.laddr
    87		fd2.r = fd.w
    88		fd2.w = fd.r
    89		listenersMu.Lock()
    90		l, ok := listeners[fd.raddr.(*TCPAddr).String()]
    91		if !ok {
    92			listenersMu.Unlock()
    93			return nil, syscall.ECONNREFUSED
    94		}
    95		l.incoming <- fd2
    96		listenersMu.Unlock()
    97	
    98		return fd, nil
    99	}
   100	
   101	func (fd *netFD) Read(p []byte) (n int, err error) {
   102		return fd.r.Read(p)
   103	}
   104	
   105	func (fd *netFD) Write(p []byte) (nn int, err error) {
   106		return fd.w.Write(p)
   107	}
   108	
   109	func (fd *netFD) Close() error {
   110		fd.closedMu.Lock()
   111		if fd.closed {
   112			fd.closedMu.Unlock()
   113			return nil
   114		}
   115		fd.closed = true
   116		fd.closedMu.Unlock()
   117	
   118		if fd.listener {
   119			listenersMu.Lock()
   120			delete(listeners, fd.laddr.String())
   121			close(fd.incoming)
   122			fd.listener = false
   123			listenersMu.Unlock()
   124			return nil
   125		}
   126	
   127		fd.r.Close()
   128		fd.w.Close()
   129		return nil
   130	}
   131	
   132	func (fd *netFD) closeRead() error {
   133		fd.r.Close()
   134		return nil
   135	}
   136	
   137	func (fd *netFD) closeWrite() error {
   138		fd.w.Close()
   139		return nil
   140	}
   141	
   142	func (fd *netFD) accept() (*netFD, error) {
   143		c, ok := <-fd.incoming
   144		if !ok {
   145			return nil, syscall.EINVAL
   146		}
   147		return c, nil
   148	}
   149	
   150	func (fd *netFD) SetDeadline(t time.Time) error {
   151		fd.r.SetReadDeadline(t)
   152		fd.w.SetWriteDeadline(t)
   153		return nil
   154	}
   155	
   156	func (fd *netFD) SetReadDeadline(t time.Time) error {
   157		fd.r.SetReadDeadline(t)
   158		return nil
   159	}
   160	
   161	func (fd *netFD) SetWriteDeadline(t time.Time) error {
   162		fd.w.SetWriteDeadline(t)
   163		return nil
   164	}
   165	
   166	func newBufferedPipe(softLimit int) *bufferedPipe {
   167		p := &bufferedPipe{softLimit: softLimit}
   168		p.rCond.L = &p.mu
   169		p.wCond.L = &p.mu
   170		return p
   171	}
   172	
   173	type bufferedPipe struct {
   174		softLimit int
   175		mu        sync.Mutex
   176		buf       []byte
   177		closed    bool
   178		rCond     sync.Cond
   179		wCond     sync.Cond
   180		rDeadline time.Time
   181		wDeadline time.Time
   182	}
   183	
   184	func (p *bufferedPipe) Read(b []byte) (int, error) {
   185		p.mu.Lock()
   186		defer p.mu.Unlock()
   187	
   188		for {
   189			if p.closed && len(p.buf) == 0 {
   190				return 0, io.EOF
   191			}
   192			if !p.rDeadline.IsZero() {
   193				d := time.Until(p.rDeadline)
   194				if d <= 0 {
   195					return 0, syscall.EAGAIN
   196				}
   197				time.AfterFunc(d, p.rCond.Broadcast)
   198			}
   199			if len(p.buf) > 0 {
   200				break
   201			}
   202			p.rCond.Wait()
   203		}
   204	
   205		n := copy(b, p.buf)
   206		p.buf = p.buf[n:]
   207		p.wCond.Broadcast()
   208		return n, nil
   209	}
   210	
   211	func (p *bufferedPipe) Write(b []byte) (int, error) {
   212		p.mu.Lock()
   213		defer p.mu.Unlock()
   214	
   215		for {
   216			if p.closed {
   217				return 0, syscall.ENOTCONN
   218			}
   219			if !p.wDeadline.IsZero() {
   220				d := time.Until(p.wDeadline)
   221				if d <= 0 {
   222					return 0, syscall.EAGAIN
   223				}
   224				time.AfterFunc(d, p.wCond.Broadcast)
   225			}
   226			if len(p.buf) <= p.softLimit {
   227				break
   228			}
   229			p.wCond.Wait()
   230		}
   231	
   232		p.buf = append(p.buf, b...)
   233		p.rCond.Broadcast()
   234		return len(b), nil
   235	}
   236	
   237	func (p *bufferedPipe) Close() {
   238		p.mu.Lock()
   239		defer p.mu.Unlock()
   240	
   241		p.closed = true
   242		p.rCond.Broadcast()
   243		p.wCond.Broadcast()
   244	}
   245	
   246	func (p *bufferedPipe) SetReadDeadline(t time.Time) {
   247		p.mu.Lock()
   248		defer p.mu.Unlock()
   249	
   250		p.rDeadline = t
   251		p.rCond.Broadcast()
   252	}
   253	
   254	func (p *bufferedPipe) SetWriteDeadline(t time.Time) {
   255		p.mu.Lock()
   256		defer p.mu.Unlock()
   257	
   258		p.wDeadline = t
   259		p.wCond.Broadcast()
   260	}
   261	
   262	func sysSocket(family, sotype, proto int) (int, error) {
   263		return 0, syscall.ENOSYS
   264	}
   265	
   266	func (fd *netFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
   267		return 0, nil, syscall.ENOSYS
   268	}
   269	
   270	func (fd *netFD) readMsg(p []byte, oob []byte) (n, oobn, flags int, sa syscall.Sockaddr, err error) {
   271		return 0, 0, 0, nil, syscall.ENOSYS
   272	}
   273	
   274	func (fd *netFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
   275		return 0, syscall.ENOSYS
   276	}
   277	
   278	func (fd *netFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
   279		return 0, 0, syscall.ENOSYS
   280	}
   281	
   282	func (fd *netFD) dup() (f *os.File, err error) {
   283		return nil, syscall.ENOSYS
   284	}
   285	

View as plain text