1 // Copyright 2009 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 !js 6 7 package net 8 9 import ( 10 "errors" 11 "fmt" 12 "internal/testenv" 13 "io" 14 "net/internal/socktest" 15 "os" 16 "runtime" 17 "testing" 18 "time" 19 ) 20 21 func TestCloseRead(t *testing.T) { 22 switch runtime.GOOS { 23 case "plan9": 24 t.Skipf("not supported on %s", runtime.GOOS) 25 } 26 27 for _, network := range []string{"tcp", "unix", "unixpacket"} { 28 if !testableNetwork(network) { 29 t.Logf("skipping %s test", network) 30 continue 31 } 32 33 ln, err := newLocalListener(network) 34 if err != nil { 35 t.Fatal(err) 36 } 37 switch network { 38 case "unix", "unixpacket": 39 defer os.Remove(ln.Addr().String()) 40 } 41 defer ln.Close() 42 43 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 44 if err != nil { 45 t.Fatal(err) 46 } 47 switch network { 48 case "unix", "unixpacket": 49 defer os.Remove(c.LocalAddr().String()) 50 } 51 defer c.Close() 52 53 switch c := c.(type) { 54 case *TCPConn: 55 err = c.CloseRead() 56 case *UnixConn: 57 err = c.CloseRead() 58 } 59 if err != nil { 60 if perr := parseCloseError(err, true); perr != nil { 61 t.Error(perr) 62 } 63 t.Fatal(err) 64 } 65 var b [1]byte 66 n, err := c.Read(b[:]) 67 if n != 0 || err == nil { 68 t.Fatalf("got (%d, %v); want (0, error)", n, err) 69 } 70 } 71 } 72 73 func TestCloseWrite(t *testing.T) { 74 switch runtime.GOOS { 75 case "nacl", "plan9": 76 t.Skipf("not supported on %s", runtime.GOOS) 77 } 78 79 handler := func(ls *localServer, ln Listener) { 80 c, err := ln.Accept() 81 if err != nil { 82 t.Error(err) 83 return 84 } 85 defer c.Close() 86 87 var b [1]byte 88 n, err := c.Read(b[:]) 89 if n != 0 || err != io.EOF { 90 t.Errorf("got (%d, %v); want (0, io.EOF)", n, err) 91 return 92 } 93 switch c := c.(type) { 94 case *TCPConn: 95 err = c.CloseWrite() 96 case *UnixConn: 97 err = c.CloseWrite() 98 } 99 if err != nil { 100 if perr := parseCloseError(err, true); perr != nil { 101 t.Error(perr) 102 } 103 t.Error(err) 104 return 105 } 106 n, err = c.Write(b[:]) 107 if err == nil { 108 t.Errorf("got (%d, %v); want (any, error)", n, err) 109 return 110 } 111 } 112 113 for _, network := range []string{"tcp", "unix", "unixpacket"} { 114 if !testableNetwork(network) { 115 t.Logf("skipping %s test", network) 116 continue 117 } 118 119 ls, err := newLocalServer(network) 120 if err != nil { 121 t.Fatal(err) 122 } 123 defer ls.teardown() 124 if err := ls.buildup(handler); err != nil { 125 t.Fatal(err) 126 } 127 128 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 129 if err != nil { 130 t.Fatal(err) 131 } 132 switch network { 133 case "unix", "unixpacket": 134 defer os.Remove(c.LocalAddr().String()) 135 } 136 defer c.Close() 137 138 switch c := c.(type) { 139 case *TCPConn: 140 err = c.CloseWrite() 141 case *UnixConn: 142 err = c.CloseWrite() 143 } 144 if err != nil { 145 if perr := parseCloseError(err, true); perr != nil { 146 t.Error(perr) 147 } 148 t.Fatal(err) 149 } 150 var b [1]byte 151 n, err := c.Read(b[:]) 152 if n != 0 || err != io.EOF { 153 t.Fatalf("got (%d, %v); want (0, io.EOF)", n, err) 154 } 155 n, err = c.Write(b[:]) 156 if err == nil { 157 t.Fatalf("got (%d, %v); want (any, error)", n, err) 158 } 159 } 160 } 161 162 func TestConnClose(t *testing.T) { 163 for _, network := range []string{"tcp", "unix", "unixpacket"} { 164 if !testableNetwork(network) { 165 t.Logf("skipping %s test", network) 166 continue 167 } 168 169 ln, err := newLocalListener(network) 170 if err != nil { 171 t.Fatal(err) 172 } 173 switch network { 174 case "unix", "unixpacket": 175 defer os.Remove(ln.Addr().String()) 176 } 177 defer ln.Close() 178 179 c, err := Dial(ln.Addr().Network(), ln.Addr().String()) 180 if err != nil { 181 t.Fatal(err) 182 } 183 switch network { 184 case "unix", "unixpacket": 185 defer os.Remove(c.LocalAddr().String()) 186 } 187 defer c.Close() 188 189 if err := c.Close(); err != nil { 190 if perr := parseCloseError(err, false); perr != nil { 191 t.Error(perr) 192 } 193 t.Fatal(err) 194 } 195 var b [1]byte 196 n, err := c.Read(b[:]) 197 if n != 0 || err == nil { 198 t.Fatalf("got (%d, %v); want (0, error)", n, err) 199 } 200 } 201 } 202 203 func TestListenerClose(t *testing.T) { 204 for _, network := range []string{"tcp", "unix", "unixpacket"} { 205 if !testableNetwork(network) { 206 t.Logf("skipping %s test", network) 207 continue 208 } 209 210 ln, err := newLocalListener(network) 211 if err != nil { 212 t.Fatal(err) 213 } 214 switch network { 215 case "unix", "unixpacket": 216 defer os.Remove(ln.Addr().String()) 217 } 218 219 dst := ln.Addr().String() 220 if err := ln.Close(); err != nil { 221 if perr := parseCloseError(err, false); perr != nil { 222 t.Error(perr) 223 } 224 t.Fatal(err) 225 } 226 c, err := ln.Accept() 227 if err == nil { 228 c.Close() 229 t.Fatal("should fail") 230 } 231 232 if network == "tcp" { 233 // We will have two TCP FSMs inside the 234 // kernel here. There's no guarantee that a 235 // signal comes from the far end FSM will be 236 // delivered immediately to the near end FSM, 237 // especially on the platforms that allow 238 // multiple consumer threads to pull pending 239 // established connections at the same time by 240 // enabling SO_REUSEPORT option such as Linux, 241 // DragonFly BSD. So we need to give some time 242 // quantum to the kernel. 243 // 244 // Note that net.inet.tcp.reuseport_ext=1 by 245 // default on DragonFly BSD. 246 time.Sleep(time.Millisecond) 247 248 cc, err := Dial("tcp", dst) 249 if err == nil { 250 t.Error("Dial to closed TCP listener succeeded.") 251 cc.Close() 252 } 253 } 254 } 255 } 256 257 func TestPacketConnClose(t *testing.T) { 258 for _, network := range []string{"udp", "unixgram"} { 259 if !testableNetwork(network) { 260 t.Logf("skipping %s test", network) 261 continue 262 } 263 264 c, err := newLocalPacketListener(network) 265 if err != nil { 266 t.Fatal(err) 267 } 268 switch network { 269 case "unixgram": 270 defer os.Remove(c.LocalAddr().String()) 271 } 272 defer c.Close() 273 274 if err := c.Close(); err != nil { 275 if perr := parseCloseError(err, false); perr != nil { 276 t.Error(perr) 277 } 278 t.Fatal(err) 279 } 280 var b [1]byte 281 n, _, err := c.ReadFrom(b[:]) 282 if n != 0 || err == nil { 283 t.Fatalf("got (%d, %v); want (0, error)", n, err) 284 } 285 } 286 } 287 288 // nacl was previous failing to reuse an address. 289 func TestListenCloseListen(t *testing.T) { 290 const maxTries = 10 291 for tries := 0; tries < maxTries; tries++ { 292 ln, err := newLocalListener("tcp") 293 if err != nil { 294 t.Fatal(err) 295 } 296 addr := ln.Addr().String() 297 if err := ln.Close(); err != nil { 298 if perr := parseCloseError(err, false); perr != nil { 299 t.Error(perr) 300 } 301 t.Fatal(err) 302 } 303 ln, err = Listen("tcp", addr) 304 if err == nil { 305 // Success. nacl couldn't do this before. 306 ln.Close() 307 return 308 } 309 t.Errorf("failed on try %d/%d: %v", tries+1, maxTries, err) 310 } 311 t.Fatalf("failed to listen/close/listen on same address after %d tries", maxTries) 312 } 313 314 // See golang.org/issue/6163, golang.org/issue/6987. 315 func TestAcceptIgnoreAbortedConnRequest(t *testing.T) { 316 switch runtime.GOOS { 317 case "plan9": 318 t.Skipf("%s does not have full support of socktest", runtime.GOOS) 319 } 320 321 syserr := make(chan error) 322 go func() { 323 defer close(syserr) 324 for _, err := range abortedConnRequestErrors { 325 syserr <- err 326 } 327 }() 328 sw.Set(socktest.FilterAccept, func(so *socktest.Status) (socktest.AfterFilter, error) { 329 if err, ok := <-syserr; ok { 330 return nil, err 331 } 332 return nil, nil 333 }) 334 defer sw.Set(socktest.FilterAccept, nil) 335 336 operr := make(chan error, 1) 337 handler := func(ls *localServer, ln Listener) { 338 defer close(operr) 339 c, err := ln.Accept() 340 if err != nil { 341 if perr := parseAcceptError(err); perr != nil { 342 operr <- perr 343 } 344 operr <- err 345 return 346 } 347 c.Close() 348 } 349 ls, err := newLocalServer("tcp") 350 if err != nil { 351 t.Fatal(err) 352 } 353 defer ls.teardown() 354 if err := ls.buildup(handler); err != nil { 355 t.Fatal(err) 356 } 357 358 c, err := Dial(ls.Listener.Addr().Network(), ls.Listener.Addr().String()) 359 if err != nil { 360 t.Fatal(err) 361 } 362 c.Close() 363 364 for err := range operr { 365 t.Error(err) 366 } 367 } 368 369 func TestZeroByteRead(t *testing.T) { 370 for _, network := range []string{"tcp", "unix", "unixpacket"} { 371 if !testableNetwork(network) { 372 t.Logf("skipping %s test", network) 373 continue 374 } 375 376 ln, err := newLocalListener(network) 377 if err != nil { 378 t.Fatal(err) 379 } 380 connc := make(chan Conn, 1) 381 go func() { 382 defer ln.Close() 383 c, err := ln.Accept() 384 if err != nil { 385 t.Error(err) 386 } 387 connc <- c // might be nil 388 }() 389 c, err := Dial(network, ln.Addr().String()) 390 if err != nil { 391 t.Fatal(err) 392 } 393 defer c.Close() 394 sc := <-connc 395 if sc == nil { 396 continue 397 } 398 defer sc.Close() 399 400 if runtime.GOOS == "windows" { 401 // A zero byte read on Windows caused a wait for readability first. 402 // Rather than change that behavior, satisfy it in this test. 403 // See Issue 15735. 404 go io.WriteString(sc, "a") 405 } 406 407 n, err := c.Read(nil) 408 if n != 0 || err != nil { 409 t.Errorf("%s: zero byte client read = %v, %v; want 0, nil", network, n, err) 410 } 411 412 if runtime.GOOS == "windows" { 413 // Same as comment above. 414 go io.WriteString(c, "a") 415 } 416 n, err = sc.Read(nil) 417 if n != 0 || err != nil { 418 t.Errorf("%s: zero byte server read = %v, %v; want 0, nil", network, n, err) 419 } 420 } 421 } 422 423 // withTCPConnPair sets up a TCP connection between two peers, then 424 // runs peer1 and peer2 concurrently. withTCPConnPair returns when 425 // both have completed. 426 func withTCPConnPair(t *testing.T, peer1, peer2 func(c *TCPConn) error) { 427 ln, err := newLocalListener("tcp") 428 if err != nil { 429 t.Fatal(err) 430 } 431 defer ln.Close() 432 errc := make(chan error, 2) 433 go func() { 434 c1, err := ln.Accept() 435 if err != nil { 436 errc <- err 437 return 438 } 439 defer c1.Close() 440 errc <- peer1(c1.(*TCPConn)) 441 }() 442 go func() { 443 c2, err := Dial("tcp", ln.Addr().String()) 444 if err != nil { 445 errc <- err 446 return 447 } 448 defer c2.Close() 449 errc <- peer2(c2.(*TCPConn)) 450 }() 451 for i := 0; i < 2; i++ { 452 if err := <-errc; err != nil { 453 t.Fatal(err) 454 } 455 } 456 } 457 458 // Tests that a blocked Read is interrupted by a concurrent SetReadDeadline 459 // modifying that Conn's read deadline to the past. 460 // See golang.org/cl/30164 which documented this. The net/http package 461 // depends on this. 462 func TestReadTimeoutUnblocksRead(t *testing.T) { 463 serverDone := make(chan struct{}) 464 server := func(cs *TCPConn) error { 465 defer close(serverDone) 466 errc := make(chan error, 1) 467 go func() { 468 defer close(errc) 469 go func() { 470 // TODO: find a better way to wait 471 // until we're blocked in the cs.Read 472 // call below. Sleep is lame. 473 time.Sleep(100 * time.Millisecond) 474 475 // Interrupt the upcoming Read, unblocking it: 476 cs.SetReadDeadline(time.Unix(123, 0)) // time in the past 477 }() 478 var buf [1]byte 479 n, err := cs.Read(buf[:1]) 480 if n != 0 || err == nil { 481 errc <- fmt.Errorf("Read = %v, %v; want 0, non-nil", n, err) 482 } 483 }() 484 select { 485 case err := <-errc: 486 return err 487 case <-time.After(5 * time.Second): 488 buf := make([]byte, 2<<20) 489 buf = buf[:runtime.Stack(buf, true)] 490 println("Stacks at timeout:\n", string(buf)) 491 return errors.New("timeout waiting for Read to finish") 492 } 493 494 } 495 // Do nothing in the client. Never write. Just wait for the 496 // server's half to be done. 497 client := func(*TCPConn) error { 498 <-serverDone 499 return nil 500 } 501 withTCPConnPair(t, client, server) 502 } 503 504 // Issue 17695: verify that a blocked Read is woken up by a Close. 505 func TestCloseUnblocksRead(t *testing.T) { 506 t.Parallel() 507 server := func(cs *TCPConn) error { 508 // Give the client time to get stuck in a Read: 509 time.Sleep(20 * time.Millisecond) 510 cs.Close() 511 return nil 512 } 513 client := func(ss *TCPConn) error { 514 n, err := ss.Read([]byte{0}) 515 if n != 0 || err != io.EOF { 516 return fmt.Errorf("Read = %v, %v; want 0, EOF", n, err) 517 } 518 return nil 519 } 520 withTCPConnPair(t, client, server) 521 } 522 523 // Issue 24808: verify that ECONNRESET is not temporary for read. 524 func TestNotTemporaryRead(t *testing.T) { 525 if runtime.GOOS == "freebsd" { 526 testenv.SkipFlaky(t, 25289) 527 } 528 if runtime.GOOS == "aix" { 529 testenv.SkipFlaky(t, 29685) 530 } 531 t.Parallel() 532 server := func(cs *TCPConn) error { 533 cs.SetLinger(0) 534 // Give the client time to get stuck in a Read. 535 time.Sleep(50 * time.Millisecond) 536 cs.Close() 537 return nil 538 } 539 client := func(ss *TCPConn) error { 540 _, err := ss.Read([]byte{0}) 541 if err == nil { 542 return errors.New("Read succeeded unexpectedly") 543 } else if err == io.EOF { 544 // This happens on NaCl and Plan 9. 545 return nil 546 } else if ne, ok := err.(Error); !ok { 547 return fmt.Errorf("unexpected error %v", err) 548 } else if ne.Temporary() { 549 return fmt.Errorf("unexpected temporary error %v", err) 550 } 551 return nil 552 } 553 withTCPConnPair(t, client, server) 554 } 555
View as plain text