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