github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/net/unixsock_test.go (about) 1 // Copyright 2013 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 //go:build !js && !plan9 && !windows 6 7 package net 8 9 import ( 10 "bytes" 11 "internal/testenv" 12 "os" 13 "reflect" 14 "runtime" 15 "syscall" 16 "testing" 17 "time" 18 ) 19 20 func TestReadUnixgramWithUnnamedSocket(t *testing.T) { 21 if !testableNetwork("unixgram") { 22 t.Skip("unixgram test") 23 } 24 if runtime.GOOS == "openbsd" { 25 testenv.SkipFlaky(t, 15157) 26 } 27 28 addr := testUnixAddr(t) 29 la, err := ResolveUnixAddr("unixgram", addr) 30 if err != nil { 31 t.Fatal(err) 32 } 33 c, err := ListenUnixgram("unixgram", la) 34 if err != nil { 35 t.Fatal(err) 36 } 37 defer func() { 38 c.Close() 39 os.Remove(addr) 40 }() 41 42 off := make(chan bool) 43 data := [5]byte{1, 2, 3, 4, 5} 44 go func() { 45 defer func() { off <- true }() 46 s, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_DGRAM, 0) 47 if err != nil { 48 t.Error(err) 49 return 50 } 51 defer syscall.Close(s) 52 rsa := &syscall.SockaddrUnix{Name: addr} 53 if err := syscall.Sendto(s, data[:], 0, rsa); err != nil { 54 t.Error(err) 55 return 56 } 57 }() 58 59 <-off 60 b := make([]byte, 64) 61 c.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 62 n, from, err := c.ReadFrom(b) 63 if err != nil { 64 t.Fatal(err) 65 } 66 if from != nil { 67 t.Fatalf("unexpected peer address: %v", from) 68 } 69 if !bytes.Equal(b[:n], data[:]) { 70 t.Fatalf("got %v; want %v", b[:n], data[:]) 71 } 72 } 73 74 func TestUnixgramZeroBytePayload(t *testing.T) { 75 if !testableNetwork("unixgram") { 76 t.Skip("unixgram test") 77 } 78 79 c1 := newLocalPacketListener(t, "unixgram") 80 defer os.Remove(c1.LocalAddr().String()) 81 defer c1.Close() 82 83 c2, err := Dial("unixgram", c1.LocalAddr().String()) 84 if err != nil { 85 t.Fatal(err) 86 } 87 defer os.Remove(c2.LocalAddr().String()) 88 defer c2.Close() 89 90 for _, genericRead := range []bool{false, true} { 91 n, err := c2.Write(nil) 92 if err != nil { 93 t.Fatal(err) 94 } 95 if n != 0 { 96 t.Errorf("got %d; want 0", n) 97 } 98 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 99 var b [1]byte 100 var peer Addr 101 if genericRead { 102 _, err = c1.(Conn).Read(b[:]) 103 } else { 104 _, peer, err = c1.ReadFrom(b[:]) 105 } 106 switch err { 107 case nil: // ReadFrom succeeds 108 if peer != nil { // peer is connected-mode 109 t.Fatalf("unexpected peer address: %v", peer) 110 } 111 default: // Read may timeout, it depends on the platform 112 if !isDeadlineExceeded(err) { 113 t.Fatal(err) 114 } 115 } 116 } 117 } 118 119 func TestUnixgramZeroByteBuffer(t *testing.T) { 120 if !testableNetwork("unixgram") { 121 t.Skip("unixgram test") 122 } 123 // issue 4352: Recvfrom failed with "address family not 124 // supported by protocol family" if zero-length buffer provided 125 126 c1 := newLocalPacketListener(t, "unixgram") 127 defer os.Remove(c1.LocalAddr().String()) 128 defer c1.Close() 129 130 c2, err := Dial("unixgram", c1.LocalAddr().String()) 131 if err != nil { 132 t.Fatal(err) 133 } 134 defer os.Remove(c2.LocalAddr().String()) 135 defer c2.Close() 136 137 b := []byte("UNIXGRAM ZERO BYTE BUFFER TEST") 138 for _, genericRead := range []bool{false, true} { 139 n, err := c2.Write(b) 140 if err != nil { 141 t.Fatal(err) 142 } 143 if n != len(b) { 144 t.Errorf("got %d; want %d", n, len(b)) 145 } 146 c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond)) 147 var peer Addr 148 if genericRead { 149 _, err = c1.(Conn).Read(nil) 150 } else { 151 _, peer, err = c1.ReadFrom(nil) 152 } 153 switch err { 154 case nil: // ReadFrom succeeds 155 if peer != nil { // peer is connected-mode 156 t.Fatalf("unexpected peer address: %v", peer) 157 } 158 default: // Read may timeout, it depends on the platform 159 if !isDeadlineExceeded(err) { 160 t.Fatal(err) 161 } 162 } 163 } 164 } 165 166 func TestUnixgramWrite(t *testing.T) { 167 if !testableNetwork("unixgram") { 168 t.Skip("unixgram test") 169 } 170 171 addr := testUnixAddr(t) 172 laddr, err := ResolveUnixAddr("unixgram", addr) 173 if err != nil { 174 t.Fatal(err) 175 } 176 c, err := ListenPacket("unixgram", addr) 177 if err != nil { 178 t.Fatal(err) 179 } 180 defer os.Remove(addr) 181 defer c.Close() 182 183 testUnixgramWriteConn(t, laddr) 184 testUnixgramWritePacketConn(t, laddr) 185 } 186 187 func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) { 188 c, err := Dial("unixgram", raddr.String()) 189 if err != nil { 190 t.Fatal(err) 191 } 192 defer c.Close() 193 194 b := []byte("CONNECTED-MODE SOCKET") 195 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil { 196 t.Fatal("should fail") 197 } else if err.(*OpError).Err != ErrWriteToConnected { 198 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 199 } 200 if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil { 201 t.Fatal("should fail") 202 } else if err.(*OpError).Err != ErrWriteToConnected { 203 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 204 } 205 if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil { 206 t.Fatal("should fail") 207 } else if err.(*OpError).Err != ErrWriteToConnected { 208 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 209 } 210 if _, err := c.Write(b); err != nil { 211 t.Fatal(err) 212 } 213 } 214 215 func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) { 216 addr := testUnixAddr(t) 217 c, err := ListenPacket("unixgram", addr) 218 if err != nil { 219 t.Fatal(err) 220 } 221 defer os.Remove(addr) 222 defer c.Close() 223 224 b := []byte("UNCONNECTED-MODE SOCKET") 225 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil { 226 t.Fatal(err) 227 } 228 if _, err := c.WriteTo(b, raddr); err != nil { 229 t.Fatal(err) 230 } 231 if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil { 232 t.Fatal(err) 233 } 234 if _, err := c.(*UnixConn).Write(b); err == nil { 235 t.Fatal("should fail") 236 } 237 } 238 239 func TestUnixConnLocalAndRemoteNames(t *testing.T) { 240 if !testableNetwork("unix") { 241 t.Skip("unix test") 242 } 243 244 handler := func(ls *localServer, ln Listener) {} 245 for _, laddr := range []string{"", testUnixAddr(t)} { 246 laddr := laddr 247 taddr := testUnixAddr(t) 248 ta, err := ResolveUnixAddr("unix", taddr) 249 if err != nil { 250 t.Fatal(err) 251 } 252 ln, err := ListenUnix("unix", ta) 253 if err != nil { 254 t.Fatal(err) 255 } 256 ls := (&streamListener{Listener: ln}).newLocalServer() 257 defer ls.teardown() 258 if err := ls.buildup(handler); err != nil { 259 t.Fatal(err) 260 } 261 262 la, err := ResolveUnixAddr("unix", laddr) 263 if err != nil { 264 t.Fatal(err) 265 } 266 c, err := DialUnix("unix", la, ta) 267 if err != nil { 268 t.Fatal(err) 269 } 270 defer func() { 271 c.Close() 272 if la != nil { 273 defer os.Remove(laddr) 274 } 275 }() 276 if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil { 277 t.Fatal(err) 278 } 279 280 switch runtime.GOOS { 281 case "android", "linux": 282 if laddr == "" { 283 laddr = "@" // autobind feature 284 } 285 } 286 var connAddrs = [3]struct{ got, want Addr }{ 287 {ln.Addr(), ta}, 288 {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}}, 289 {c.RemoteAddr(), ta}, 290 } 291 for _, ca := range connAddrs { 292 if !reflect.DeepEqual(ca.got, ca.want) { 293 t.Fatalf("got %#v, expected %#v", ca.got, ca.want) 294 } 295 } 296 } 297 } 298 299 func TestUnixgramConnLocalAndRemoteNames(t *testing.T) { 300 if !testableNetwork("unixgram") { 301 t.Skip("unixgram test") 302 } 303 304 for _, laddr := range []string{"", testUnixAddr(t)} { 305 laddr := laddr 306 taddr := testUnixAddr(t) 307 ta, err := ResolveUnixAddr("unixgram", taddr) 308 if err != nil { 309 t.Fatal(err) 310 } 311 c1, err := ListenUnixgram("unixgram", ta) 312 if err != nil { 313 t.Fatal(err) 314 } 315 defer func() { 316 c1.Close() 317 os.Remove(taddr) 318 }() 319 320 var la *UnixAddr 321 if laddr != "" { 322 if la, err = ResolveUnixAddr("unixgram", laddr); err != nil { 323 t.Fatal(err) 324 } 325 } 326 c2, err := DialUnix("unixgram", la, ta) 327 if err != nil { 328 t.Fatal(err) 329 } 330 defer func() { 331 c2.Close() 332 if la != nil { 333 defer os.Remove(laddr) 334 } 335 }() 336 337 switch runtime.GOOS { 338 case "android", "linux": 339 if laddr == "" { 340 laddr = "@" // autobind feature 341 } 342 } 343 344 var connAddrs = [4]struct{ got, want Addr }{ 345 {c1.LocalAddr(), ta}, 346 {c1.RemoteAddr(), nil}, 347 {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}}, 348 {c2.RemoteAddr(), ta}, 349 } 350 for _, ca := range connAddrs { 351 if !reflect.DeepEqual(ca.got, ca.want) { 352 t.Fatalf("got %#v; want %#v", ca.got, ca.want) 353 } 354 } 355 } 356 } 357 358 func TestUnixUnlink(t *testing.T) { 359 if !testableNetwork("unix") { 360 t.Skip("unix test") 361 } 362 name := testUnixAddr(t) 363 364 listen := func(t *testing.T) *UnixListener { 365 l, err := Listen("unix", name) 366 if err != nil { 367 t.Fatal(err) 368 } 369 return l.(*UnixListener) 370 } 371 checkExists := func(t *testing.T, desc string) { 372 if _, err := os.Stat(name); err != nil { 373 t.Fatalf("unix socket does not exist %s: %v", desc, err) 374 } 375 } 376 checkNotExists := func(t *testing.T, desc string) { 377 if _, err := os.Stat(name); err == nil { 378 t.Fatalf("unix socket does exist %s: %v", desc, err) 379 } 380 } 381 382 // Listener should remove on close. 383 t.Run("Listen", func(t *testing.T) { 384 l := listen(t) 385 checkExists(t, "after Listen") 386 l.Close() 387 checkNotExists(t, "after Listener close") 388 }) 389 390 // FileListener should not. 391 t.Run("FileListener", func(t *testing.T) { 392 l := listen(t) 393 f, _ := l.File() 394 l1, _ := FileListener(f) 395 checkExists(t, "after FileListener") 396 f.Close() 397 checkExists(t, "after File close") 398 l1.Close() 399 checkExists(t, "after FileListener close") 400 l.Close() 401 checkNotExists(t, "after Listener close") 402 }) 403 404 // Only first call to l.Close should remove. 405 t.Run("SecondClose", func(t *testing.T) { 406 l := listen(t) 407 checkExists(t, "after Listen") 408 l.Close() 409 checkNotExists(t, "after Listener close") 410 if err := os.WriteFile(name, []byte("hello world"), 0666); err != nil { 411 t.Fatalf("cannot recreate socket file: %v", err) 412 } 413 checkExists(t, "after writing temp file") 414 l.Close() 415 checkExists(t, "after second Listener close") 416 os.Remove(name) 417 }) 418 419 // SetUnlinkOnClose should do what it says. 420 421 t.Run("Listen/SetUnlinkOnClose(true)", func(t *testing.T) { 422 l := listen(t) 423 checkExists(t, "after Listen") 424 l.SetUnlinkOnClose(true) 425 l.Close() 426 checkNotExists(t, "after Listener close") 427 }) 428 429 t.Run("Listen/SetUnlinkOnClose(false)", func(t *testing.T) { 430 l := listen(t) 431 checkExists(t, "after Listen") 432 l.SetUnlinkOnClose(false) 433 l.Close() 434 checkExists(t, "after Listener close") 435 os.Remove(name) 436 }) 437 438 t.Run("FileListener/SetUnlinkOnClose(true)", func(t *testing.T) { 439 l := listen(t) 440 f, _ := l.File() 441 l1, _ := FileListener(f) 442 checkExists(t, "after FileListener") 443 l1.(*UnixListener).SetUnlinkOnClose(true) 444 f.Close() 445 checkExists(t, "after File close") 446 l1.Close() 447 checkNotExists(t, "after FileListener close") 448 l.Close() 449 }) 450 451 t.Run("FileListener/SetUnlinkOnClose(false)", func(t *testing.T) { 452 l := listen(t) 453 f, _ := l.File() 454 l1, _ := FileListener(f) 455 checkExists(t, "after FileListener") 456 l1.(*UnixListener).SetUnlinkOnClose(false) 457 f.Close() 458 checkExists(t, "after File close") 459 l1.Close() 460 checkExists(t, "after FileListener close") 461 l.Close() 462 }) 463 }