Source file
src/net/net_fake.go
1
2
3
4
5
6
7
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
48
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