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