Source file
src/net/net_fake.go
Documentation: net
1
2
3
4
5
6
7
8
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
36 type netFD struct {
37 r *bufferedPipe
38 w *bufferedPipe
39 incoming chan *netFD
40
41 closedMu sync.Mutex
42 closed bool
43
44
45 listener bool
46 family int
47 sotype int
48 net string
49 laddr Addr
50 raddr Addr
51
52
53 pfd poll.FD
54 isConnected bool
55 }
56
57
58
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 {
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 }
286
View as plain text