3
0

cache.go 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package firewall
  2. import (
  3. "sync/atomic"
  4. "time"
  5. "github.com/sirupsen/logrus"
  6. )
  7. // ConntrackCache is used as a local routine cache to know if a given flow
  8. // has been seen in the conntrack table.
  9. type ConntrackCache map[Packet]struct{}
  10. type ConntrackCacheTicker struct {
  11. cacheV uint64
  12. cacheTick atomic.Uint64
  13. cache ConntrackCache
  14. }
  15. func NewConntrackCacheTicker(d time.Duration) *ConntrackCacheTicker {
  16. if d == 0 {
  17. return nil
  18. }
  19. c := &ConntrackCacheTicker{
  20. cache: ConntrackCache{},
  21. }
  22. go c.tick(d)
  23. return c
  24. }
  25. func (c *ConntrackCacheTicker) tick(d time.Duration) {
  26. for {
  27. time.Sleep(d)
  28. c.cacheTick.Add(1)
  29. }
  30. }
  31. // Get checks if the cache ticker has moved to the next version before returning
  32. // the map. If it has moved, we reset the map.
  33. func (c *ConntrackCacheTicker) Get(l *logrus.Logger) ConntrackCache {
  34. if c == nil {
  35. return nil
  36. }
  37. if tick := c.cacheTick.Load(); tick != c.cacheV {
  38. c.cacheV = tick
  39. if ll := len(c.cache); ll > 0 {
  40. if l.Level == logrus.DebugLevel {
  41. l.WithField("len", ll).Debug("resetting conntrack cache")
  42. }
  43. c.cache = make(ConntrackCache, ll)
  44. }
  45. }
  46. return c.cache
  47. }