mirror of
https://github.com/namecoin/ncdns
synced 2024-11-10 01:10:31 +00:00
refactoring
This commit is contained in:
parent
b43778c158
commit
13d64f59a7
26
backend.go
26
backend.go
@ -8,6 +8,8 @@ import "encoding/hex"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
import "net"
|
||||
import "github.com/hlandau/ncdns/namecoin"
|
||||
import "github.com/hlandau/ncdns/ncerr"
|
||||
|
||||
type Backend interface {
|
||||
// Lookup all resource records having a given fully-qualified owner name,
|
||||
@ -25,7 +27,7 @@ type Backend interface {
|
||||
|
||||
type ncBackend struct {
|
||||
s *Server
|
||||
nc NamecoinConn
|
||||
nc namecoin.NamecoinConn
|
||||
cache lru.Cache // items are of type *Domain
|
||||
}
|
||||
|
||||
@ -125,7 +127,7 @@ func (tx *Btx) determineDomain() (subname, basename, rootname string, err error)
|
||||
parts := strings.Split(qname, ".")
|
||||
if len(parts) < 2 {
|
||||
if parts[0] != "bit" {
|
||||
err = ErrNotInZone
|
||||
err = ncerr.ErrNotInZone
|
||||
return
|
||||
}
|
||||
|
||||
@ -150,7 +152,7 @@ func (tx *Btx) determineDomain() (subname, basename, rootname string, err error)
|
||||
}
|
||||
}
|
||||
|
||||
err = ErrNotInZone
|
||||
err = ncerr.ErrNotInZone
|
||||
return
|
||||
}
|
||||
|
||||
@ -165,7 +167,7 @@ func (tx *Btx) Do() (rrs []dns.RR, err error) {
|
||||
|
||||
if tx.rootname == "" {
|
||||
// REFUSED
|
||||
return nil, ErrNotInZone
|
||||
return nil, ncerr.ErrNotInZone
|
||||
}
|
||||
|
||||
if tx.subname == "" && tx.basename == "" {
|
||||
@ -272,7 +274,7 @@ func (tx *Btx) doUserDomain() (rrs []dns.RR, err error) {
|
||||
|
||||
func (tx *Btx) doUnderDomain(d *Domain) (rrs []dns.RR, err error) {
|
||||
rrs, err = tx.addAnswersUnderNCValue(d.ncv, tx.subname)
|
||||
if err == ErrNoResults {
|
||||
if err == ncerr.ErrNoResults {
|
||||
err = nil
|
||||
}
|
||||
|
||||
@ -315,14 +317,14 @@ func (tx *Btx) _findNCValue(ncv *ncValue, isubname, subname string, depth int,
|
||||
if !ok {
|
||||
sub, ok = ncv.Map["*"]
|
||||
if !ok {
|
||||
return nil, "", ErrNoSuchDomain
|
||||
return nil, "", ncerr.ErrNoSuchDomain
|
||||
}
|
||||
}
|
||||
return tx._findNCValue(sub, rest, head + "." + subname, depth+1, shortCircuitFunc)
|
||||
}
|
||||
|
||||
if shortCircuitFunc != nil {
|
||||
return nil, subname, ErrNoSuchDomain
|
||||
return nil, subname, ncerr.ErrNoSuchDomain
|
||||
}
|
||||
|
||||
return ncv, subname, nil
|
||||
@ -493,16 +495,6 @@ func (ncv *ncValue) GetDSs() (dss []dns.DS, err error) {
|
||||
// f[b]("a", "b.c.d.e.f.g.zzz.bit")
|
||||
// f[a]("", "a.b.c.d.e.f.g.zzz.bit")
|
||||
|
||||
func absname(n string) string {
|
||||
if n == "" {
|
||||
return "."
|
||||
}
|
||||
if n[len(n)-1] != '.' {
|
||||
return n + "."
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Do low-level queries against an abstract zone file.
|
||||
func (b *ncBackend) Lookup(qname string) (rrs []dns.RR, err error) {
|
||||
btx := &Btx{}
|
||||
|
@ -1,10 +1,14 @@
|
||||
package main
|
||||
package namecoin
|
||||
|
||||
// btcjson had to be modified a bit to get correct error reporting.
|
||||
import "github.com/hlandauf/btcjson"
|
||||
import "github.com/hlandau/ncdns/ncerr"
|
||||
|
||||
import "encoding/json"
|
||||
import "sync/atomic"
|
||||
import "fmt"
|
||||
//import "github.com/hlandau/degoutils/log"
|
||||
|
||||
// Used for generating IDs for JSON-RPC requests.
|
||||
var idCounter int32 = 0
|
||||
|
||||
func newID() int32 {
|
||||
@ -108,7 +112,7 @@ func (nc *NamecoinConn) Query(name string) (v string, err error) {
|
||||
if r.Error != nil {
|
||||
//log.Info("RPC error: ", r.Error)
|
||||
if r.Error.Code == -4 {
|
||||
return "", ErrNoSuchDomain
|
||||
return "", ncerr.ErrNoSuchDomain
|
||||
}
|
||||
return "", r.Error
|
||||
}
|
13
ncdns.go
13
ncdns.go
@ -8,6 +8,7 @@ import "fmt"
|
||||
import "strings"
|
||||
import "sort"
|
||||
import "github.com/hlandau/degoutils/config"
|
||||
import "github.com/hlandau/ncdns/ncerr"
|
||||
|
||||
// A Go daemon to serve Namecoin domain records via DNS.
|
||||
// This daemon is intended to be used in one of the following situations:
|
||||
@ -161,10 +162,6 @@ func (s *Server) runListener(net string) *dns.Server {
|
||||
return ds
|
||||
}
|
||||
|
||||
var ErrNoSuchDomain = rerrorf(dns.RcodeNameError, "no such domain")
|
||||
var ErrNotInZone = rerrorf(dns.RcodeRefused, "domain not in zone")
|
||||
var ErrNoResults = rerrorf(0, "no results")
|
||||
|
||||
type Tx struct {
|
||||
req *dns.Msg
|
||||
res *dns.Msg
|
||||
@ -224,9 +221,9 @@ func (s *Server) handle(rw dns.ResponseWriter, reqMsg *dns.Msg) {
|
||||
|
||||
err := tx.addAnswers()
|
||||
if err != nil {
|
||||
if err == ErrNoResults {
|
||||
if err == ncerr.ErrNoResults {
|
||||
tx.rcode = 0
|
||||
} else if err == ErrNoSuchDomain {
|
||||
} else if err == ncerr.ErrNoSuchDomain {
|
||||
tx.rcode = dns.RcodeNameError
|
||||
} else if tx.rcode == 0 {
|
||||
log.Infoe(err, "Handler error, doing SERVFAIL")
|
||||
@ -248,7 +245,7 @@ func (tx *Tx) blookup(qname string) (rrs []dns.RR, err error) {
|
||||
log.Info("blookup: ", qname)
|
||||
rrs, err = tx.s.b.Lookup(qname)
|
||||
if err == nil && len(rrs) == 0 {
|
||||
err = ErrNoResults
|
||||
err = ncerr.ErrNoResults
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -380,7 +377,7 @@ A:
|
||||
|
||||
if soa == nil {
|
||||
// If we didn't even get a SOA at any point, we don't have any appropriate zone for this query.
|
||||
return ErrNotInZone
|
||||
return ncerr.ErrNotInZone
|
||||
}
|
||||
|
||||
tx.soa = soa
|
||||
|
35
ncerr/ncerr.go
Normal file
35
ncerr/ncerr.go
Normal file
@ -0,0 +1,35 @@
|
||||
package ncerr
|
||||
import "github.com/miekg/dns"
|
||||
import "fmt"
|
||||
|
||||
// An Error interface which allows an associated rcode to be queried.
|
||||
type Error interface {
|
||||
error
|
||||
Rcode() int
|
||||
}
|
||||
|
||||
type Rerr struct {
|
||||
error
|
||||
e error
|
||||
rcode int
|
||||
}
|
||||
|
||||
func (re *Rerr) Error() string {
|
||||
return re.e.Error()
|
||||
}
|
||||
|
||||
func (re *Rerr) Rcode() int {
|
||||
return re.rcode
|
||||
}
|
||||
|
||||
func rerrorf(rcode int, fmts string, args ...interface{}) Error {
|
||||
re := &Rerr{}
|
||||
re.e = fmt.Errorf(fmts, args...)
|
||||
re.rcode = rcode
|
||||
return re
|
||||
}
|
||||
|
||||
// Standard errors.
|
||||
var ErrNoSuchDomain = rerrorf(dns.RcodeNameError, "no such domain")
|
||||
var ErrNotInZone = rerrorf(dns.RcodeRefused, "domain not in zone")
|
||||
var ErrNoResults = rerrorf(0, "no results")
|
85
util.go
85
util.go
@ -6,6 +6,18 @@ import "github.com/miekg/dns"
|
||||
import "github.com/hlandau/degoutils/log"
|
||||
import "time"
|
||||
|
||||
// miekg/dns demands a superflous trailing dot, this makes sure it is correctly appended.
|
||||
func absname(n string) string {
|
||||
if n == "" {
|
||||
return "."
|
||||
}
|
||||
if n[len(n)-1] != '.' {
|
||||
return n + "."
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// Split a domain name a.b.c.d.e into parts a (the head) and b.c.d.e (the rest).
|
||||
func splitDomainHead(name string) (head string, rest string, err error) {
|
||||
parts := strings.Split(name, ".")
|
||||
|
||||
@ -18,32 +30,25 @@ func splitDomainHead(name string) (head string, rest string, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// unused
|
||||
func splitDomainName(name string) (parts []string) {
|
||||
if len(name) == 0 {
|
||||
return
|
||||
// Determines if a transaction should be considered to have the given query type.
|
||||
// Returns true iff the query type was qtype or ANY.
|
||||
func (tx *Tx) istype(qtype uint16) bool {
|
||||
return tx.qtype == qtype || tx.qtype == dns.TypeANY
|
||||
}
|
||||
|
||||
if name[len(name)-1] == '.' {
|
||||
name = name[0:len(name)-1]
|
||||
}
|
||||
|
||||
parts = strings.Split(name, ".")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Tx) istype(x uint16) bool {
|
||||
return tx.qtype == x || tx.qtype == dns.TypeANY
|
||||
}
|
||||
|
||||
func stepName(n string) string {
|
||||
if len(n) == 0 {
|
||||
// This is used in NSEC3 hash generation. A hash like ...decafbad has one added
|
||||
// to it so that it becomes ...decafbae. This is needed because NSEC3's hashes
|
||||
// are inclusive-exclusive (i.e. "[,)"), and we want a hash that covers only the
|
||||
// name specified.
|
||||
//
|
||||
// Takes a hash in base32hex form.
|
||||
func stepName(hashB32Hex string) string {
|
||||
if len(hashB32Hex) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
b, err := base32.HexEncoding.DecodeString(n)
|
||||
log.Panice(err, n)
|
||||
b, err := base32.HexEncoding.DecodeString(hashB32Hex)
|
||||
log.Panice(err, hashB32Hex)
|
||||
|
||||
for i := len(b)-1; i>=0; i-- {
|
||||
b[i] += 1
|
||||
@ -55,8 +60,8 @@ func stepName(n string) string {
|
||||
return base32.HexEncoding.EncodeToString(b)
|
||||
}
|
||||
|
||||
// Returns true iff a type should be covered by a RRSIG.
|
||||
func shouldSignType(t uint16, isAuthoritySection bool) bool {
|
||||
//log.Info("shouldSignType ", t, " ", isAuthoritySection)
|
||||
switch t {
|
||||
case dns.TypeOPT:
|
||||
return false
|
||||
@ -67,6 +72,7 @@ func shouldSignType(t uint16, isAuthoritySection bool) bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true iff a client requested DNSSEC.
|
||||
func (tx *Tx) useDNSSEC() bool {
|
||||
opt := tx.req.IsEdns0()
|
||||
if opt == nil {
|
||||
@ -75,38 +81,18 @@ func (tx *Tx) useDNSSEC() bool {
|
||||
return opt.Do()
|
||||
}
|
||||
|
||||
// Sets an rcode for the response if there is no error rcode currently set for
|
||||
// the response. The idea is to return the rcode corresponding to the first
|
||||
// error which occurs.
|
||||
func (tx *Tx) setRcode(x int) {
|
||||
if tx.rcode == 0 {
|
||||
tx.rcode = x
|
||||
}
|
||||
}
|
||||
|
||||
type Error interface {
|
||||
error
|
||||
Rcode() int
|
||||
}
|
||||
|
||||
type Rerr struct {
|
||||
error
|
||||
e error
|
||||
rcode int
|
||||
}
|
||||
|
||||
func (re *Rerr) Error() string {
|
||||
return re.e.Error()
|
||||
}
|
||||
|
||||
func (re *Rerr) Rcode() int {
|
||||
return re.rcode
|
||||
}
|
||||
|
||||
func rerrorf(rcode int, fmts string, args ...interface{}) Error {
|
||||
re := &Rerr{}
|
||||
re.e = fmt.Errorf(fmts, args...)
|
||||
re.rcode = rcode
|
||||
return re
|
||||
}
|
||||
|
||||
// Determines the maximum TTL for a slice of resource records.
|
||||
// Returns 0 if the slice is empty.
|
||||
func rraMaxTTL(rra []dns.RR) uint32 {
|
||||
x := uint32(0)
|
||||
for _, rr := range rra {
|
||||
@ -118,6 +104,7 @@ func rraMaxTTL(rra []dns.RR) uint32 {
|
||||
return x
|
||||
}
|
||||
|
||||
// Used by signResponseSection.
|
||||
func (tx *Tx) signRRs(rra []dns.RR, useKSK bool) (dns.RR, error) {
|
||||
if len(rra) == 0 {
|
||||
return nil, fmt.Errorf("no RRs to such")
|
||||
@ -152,6 +139,7 @@ func (tx *Tx) signRRs(rra []dns.RR, useKSK bool) (dns.RR, error) {
|
||||
return rrsig, nil
|
||||
}
|
||||
|
||||
// Used by signResponse.
|
||||
func (tx *Tx) signResponseSection(rra *[]dns.RR) error {
|
||||
if len(*rra) == 0 {
|
||||
return nil
|
||||
@ -202,6 +190,8 @@ func (tx *Tx) signResponseSection(rra *[]dns.RR) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is called to append RRSIGs to the response based on the current records in the Answer and
|
||||
// Authority sections of the response. Records in the Additional section are not signed.
|
||||
func (tx *Tx) signResponse() error {
|
||||
if !tx.useDNSSEC() {
|
||||
return nil
|
||||
@ -219,6 +209,7 @@ func (tx *Tx) signResponse() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Used for sorting RRTYPE lists for encoding into type bit maps.
|
||||
type uint16Slice []uint16
|
||||
func (p uint16Slice) Len() int { return len(p) }
|
||||
func (p uint16Slice) Less(i, j int) bool { return p[i] < p[j] }
|
||||
|
Loading…
Reference in New Issue
Block a user