github.com/slackhq/nebula@v1.9.0/firewall/cache.go (about)

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