diff --git a/backend/backend.go b/backend/backend.go
index c80841e..59df4d7 100644
--- a/backend/backend.go
+++ b/backend/backend.go
@@ -6,11 +6,13 @@ import "gopkg.in/hlandau/madns.v1/merr"
import "github.com/hlandau/ncdns/namecoin"
import "github.com/hlandau/ncdns/util"
import "github.com/hlandau/ncdns/ncdomain"
+import "github.com/hlandau/xlog"
import "sync"
import "fmt"
import "net"
import "net/mail"
import "strings"
+import "time"
// Provides an abstract zone file for the Namecoin .bit TLD.
type Backend struct {
@@ -23,6 +25,8 @@ type Backend struct {
const defaultMaxEntries = 100
+var log, Log = xlog.New("ncdns.backend")
+
// Backend configuration.
type Config struct {
NamecoinConn namecoin.Conn
@@ -337,12 +341,22 @@ func (b *Backend) resolveName(name string) (jsonValue string, err error) {
return fv, nil
}
- v, err := b.nc.Query(name)
- if err != nil {
- return "", err
- }
+ // The btcjson package has quite a long timeout, far in excess of standard
+ // DNS timeouts. We need to return an error response rapidly if we can't
+ // query the backend. Be generous with the timeout as responses from the
+ // Namecoin JSON-RPC seem sluggish sometimes.
+ result := make(chan struct{}, 1)
+ go func() {
+ jsonValue, err = b.nc.Query(name)
+ result <- struct{}{}
+ }()
- return v, nil
+ select {
+ case <-result:
+ return
+ case <-time.After(1500 * time.Millisecond):
+ return "", fmt.Errorf("timeout")
+ }
}
func (b *Backend) jsonToDomain(name, jsonValue string) (*domain, error) {
diff --git a/server/server.go b/server/server.go
index d873259..8a118da 100644
--- a/server/server.go
+++ b/server/server.go
@@ -1,7 +1,6 @@
package server
import "gopkg.in/hlandau/madns.v1"
-import "github.com/hlandau/degoutils/log"
import "github.com/hlandau/ncdns/backend"
import "github.com/hlandau/ncdns/namecoin"
import "github.com/miekg/dns"
@@ -12,9 +11,12 @@ import "sync"
import "strings"
import "path/filepath"
import "crypto"
+import "github.com/hlandau/xlog"
const version = "1.0"
+var log, Log = xlog.New("ncdns.server")
+
type Server struct {
cfg ServerConfig
@@ -49,6 +51,8 @@ type ServerConfig struct {
Hostmaster string `default:"" usage:"Hostmaster e. mail address"`
VanityIPs string `default:"" usage:"Comma separated list of IP addresses to place in A/AAAA records at the zone apex (default: don't add any records)"`
vanityIPs []net.IP
+ TplSet string `default:"std" usage:"The template set to use"`
+ TplPath string `default:"" usage:"The path to the tpl directory (empty: autodetect)"`
ConfigDir string // path to interpret filenames relative to
}
@@ -170,7 +174,6 @@ func (s *Server) loadKey(fn, privateFn string) (k *dns.DNSKEY, privatek crypto.P
}
func (s *Server) Start() error {
-
s.mux = dns.NewServeMux()
s.mux.Handle(".", s.engine)
@@ -179,6 +182,7 @@ func (s *Server) Start() error {
s.tcpListener = s.runListener("tcp")
s.wgStart.Wait()
+ log.Info("Listeners started")
return nil
}
diff --git a/server/web.go b/server/web.go
index 5d73044..43b0627 100644
--- a/server/web.go
+++ b/server/web.go
@@ -2,7 +2,6 @@ package server
import "net/http"
import "html/template"
-import "github.com/hlandau/degoutils/log"
import "github.com/hlandau/ncdns/util"
import "github.com/hlandau/ncdns/ncdomain"
import "github.com/miekg/dns"
@@ -11,35 +10,28 @@ import "path/filepath"
import "time"
import "strings"
import "fmt"
-import "flag"
var layoutTpl *template.Template
var mainPageTpl *template.Template
var lookupPageTpl *template.Template
-var tplSetFlag = flag.String("tplset", "std", "Subdirectory of tpl/ to look for templates in (default: std)")
-
-func initTemplates(configDir string) error {
+func (s *Server) initTemplates() error {
if lookupPageTpl != nil {
return nil
}
- if *tplSetFlag == "" {
- *tplSetFlag = "std"
- }
-
var err error
- layoutTpl, err = template.ParseFiles(tplFilename(configDir, "layout"))
+ layoutTpl, err = template.ParseFiles(s.tplFilename("layout"))
if err != nil {
return err
}
- mainPageTpl, err = deriveTemplate(tplFilename(configDir, "main"))
+ mainPageTpl, err = deriveTemplate(s.tplFilename("main"))
if err != nil {
return err
}
- lookupPageTpl, err = deriveTemplate(tplFilename(configDir, "lookup"))
+ lookupPageTpl, err = deriveTemplate(s.tplFilename("lookup"))
if err != nil {
return err
}
@@ -55,9 +47,13 @@ func deriveTemplate(filename string) (*template.Template, error) {
return cl.ParseFiles(filename)
}
-func tplFilename(configDir, filename string) string {
- s := "tpl/" + *tplSetFlag + "/" + filename + ".tpl"
- return filepath.Join(configDir, "..", s)
+func (s *Server) tplFilename(filename string) string {
+ td := filepath.Join(s.cfg.ConfigDir, "..", "tpl")
+ if s.cfg.TplPath != "" {
+ td = s.cfg.TplPath
+ }
+
+ return filepath.Join(td, s.cfg.TplSet, filename+".tpl")
}
type webServer struct {
@@ -83,6 +79,11 @@ func (ws *webServer) layoutInfo() *layoutInfo {
cshtml = `` + csparts[0] + `.` + csparts[1] + ``
}
+ var tld string
+ if len(csparts) > 1 {
+ tld = "." + csparts[1]
+ }
+
li := &layoutInfo{
SelfName: ws.s.ServerName(),
Time: time.Now().Format("2006-01-02 15:04:05"),
@@ -90,7 +91,7 @@ func (ws *webServer) layoutInfo() *layoutInfo {
CanonicalNameservers: ws.s.cfg.canonicalNameservers,
Hostmaster: ws.s.cfg.Hostmaster,
CanonicalSuffixHTML: template.HTML(cshtml),
- TLD: "." + csparts[1],
+ TLD: tld,
HasDNSSEC: ws.s.cfg.ZonePublicKey != "",
}
@@ -200,7 +201,7 @@ func clearAllCookies(rw http.ResponseWriter, req *http.Request) {
}
func webStart(listenAddr string, server *Server) error {
- err := initTemplates(server.cfg.ConfigDir)
+ err := server.initTemplates()
if err != nil {
return err
}