github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/net/net_fake.go (about) 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 "github.com/x04/go/src/context" 13 "github.com/x04/go/src/internal/poll" 14 "github.com/x04/go/src/io" 15 "github.com/x04/go/src/os" 16 "github.com/x04/go/src/sync" 17 "github.com/x04/go/src/syscall" 18 "github.com/x04/go/src/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 }