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