icmp_posix_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. //go:build darwin || linux
  2. package ingress
  3. import (
  4. "context"
  5. "os"
  6. "testing"
  7. "time"
  8. "github.com/fortytw2/leaktest"
  9. "github.com/google/gopacket/layers"
  10. "github.com/rs/zerolog"
  11. "github.com/stretchr/testify/require"
  12. "golang.org/x/net/icmp"
  13. "golang.org/x/net/ipv4"
  14. "github.com/cloudflare/cloudflared/packet"
  15. )
  16. func TestFunnelIdleTimeout(t *testing.T) {
  17. defer leaktest.Check(t)()
  18. const (
  19. idleTimeout = time.Second
  20. echoID = 42573
  21. startSeq = 8129
  22. )
  23. logger := zerolog.New(os.Stderr)
  24. proxy, err := newICMPProxy(localhostIP, "", &logger, idleTimeout)
  25. require.NoError(t, err)
  26. ctx, cancel := context.WithCancel(context.Background())
  27. proxyDone := make(chan struct{})
  28. go func() {
  29. proxy.Serve(ctx)
  30. close(proxyDone)
  31. }()
  32. // Send a packet to register the flow
  33. pk := packet.ICMP{
  34. IP: &packet.IP{
  35. Src: localhostIP,
  36. Dst: localhostIP,
  37. Protocol: layers.IPProtocolICMPv4,
  38. },
  39. Message: &icmp.Message{
  40. Type: ipv4.ICMPTypeEcho,
  41. Code: 0,
  42. Body: &icmp.Echo{
  43. ID: echoID,
  44. Seq: startSeq,
  45. Data: []byte(t.Name()),
  46. },
  47. },
  48. }
  49. muxer := newMockMuxer(0)
  50. responder := packetResponder{
  51. datagramMuxer: muxer,
  52. }
  53. require.NoError(t, proxy.Request(ctx, &pk, &responder))
  54. validateEchoFlow(t, <-muxer.cfdToEdge, &pk)
  55. // Send second request, should reuse the funnel
  56. require.NoError(t, proxy.Request(ctx, &pk, &packetResponder{
  57. datagramMuxer: muxer,
  58. }))
  59. validateEchoFlow(t, <-muxer.cfdToEdge, &pk)
  60. time.Sleep(idleTimeout * 2)
  61. newMuxer := newMockMuxer(0)
  62. newResponder := packetResponder{
  63. datagramMuxer: newMuxer,
  64. }
  65. require.NoError(t, proxy.Request(ctx, &pk, &newResponder))
  66. validateEchoFlow(t, <-newMuxer.cfdToEdge, &pk)
  67. time.Sleep(idleTimeout * 2)
  68. cancel()
  69. <-proxyDone
  70. }
  71. func TestReuseFunnel(t *testing.T) {
  72. defer leaktest.Check(t)()
  73. const (
  74. idleTimeout = time.Millisecond * 100
  75. echoID = 42573
  76. startSeq = 8129
  77. )
  78. logger := zerolog.New(os.Stderr)
  79. proxy, err := newICMPProxy(localhostIP, "", &logger, idleTimeout)
  80. require.NoError(t, err)
  81. ctx, cancel := context.WithCancel(context.Background())
  82. proxyDone := make(chan struct{})
  83. go func() {
  84. proxy.Serve(ctx)
  85. close(proxyDone)
  86. }()
  87. // Send a packet to register the flow
  88. pk := packet.ICMP{
  89. IP: &packet.IP{
  90. Src: localhostIP,
  91. Dst: localhostIP,
  92. Protocol: layers.IPProtocolICMPv4,
  93. },
  94. Message: &icmp.Message{
  95. Type: ipv4.ICMPTypeEcho,
  96. Code: 0,
  97. Body: &icmp.Echo{
  98. ID: echoID,
  99. Seq: startSeq,
  100. Data: []byte(t.Name()),
  101. },
  102. },
  103. }
  104. tuple := flow3Tuple{
  105. srcIP: pk.Src,
  106. dstIP: pk.Dst,
  107. originalEchoID: echoID,
  108. }
  109. muxer := newMockMuxer(0)
  110. responder := packetResponder{
  111. datagramMuxer: muxer,
  112. }
  113. require.NoError(t, proxy.Request(ctx, &pk, &responder))
  114. validateEchoFlow(t, <-muxer.cfdToEdge, &pk)
  115. funnel1, found := getFunnel(t, proxy, tuple)
  116. require.True(t, found)
  117. // Send second request, should reuse the funnel
  118. require.NoError(t, proxy.Request(ctx, &pk, &packetResponder{
  119. datagramMuxer: muxer,
  120. }))
  121. validateEchoFlow(t, <-muxer.cfdToEdge, &pk)
  122. funnel2, found := getFunnel(t, proxy, tuple)
  123. require.True(t, found)
  124. require.Equal(t, funnel1, funnel2)
  125. time.Sleep(idleTimeout * 2)
  126. cancel()
  127. <-proxyDone
  128. }