cloudflared-mirror/ingress/icmp_posix_test.go

77 lines
1.5 KiB
Go

//go:build darwin || linux
package ingress
import (
"context"
"os"
"testing"
"time"
"github.com/google/gopacket/layers"
"github.com/rs/zerolog"
"github.com/stretchr/testify/require"
"golang.org/x/net/icmp"
"golang.org/x/net/ipv4"
"github.com/cloudflare/cloudflared/packet"
)
func TestFunnelIdleTimeout(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()),
},
},
}
responder := echoFlowResponder{
decoder: packet.NewICMPDecoder(),
respChan: make(chan []byte),
}
require.NoError(t, proxy.Request(&pk, &responder))
responder.validate(t, &pk)
// Send second request, should reuse the funnel
require.NoError(t, proxy.Request(&pk, nil))
responder.validate(t, &pk)
time.Sleep(idleTimeout * 2)
newResponder := echoFlowResponder{
decoder: packet.NewICMPDecoder(),
respChan: make(chan []byte),
}
require.NoError(t, proxy.Request(&pk, &newResponder))
newResponder.validate(t, &pk)
cancel()
<-proxyDone
}