mirror of
https://github.com/netbirdio/netbird.git
synced 2025-07-22 16:44:26 +02:00
adds NetFlow functionality to track and log network traffic information between peers, with features including: - Flow logging for TCP, UDP, and ICMP traffic - Integration with connection tracking system - Resource ID tracking in NetFlow events - DNS and exit node collection configuration - Flow API and Redis cache in management - Memory-based flow storage implementation - Kernel conntrack counters and userspace counters - TCP state machine improvements for more accurate tracking - Migration from net.IP to netip.Addr in the userspace firewall
114 lines
3.3 KiB
Go
114 lines
3.3 KiB
Go
package cache
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/eko/gocache/lib/v4/cache"
|
|
"github.com/eko/gocache/lib/v4/marshaler"
|
|
"github.com/eko/gocache/lib/v4/store"
|
|
"github.com/eko/gocache/store/redis/v4"
|
|
"github.com/vmihailenco/msgpack/v5"
|
|
|
|
"github.com/netbirdio/netbird/management/server/idp"
|
|
)
|
|
|
|
const (
|
|
DefaultIDPCacheExpirationMax = 7 * 24 * time.Hour // 7 days
|
|
DefaultIDPCacheExpirationMin = 3 * 24 * time.Hour // 3 days
|
|
DefaultIDPCacheCleanupInterval = 30 * time.Minute
|
|
)
|
|
|
|
// UserDataCache is an interface that wraps the basic Get, Set and Delete methods for idp.UserData objects.
|
|
type UserDataCache interface {
|
|
Get(ctx context.Context, key string) (*idp.UserData, error)
|
|
Set(ctx context.Context, key string, value *idp.UserData, expiration time.Duration) error
|
|
Delete(ctx context.Context, key string) error
|
|
}
|
|
|
|
// UserDataCacheImpl is a struct that implements the UserDataCache interface.
|
|
type UserDataCacheImpl struct {
|
|
cache Marshaler
|
|
}
|
|
|
|
func (u *UserDataCacheImpl) Get(ctx context.Context, key string) (*idp.UserData, error) {
|
|
v, err := u.cache.Get(ctx, key, new(idp.UserData))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
data := v.(*idp.UserData)
|
|
return data, nil
|
|
}
|
|
|
|
func (u *UserDataCacheImpl) Set(ctx context.Context, key string, value *idp.UserData, expiration time.Duration) error {
|
|
return u.cache.Set(ctx, key, value, store.WithExpiration(expiration))
|
|
}
|
|
|
|
func (u *UserDataCacheImpl) Delete(ctx context.Context, key string) error {
|
|
return u.cache.Delete(ctx, key)
|
|
}
|
|
|
|
// NewUserDataCache creates a new UserDataCacheImpl object.
|
|
func NewUserDataCache(store store.StoreInterface) *UserDataCacheImpl {
|
|
simpleCache := cache.New[any](store)
|
|
if store.GetType() == redis.RedisType {
|
|
m := marshaler.New(simpleCache)
|
|
return &UserDataCacheImpl{cache: m}
|
|
}
|
|
return &UserDataCacheImpl{cache: &marshalerWraper{simpleCache}}
|
|
}
|
|
|
|
// AccountUserDataCache wraps the basic Get, Set and Delete methods for []*idp.UserData objects.
|
|
type AccountUserDataCache struct {
|
|
cache Marshaler
|
|
}
|
|
|
|
func (a *AccountUserDataCache) Get(ctx context.Context, key string) ([]*idp.UserData, error) {
|
|
var m []*idp.UserData
|
|
v, err := a.cache.Get(ctx, key, &m)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
switch v := v.(type) {
|
|
case []*idp.UserData:
|
|
return v, nil
|
|
case *[]*idp.UserData:
|
|
return *v, nil
|
|
case []byte:
|
|
return unmarshalUserData(v)
|
|
}
|
|
|
|
return nil, fmt.Errorf("unexpected type: %T", v)
|
|
}
|
|
|
|
func unmarshalUserData(data []byte) ([]*idp.UserData, error) {
|
|
returnObj := &[]*idp.UserData{}
|
|
err := msgpack.Unmarshal(data, returnObj)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return *returnObj, nil
|
|
}
|
|
|
|
func (a *AccountUserDataCache) Set(ctx context.Context, key string, value []*idp.UserData, expiration time.Duration) error {
|
|
return a.cache.Set(ctx, key, value, store.WithExpiration(expiration))
|
|
}
|
|
|
|
func (a *AccountUserDataCache) Delete(ctx context.Context, key string) error {
|
|
return a.cache.Delete(ctx, key)
|
|
}
|
|
|
|
// NewAccountUserDataCache creates a new AccountUserDataCache object.
|
|
func NewAccountUserDataCache(loadableFunc cache.LoadFunction[any], store store.StoreInterface) *AccountUserDataCache {
|
|
simpleCache := cache.New[any](store)
|
|
loadable := cache.NewLoadable[any](loadableFunc, simpleCache)
|
|
if store.GetType() == redis.RedisType {
|
|
m := marshaler.New(loadable)
|
|
return &AccountUserDataCache{cache: m}
|
|
}
|
|
return &AccountUserDataCache{cache: &marshalerWraper{loadable}}
|
|
}
|