github.com/ltltlt/go-source-code@v0.0.0-20190830023027-95be009773aa/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 TestUnixgramWrite(t *testing.T) { 174 if !testableNetwork("unixgram") { 175 t.Skip("unixgram test") 176 } 177 178 addr := testUnixAddr() 179 laddr, err := ResolveUnixAddr("unixgram", addr) 180 if err != nil { 181 t.Fatal(err) 182 } 183 c, err := ListenPacket("unixgram", addr) 184 if err != nil { 185 t.Fatal(err) 186 } 187 defer os.Remove(addr) 188 defer c.Close() 189 190 testUnixgramWriteConn(t, laddr) 191 testUnixgramWritePacketConn(t, laddr) 192 } 193 194 func testUnixgramWriteConn(t *testing.T, raddr *UnixAddr) { 195 c, err := Dial("unixgram", raddr.String()) 196 if err != nil { 197 t.Fatal(err) 198 } 199 defer c.Close() 200 201 b := []byte("CONNECTED-MODE SOCKET") 202 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err == nil { 203 t.Fatal("should fail") 204 } else if err.(*OpError).Err != ErrWriteToConnected { 205 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 206 } 207 if _, err = c.(*UnixConn).WriteTo(b, raddr); err == nil { 208 t.Fatal("should fail") 209 } else if err.(*OpError).Err != ErrWriteToConnected { 210 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 211 } 212 if _, _, err = c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err == nil { 213 t.Fatal("should fail") 214 } else if err.(*OpError).Err != ErrWriteToConnected { 215 t.Fatalf("should fail as ErrWriteToConnected: %v", err) 216 } 217 if _, err := c.Write(b); err != nil { 218 t.Fatal(err) 219 } 220 } 221 222 func testUnixgramWritePacketConn(t *testing.T, raddr *UnixAddr) { 223 addr := testUnixAddr() 224 c, err := ListenPacket("unixgram", addr) 225 if err != nil { 226 t.Fatal(err) 227 } 228 defer os.Remove(addr) 229 defer c.Close() 230 231 b := []byte("UNCONNECTED-MODE SOCKET") 232 if _, err := c.(*UnixConn).WriteToUnix(b, raddr); err != nil { 233 t.Fatal(err) 234 } 235 if _, err := c.WriteTo(b, raddr); err != nil { 236 t.Fatal(err) 237 } 238 if _, _, err := c.(*UnixConn).WriteMsgUnix(b, nil, raddr); err != nil { 239 t.Fatal(err) 240 } 241 if _, err := c.(*UnixConn).Write(b); err == nil { 242 t.Fatal("should fail") 243 } 244 } 245 246 func TestUnixConnLocalAndRemoteNames(t *testing.T) { 247 if !testableNetwork("unix") { 248 t.Skip("unix test") 249 } 250 251 handler := func(ls *localServer, ln Listener) {} 252 for _, laddr := range []string{"", testUnixAddr()} { 253 laddr := laddr 254 taddr := testUnixAddr() 255 ta, err := ResolveUnixAddr("unix", taddr) 256 if err != nil { 257 t.Fatal(err) 258 } 259 ln, err := ListenUnix("unix", ta) 260 if err != nil { 261 t.Fatal(err) 262 } 263 ls, err := (&streamListener{Listener: ln}).newLocalServer() 264 if err != nil { 265 t.Fatal(err) 266 } 267 defer ls.teardown() 268 if err := ls.buildup(handler); err != nil { 269 t.Fatal(err) 270 } 271 272 la, err := ResolveUnixAddr("unix", laddr) 273 if err != nil { 274 t.Fatal(err) 275 } 276 c, err := DialUnix("unix", la, ta) 277 if err != nil { 278 t.Fatal(err) 279 } 280 defer func() { 281 c.Close() 282 if la != nil { 283 defer os.Remove(laddr) 284 } 285 }() 286 if _, err := c.Write([]byte("UNIXCONN LOCAL AND REMOTE NAME TEST")); err != nil { 287 t.Fatal(err) 288 } 289 290 switch runtime.GOOS { 291 case "android", "linux": 292 if laddr == "" { 293 laddr = "@" // autobind feature 294 } 295 } 296 var connAddrs = [3]struct{ got, want Addr }{ 297 {ln.Addr(), ta}, 298 {c.LocalAddr(), &UnixAddr{Name: laddr, Net: "unix"}}, 299 {c.RemoteAddr(), ta}, 300 } 301 for _, ca := range connAddrs { 302 if !reflect.DeepEqual(ca.got, ca.want) { 303 t.Fatalf("got %#v, expected %#v", ca.got, ca.want) 304 } 305 } 306 } 307 } 308 309 func TestUnixgramConnLocalAndRemoteNames(t *testing.T) { 310 if !testableNetwork("unixgram") { 311 t.Skip("unixgram test") 312 } 313 314 for _, laddr := range []string{"", testUnixAddr()} { 315 laddr := laddr 316 taddr := testUnixAddr() 317 ta, err := ResolveUnixAddr("unixgram", taddr) 318 if err != nil { 319 t.Fatal(err) 320 } 321 c1, err := ListenUnixgram("unixgram", ta) 322 if err != nil { 323 t.Fatal(err) 324 } 325 defer func() { 326 c1.Close() 327 os.Remove(taddr) 328 }() 329 330 var la *UnixAddr 331 if laddr != "" { 332 if la, err = ResolveUnixAddr("unixgram", laddr); err != nil { 333 t.Fatal(err) 334 } 335 } 336 c2, err := DialUnix("unixgram", la, ta) 337 if err != nil { 338 t.Fatal(err) 339 } 340 defer func() { 341 c2.Close() 342 if la != nil { 343 defer os.Remove(laddr) 344 } 345 }() 346 347 switch runtime.GOOS { 348 case "android", "linux": 349 if laddr == "" { 350 laddr = "@" // autobind feature 351 } 352 } 353 354 var connAddrs = [4]struct{ got, want Addr }{ 355 {c1.LocalAddr(), ta}, 356 {c1.RemoteAddr(), nil}, 357 {c2.LocalAddr(), &UnixAddr{Name: laddr, Net: "unixgram"}}, 358 {c2.RemoteAddr(), ta}, 359 } 360 for _, ca := range connAddrs { 361 if !reflect.DeepEqual(ca.got, ca.want) { 362 t.Fatalf("got %#v; want %#v", ca.got, ca.want) 363 } 364 } 365 } 366 } 367 368 func TestUnixUnlink(t *testing.T) { 369 if !testableNetwork("unix") { 370 t.Skip("unix test") 371 } 372 name := testUnixAddr() 373 374 listen := func(t *testing.T) *UnixListener { 375 l, err := Listen("unix", name) 376 if err != nil { 377 t.Fatal(err) 378 } 379 return l.(*UnixListener) 380 } 381 checkExists := func(t *testing.T, desc string) { 382 if _, err := os.Stat(name); err != nil { 383 t.Fatalf("unix socket does not exist %s: %v", desc, err) 384 } 385 } 386 checkNotExists := func(t *testing.T, desc string) { 387 if _, err := os.Stat(name); err == nil { 388 t.Fatalf("unix socket does exist %s: %v", desc, err) 389 } 390 } 391 392 // Listener should remove on close. 393 t.Run("Listen", func(t *testing.T) { 394 l := listen(t) 395 checkExists(t, "after Listen") 396 l.Close() 397 checkNotExists(t, "after Listener close") 398 }) 399 400 // FileListener should not. 401 t.Run("FileListener", func(t *testing.T) { 402 l := listen(t) 403 f, _ := l.File() 404 l1, _ := FileListener(f) 405 checkExists(t, "after FileListener") 406 f.Close() 407 checkExists(t, "after File close") 408 l1.Close() 409 checkExists(t, "after FileListener close") 410 l.Close() 411 checkNotExists(t, "after Listener close") 412 }) 413 414 // Only first call to l.Close should remove. 415 t.Run("SecondClose", func(t *testing.T) { 416 l := listen(t) 417 checkExists(t, "after Listen") 418 l.Close() 419 checkNotExists(t, "after Listener close") 420 if err := ioutil.WriteFile(name, []byte("hello world"), 0666); err != nil { 421 t.Fatalf("cannot recreate socket file: %v", err) 422 } 423 checkExists(t, "after writing temp file") 424 l.Close() 425 checkExists(t, "after second Listener close") 426 os.Remove(name) 427 }) 428 429 // SetUnlinkOnClose should do what it says. 430 431 t.Run("Listen/SetUnlinkOnClose(true)", func(t *testing.T) { 432 l := listen(t) 433 checkExists(t, "after Listen") 434 l.SetUnlinkOnClose(true) 435 l.Close() 436 checkNotExists(t, "after Listener close") 437 }) 438 439 t.Run("Listen/SetUnlinkOnClose(false)", func(t *testing.T) { 440 l := listen(t) 441 checkExists(t, "after Listen") 442 l.SetUnlinkOnClose(false) 443 l.Close() 444 checkExists(t, "after Listener close") 445 os.Remove(name) 446 }) 447 448 t.Run("FileListener/SetUnlinkOnClose(true)", func(t *testing.T) { 449 l := listen(t) 450 f, _ := l.File() 451 l1, _ := FileListener(f) 452 checkExists(t, "after FileListener") 453 l1.(*UnixListener).SetUnlinkOnClose(true) 454 f.Close() 455 checkExists(t, "after File close") 456 l1.Close() 457 checkNotExists(t, "after FileListener close") 458 l.Close() 459 }) 460 461 t.Run("FileListener/SetUnlinkOnClose(false)", func(t *testing.T) { 462 l := listen(t) 463 f, _ := l.File() 464 l1, _ := FileListener(f) 465 checkExists(t, "after FileListener") 466 l1.(*UnixListener).SetUnlinkOnClose(false) 467 f.Close() 468 checkExists(t, "after File close") 469 l1.Close() 470 checkExists(t, "after FileListener close") 471 l.Close() 472 }) 473 }