Source file
src/net/unixsock_test.go
1
2
3
4
5
6
7 package net
8
9 import (
10 "bytes"
11 "internal/testenv"
12 "io"
13 "os"
14 "path/filepath"
15 "reflect"
16 "runtime"
17 "syscall"
18 "testing"
19 "time"
20 )
21
22 func TestReadUnixgramWithUnnamedSocket(t *testing.T) {
23 if !testableNetwork("unixgram") {
24 t.Skip("unixgram test")
25 }
26 switch runtime.GOOS {
27 case "js", "wasip1":
28 t.Skipf("skipping: syscall.Socket not implemented on %s", runtime.GOOS)
29 }
30 if runtime.GOOS == "openbsd" {
31 testenv.SkipFlaky(t, 15157)
32 }
33
34 addr := testUnixAddr(t)
35 la, err := ResolveUnixAddr("unixgram", addr)
36 if err != nil {
37 t.Fatal(err)
38 }
39 c, err := ListenUnixgram("unixgram", la)
40 if err != nil {
41 t.Fatal(err)
42 }
43 defer func() {
44 c.Close()
45 os.Remove(addr)
46 }()
47
48 off := make(chan bool)
49 data := [5]byte{1, 2, 3, 4, 5}
50 go func() {
51 defer func() { off <- true }()
52 s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0)
53 if err != nil {
54 t.Error(err)
55 return
56 }
57 defer syscall.Close(s)
58 rsa := &syscall.SockaddrUnix{Name: addr}
59 if err := syscall.Sendto(s, data[:], 0, rsa); err != nil {
60 t.Error(err)
61 return
62 }
63 }()
64
65 <-off
66 b := make([]byte, 64)
67 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
68 n, from, err := c.ReadFrom(b)
69 if err != nil {
70 t.Fatal(err)
71 }
72 if from != nil {
73 t.Fatalf("unexpected peer address: %v", from)
74 }
75 if !bytes.Equal(b[:n], data[:]) {
76 t.Fatalf("got %v; want %v", b[:n], data[:])
77 }
78 }
79
80 func TestUnixgramZeroBytePayload(t *testing.T) {
81 if !testableNetwork("unixgram") {
82 t.Skip("unixgram test")
83 }
84
85 c1 := newLocalPacketListener(t, "unixgram")
86 defer os.Remove(c1.LocalAddr().String())
87 defer c1.Close()
88
89 c2, err := Dial("unixgram", c1.LocalAddr().String())
90 if err != nil {
91 t.Fatal(err)
92 }
93 defer os.Remove(c2.LocalAddr().String())
94 defer c2.Close()
95
96 for _, genericRead := range []bool{false, true} {
97 n, err := c2.Write(nil)
98 if err != nil {
99 t.Fatal(err)
100 }
101 if n != 0 {
102 t.Errorf("got %d; want 0", n)
103 }
104 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
105 var b [1]byte
106 var peer Addr
107 if genericRead {
108 _, err = c1.(Conn).Read(b[:])
109 } else {
110 _, peer, err = c1.ReadFrom(b[:])
111 }
112 switch err {
113 case nil:
114 if peer != nil {
115 t.Fatalf("unexpected peer address: %v", peer)
116 }
117 default:
118 if !isDeadlineExceeded(err) {
119 t.Fatal(err)
120 }
121 }
122 }
123 }
124
125 func TestUnixgramZeroByteBuffer(t *testing.T) {
126 if !testableNetwork("unixgram") {
127 t.Skip("unixgram test")
128 }
129
130
131
132 c1 := newLocalPacketListener(t, "unixgram")
133 defer os.Remove(c1.LocalAddr().String())
134 defer c1.Close()
135
136 c2, err := Dial("unixgram", c1.LocalAddr().String())
137 if err != nil {
138 t.Fatal(err)
139 }
140 defer os.Remove(c2.LocalAddr().String())
141 defer c2.Close()
142
143 b := []byte("UNIXGRAM ZERO BYTE BUFFER TEST")
144 for _, genericRead := range []bool{false, true} {
145 n, err := c2.Write(b)
146 if err != nil {
147 t.Fatal(err)
148 }
149 if n != len(b) {
150 t.Errorf("got %d; want %d", n, len(b))
151 }
152 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
153 var peer Addr
154 if genericRead {
155 _, err = c1.(Conn).Read(nil)
156 } else {
157 _, peer, err = c1.ReadFrom(nil)
158 }
159 switch err {
160 case nil:
161 if peer != nil {
162 t.Fatalf("unexpected peer address: %v", peer)
163 }
164 default:
165 if !isDeadlineExceeded(err) {
166 t.Fatal(err)
167 }
168 }
169 }
170 }
171
172 func TestUnixgramWrite(t *testing.T) {
173 if !testableNetwork("unixgram") {
174 t.Skip("unixgram test")
175 }
176
177 addr := testUnixAddr(t)
178 laddr, err := ResolveUnixAddr("unixgram", addr)
179 if err != nil {
180 t.Fatal(err)
181 }
182 c, err := ListenPacket("unixgram", addr)
183 if err != nil {
184 t.Fatal(err)
185 }
186 defer os.Remove(addr)
187 defer c.Close()
188
189 testUnixgramWriteConn(t, laddr)
190 testUnixgramWritePacketConn(t, laddr)
191 }
192
193 func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) {
194 c, err := Dial("unixgram", raddr.String())
195 if err != nil {
196 t.Fatal(err)
197 }
198 defer c.Close()
199
200 b := []byte("CONNECTED-MODE SOCKET")
201 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil {
202 t.Fatal("should fail")
203 } else if err.(*OpError).Err != ErrWriteToConnected {
204 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
205 }
206 if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil {
207 t.Fatal("should fail")
208 } else if err.(*OpError).Err != ErrWriteToConnected {
209 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
210 }
211 if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil {
212 t.Fatal("should fail")
213 } else if err.(*OpError).Err != ErrWriteToConnected {
214 t.Fatalf("should fail as ErrWriteToConnected: %v", err)
215 }
216 if _, err := c.Write(b); err != nil {
217 t.Fatal(err)
218 }
219 }
220
221 func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) {
222 addr := testUnixAddr(t)
223 c, err := ListenPacket("unixgram", addr)
224 if err != nil {
225 t.Fatal(err)
226 }
227 defer os.Remove(addr)
228 defer c.Close()
229
230 b := []byte("UNCONNECTED-MODE SOCKET")
231 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil {
232 t.Fatal(err)
233 }
234 if _, err := c.WriteTo(b, raddr); err != nil {
235 t.Fatal(err)
236 }
237 if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil {
238 t.Fatal(err)
239 }
240 if _, err := c.(*UnixConn).Write(b); err == nil {
241 t.Fatal("should fail")
242 }
243 }
244
245 func TestUnixConnLocalAndRemoteNames(t *testing.T) {
246 if !testableNetwork("unix") {
247 t.Skip("unix test")
248 }
249
250 handler := func(ls *localServer, ln Listener) {}
251 for _, laddr := range []string{"", testUnixAddr(t)} {
252 taddr := testUnixAddr(t)
253 ta, err := ResolveUnixAddr("unix", taddr)
254 if err != nil {
255 t.Fatal(err)
256 }
257 ln, err := ListenUnix("unix", ta)
258 if err != nil {
259 t.Fatal(err)
260 }
261 ls := (&streamListener{Listener: ln}).newLocalServer()
262 defer ls.teardown()
263 if err := ls.buildup(handler); err != nil {
264 t.Fatal(err)
265 }
266
267 la, err := ResolveUnixAddr("unix", laddr)
268 if err != nil {
269 t.Fatal(err)
270 }
271 c, err := DialUnix("unix", la, ta)
272 if err != nil {
273 t.Fatal(err)
274 }
275 defer func() {
276 c.Close()
277 if la != nil {
278 defer os.Remove(laddr)
279 }
280 }()
281 if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil {
282 t.Fatal(err)
283 }
284
285 switch runtime.GOOS {
286 case "android", "linux", "windows":
287 if laddr == "" {
288 laddr = "@"
289 }
290 }
291 var connAddrs = [3]struct{ got, want Addr }{
292 {ln.Addr(), ta},
293 {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}},
294 {c.RemoteAddr(), ta},
295 }
296 for _, ca := range connAddrs {
297 if !reflect.DeepEqual(ca.got, ca.want) {
298 t.Fatalf("got %#v, expected %#v", ca.got, ca.want)
299 }
300 }
301 }
302 }
303
304 func TestUnixgramConnLocalAndRemoteNames(t *testing.T) {
305 if !testableNetwork("unixgram") {
306 t.Skip("unixgram test")
307 }
308
309 for _, laddr := range []string{"", testUnixAddr(t)} {
310 taddr := testUnixAddr(t)
311 ta, err := ResolveUnixAddr("unixgram", taddr)
312 if err != nil {
313 t.Fatal(err)
314 }
315 c1, err := ListenUnixgram("unixgram", ta)
316 if err != nil {
317 t.Fatal(err)
318 }
319 defer func() {
320 c1.Close()
321 os.Remove(taddr)
322 }()
323
324 var la *UnixAddr
325 if laddr != "" {
326 if la, err = ResolveUnixAddr("unixgram", laddr); err != nil {
327 t.Fatal(err)
328 }
329 }
330 c2, err := DialUnix("unixgram", la, ta)
331 if err != nil {
332 t.Fatal(err)
333 }
334 defer func() {
335 c2.Close()
336 if la != nil {
337 defer os.Remove(laddr)
338 }
339 }()
340
341 switch runtime.GOOS {
342 case "android", "linux":
343 if laddr == "" {
344 laddr = "@"
345 }
346 }
347
348 var connAddrs = [4]struct{ got, want Addr }{
349 {c1.LocalAddr(), ta},
350 {c1.RemoteAddr(), nil},
351 {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}},
352 {c2.RemoteAddr(), ta},
353 }
354 for _, ca := range connAddrs {
355 if !reflect.DeepEqual(ca.got, ca.want) {
356 t.Fatalf("got %#v; want %#v", ca.got, ca.want)
357 }
358 }
359 }
360 }
361
362 func TestUnixUnlink(t *testing.T) {
363 if !testableNetwork("unix") {
364 t.Skip("unix test")
365 }
366 switch runtime.GOOS {
367 case "js", "wasip1":
368 t.Skipf("skipping: %s does not support Unlink", runtime.GOOS)
369 }
370
371 name := testUnixAddr(t)
372
373 listen := func(t *testing.T) *UnixListener {
374 l, err := Listen("unix", name)
375 if err != nil {
376 t.Fatal(err)
377 }
378 return l.(*UnixListener)
379 }
380 fileListener := func(t *testing.T, l *UnixListener) (*os.File, Listener) {
381 f, err := l.File()
382 if err != nil {
383 t.Fatal(err)
384 }
385 ln, err := FileListener(f)
386 if err != nil {
387 t.Fatal(err)
388 }
389 return f, ln
390 }
391 checkExists := func(t *testing.T, desc string) {
392 if _, err := os.Stat(name); err != nil {
393 t.Fatalf("unix socket does not exist %s: %v", desc, err)
394 }
395 }
396 checkNotExists := func(t *testing.T, desc string) {
397 if _, err := os.Stat(name); err == nil {
398 t.Fatalf("unix socket does exist %s: %v", desc, err)
399 }
400 }
401
402
403 t.Run("Listen", func(t *testing.T) {
404 l := listen(t)
405 checkExists(t, "after Listen")
406 l.Close()
407 checkNotExists(t, "after Listener close")
408 })
409
410
411 t.Run("FileListener", func(t *testing.T) {
412 l := listen(t)
413 f, l1 := fileListener(t, l)
414 checkExists(t, "after FileListener")
415 f.Close()
416 checkExists(t, "after File close")
417 l1.Close()
418 checkExists(t, "after FileListener close")
419 l.Close()
420 checkNotExists(t, "after Listener close")
421 })
422
423
424 t.Run("SecondClose", func(t *testing.T) {
425 l := listen(t)
426 checkExists(t, "after Listen")
427 l.Close()
428 checkNotExists(t, "after Listener close")
429 if err := os.WriteFile(name, []byte("hello world"), 0666); err != nil {
430 t.Fatalf("cannot recreate socket file: %v", err)
431 }
432 checkExists(t, "after writing temp file")
433 l.Close()
434 checkExists(t, "after second Listener close")
435 os.Remove(name)
436 })
437
438
439
440 t.Run("Listen/SetUnlinkOnClose(true)", func(t *testing.T) {
441 l := listen(t)
442 checkExists(t, "after Listen")
443 l.SetUnlinkOnClose(true)
444 l.Close()
445 checkNotExists(t, "after Listener close")
446 })
447
448 t.Run("Listen/SetUnlinkOnClose(false)", func(t *testing.T) {
449 l := listen(t)
450 checkExists(t, "after Listen")
451 l.SetUnlinkOnClose(false)
452 l.Close()
453 checkExists(t, "after Listener close")
454 os.Remove(name)
455 })
456
457 t.Run("FileListener/SetUnlinkOnClose(true)", func(t *testing.T) {
458 l := listen(t)
459 f, l1 := fileListener(t, l)
460 checkExists(t, "after FileListener")
461 l1.(*UnixListener).SetUnlinkOnClose(true)
462 f.Close()
463 checkExists(t, "after File close")
464 l1.Close()
465 checkNotExists(t, "after FileListener close")
466 l.Close()
467 })
468
469 t.Run("FileListener/SetUnlinkOnClose(false)", func(t *testing.T) {
470 l := listen(t)
471 f, l1 := fileListener(t, l)
472 checkExists(t, "after FileListener")
473 l1.(*UnixListener).SetUnlinkOnClose(false)
474 f.Close()
475 checkExists(t, "after File close")
476 l1.Close()
477 checkExists(t, "after FileListener close")
478 l.Close()
479 })
480 }
481
482
483
484 func TestUnixConnReadEOF(t *testing.T) {
485 if runtime.GOOS == "windows" {
486 t.Skip("unix sockets not reliable on windows")
487 }
488 if !testableNetwork("unix") {
489 t.Skip("unix test")
490 }
491 dir := t.TempDir()
492 addr := &UnixAddr{
493 Name: filepath.Join(dir, "sock"),
494 Net: "unix",
495 }
496
497 listen := func(t *testing.T) *UnixListener {
498 ln, err := ListenUnix("unix", addr)
499 if err != nil {
500 t.Fatal(err)
501 }
502 return ln
503 }
504
505 startServer := func(t *testing.T, ln *UnixListener) {
506 go func() {
507 srv, err := ln.AcceptUnix()
508 if err != nil {
509 t.Error(err)
510 return
511 }
512 srv.Close()
513 }()
514 }
515
516 dial := func(t *testing.T) *UnixConn {
517 cl, err := DialUnix("unix", nil, addr)
518 if err != nil {
519 t.Fatal(err)
520 }
521 return cl
522 }
523
524
525 t.Run("ReadMsgUnix", func(t *testing.T) {
526 ln := listen(t)
527 defer ln.Close()
528
529 startServer(t, ln)
530
531 cl := dial(t)
532 defer cl.Close()
533
534 _, _, _, _, err := cl.ReadMsgUnix(make([]byte, 1), nil)
535 if err != io.EOF {
536 t.Fatalf("ReadMsgUnix returned %v, want io.EOF", err)
537 }
538 })
539
540
541 t.Run("ReadFromUnix", func(t *testing.T) {
542 ln := listen(t)
543 defer ln.Close()
544
545 startServer(t, ln)
546
547 cl := dial(t)
548 defer cl.Close()
549
550 buf := make([]byte, 1)
551 _, _, err := cl.ReadFromUnix(buf)
552 if err != io.EOF {
553 t.Fatalf("ReadFromUnix returned %v, want io.EOF", err)
554 }
555 })
556
557
558 t.Run("ReadFrom", func(t *testing.T) {
559 ln := listen(t)
560 defer ln.Close()
561
562 startServer(t, ln)
563
564 cl := dial(t)
565 defer cl.Close()
566
567 buf := make([]byte, 1)
568 _, _, err := cl.ReadFrom(buf)
569 if err != io.EOF {
570 t.Fatalf("ReadFrom returned %v, want io.EOF", err)
571 }
572 })
573 }
574
View as plain text