more stuff

This commit is contained in:
Miek Gieben 2012-08-08 11:45:25 +02:00
parent 17af20cd88
commit f335343759
2 changed files with 43 additions and 18 deletions

View File

@ -4,11 +4,13 @@ import (
"dns" "dns"
"fmt" "fmt"
"log" "log"
"radix" "github.com/miekg/radix"
"strings" "strings"
"time" "time"
) )
const TTL time.Duration = 30 * 1e9 // 30 seconds
// Cache elements, we using to key (toRadixKey) to distinguish between dns and dnssec // Cache elements, we using to key (toRadixKey) to distinguish between dns and dnssec
type Packet struct { type Packet struct {
ttl time.Time // insertion time ttl time.Time // insertion time
@ -43,11 +45,28 @@ func NewCache() *Cache {
return &Cache{Radix: radix.New()} return &Cache{Radix: radix.New()}
} }
func (c *Cache) Evict() {
// A bit tedious, keys() -> find() -> remove()
for _, key := range c.Radix.Keys() {
log.Printf("look for key %s\n", key)
node := c.Radix.Find(key)
if node == nil {
continue
}
if time.Since(node.Value.(*Packet).ttl) > TTL {
c.Radix.Remove(key)
if *flaglog {
log.Printf("fsk-shield: evicting %s\n", key)
}
}
}
}
func (c *Cache) Find(d *dns.Msg) []byte { func (c *Cache) Find(d *dns.Msg) []byte {
p := c.Radix.Find(toRadixKey(d)) p := c.Radix.Find(toRadixKey(d))
if p == nil { if p == nil {
if *verbose { if *flaglog {
log.Printf("Cache miss for " + toRadixKey(d)) log.Printf("fsk-shield: cache miss for " + toRadixKey(d))
} }
return nil return nil
} }
@ -55,10 +74,10 @@ func (c *Cache) Find(d *dns.Msg) []byte {
} }
func (c *Cache) Insert(d *dns.Msg) { func (c *Cache) Insert(d *dns.Msg) {
if *verbose { if *flaglog {
log.Printf("Inserting " + toRadixKey(d)) log.Printf("fsk-shield: inserting " + toRadixKey(d))
} }
buf, _ := d.Pack() // Should always work buf, _ := d.Pack() // Should always work
c.Radix.Insert(toRadixKey(d), &Packet{d: buf, ttl: time.Now().UTC()}) c.Radix.Insert(toRadixKey(d), &Packet{d: buf, ttl: time.Now().UTC()})
} }

View File

@ -1,22 +1,19 @@
/*
* Funkensturm, a versatile DNS proxy
* Miek Gieben <miek@miek.nl> (c) 2011
* GPLv2
*/
package main package main
// TODO: locking
import ( import (
"dns" "dns"
"flag" "flag"
"log" "log"
"os" "os"
"time"
) )
var ( var (
listen = flag.String("listen", "127.0.0.1:8053", "set the listener address") listen = flag.String("listen", "127.0.0.1:8053", "set the listener address")
server = flag.String("server", "127.0.0.1:53", "remote server address(es), seperate with commas") server = flag.String("server", "127.0.0.1:53", "remote server address")
verbose = flag.Bool("verbose", false, "be more verbose") flaglog = flag.Bool("log", false, "be more verbose")
) )
func serve(w dns.ResponseWriter, r *dns.Msg, c *Cache) { func serve(w dns.ResponseWriter, r *dns.Msg, c *Cache) {
@ -29,7 +26,7 @@ func serve(w dns.ResponseWriter, r *dns.Msg, c *Cache) {
// Cache miss // Cache miss
client := new(dns.Client) client := new(dns.Client)
if p, e := client.Exchange(r, *server); e == nil { if p, e := client.Exchange(r, *server); e == nil {
if *verbose { if *flaglog {
log.Printf("fks-shield: cache miss") log.Printf("fks-shield: cache miss")
} }
// TODO(mg): If r has edns0 and p has not we create a mismatch here // TODO(mg): If r has edns0 and p has not we create a mismatch here
@ -38,7 +35,9 @@ func serve(w dns.ResponseWriter, r *dns.Msg, c *Cache) {
return return
} else { } else {
log.Printf("fks-shield: failed to get answer " + e.Error()) log.Printf("fks-shield: failed to get answer " + e.Error())
// w.Write(SERFVAIL) m := new(dns.Msg)
m.SetRcode(r, dns.RcodeServerFailure)
w.Write(m)
} }
} }
@ -54,9 +53,16 @@ func main() {
// Only listen on UDP // Only listen on UDP
go func() { go func() {
if err := dns.ListenAndServe(*listen, "udp", nil); err != nil { if err := dns.ListenAndServe(*listen, "udp", nil); err != nil {
log.Fatal("fks-shield: failed to setup %s %s", net, add) log.Fatal("fks-shield: failed to setup %s %s", *listen, "udp")
} }
} }()
go func() {
for {
// Every 10 sec run the cache cleaner
time.Sleep(10 * 1e9)
cache.Evict()
}
}()
sig := make(chan os.Signal) sig := make(chan os.Signal)
forever: forever: