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 and wasip1/wasm. It is intended to allow tests of other package to pass.
     6  
     7  //go:build (js && wasm) || wasip1
     8  
     9  package net
    10  
    11  import (
    12  	"context"
    13  	"io"
    14  	"os"
    15  	"sync"
    16  	"syscall"
    17  	"time"
    18  )
    19  
    20  var listenersMu sync.Mutex
    21  var listeners = make(map[fakeNetAddr]*netFD)
    22  
    23  var portCounterMu sync.Mutex
    24  var portCounter = 0
    25  
    26  func nextPort() int {
    27  	portCounterMu.Lock()
    28  	defer portCounterMu.Unlock()
    29  	portCounter++
    30  	return portCounter
    31  }
    32  
    33  type fakeNetAddr struct {
    34  	network string
    35  	address string
    36  }
    37  
    38  type fakeNetFD struct {
    39  	listener fakeNetAddr
    40  	r        *bufferedPipe
    41  	w        *bufferedPipe
    42  	incoming chan *netFD
    43  	closedMu sync.Mutex
    44  	closed   bool
    45  }
    46  
    47  // socket returns a network file descriptor that is ready for
    48  // asynchronous I/O using the network poller.
    49  func socket(ctx context.Context, net string, family, sotype, proto int, ipv6only bool, laddr, raddr sockaddr, ctrlCtxFn func(context.Context, string, string, syscall.RawConn) error) (*netFD, error) {
    50  	fd := &netFD{family: family, sotype: sotype, net: net}
    51  	if laddr != nil && raddr == nil {
    52  		return fakelistener(fd, laddr)
    53  	}
    54  	fd2 := &netFD{family: family, sotype: sotype, net: net}
    55  	return fakeconn(fd, fd2, laddr, raddr)
    56  }
    57  
    58  func fakeIPAndPort(ip IP, port int) (IP, int) {
    59  	if ip == nil {
    60  		ip = IPv4(127, 0, 0, 1)
    61  	}
    62  	if port == 0 {
    63  		port = nextPort()
    64  	}
    65  	return ip, port
    66  }
    67  
    68  func fakeTCPAddr(addr *TCPAddr) *TCPAddr {
    69  	var ip IP
    70  	var port int
    71  	var zone string
    72  	if addr != nil {
    73  		ip, port, zone = addr.IP, addr.Port, addr.Zone
    74  	}
    75  	ip, port = fakeIPAndPort(ip, port)
    76  	return &TCPAddr{IP: ip, Port: port, Zone: zone}
    77  }
    78  
    79  func fakeUDPAddr(addr *UDPAddr) *UDPAddr {
    80  	var ip IP
    81  	var port int
    82  	var zone string
    83  	if addr != nil {
    84  		ip, port, zone = addr.IP, addr.Port, addr.Zone
    85  	}
    86  	ip, port = fakeIPAndPort(ip, port)
    87  	return &UDPAddr{IP: ip, Port: port, Zone: zone}
    88  }
    89  
    90  func fakeUnixAddr(sotype int, addr *UnixAddr) *UnixAddr {
    91  	var net, name string
    92  	if addr != nil {
    93  		name = addr.Name
    94  	}
    95  	switch sotype {
    96  	case syscall.SOCK_DGRAM:
    97  		net = "unixgram"
    98  	case syscall.SOCK_SEQPACKET:
    99  		net = "unixpacket"
   100  	default:
   101  		net = "unix"
   102  	}
   103  	return &UnixAddr{Net: net, Name: name}
   104  }
   105  
   106  func fakelistener(fd *netFD, laddr sockaddr) (*netFD, error) {
   107  	switch l := laddr.(type) {
   108  	case *TCPAddr:
   109  		laddr = fakeTCPAddr(l)
   110  	case *UDPAddr:
   111  		laddr = fakeUDPAddr(l)
   112  	case *UnixAddr:
   113  		if l.Name == "" {
   114  			return nil, syscall.ENOENT
   115  		}
   116  		laddr = fakeUnixAddr(fd.sotype, l)
   117  	default:
   118  		return nil, syscall.EOPNOTSUPP
   119  	}
   120  
   121  	listener := fakeNetAddr{
   122  		network: laddr.Network(),
   123  		address: laddr.String(),
   124  	}
   125  
   126  	fd.fakeNetFD = &fakeNetFD{
   127  		listener: listener,
   128  		incoming: make(chan *netFD, 1024),
   129  	}
   130  
   131  	fd.laddr = laddr
   132  	listenersMu.Lock()
   133  	defer listenersMu.Unlock()
   134  	if _, exists := listeners[listener]; exists {
   135  		return nil, syscall.EADDRINUSE
   136  	}
   137  	listeners[listener] = fd
   138  	return fd, nil
   139  }
   140  
   141  func fakeconn(fd *netFD, fd2 *netFD, laddr, raddr sockaddr) (*netFD, error) {
   142  	switch r := raddr.(type) {
   143  	case *TCPAddr:
   144  		r = fakeTCPAddr(r)
   145  		raddr = r
   146  		laddr = fakeTCPAddr(laddr.(*TCPAddr))
   147  	case *UDPAddr:
   148  		r = fakeUDPAddr(r)
   149  		raddr = r
   150  		laddr = fakeUDPAddr(laddr.(*UDPAddr))
   151  	case *UnixAddr:
   152  		r = fakeUnixAddr(fd.sotype, r)
   153  		raddr = r
   154  		laddr = &UnixAddr{Net: r.Net, Name: r.Name}
   155  	default:
   156  		return nil, syscall.EAFNOSUPPORT
   157  	}
   158  	fd.laddr = laddr
   159  	fd.raddr = raddr
   160  
   161  	fd.fakeNetFD = &fakeNetFD{
   162  		r: newBufferedPipe(65536),
   163  		w: newBufferedPipe(65536),
   164  	}
   165  	fd2.fakeNetFD = &fakeNetFD{
   166  		r: fd.fakeNetFD.w,
   167  		w: fd.fakeNetFD.r,
   168  	}
   169  
   170  	fd2.laddr = fd.raddr
   171  	fd2.raddr = fd.laddr
   172  
   173  	listener := fakeNetAddr{
   174  		network: fd.raddr.Network(),
   175  		address: fd.raddr.String(),
   176  	}
   177  	listenersMu.Lock()
   178  	defer listenersMu.Unlock()
   179  	l, ok := listeners[listener]
   180  	if !ok {
   181  		return nil, syscall.ECONNREFUSED
   182  	}
   183  	l.incoming <- fd2
   184  	return fd, nil
   185  }
   186  
   187  func (fd *fakeNetFD) Read(p []byte) (n int, err error) {
   188  	return fd.r.Read(p)
   189  }
   190  
   191  func (fd *fakeNetFD) Write(p []byte) (nn int, err error) {
   192  	return fd.w.Write(p)
   193  }
   194  
   195  func (fd *fakeNetFD) Close() error {
   196  	fd.closedMu.Lock()
   197  	if fd.closed {
   198  		fd.closedMu.Unlock()
   199  		return nil
   200  	}
   201  	fd.closed = true
   202  	fd.closedMu.Unlock()
   203  
   204  	if fd.listener != (fakeNetAddr{}) {
   205  		listenersMu.Lock()
   206  		delete(listeners, fd.listener)
   207  		close(fd.incoming)
   208  		fd.listener = fakeNetAddr{}
   209  		listenersMu.Unlock()
   210  		return nil
   211  	}
   212  
   213  	fd.r.Close()
   214  	fd.w.Close()
   215  	return nil
   216  }
   217  
   218  func (fd *fakeNetFD) closeRead() error {
   219  	fd.r.Close()
   220  	return nil
   221  }
   222  
   223  func (fd *fakeNetFD) closeWrite() error {
   224  	fd.w.Close()
   225  	return nil
   226  }
   227  
   228  func (fd *fakeNetFD) accept() (*netFD, error) {
   229  	c, ok := <-fd.incoming
   230  	if !ok {
   231  		return nil, syscall.EINVAL
   232  	}
   233  	return c, nil
   234  }
   235  
   236  func (fd *fakeNetFD) SetDeadline(t time.Time) error {
   237  	fd.r.SetReadDeadline(t)
   238  	fd.w.SetWriteDeadline(t)
   239  	return nil
   240  }
   241  
   242  func (fd *fakeNetFD) SetReadDeadline(t time.Time) error {
   243  	fd.r.SetReadDeadline(t)
   244  	return nil
   245  }
   246  
   247  func (fd *fakeNetFD) SetWriteDeadline(t time.Time) error {
   248  	fd.w.SetWriteDeadline(t)
   249  	return nil
   250  }
   251  
   252  func newBufferedPipe(softLimit int) *bufferedPipe {
   253  	p := &bufferedPipe{softLimit: softLimit}
   254  	p.rCond.L = &p.mu
   255  	p.wCond.L = &p.mu
   256  	return p
   257  }
   258  
   259  type bufferedPipe struct {
   260  	softLimit int
   261  	mu        sync.Mutex
   262  	buf       []byte
   263  	closed    bool
   264  	rCond     sync.Cond
   265  	wCond     sync.Cond
   266  	rDeadline time.Time
   267  	wDeadline time.Time
   268  }
   269  
   270  func (p *bufferedPipe) Read(b []byte) (int, error) {
   271  	p.mu.Lock()
   272  	defer p.mu.Unlock()
   273  
   274  	for {
   275  		if p.closed && len(p.buf) == 0 {
   276  			return 0, io.EOF
   277  		}
   278  		if !p.rDeadline.IsZero() {
   279  			d := time.Until(p.rDeadline)
   280  			if d <= 0 {
   281  				return 0, os.ErrDeadlineExceeded
   282  			}
   283  			time.AfterFunc(d, p.rCond.Broadcast)
   284  		}
   285  		if len(p.buf) > 0 {
   286  			break
   287  		}
   288  		p.rCond.Wait()
   289  	}
   290  
   291  	n := copy(b, p.buf)
   292  	p.buf = p.buf[n:]
   293  	p.wCond.Broadcast()
   294  	return n, nil
   295  }
   296  
   297  func (p *bufferedPipe) Write(b []byte) (int, error) {
   298  	p.mu.Lock()
   299  	defer p.mu.Unlock()
   300  
   301  	for {
   302  		if p.closed {
   303  			return 0, syscall.ENOTCONN
   304  		}
   305  		if !p.wDeadline.IsZero() {
   306  			d := time.Until(p.wDeadline)
   307  			if d <= 0 {
   308  				return 0, os.ErrDeadlineExceeded
   309  			}
   310  			time.AfterFunc(d, p.wCond.Broadcast)
   311  		}
   312  		if len(p.buf) <= p.softLimit {
   313  			break
   314  		}
   315  		p.wCond.Wait()
   316  	}
   317  
   318  	p.buf = append(p.buf, b...)
   319  	p.rCond.Broadcast()
   320  	return len(b), nil
   321  }
   322  
   323  func (p *bufferedPipe) Close() {
   324  	p.mu.Lock()
   325  	defer p.mu.Unlock()
   326  
   327  	p.closed = true
   328  	p.rCond.Broadcast()
   329  	p.wCond.Broadcast()
   330  }
   331  
   332  func (p *bufferedPipe) SetReadDeadline(t time.Time) {
   333  	p.mu.Lock()
   334  	defer p.mu.Unlock()
   335  
   336  	p.rDeadline = t
   337  	p.rCond.Broadcast()
   338  }
   339  
   340  func (p *bufferedPipe) SetWriteDeadline(t time.Time) {
   341  	p.mu.Lock()
   342  	defer p.mu.Unlock()
   343  
   344  	p.wDeadline = t
   345  	p.wCond.Broadcast()
   346  }
   347  
   348  func sysSocket(family, sotype, proto int) (int, error) {
   349  	return 0, syscall.ENOSYS
   350  }
   351  
   352  func (fd *fakeNetFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (syscall.Sockaddr, error) {
   353  	return nil, syscall.ENOSYS
   354  }
   355  
   356  func (fd *fakeNetFD) readFrom(p []byte) (n int, sa syscall.Sockaddr, err error) {
   357  	return 0, nil, syscall.ENOSYS
   358  
   359  }
   360  func (fd *fakeNetFD) readFromInet4(p []byte, sa *syscall.SockaddrInet4) (n int, err error) {
   361  	return 0, syscall.ENOSYS
   362  }
   363  
   364  func (fd *fakeNetFD) readFromInet6(p []byte, sa *syscall.SockaddrInet6) (n int, err error) {
   365  	return 0, syscall.ENOSYS
   366  }
   367  
   368  func (fd *fakeNetFD) readMsg(p []byte, oob []byte, flags int) (n, oobn, retflags int, sa syscall.Sockaddr, err error) {
   369  	return 0, 0, 0, nil, syscall.ENOSYS
   370  }
   371  
   372  func (fd *fakeNetFD) readMsgInet4(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet4) (n, oobn, retflags int, err error) {
   373  	return 0, 0, 0, syscall.ENOSYS
   374  }
   375  
   376  func (fd *fakeNetFD) readMsgInet6(p []byte, oob []byte, flags int, sa *syscall.SockaddrInet6) (n, oobn, retflags int, err error) {
   377  	return 0, 0, 0, syscall.ENOSYS
   378  }
   379  
   380  func (fd *fakeNetFD) writeMsgInet4(p []byte, oob []byte, sa *syscall.SockaddrInet4) (n int, oobn int, err error) {
   381  	return 0, 0, syscall.ENOSYS
   382  }
   383  
   384  func (fd *fakeNetFD) writeMsgInet6(p []byte, oob []byte, sa *syscall.SockaddrInet6) (n int, oobn int, err error) {
   385  	return 0, 0, syscall.ENOSYS
   386  }
   387  
   388  func (fd *fakeNetFD) writeTo(p []byte, sa syscall.Sockaddr) (n int, err error) {
   389  	return 0, syscall.ENOSYS
   390  }
   391  
   392  func (fd *fakeNetFD) writeToInet4(p []byte, sa *syscall.SockaddrInet4) (n int, err error) {
   393  	return 0, syscall.ENOSYS
   394  }
   395  
   396  func (fd *fakeNetFD) writeToInet6(p []byte, sa *syscall.SockaddrInet6) (n int, err error) {
   397  	return 0, syscall.ENOSYS
   398  }
   399  
   400  func (fd *fakeNetFD) writeMsg(p []byte, oob []byte, sa syscall.Sockaddr) (n int, oobn int, err error) {
   401  	return 0, 0, syscall.ENOSYS
   402  }
   403  
   404  func (fd *fakeNetFD) dup() (f *os.File, err error) {
   405  	return nil, syscall.ENOSYS
   406  }
   407  

View as plain text