Initial restructure of server
This commit is contained in:
		
							
								
								
									
										47
									
								
								cache/cache.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								cache/cache.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type KeyNotFound struct {
 | 
			
		||||
	key string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e KeyNotFound) Error() string {
 | 
			
		||||
	return e.key + " " + "not found"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type KeyExpired struct {
 | 
			
		||||
	Key string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e KeyExpired) Error() string {
 | 
			
		||||
	return e.Key + " " + "expired"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type CacheIsFull struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e CacheIsFull) Error() string {
 | 
			
		||||
	return "Cache is Full"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type SerializerError struct {
 | 
			
		||||
	err error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e SerializerError) Error() string {
 | 
			
		||||
	return fmt.Sprintf("Serializer error: got %v", e.err)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Cache interface {
 | 
			
		||||
	Get(key string) (Msg *dns.Msg, err error)
 | 
			
		||||
	Set(key string, Msg *dns.Msg) error
 | 
			
		||||
	Exists(key string) bool
 | 
			
		||||
	Remove(key string) error
 | 
			
		||||
	Full() bool
 | 
			
		||||
	Purge() error
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										70
									
								
								cache/cache_memcached.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								cache/cache_memcached.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,70 @@
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/bradfitz/gomemcache/memcache"
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewMemcachedCache(servers []string, expire int32) *MemcachedCache {
 | 
			
		||||
	c := memcache.New(servers...)
 | 
			
		||||
	return &MemcachedCache{
 | 
			
		||||
		backend: c,
 | 
			
		||||
		expire:  expire,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MemcachedCache struct {
 | 
			
		||||
	backend *memcache.Client
 | 
			
		||||
	expire  int32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MemcachedCache) Set(key string, msg *dns.Msg) error {
 | 
			
		||||
	var val []byte
 | 
			
		||||
	var err error
 | 
			
		||||
 | 
			
		||||
	// 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(&memcache.Item{Key: key, Value: val, Expiration: m.expire})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MemcachedCache) Get(key string) (*dns.Msg, error) {
 | 
			
		||||
	var msg dns.Msg
 | 
			
		||||
	item, err := m.backend.Get(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		err = KeyNotFound{key}
 | 
			
		||||
		return &msg, err
 | 
			
		||||
	}
 | 
			
		||||
	err = msg.Unpack(item.Value)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		err = SerializerError{err}
 | 
			
		||||
	}
 | 
			
		||||
	return &msg, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MemcachedCache) Exists(key string) bool {
 | 
			
		||||
	_, err := m.backend.Get(key)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return true
 | 
			
		||||
	}
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MemcachedCache) Remove(key string) error {
 | 
			
		||||
	return m.backend.Delete(key)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MemcachedCache) Full() bool {
 | 
			
		||||
	// memcache is never full (LRU)
 | 
			
		||||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MemcachedCache) Purge() error {
 | 
			
		||||
	return m.backend.DeleteAll()
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								cache/cache_memory.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								cache/cache_memory.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
package cache
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"github.com/miekg/dns"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func NewMemoryCache(expire time.Duration, maxCount int) *MemoryCache {
 | 
			
		||||
	return &MemoryCache{
 | 
			
		||||
		backend:  make(map[string]Mesg),
 | 
			
		||||
		Expire:   expire,
 | 
			
		||||
		Maxcount: maxCount,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Mesg struct {
 | 
			
		||||
	Msg    *dns.Msg
 | 
			
		||||
	Expire time.Time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MemoryCache struct {
 | 
			
		||||
	Cache
 | 
			
		||||
 | 
			
		||||
	backend  map[string]Mesg
 | 
			
		||||
	Expire   time.Duration
 | 
			
		||||
	Maxcount int
 | 
			
		||||
	mu       sync.RWMutex
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) initialize() {
 | 
			
		||||
	c.backend = make(map[string]Mesg)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Get(key string) (*dns.Msg, error) {
 | 
			
		||||
	c.mu.RLock()
 | 
			
		||||
	mesg, ok := c.backend[key]
 | 
			
		||||
	c.mu.RUnlock()
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return nil, KeyNotFound{key}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if mesg.Expire.Before(time.Now()) {
 | 
			
		||||
		c.Remove(key)
 | 
			
		||||
		return nil, KeyExpired{key}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return mesg.Msg, nil
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Set(key string, msg *dns.Msg) error {
 | 
			
		||||
	if c.Full() && !c.Exists(key) {
 | 
			
		||||
		return CacheIsFull{}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	expire := time.Now().Add(c.Expire)
 | 
			
		||||
	mesg := Mesg{msg, expire}
 | 
			
		||||
	c.mu.Lock()
 | 
			
		||||
	c.backend[key] = mesg
 | 
			
		||||
	c.mu.Unlock()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Remove(key string) error {
 | 
			
		||||
	c.mu.Lock()
 | 
			
		||||
	delete(c.backend, key)
 | 
			
		||||
	c.mu.Unlock()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Exists(key string) bool {
 | 
			
		||||
	c.mu.RLock()
 | 
			
		||||
	_, ok := c.backend[key]
 | 
			
		||||
	c.mu.RUnlock()
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Length() int {
 | 
			
		||||
	c.mu.RLock()
 | 
			
		||||
	defer c.mu.RUnlock()
 | 
			
		||||
	return len(c.backend)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Full() bool {
 | 
			
		||||
	// if Maxcount is zero. the cache will never be full.
 | 
			
		||||
	if c.Maxcount == 0 {
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
	return c.Length() >= c.Maxcount
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *MemoryCache) Purge() error {
 | 
			
		||||
	c.mu.Lock()
 | 
			
		||||
	defer c.mu.Unlock()
 | 
			
		||||
 | 
			
		||||
	c.initialize()
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								cache/cache_redis.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								cache/cache_redis.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
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 int32) *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     int32
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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, time.Duration(m.expire) * time.Second).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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user