diff options
| -rw-r--r-- | CHANGELOG.adoc | 47 | ||||
| -rw-r--r-- | environment.go | 2 | ||||
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 4 | ||||
| -rw-r--r-- | rescached.go | 54 |
5 files changed, 103 insertions, 6 deletions
diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c9ea516..15fc88e 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -1,3 +1,50 @@ += Rescached v4.1.0 (2021-11-xx) + +== New features + +* Add support to save and load caches to/from storage upon restart + + rescached now able to save and load caches to local storage upon restart. + + On POSIX, the caches is stored in /var/cache/rescached/rescached.gob, + encoded using gob. + + Update #9 + +== Bug fixes + +* make the TCP forwarders as complementary of UDP + + The TCP forwarders only active when client send the DNS request as TCP. + When the server receive that request it should also forward the request + as TCP not as UDP to prevent the truncated response. + + Another use case for TCP is when the response is truncated, the client + will send the query back through TCP connection. The server should + forward this request using TCP instead of UDP. + +== Enhancements + +* remove the fallback name servers (NS) from server options + + The original idea of fallback NS is to send the query to the one + define in resolv.conf, instead of using the one defined by user in + ServerOptions NameServers, when an error occured. + + But, most of error usually caused by network (disconnected, time out), + so re-sending query to fallback NS does not have any effect if the + network it self is not working. + + This changes remove the unnecessary and complex fallback NS from + server. + +* Do not cache truncated answer + + Previously only answer with non-zero response code is ignored. + + This changes ignore also answer where response header is truncated. + + = Rescached v4.0.0 (2021-01-25) == New features diff --git a/environment.go b/environment.go index d976702..bd316c6 100644 --- a/environment.go +++ b/environment.go @@ -153,8 +153,6 @@ func (env *environment) loadResolvConf() (ok bool, err error) { if len(env.NameServers) == 0 { env.NameServers = rc.NameServers - } else { - env.FallbackNS = rc.NameServers } return true, nil @@ -2,6 +2,6 @@ module github.com/shuLhan/rescached-go/v4 go 1.16 -require github.com/shuLhan/share v0.31.0 +require github.com/shuLhan/share v0.31.1-0.20211113074110-0520e7df9127 //replace github.com/shuLhan/share => ../share @@ -1,5 +1,5 @@ -github.com/shuLhan/share v0.31.0 h1:QUqu4XGokbxqbIBEQZDbYa/N13+sfD3wcsVZIdkN8JY= -github.com/shuLhan/share v0.31.0/go.mod h1:1E7VQSKC7cbCmAi6izvm2S8jH5Z98a9SSS2IlvmNs/Y= +github.com/shuLhan/share v0.31.1-0.20211113074110-0520e7df9127 h1:7w78woxSI+vpViEq37rOk8cqmHL/FAsmxGcG3G9F/Hc= +github.com/shuLhan/share v0.31.1-0.20211113074110-0520e7df9127/go.mod h1:1E7VQSKC7cbCmAi6izvm2S8jH5Z98a9SSS2IlvmNs/Y= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211007125505-59d4e928ea9d h1:QWMn1lFvU/nZ58ssWqiFJMd3DKIII8NYc4sn708XgKs= diff --git a/rescached.go b/rescached.go index 6d6464f..c990b77 100644 --- a/rescached.go +++ b/rescached.go @@ -10,6 +10,7 @@ import ( "fmt" "log" "os" + "path/filepath" "sync" "github.com/shuLhan/share/lib/debug" @@ -18,6 +19,11 @@ import ( libio "github.com/shuLhan/share/lib/io" ) +const ( + cachesDir = "/var/cache/rescached/" + cachesFile = "rescached.gob" +) + // Server implement caching DNS server. type Server struct { fileConfig string @@ -57,11 +63,31 @@ func New(fileConfig string) (srv *Server, err error) { // it. // func (srv *Server) Start() (err error) { + logp := "Start" + srv.dns, err = dns.NewServer(&srv.env.ServerOptions) if err != nil { return err } + cachesPath := filepath.Join(cachesDir, cachesFile) + + fcaches, err := os.Open(cachesPath) + if err == nil { + // Load stored caches from file. + answers, err := srv.dns.CachesLoad(fcaches) + if err != nil { + log.Printf("%s: %s", logp, err) + } else { + fmt.Printf("%s: %d caches loaded from %s\n", logp, len(answers), cachesPath) + } + + err = fcaches.Close() + if err != nil { + log.Printf("%s: %s", logp, err) + } + } + systemHostsFile, err := dns.ParseHostsFile(dns.GetSystemHosts()) if err != nil { return err @@ -134,10 +160,36 @@ func (srv *Server) run() { // Stop the server. // func (srv *Server) Stop() { + logp := "Stop" + if srv.rcWatcher != nil { srv.rcWatcher.Stop() } srv.dns.Stop() + + cachesPath := filepath.Join(cachesDir, cachesFile) + + // Stores caches to file for next start. + err := os.MkdirAll(cachesDir, 0700) + if err != nil { + log.Printf("%s: %s", logp, err) + return + } + fcaches, err := os.Create(cachesPath) + if err != nil { + log.Printf("%s: %s", logp, err) + return + } + n, err := srv.dns.CachesSave(fcaches) + if err != nil { + log.Printf("%s: %s", logp, err) + // fall-through for Close. + } + err = fcaches.Close() + if err != nil { + log.Printf("%s: %s", logp, err) + } + fmt.Printf("%s: %d caches stored to %s\n", logp, n, cachesPath) } func (srv *Server) watchResolvConf(ns *libio.NodeState) { @@ -155,6 +207,6 @@ func (srv *Server) watchResolvConf(ns *libio.NodeState) { break } - srv.dns.RestartForwarders(srv.env.NameServers, srv.env.FallbackNS) + srv.dns.RestartForwarders(srv.env.NameServers) } } |
