icmp_darwin_test.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //go:build darwin
  2. package ingress
  3. import (
  4. "math"
  5. "net/netip"
  6. "testing"
  7. "github.com/stretchr/testify/require"
  8. "github.com/cloudflare/cloudflared/packet"
  9. )
  10. func TestSingleEchoIDTracker(t *testing.T) {
  11. tracker := newEchoIDTracker()
  12. key := flow3Tuple{
  13. srcIP: netip.MustParseAddr("172.16.0.1"),
  14. dstIP: netip.MustParseAddr("172.16.0.2"),
  15. originalEchoID: 5182,
  16. }
  17. // not assigned yet, so nothing to release
  18. require.False(t, tracker.release(key, 0))
  19. echoID, ok := tracker.getOrAssign(key)
  20. require.True(t, ok)
  21. require.Equal(t, uint16(0), echoID)
  22. // Second time should return the same echo ID
  23. echoID, ok = tracker.getOrAssign(key)
  24. require.True(t, ok)
  25. require.Equal(t, uint16(0), echoID)
  26. // releasing a different ID returns false
  27. require.False(t, tracker.release(key, 1999))
  28. require.True(t, tracker.release(key, echoID))
  29. // releasing the second time returns false
  30. require.False(t, tracker.release(key, echoID))
  31. // Move to the next IP
  32. echoID, ok = tracker.getOrAssign(key)
  33. require.True(t, ok)
  34. require.Equal(t, uint16(1), echoID)
  35. }
  36. func TestFullEchoIDTracker(t *testing.T) {
  37. var (
  38. dstIP = netip.MustParseAddr("192.168.0.1")
  39. originalEchoID = 41820
  40. )
  41. tracker := newEchoIDTracker()
  42. firstSrcIP := netip.MustParseAddr("172.16.0.1")
  43. srcIP := firstSrcIP
  44. for i := uint16(0); i < math.MaxUint16; i++ {
  45. key := flow3Tuple{
  46. srcIP: srcIP,
  47. dstIP: dstIP,
  48. originalEchoID: originalEchoID,
  49. }
  50. echoID, ok := tracker.getOrAssign(key)
  51. require.True(t, ok)
  52. require.Equal(t, i, echoID)
  53. echoID, ok = tracker.get(key)
  54. require.True(t, ok)
  55. require.Equal(t, i, echoID)
  56. srcIP = srcIP.Next()
  57. }
  58. key := flow3Tuple{
  59. srcIP: srcIP.Next(),
  60. dstIP: dstIP,
  61. originalEchoID: originalEchoID,
  62. }
  63. // All echo IDs are assigned
  64. echoID, ok := tracker.getOrAssign(key)
  65. require.False(t, ok)
  66. require.Equal(t, uint16(0), echoID)
  67. srcIP = firstSrcIP
  68. for i := uint16(0); i < math.MaxUint16; i++ {
  69. key := flow3Tuple{
  70. srcIP: srcIP,
  71. dstIP: dstIP,
  72. originalEchoID: originalEchoID,
  73. }
  74. ok := tracker.release(key, i)
  75. require.True(t, ok)
  76. echoID, ok = tracker.get(key)
  77. require.False(t, ok)
  78. require.Equal(t, uint16(0), echoID)
  79. srcIP = srcIP.Next()
  80. }
  81. // The IDs are assignable again
  82. srcIP = firstSrcIP
  83. for i := uint16(0); i < math.MaxUint16; i++ {
  84. key := flow3Tuple{
  85. srcIP: srcIP,
  86. dstIP: dstIP,
  87. originalEchoID: originalEchoID,
  88. }
  89. echoID, ok := tracker.getOrAssign(key)
  90. require.True(t, ok)
  91. require.Equal(t, i, echoID)
  92. echoID, ok = tracker.get(key)
  93. require.True(t, ok)
  94. require.Equal(t, i, echoID)
  95. srcIP = srcIP.Next()
  96. }
  97. }
  98. func (eit *echoIDTracker) get(key flow3Tuple) (id uint16, exist bool) {
  99. eit.lock.Lock()
  100. defer eit.lock.Unlock()
  101. id, exists := eit.mapping[key]
  102. return id, exists
  103. }
  104. func getFunnel(t *testing.T, proxy *icmpProxy, tuple flow3Tuple) (packet.Funnel, bool) {
  105. assignedEchoID, success := proxy.echoIDTracker.getOrAssign(tuple)
  106. require.True(t, success)
  107. return proxy.srcFunnelTracker.Get(echoFunnelID(assignedEchoID))
  108. }