github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/tcpip/transport/tcp/dual_stack_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tcp_test 16 17 import ( 18 "strings" 19 "testing" 20 "time" 21 22 "github.com/google/go-cmp/cmp" 23 "github.com/SagerNet/gvisor/pkg/tcpip" 24 "github.com/SagerNet/gvisor/pkg/tcpip/checker" 25 "github.com/SagerNet/gvisor/pkg/tcpip/header" 26 "github.com/SagerNet/gvisor/pkg/tcpip/network/ipv4" 27 "github.com/SagerNet/gvisor/pkg/tcpip/seqnum" 28 "github.com/SagerNet/gvisor/pkg/tcpip/transport/tcp" 29 "github.com/SagerNet/gvisor/pkg/tcpip/transport/tcp/testing/context" 30 "github.com/SagerNet/gvisor/pkg/waiter" 31 ) 32 33 func TestV4MappedConnectOnV6Only(t *testing.T) { 34 c := context.New(t, defaultMTU) 35 defer c.Cleanup() 36 37 c.CreateV6Endpoint(true) 38 39 // Start connection attempt, it must fail. 40 err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV4MappedAddr, Port: context.TestPort}) 41 if d := cmp.Diff(&tcpip.ErrNoRoute{}, err); d != "" { 42 t.Fatalf("c.EP.Connect(...) mismatch (-want +got):\n%s", d) 43 } 44 } 45 46 func testV4Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) { 47 // Start connection attempt. 48 we, ch := waiter.NewChannelEntry(nil) 49 c.WQ.EventRegister(&we, waiter.WritableEvents) 50 defer c.WQ.EventUnregister(&we) 51 52 err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV4MappedAddr, Port: context.TestPort}) 53 if d := cmp.Diff(&tcpip.ErrConnectStarted{}, err); d != "" { 54 t.Fatalf("c.EP.Connect(...) mismatch (-want +got):\n%s", d) 55 } 56 57 // Receive SYN packet. 58 b := c.GetPacket() 59 synCheckers := append(checkers, checker.TCP( 60 checker.DstPort(context.TestPort), 61 checker.TCPFlags(header.TCPFlagSyn), 62 )) 63 checker.IPv4(t, b, synCheckers...) 64 65 tcp := header.TCP(header.IPv4(b).Payload()) 66 c.IRS = seqnum.Value(tcp.SequenceNumber()) 67 68 iss := seqnum.Value(789) 69 c.SendPacket(nil, &context.Headers{ 70 SrcPort: tcp.DestinationPort(), 71 DstPort: tcp.SourcePort(), 72 Flags: header.TCPFlagSyn | header.TCPFlagAck, 73 SeqNum: iss, 74 AckNum: c.IRS.Add(1), 75 RcvWnd: 30000, 76 }) 77 78 // Receive ACK packet. 79 ackCheckers := append(checkers, checker.TCP( 80 checker.DstPort(context.TestPort), 81 checker.TCPFlags(header.TCPFlagAck), 82 checker.TCPSeqNum(uint32(c.IRS)+1), 83 checker.TCPAckNum(uint32(iss)+1), 84 )) 85 checker.IPv4(t, c.GetPacket(), ackCheckers...) 86 87 // Wait for connection to be established. 88 select { 89 case <-ch: 90 if err := c.EP.LastError(); err != nil { 91 t.Fatalf("Unexpected error when connecting: %v", err) 92 } 93 case <-time.After(1 * time.Second): 94 t.Fatalf("Timed out waiting for connection") 95 } 96 } 97 98 func TestV4MappedConnect(t *testing.T) { 99 c := context.New(t, defaultMTU) 100 defer c.Cleanup() 101 102 c.CreateV6Endpoint(false) 103 104 // Test the connection request. 105 testV4Connect(t, c) 106 } 107 108 func TestV4ConnectWhenBoundToWildcard(t *testing.T) { 109 c := context.New(t, defaultMTU) 110 defer c.Cleanup() 111 112 c.CreateV6Endpoint(false) 113 114 // Bind to wildcard. 115 if err := c.EP.Bind(tcpip.FullAddress{}); err != nil { 116 t.Fatalf("Bind failed: %v", err) 117 } 118 119 // Test the connection request. 120 testV4Connect(t, c) 121 } 122 123 func TestV4ConnectWhenBoundToV4MappedWildcard(t *testing.T) { 124 c := context.New(t, defaultMTU) 125 defer c.Cleanup() 126 127 c.CreateV6Endpoint(false) 128 129 // Bind to v4 mapped wildcard. 130 if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr}); err != nil { 131 t.Fatalf("Bind failed: %v", err) 132 } 133 134 // Test the connection request. 135 testV4Connect(t, c) 136 } 137 138 func TestV4ConnectWhenBoundToV4Mapped(t *testing.T) { 139 c := context.New(t, defaultMTU) 140 defer c.Cleanup() 141 142 c.CreateV6Endpoint(false) 143 144 // Bind to v4 mapped address. 145 if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr}); err != nil { 146 t.Fatalf("Bind failed: %v", err) 147 } 148 149 // Test the connection request. 150 testV4Connect(t, c) 151 } 152 153 func testV6Connect(t *testing.T, c *context.Context, checkers ...checker.NetworkChecker) { 154 // Start connection attempt to IPv6 address. 155 we, ch := waiter.NewChannelEntry(nil) 156 c.WQ.EventRegister(&we, waiter.WritableEvents) 157 defer c.WQ.EventUnregister(&we) 158 159 err := c.EP.Connect(tcpip.FullAddress{Addr: context.TestV6Addr, Port: context.TestPort}) 160 if d := cmp.Diff(&tcpip.ErrConnectStarted{}, err); d != "" { 161 t.Fatalf("Connect(...) mismatch (-want +got):\n%s", d) 162 } 163 164 // Receive SYN packet. 165 b := c.GetV6Packet() 166 synCheckers := append(checkers, checker.TCP( 167 checker.DstPort(context.TestPort), 168 checker.TCPFlags(header.TCPFlagSyn), 169 )) 170 checker.IPv6(t, b, synCheckers...) 171 172 tcp := header.TCP(header.IPv6(b).Payload()) 173 c.IRS = seqnum.Value(tcp.SequenceNumber()) 174 175 iss := seqnum.Value(789) 176 c.SendV6Packet(nil, &context.Headers{ 177 SrcPort: tcp.DestinationPort(), 178 DstPort: tcp.SourcePort(), 179 Flags: header.TCPFlagSyn | header.TCPFlagAck, 180 SeqNum: iss, 181 AckNum: c.IRS.Add(1), 182 RcvWnd: 30000, 183 }) 184 185 // Receive ACK packet. 186 ackCheckers := append(checkers, checker.TCP( 187 checker.DstPort(context.TestPort), 188 checker.TCPFlags(header.TCPFlagAck), 189 checker.TCPSeqNum(uint32(c.IRS)+1), 190 checker.TCPAckNum(uint32(iss)+1), 191 )) 192 checker.IPv6(t, c.GetV6Packet(), ackCheckers...) 193 194 // Wait for connection to be established. 195 select { 196 case <-ch: 197 if err := c.EP.LastError(); err != nil { 198 t.Fatalf("Unexpected error when connecting: %v", err) 199 } 200 case <-time.After(1 * time.Second): 201 t.Fatalf("Timed out waiting for connection") 202 } 203 } 204 205 func TestV6Connect(t *testing.T) { 206 c := context.New(t, defaultMTU) 207 defer c.Cleanup() 208 209 c.CreateV6Endpoint(false) 210 211 // Test the connection request. 212 testV6Connect(t, c) 213 } 214 215 func TestV6ConnectV6Only(t *testing.T) { 216 c := context.New(t, defaultMTU) 217 defer c.Cleanup() 218 219 c.CreateV6Endpoint(true) 220 221 // Test the connection request. 222 testV6Connect(t, c) 223 } 224 225 func TestV6ConnectWhenBoundToWildcard(t *testing.T) { 226 c := context.New(t, defaultMTU) 227 defer c.Cleanup() 228 229 c.CreateV6Endpoint(false) 230 231 // Bind to wildcard. 232 if err := c.EP.Bind(tcpip.FullAddress{}); err != nil { 233 t.Fatalf("Bind failed: %v", err) 234 } 235 236 // Test the connection request. 237 testV6Connect(t, c) 238 } 239 240 func TestStackV6OnlyConnectWhenBoundToWildcard(t *testing.T) { 241 c := context.NewWithOpts(t, context.Options{ 242 EnableV6: true, 243 MTU: defaultMTU, 244 }) 245 defer c.Cleanup() 246 247 // Create a v6 endpoint but don't set the v6-only TCP option. 248 c.CreateV6Endpoint(false) 249 250 // Bind to wildcard. 251 if err := c.EP.Bind(tcpip.FullAddress{}); err != nil { 252 t.Fatalf("Bind failed: %v", err) 253 } 254 255 // Test the connection request. 256 testV6Connect(t, c) 257 } 258 259 func TestV6ConnectWhenBoundToLocalAddress(t *testing.T) { 260 c := context.New(t, defaultMTU) 261 defer c.Cleanup() 262 263 c.CreateV6Endpoint(false) 264 265 // Bind to local address. 266 if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV6Addr}); err != nil { 267 t.Fatalf("Bind failed: %v", err) 268 } 269 270 // Test the connection request. 271 testV6Connect(t, c) 272 } 273 274 func TestV4RefuseOnV6Only(t *testing.T) { 275 c := context.New(t, defaultMTU) 276 defer c.Cleanup() 277 278 c.CreateV6Endpoint(true) 279 280 // Bind to wildcard. 281 if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { 282 t.Fatalf("Bind failed: %v", err) 283 } 284 285 // Start listening. 286 if err := c.EP.Listen(10); err != nil { 287 t.Fatalf("Listen failed: %v", err) 288 } 289 290 // Send a SYN request. 291 irs := seqnum.Value(789) 292 c.SendPacket(nil, &context.Headers{ 293 SrcPort: context.TestPort, 294 DstPort: context.StackPort, 295 Flags: header.TCPFlagSyn, 296 SeqNum: irs, 297 RcvWnd: 30000, 298 }) 299 300 // Receive the RST reply. 301 checker.IPv4(t, c.GetPacket(), 302 checker.TCP( 303 checker.SrcPort(context.StackPort), 304 checker.DstPort(context.TestPort), 305 checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck), 306 checker.TCPAckNum(uint32(irs)+1), 307 ), 308 ) 309 } 310 311 func TestV6RefuseOnBoundToV4Mapped(t *testing.T) { 312 c := context.New(t, defaultMTU) 313 defer c.Cleanup() 314 315 c.CreateV6Endpoint(false) 316 317 // Bind and listen. 318 if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil { 319 t.Fatalf("Bind failed: %v", err) 320 } 321 322 if err := c.EP.Listen(10); err != nil { 323 t.Fatalf("Listen failed: %v", err) 324 } 325 326 // Send a SYN request. 327 irs := seqnum.Value(789) 328 c.SendV6Packet(nil, &context.Headers{ 329 SrcPort: context.TestPort, 330 DstPort: context.StackPort, 331 Flags: header.TCPFlagSyn, 332 SeqNum: irs, 333 RcvWnd: 30000, 334 }) 335 336 // Receive the RST reply. 337 checker.IPv6(t, c.GetV6Packet(), 338 checker.TCP( 339 checker.SrcPort(context.StackPort), 340 checker.DstPort(context.TestPort), 341 checker.TCPFlags(header.TCPFlagRst|header.TCPFlagAck), 342 checker.TCPAckNum(uint32(irs)+1), 343 ), 344 ) 345 } 346 347 func testV4Accept(t *testing.T, c *context.Context) { 348 c.SetGSOEnabled(true) 349 defer c.SetGSOEnabled(false) 350 351 // Start listening. 352 if err := c.EP.Listen(10); err != nil { 353 t.Fatalf("Listen failed: %v", err) 354 } 355 356 // Send a SYN request. 357 irs := seqnum.Value(789) 358 c.SendPacket(nil, &context.Headers{ 359 SrcPort: context.TestPort, 360 DstPort: context.StackPort, 361 Flags: header.TCPFlagSyn, 362 SeqNum: irs, 363 RcvWnd: 30000, 364 }) 365 366 // Receive the SYN-ACK reply. 367 b := c.GetPacket() 368 tcp := header.TCP(header.IPv4(b).Payload()) 369 iss := seqnum.Value(tcp.SequenceNumber()) 370 checker.IPv4(t, b, 371 checker.TCP( 372 checker.SrcPort(context.StackPort), 373 checker.DstPort(context.TestPort), 374 checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn), 375 checker.TCPAckNum(uint32(irs)+1), 376 ), 377 ) 378 379 // Send ACK. 380 c.SendPacket(nil, &context.Headers{ 381 SrcPort: context.TestPort, 382 DstPort: context.StackPort, 383 Flags: header.TCPFlagAck, 384 SeqNum: irs + 1, 385 AckNum: iss + 1, 386 RcvWnd: 30000, 387 }) 388 389 // Try to accept the connection. 390 we, ch := waiter.NewChannelEntry(nil) 391 c.WQ.EventRegister(&we, waiter.ReadableEvents) 392 defer c.WQ.EventUnregister(&we) 393 394 nep, _, err := c.EP.Accept(nil) 395 if cmp.Equal(&tcpip.ErrWouldBlock{}, err) { 396 // Wait for connection to be established. 397 select { 398 case <-ch: 399 nep, _, err = c.EP.Accept(nil) 400 if err != nil { 401 t.Fatalf("Accept failed: %v", err) 402 } 403 404 case <-time.After(1 * time.Second): 405 t.Fatalf("Timed out waiting for accept") 406 } 407 } 408 409 // Check the peer address. 410 addr, err := nep.GetRemoteAddress() 411 if err != nil { 412 t.Fatalf("GetRemoteAddress failed failed: %v", err) 413 } 414 415 if addr.Addr != context.TestAddr { 416 t.Fatalf("Unexpected remote address: got %v, want %v", addr.Addr, context.TestAddr) 417 } 418 419 var r strings.Reader 420 data := "Don't panic" 421 r.Reset(data) 422 nep.Write(&r, tcpip.WriteOptions{}) 423 b = c.GetPacket() 424 tcp = header.IPv4(b).Payload() 425 if string(tcp.Payload()) != data { 426 t.Fatalf("Unexpected data: got %v, want %v", string(tcp.Payload()), data) 427 } 428 } 429 430 func TestV4AcceptOnV6(t *testing.T) { 431 c := context.New(t, defaultMTU) 432 defer c.Cleanup() 433 434 c.CreateV6Endpoint(false) 435 436 // Bind to wildcard. 437 if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { 438 t.Fatalf("Bind failed: %v", err) 439 } 440 441 // Test acceptance. 442 testV4Accept(t, c) 443 } 444 445 func TestV4AcceptOnBoundToV4MappedWildcard(t *testing.T) { 446 c := context.New(t, defaultMTU) 447 defer c.Cleanup() 448 449 c.CreateV6Endpoint(false) 450 451 // Bind to v4 mapped wildcard. 452 if err := c.EP.Bind(tcpip.FullAddress{Addr: context.V4MappedWildcardAddr, Port: context.StackPort}); err != nil { 453 t.Fatalf("Bind failed: %v", err) 454 } 455 456 // Test acceptance. 457 testV4Accept(t, c) 458 } 459 460 func TestV4AcceptOnBoundToV4Mapped(t *testing.T) { 461 c := context.New(t, defaultMTU) 462 defer c.Cleanup() 463 464 c.CreateV6Endpoint(false) 465 466 // Bind and listen. 467 if err := c.EP.Bind(tcpip.FullAddress{Addr: context.StackV4MappedAddr, Port: context.StackPort}); err != nil { 468 t.Fatalf("Bind failed: %v", err) 469 } 470 471 // Test acceptance. 472 testV4Accept(t, c) 473 } 474 475 func TestV6AcceptOnV6(t *testing.T) { 476 c := context.New(t, defaultMTU) 477 defer c.Cleanup() 478 479 c.CreateV6Endpoint(false) 480 481 // Bind and listen. 482 if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { 483 t.Fatalf("Bind failed: %v", err) 484 } 485 486 if err := c.EP.Listen(10); err != nil { 487 t.Fatalf("Listen failed: %v", err) 488 } 489 490 // Send a SYN request. 491 irs := seqnum.Value(789) 492 c.SendV6Packet(nil, &context.Headers{ 493 SrcPort: context.TestPort, 494 DstPort: context.StackPort, 495 Flags: header.TCPFlagSyn, 496 SeqNum: irs, 497 RcvWnd: 30000, 498 }) 499 500 // Receive the SYN-ACK reply. 501 b := c.GetV6Packet() 502 tcp := header.TCP(header.IPv6(b).Payload()) 503 iss := seqnum.Value(tcp.SequenceNumber()) 504 checker.IPv6(t, b, 505 checker.TCP( 506 checker.SrcPort(context.StackPort), 507 checker.DstPort(context.TestPort), 508 checker.TCPFlags(header.TCPFlagAck|header.TCPFlagSyn), 509 checker.TCPAckNum(uint32(irs)+1), 510 ), 511 ) 512 513 // Send ACK. 514 c.SendV6Packet(nil, &context.Headers{ 515 SrcPort: context.TestPort, 516 DstPort: context.StackPort, 517 Flags: header.TCPFlagAck, 518 SeqNum: irs + 1, 519 AckNum: iss + 1, 520 RcvWnd: 30000, 521 }) 522 523 // Try to accept the connection. 524 we, ch := waiter.NewChannelEntry(nil) 525 c.WQ.EventRegister(&we, waiter.ReadableEvents) 526 defer c.WQ.EventUnregister(&we) 527 var addr tcpip.FullAddress 528 _, _, err := c.EP.Accept(&addr) 529 if cmp.Equal(&tcpip.ErrWouldBlock{}, err) { 530 // Wait for connection to be established. 531 select { 532 case <-ch: 533 _, _, err = c.EP.Accept(&addr) 534 if err != nil { 535 t.Fatalf("Accept failed: %v", err) 536 } 537 538 case <-time.After(1 * time.Second): 539 t.Fatalf("Timed out waiting for accept") 540 } 541 } 542 543 if addr.Addr != context.TestV6Addr { 544 t.Errorf("Unexpected remote address: got %s, want %s", addr.Addr, context.TestV6Addr) 545 } 546 } 547 548 func TestV4AcceptOnV4(t *testing.T) { 549 c := context.New(t, defaultMTU) 550 defer c.Cleanup() 551 552 // Create TCP endpoint. 553 var err tcpip.Error 554 c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ) 555 if err != nil { 556 t.Fatalf("NewEndpoint failed: %v", err) 557 } 558 559 // Bind to wildcard. 560 if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { 561 t.Fatalf("Bind failed: %v", err) 562 } 563 564 // Test acceptance. 565 testV4Accept(t, c) 566 } 567 568 func testV4ListenClose(t *testing.T, c *context.Context) { 569 opt := tcpip.TCPAlwaysUseSynCookies(true) 570 if err := c.Stack().SetTransportProtocolOption(tcp.ProtocolNumber, &opt); err != nil { 571 t.Fatalf("SetTransportProtocolOption(%d, &%T(%t)): %s", tcp.ProtocolNumber, opt, opt, err) 572 } 573 574 const n = 32 575 576 // Start listening. 577 if err := c.EP.Listen(n); err != nil { 578 t.Fatalf("Listen failed: %v", err) 579 } 580 581 irs := seqnum.Value(789) 582 for i := uint16(0); i < n; i++ { 583 // Send a SYN request. 584 c.SendPacket(nil, &context.Headers{ 585 SrcPort: context.TestPort + i, 586 DstPort: context.StackPort, 587 Flags: header.TCPFlagSyn, 588 SeqNum: irs, 589 RcvWnd: 30000, 590 }) 591 } 592 593 // Each of these ACKs will cause a syn-cookie based connection to be 594 // accepted and delivered to the listening endpoint. 595 for i := 0; i < n; i++ { 596 b := c.GetPacket() 597 tcp := header.TCP(header.IPv4(b).Payload()) 598 iss := seqnum.Value(tcp.SequenceNumber()) 599 // Send ACK. 600 c.SendPacket(nil, &context.Headers{ 601 SrcPort: tcp.DestinationPort(), 602 DstPort: context.StackPort, 603 Flags: header.TCPFlagAck, 604 SeqNum: irs + 1, 605 AckNum: iss + 1, 606 RcvWnd: 30000, 607 }) 608 } 609 610 // Try to accept the connection. 611 we, ch := waiter.NewChannelEntry(nil) 612 c.WQ.EventRegister(&we, waiter.ReadableEvents) 613 defer c.WQ.EventUnregister(&we) 614 nep, _, err := c.EP.Accept(nil) 615 if cmp.Equal(&tcpip.ErrWouldBlock{}, err) { 616 // Wait for connection to be established. 617 select { 618 case <-ch: 619 nep, _, err = c.EP.Accept(nil) 620 if err != nil { 621 t.Fatalf("Accept failed: %v", err) 622 } 623 624 case <-time.After(10 * time.Second): 625 t.Fatalf("Timed out waiting for accept") 626 } 627 } 628 nep.Close() 629 c.EP.Close() 630 } 631 632 func TestV4ListenCloseOnV4(t *testing.T) { 633 c := context.New(t, defaultMTU) 634 defer c.Cleanup() 635 636 // Create TCP endpoint. 637 var err tcpip.Error 638 c.EP, err = c.Stack().NewEndpoint(tcp.ProtocolNumber, ipv4.ProtocolNumber, &c.WQ) 639 if err != nil { 640 t.Fatalf("NewEndpoint failed: %v", err) 641 } 642 643 // Bind to wildcard. 644 if err := c.EP.Bind(tcpip.FullAddress{Port: context.StackPort}); err != nil { 645 t.Fatalf("Bind failed: %v", err) 646 } 647 648 // Test acceptance. 649 testV4ListenClose(t, c) 650 }