cache.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package firewall
  2. import (
  3. "context"
  4. "log/slog"
  5. "net/netip"
  6. "sync/atomic"
  7. "time"
  8. "github.com/slackhq/nebula/logging"
  9. )
  10. // ConntrackKey identifies a tracked flow by its packet and the peer it was allowed for, so peers that route
  11. // the same unsafe network never share a conntrack entry.
  12. type ConntrackKey struct {
  13. Peer netip.Addr
  14. Packet
  15. }
  16. // ConntrackCache is used as a local routine cache to know if a given flow
  17. // has been seen in the conntrack table.
  18. type ConntrackCache map[ConntrackKey]struct{}
  19. type ConntrackCacheTicker struct {
  20. cacheV uint64
  21. cacheTick atomic.Uint64
  22. l *slog.Logger
  23. cache ConntrackCache
  24. }
  25. func NewConntrackCacheTicker(ctx context.Context, l *slog.Logger, d time.Duration) *ConntrackCacheTicker {
  26. if d == 0 {
  27. return nil
  28. }
  29. c := &ConntrackCacheTicker{
  30. l: l,
  31. cache: ConntrackCache{},
  32. }
  33. go c.tick(ctx, d)
  34. return c
  35. }
  36. func (c *ConntrackCacheTicker) tick(ctx context.Context, d time.Duration) {
  37. t := time.NewTicker(d)
  38. defer t.Stop()
  39. for {
  40. select {
  41. case <-ctx.Done():
  42. return
  43. case <-t.C:
  44. c.cacheTick.Add(1)
  45. }
  46. }
  47. }
  48. // Get checks if the cache ticker has moved to the next version before returning
  49. // the map. If it has moved, we reset the map.
  50. func (c *ConntrackCacheTicker) Get() ConntrackCache {
  51. if c == nil {
  52. return nil
  53. }
  54. if tick := c.cacheTick.Load(); tick != c.cacheV {
  55. c.cacheV = tick
  56. if ll := len(c.cache); ll > 0 {
  57. if c.l.Enabled(context.Background(), logging.LevelTrace) {
  58. c.l.Log(context.Background(), logging.LevelTrace, "resetting conntrack cache", "len", ll)
  59. }
  60. c.cache = make(ConntrackCache, ll)
  61. }
  62. }
  63. return c.cache
  64. }