mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-27 19:59:58 +00:00
TUN-6744: On posix platforms, assign unique echo ID per (src, dst, echo ID)
This also refactor FunnelTracker to provide a GetOrRegister method to prevent race condition
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/google/gopacket/layers"
|
||||
@@ -97,6 +98,91 @@ func testICMPRouterEcho(t *testing.T, sendIPv4 bool) {
|
||||
<-proxyDone
|
||||
}
|
||||
|
||||
// TestConcurrentRequests makes sure icmpRouter can send concurrent requests to the same destination with different
|
||||
// echo ID. This simulates concurrent ping to the same destination.
|
||||
func TestConcurrentRequestsToSameDst(t *testing.T) {
|
||||
const (
|
||||
concurrentPings = 5
|
||||
endSeq = 5
|
||||
)
|
||||
|
||||
router, err := NewICMPRouter(&noopLogger)
|
||||
require.NoError(t, err)
|
||||
|
||||
proxyDone := make(chan struct{})
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
go func() {
|
||||
router.Serve(ctx)
|
||||
close(proxyDone)
|
||||
}()
|
||||
|
||||
var wg sync.WaitGroup
|
||||
// icmpv4 and icmpv6 each has concurrentPings
|
||||
wg.Add(concurrentPings * 2)
|
||||
for i := 0; i < concurrentPings; i++ {
|
||||
echoID := 38451 + i
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
responder := echoFlowResponder{
|
||||
decoder: packet.NewICMPDecoder(),
|
||||
respChan: make(chan []byte, 1),
|
||||
}
|
||||
for seq := 0; seq < endSeq; seq++ {
|
||||
pk := &packet.ICMP{
|
||||
IP: &packet.IP{
|
||||
Src: localhostIP,
|
||||
Dst: localhostIP,
|
||||
Protocol: layers.IPProtocolICMPv4,
|
||||
TTL: packet.DefaultTTL,
|
||||
},
|
||||
Message: &icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho,
|
||||
Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: echoID,
|
||||
Seq: seq,
|
||||
Data: []byte(fmt.Sprintf("icmpv4 echo id %d, seq %d", echoID, seq)),
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, router.Request(pk, &responder))
|
||||
responder.validate(t, pk)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
responder := echoFlowResponder{
|
||||
decoder: packet.NewICMPDecoder(),
|
||||
respChan: make(chan []byte, 1),
|
||||
}
|
||||
for seq := 0; seq < endSeq; seq++ {
|
||||
pk := &packet.ICMP{
|
||||
IP: &packet.IP{
|
||||
Src: localhostIPv6,
|
||||
Dst: localhostIPv6,
|
||||
Protocol: layers.IPProtocolICMPv6,
|
||||
TTL: packet.DefaultTTL,
|
||||
},
|
||||
Message: &icmp.Message{
|
||||
Type: ipv6.ICMPTypeEchoRequest,
|
||||
Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: echoID,
|
||||
Seq: seq,
|
||||
Data: []byte(fmt.Sprintf("icmpv6 echo id %d, seq %d", echoID, seq)),
|
||||
},
|
||||
},
|
||||
}
|
||||
require.NoError(t, router.Request(pk, &responder))
|
||||
responder.validate(t, pk)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
cancel()
|
||||
<-proxyDone
|
||||
}
|
||||
|
||||
// TestICMPProxyRejectNotEcho makes sure it rejects messages other than echo
|
||||
func TestICMPRouterRejectNotEcho(t *testing.T) {
|
||||
msgs := []icmp.Message{
|
||||
|
Reference in New Issue
Block a user