package cache import ( "github.com/go-redis/redis/v7" "github.com/miekg/dns" "meow.tf/joker/godns/settings" "time" ) func NewRedisCache(c settings.RedisSettings, expire time.Duration) *RedisCache { rc := redis.NewClient(&redis.Options{Addr: c.Addr(), DB: c.DB, Password: c.Password}) return &RedisCache{ backend: rc, expire: expire, } } type RedisCache struct { Cache backend *redis.Client expire time.Duration } func (m *RedisCache) Set(key string, msg *dns.Msg) error { var val []byte var err error key = "cache:" + key // handle cases for negacache where it sets nil values if msg == nil { val = []byte("nil") } else { val, err = msg.Pack() } if err != nil { err = SerializerError{err} } return m.backend.Set(key, val, m.expire).Err() } func (m *RedisCache) Get(key string) (*dns.Msg, error) { var msg dns.Msg var err error key = "cache:" + key item, err := m.backend.Get(key).Bytes() if err != nil { err = KeyNotFound{key} return &msg, err } err = msg.Unpack(item) if err != nil { err = SerializerError{err} } return &msg, err } func (m *RedisCache) Exists(key string) bool { res, err := m.backend.Exists(key).Result() if err != nil { return true } return res == 1 } func (m *RedisCache) Remove(key string) error { return m.backend.Del(key).Err() } func (m *RedisCache) Full() bool { // redis is never full (LRU) return false } func (m *RedisCache) Purge() error { iter := m.backend.Scan(0, "cache:*", 0).Iterator() if iter.Err() != nil { return iter.Err() } var err error for iter.Next() { err = m.backend.Del(iter.Val()).Err() if err != nil { return err } } return nil }