TestTCPForwardLimits verifies that the limits on the TCP forwarder work in a success case (i.e. when we don't hit the limit).
(t *testing.T)
| 737 | // TestTCPForwardLimits verifies that the limits on the TCP forwarder work in a |
| 738 | // success case (i.e. when we don't hit the limit). |
| 739 | func TestTCPForwardLimits(t *testing.T) { |
| 740 | tstest.AssertNotParallel(t) // calls envknob.Setenv |
| 741 | envknob.Setenv("TS_DEBUG_NETSTACK", "true") |
| 742 | t.Cleanup(func() { envknob.Setenv("TS_DEBUG_NETSTACK", "") }) |
| 743 | |
| 744 | impl := makeNetstack(t, func(impl *Impl) { |
| 745 | impl.ProcessSubnets = true |
| 746 | }) |
| 747 | |
| 748 | dialFn, gotConn := makeHangDialer(t) |
| 749 | impl.forwardDialFunc = dialFn |
| 750 | |
| 751 | prefs := ipn.NewPrefs() |
| 752 | prefs.AdvertiseRoutes = []netip.Prefix{ |
| 753 | // This is the TEST-NET-1 IP block for use in documentation, |
| 754 | // and should never actually be routable. |
| 755 | netip.MustParsePrefix("192.0.2.0/24"), |
| 756 | } |
| 757 | impl.lb.Start(ipn.Options{ |
| 758 | UpdatePrefs: prefs, |
| 759 | }) |
| 760 | impl.atomicIsLocalIPFunc.Store(looksLikeATailscaleSelfAddress) |
| 761 | |
| 762 | // Inject an "outbound" packet that's going to an IP address that times |
| 763 | // out. We need to re-parse from a byte slice so that the internal |
| 764 | // buffer in the packet.Parsed type is filled out. |
| 765 | client := netip.MustParseAddr("100.101.102.103") |
| 766 | destAddr := netip.MustParseAddr("192.0.2.1") |
| 767 | pkt := tcp4syn(t, client, destAddr, 1234, 4567) |
| 768 | var parsed packet.Parsed |
| 769 | parsed.Decode(pkt) |
| 770 | |
| 771 | // When injecting this packet, we want the outcome to be "drop |
| 772 | // silently", which indicates that netstack is processing the |
| 773 | // packet and not delivering it to the host system. |
| 774 | if resp, _ := impl.injectInbound(&parsed, impl.tundev, nil); resp != filter.DropSilently { |
| 775 | t.Errorf("got filter outcome %v, want filter.DropSilently", resp) |
| 776 | } |
| 777 | |
| 778 | ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) |
| 779 | defer cancel() |
| 780 | |
| 781 | // Wait until we have an in-flight outgoing connection. |
| 782 | select { |
| 783 | case <-ctx.Done(): |
| 784 | t.Fatalf("timed out waiting for connection") |
| 785 | case <-gotConn: |
| 786 | t.Logf("got connection in progress") |
| 787 | } |
| 788 | |
| 789 | // Inject another packet, which will be deduplicated and thus not |
| 790 | // increment our counter. |
| 791 | parsed.Decode(pkt) |
| 792 | if resp, _ := impl.injectInbound(&parsed, impl.tundev, nil); resp != filter.DropSilently { |
| 793 | t.Errorf("got filter outcome %v, want filter.DropSilently", resp) |
| 794 | } |
| 795 | |
| 796 | // Verify that we now have a single in-flight address in our map. |
nothing calls this directly
no test coverage detected
searching dependent graphs…