13
									
								
								cache.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								cache.go
									
									
									
									
									
								
							| @ -6,6 +6,7 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"github.com/hoisie/redis" | 	"github.com/hoisie/redis" | ||||||
| 	"github.com/miekg/dns" | 	"github.com/miekg/dns" | ||||||
|  | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @ -56,11 +57,13 @@ type MemoryCache struct { | |||||||
| 	Backend  map[string]Mesg | 	Backend  map[string]Mesg | ||||||
| 	Expire   time.Duration | 	Expire   time.Duration | ||||||
| 	Maxcount int | 	Maxcount int | ||||||
|  | 	mu       *sync.RWMutex | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *MemoryCache) Get(key string) (*dns.Msg, error) { | func (c *MemoryCache) Get(key string) (*dns.Msg, error) { | ||||||
|  | 	c.mu.RLock() | ||||||
| 	mesg, ok := c.Backend[key] | 	mesg, ok := c.Backend[key] | ||||||
|  | 	c.mu.RUnlock() | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		return nil, KeyNotFound{key} | 		return nil, KeyNotFound{key} | ||||||
| 	} | 	} | ||||||
| @ -81,20 +84,28 @@ func (c *MemoryCache) Set(key string, msg *dns.Msg) error { | |||||||
|  |  | ||||||
| 	expire := time.Now().Add(c.Expire) | 	expire := time.Now().Add(c.Expire) | ||||||
| 	mesg := Mesg{msg, expire} | 	mesg := Mesg{msg, expire} | ||||||
|  | 	c.mu.Lock() | ||||||
| 	c.Backend[key] = mesg | 	c.Backend[key] = mesg | ||||||
|  | 	c.mu.Unlock() | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *MemoryCache) Remove(key string) { | func (c *MemoryCache) Remove(key string) { | ||||||
|  | 	c.mu.RLock() | ||||||
| 	delete(c.Backend, key) | 	delete(c.Backend, key) | ||||||
|  | 	c.mu.RUnlock() | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *MemoryCache) Exists(key string) bool { | func (c *MemoryCache) Exists(key string) bool { | ||||||
|  | 	c.mu.RLock() | ||||||
| 	_, ok := c.Backend[key] | 	_, ok := c.Backend[key] | ||||||
|  | 	c.mu.RUnlock() | ||||||
| 	return ok | 	return ok | ||||||
| } | } | ||||||
|  |  | ||||||
| func (c *MemoryCache) Length() int { | func (c *MemoryCache) Length() int { | ||||||
|  | 	c.mu.RLock() | ||||||
|  | 	defer c.mu.RUnlock() | ||||||
| 	return len(c.Backend) | 	return len(c.Backend) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ package main | |||||||
| import ( | import ( | ||||||
| 	"github.com/miekg/dns" | 	"github.com/miekg/dns" | ||||||
| 	"net" | 	"net" | ||||||
|  | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| @ -20,6 +21,7 @@ type GODNSHandler struct { | |||||||
| 	resolver *Resolver | 	resolver *Resolver | ||||||
| 	cache    Cache | 	cache    Cache | ||||||
| 	hosts    Hosts | 	hosts    Hosts | ||||||
|  | 	mu       *sync.Mutex | ||||||
| } | } | ||||||
|  |  | ||||||
| func NewHandler() *GODNSHandler { | func NewHandler() *GODNSHandler { | ||||||
| @ -48,6 +50,7 @@ func NewHandler() *GODNSHandler { | |||||||
| 			Backend:  make(map[string]Mesg), | 			Backend:  make(map[string]Mesg), | ||||||
| 			Expire:   time.Duration(cacheConfig.Expire) * time.Second, | 			Expire:   time.Duration(cacheConfig.Expire) * time.Second, | ||||||
| 			Maxcount: cacheConfig.Maxcount, | 			Maxcount: cacheConfig.Maxcount, | ||||||
|  | 			mu:       new(sync.RWMutex), | ||||||
| 		} | 		} | ||||||
| 	case "redis": | 	case "redis": | ||||||
| 		// cache = &MemoryCache{ | 		// cache = &MemoryCache{ | ||||||
| @ -64,11 +67,10 @@ func NewHandler() *GODNSHandler { | |||||||
|  |  | ||||||
| 	hosts := NewHosts(settings.Hosts, settings.Redis) | 	hosts := NewHosts(settings.Hosts, settings.Redis) | ||||||
|  |  | ||||||
| 	return &GODNSHandler{resolver, cache, hosts} | 	return &GODNSHandler{resolver, cache, hosts, new(sync.Mutex)} | ||||||
| } | } | ||||||
|  |  | ||||||
| func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) { | func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) { | ||||||
|  |  | ||||||
| 	q := req.Question[0] | 	q := req.Question[0] | ||||||
| 	Q := Question{UnFqdn(q.Name), dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass]} | 	Q := Question{UnFqdn(q.Name), dns.TypeToString[q.Qtype], dns.ClassToString[q.Qclass]} | ||||||
|  |  | ||||||
| @ -97,8 +99,10 @@ func (h *GODNSHandler) do(Net string, w dns.ResponseWriter, req *dns.Msg) { | |||||||
| 			Debug("%s didn't hit cache: %s", Q.String(), err) | 			Debug("%s didn't hit cache: %s", Q.String(), err) | ||||||
| 		} else { | 		} else { | ||||||
| 			Debug("%s hit cache", Q.String()) | 			Debug("%s hit cache", Q.String()) | ||||||
|  | 			h.mu.Lock() | ||||||
| 			mesg.Id = req.Id | 			mesg.Id = req.Id | ||||||
| 			w.WriteMsg(mesg) | 			w.WriteMsg(mesg) | ||||||
|  | 			h.mu.Unlock() | ||||||
| 			return | 			return | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user