From 6a1dad0ce21f075f36942feb5fced8258f7ff124 Mon Sep 17 00:00:00 2001 From: Joel May Date: Thu, 10 Nov 2022 09:09:47 -0800 Subject: [PATCH] ZTC-234: macOS tests --- ingress/icmp_darwin.go | 1 - ingress/icmp_darwin_test.go | 8 +++++ ingress/icmp_linux_test.go | 13 +++++++ ingress/icmp_posix_test.go | 72 +++++++++++++++++++++++++++++++------ 4 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 ingress/icmp_linux_test.go diff --git a/ingress/icmp_darwin.go b/ingress/icmp_darwin.go index dd03e46b..8f95ee89 100644 --- a/ingress/icmp_darwin.go +++ b/ingress/icmp_darwin.go @@ -148,7 +148,6 @@ func (ip *icmpProxy) Request(ctx context.Context, pk *packet.ICMP, responder *pa dstIP: pk.Dst, originalEchoID: originalEcho.ID, } - // TODO: TUN-6744 assign unique flow per (src, echo ID) assignedEchoID, success := ip.echoIDTracker.getOrAssign(echoIDTrackerKey) if !success { err := fmt.Errorf("failed to assign unique echo ID") diff --git a/ingress/icmp_darwin_test.go b/ingress/icmp_darwin_test.go index 90b92710..6cfacb9d 100644 --- a/ingress/icmp_darwin_test.go +++ b/ingress/icmp_darwin_test.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/stretchr/testify/require" + + "github.com/cloudflare/cloudflared/packet" ) func TestSingleEchoIDTracker(t *testing.T) { @@ -119,3 +121,9 @@ func (eit *echoIDTracker) get(key flow3Tuple) (id uint16, exist bool) { id, exists := eit.mapping[key] return id, exists } + +func getFunnel(t *testing.T, proxy *icmpProxy, tuple flow3Tuple) (packet.Funnel, bool) { + assignedEchoID, success := proxy.echoIDTracker.getOrAssign(tuple) + require.True(t, success) + return proxy.srcFunnelTracker.Get(echoFunnelID(assignedEchoID)) +} diff --git a/ingress/icmp_linux_test.go b/ingress/icmp_linux_test.go new file mode 100644 index 00000000..597b5557 --- /dev/null +++ b/ingress/icmp_linux_test.go @@ -0,0 +1,13 @@ +//go:build linux + +package ingress + +import ( + "testing" + + "github.com/cloudflare/cloudflared/packet" +) + +func getFunnel(t *testing.T, proxy *icmpProxy, tuple flow3Tuple) (packet.Funnel, bool) { + return proxy.srcFunnelTracker.Get(tuple) +} diff --git a/ingress/icmp_posix_test.go b/ingress/icmp_posix_test.go index 2e81a65b..79c6c89a 100644 --- a/ingress/icmp_posix_test.go +++ b/ingress/icmp_posix_test.go @@ -52,28 +52,18 @@ func TestFunnelIdleTimeout(t *testing.T) { }, }, } - funnelID := flow3Tuple{ - srcIP: pk.Src, - dstIP: pk.Dst, - originalEchoID: echoID, - } muxer := newMockMuxer(0) responder := packetResponder{ datagramMuxer: muxer, } require.NoError(t, proxy.Request(ctx, &pk, &responder)) validateEchoFlow(t, <-muxer.cfdToEdge, &pk) - funnel1, found := proxy.srcFunnelTracker.Get(funnelID) - require.True(t, found) // Send second request, should reuse the funnel require.NoError(t, proxy.Request(ctx, &pk, &packetResponder{ datagramMuxer: muxer, })) validateEchoFlow(t, <-muxer.cfdToEdge, &pk) - funnel2, found := proxy.srcFunnelTracker.Get(funnelID) - require.True(t, found) - require.Equal(t, funnel1, funnel2) time.Sleep(idleTimeout * 2) newMuxer := newMockMuxer(0) @@ -86,3 +76,65 @@ func TestFunnelIdleTimeout(t *testing.T) { cancel() <-proxyDone } + +func TestReuseFunnel(t *testing.T) { + const ( + idleTimeout = time.Second + echoID = 42573 + startSeq = 8129 + ) + logger := zerolog.New(os.Stderr) + proxy, err := newICMPProxy(localhostIP, "", &logger, idleTimeout) + require.NoError(t, err) + + ctx, cancel := context.WithCancel(context.Background()) + + proxyDone := make(chan struct{}) + go func() { + proxy.Serve(ctx) + close(proxyDone) + }() + + // Send a packet to register the flow + pk := packet.ICMP{ + IP: &packet.IP{ + Src: localhostIP, + Dst: localhostIP, + Protocol: layers.IPProtocolICMPv4, + }, + Message: &icmp.Message{ + Type: ipv4.ICMPTypeEcho, + Code: 0, + Body: &icmp.Echo{ + ID: echoID, + Seq: startSeq, + Data: []byte(t.Name()), + }, + }, + } + tuple := flow3Tuple{ + srcIP: pk.Src, + dstIP: pk.Dst, + originalEchoID: echoID, + } + muxer := newMockMuxer(0) + responder := packetResponder{ + datagramMuxer: muxer, + } + require.NoError(t, proxy.Request(ctx, &pk, &responder)) + validateEchoFlow(t, <-muxer.cfdToEdge, &pk) + funnel1, found := getFunnel(t, proxy, tuple) + require.True(t, found) + + // Send second request, should reuse the funnel + require.NoError(t, proxy.Request(ctx, &pk, &packetResponder{ + datagramMuxer: muxer, + })) + validateEchoFlow(t, <-muxer.cfdToEdge, &pk) + funnel2, found := getFunnel(t, proxy, tuple) + require.True(t, found) + require.Equal(t, funnel1, funnel2) + + cancel() + <-proxyDone +}