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