aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.adoc47
-rw-r--r--environment.go2
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--rescached.go54
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
diff --git a/go.mod b/go.mod
index db6ed54..113a377 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 35d3dc8..4492535 100644
--- a/go.sum
+++ b/go.sum
@@ -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)
}
}