pull/18/head
Hugo Landau 10 years ago
parent a4a9e7038e
commit c3288a252c

@ -2,5 +2,3 @@ language: go
go:
- 1.3
- tip
# COVERALLS_TOKEN
secure: "K748GqgZz2I4yHcS49Zi78MWx/xWR79zl1YIGoFxHU4TS6JtGJF9gjqDdSv8DBvBEZRXFMq3n5M+/CtYkIf2jQeQawT6I+PKxHJvpFlpqseWxN/aJRHfVsd0NxbWq6Icx7qzUOvgwKDxMSgXqdndh3reHkyTgkou5XIDlU2zf7g="

@ -118,7 +118,7 @@ func (b *Backend) getNamecoinEntryLL(name string) (*domain, error) {
log.Info("namecoin query (", name, ") succeeded: ", v)
d, err := jsonToDomain(v)
d, err := b.jsonToDomain(v)
if err != nil {
log.Infoe(err, "cannot convert JSON to domain")
return nil, err
@ -127,10 +127,10 @@ func (b *Backend) getNamecoinEntryLL(name string) (*domain, error) {
return d, nil
}
func jsonToDomain(jsonValue string) (*domain, error) {
func (b *Backend) jsonToDomain(jsonValue string) (*domain, error) {
d := &domain{}
v, err := ncdomain.ParseValue(jsonValue, nil)
v, err := ncdomain.ParseValue(jsonValue, b.resolveExtraName)
if err != nil {
return nil, err
}
@ -140,6 +140,16 @@ func jsonToDomain(jsonValue string) (*domain, error) {
return d, nil
}
func (b *Backend) resolveExtraName(name string) (jsonValue string, err error) {
v, err := b.nc.Query(name)
if err != nil {
log.Infoe(err, "namecoin subquery failed: ", err)
return "", err
}
return v, nil
}
type btx struct {
b *Backend
qname string

@ -30,19 +30,30 @@ func (v *Value) RRs(out []dns.RR, suffix string) ([]dns.RR, error) {
il := len(out)
suffix = dns.Fqdn(suffix)
out, _ = v.appendIPs(out, suffix)
out, _ = v.appendIP6s(out, suffix)
out, _ = v.appendNSs(out, suffix)
out, _ = v.appendTXTs(out, suffix)
if len(v.NS) == 0 {
out, _ = v.appendTranslate(out, suffix)
if v.Translate == "" {
out, _ = v.appendAlias(out, suffix)
if v.Alias == "" {
out, _ = v.appendIPs(out, suffix)
out, _ = v.appendIP6s(out, suffix)
out, _ = v.appendTXTs(out, suffix)
out, _ = v.appendServices(out, suffix)
out, _ = v.appendMXs(out, suffix)
}
}
}
out, _ = v.appendDSs(out, suffix)
out, _ = v.appendServices(out, suffix)
out, _ = v.appendMXs(out, suffix)
out, _ = v.appendAlias(out, suffix)
out, _ = v.appendTranslate(out, suffix)
xout := out[il:]
for i := range xout {
xout[i].Header().Name = suffix
h := xout[i].Header()
if h.Rrtype == dns.TypeSRV {
h.Name += "." + suffix
} else {
h.Name = suffix
}
}
return out, nil
@ -175,10 +186,14 @@ func (v *Value) RRsRecursive(out []dns.RR, suffix string) ([]dns.RR, error) {
}
for mk, mv := range v.Map {
out, err = mv.RRsRecursive(out, mk+"."+suffix)
if err != nil {
return nil, err
if !validateLabel(mk) && mk != "" && mk != "*" {
continue
}
out, err = mv.RRsRecursive(out, mk+"."+suffix)
//if err != nil {
// return nil, err
//}
}
return out, nil
@ -188,6 +203,7 @@ type rawValue struct {
IP interface{} `json:"ip"`
IP6 interface{} `json:"ip6"`
NS interface{} `json:"ns"`
nsSet map[string]struct{}
DNS interface{} `json:"dns"` // actually an alias for NS
Alias interface{} `json:"alias"`
Translate interface{} `json:"translate"`
@ -326,30 +342,42 @@ func (rv *rawValue) parseNS(v *Value) error {
v.NS = nil
if rv.nsSet == nil {
rv.nsSet = map[string]struct{}{}
}
switch rv.NS.(type) {
case []interface{}:
for _, si := range rv.NS.([]interface{}) {
s, ok := si.(string)
if !ok || !validateHostName(s) {
if !ok {
continue
}
v.NS = append(v.NS, s)
rv.addNS(v, s)
}
return nil
case string:
s := rv.NS.(string)
if !validateHostName(s) {
return fmt.Errorf("malformed NS hostname")
}
v.NS = append(v.NS, s)
rv.addNS(v, s)
return nil
default:
return fmt.Errorf("unknown NS field format")
}
}
func (rv *rawValue) addNS(v *Value, s string) error {
if !validateHostName(s) {
return fmt.Errorf("malformed NS hostname")
}
if _, ok := rv.nsSet[s]; !ok {
v.NS = append(v.NS, s)
rv.nsSet[s] = struct{}{}
}
return nil
}
func (rv *rawValue) parseAlias(v *Value) error {
if rv.Alias == nil {
return nil
@ -417,7 +445,7 @@ func (rv *rawValue) parseDelegate(v *Value, resolve ResolveFunc, depth, mergeDep
}
func (rv *rawValue) parseHostmaster(v *Value) error {
if rv.Translate == nil {
if rv.Hostmaster == nil {
return nil
}
@ -498,11 +526,13 @@ func (rv *rawValue) parseTXT(v *Value) error {
// [["...", "..."], ["...", "..."]]
a := []string{}
for _, x := range sa {
if xs, ok := x.(string); ok {
if xs, ok := x.(string); ok && len(xs) <= 255 {
a = append(a, xs)
}
}
v.TXT = append(v.TXT, a)
if len(a) > 0 {
v.TXT = append(v.TXT, a)
}
} else if s, ok := vv.(string); ok {
v.TXT = append(v.TXT, segmentizeTXT(s))
} else {
@ -518,6 +548,24 @@ func (rv *rawValue) parseTXT(v *Value) error {
}
}
// Make sure the content of each TXT record does not exceed 65535 bytes.
for i := range v.TXT {
for {
L := 0
for j := range v.TXT[i] {
L += len(v.TXT[i][j]) + 1
}
if L <= 65535 {
break
}
// Pop segments until under the limit.
v.TXT[i] = v.TXT[i][0 : len(v.TXT[i])-1]
}
}
return nil
}
@ -725,8 +773,12 @@ func (v *Value) moveEmptyMapItems() error {
// Validation functions
var re_hostName = regexp.MustCompilePOSIX(`^([a-z0-9_-]+\.)*[a-z0-9_-]+\.?$`)
// This is used to validate NS records, targets in SRV records, etc. In these cases
// an IP address is not allowed. Therefore this regex must exclude all-numeric domain names.
// This is done by requiring the final part to start with an alphabetic character.
var re_hostName = regexp.MustCompilePOSIX(`^([a-z0-9_][a-z0-9_-]{0,62}\.)*[a-z_][a-z0-9_-]{0,62}\.?$`)
var re_serviceName = regexp.MustCompilePOSIX(`^[a-z_][a-z0-9_-]*$`)
var re_label = regexp.MustCompilePOSIX(`^[a-z0-9_][a-z0-9_-]*$`)
func validateHostName(name string) bool {
name = dns.Fqdn(name)
@ -737,6 +789,10 @@ func validateServiceName(name string) bool {
return len(name) < 63 && re_serviceName.MatchString(name)
}
func validateLabel(name string) bool {
return len(name) <= 63 && re_label.MatchString(name)
}
func validateEmail(email string) bool {
addr, err := mail.ParseAddress(email)
if addr == nil || err != nil {

@ -5,51 +5,53 @@ import "github.com/miekg/dns"
import "testing"
import "net"
import "fmt"
import "strings"
type item struct {
jsonValue string
value *ncdomain.Value
expectedError error
merges map[string]string
rrstr string
}
var suite = []item{
item{`{}`, &ncdomain.Value{}, nil, nil},
item{`{"ip":"1.2.3.4"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil},
item{`{"ip":["1.2.3.4"]}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil},
item{`{"ip":["1.2.3.4","200.200.200.200"]}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4"), net.ParseIP("200.200.200.200")}}, nil, nil},
item{`{"ip6":"dead:b33f::deca:fbad"}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad")}}, nil, nil},
item{`{"ip6":["dead:b33f::deca:fbad"]}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad")}}, nil, nil},
item{`{"ip6":["dead:b33f::deca:fbad","1234:abcd:5678:bcde:9876:fedc:5432:ba98"]}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad"), net.ParseIP("1234:abcd:5678:bcde:9876:fedc:5432:ba98")}}, nil, nil},
item{`{"ns":"alpha.beta.gamma.delta"}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta"}}, nil, nil},
item{`{"ns":["alpha.beta.gamma.delta"]}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta"}}, nil, nil},
item{`{"ns":["alpha.beta.gamma.delta","delta.gamma.beta.alpha"]}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta", "delta.gamma.beta.alpha"}}, nil, nil},
item{`{"mx":[[10,"alpha.beta.gamma.delta"]]}`, &ncdomain.Value{MX: []*dns.MX{&dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 10, Mx: "alpha.beta.gamma.delta"}}}, nil, nil},
item{`{"mx":[[10,"alpha.beta.gamma.delta"],[20,"epsilon.example"]]}`, &ncdomain.Value{MX: []*dns.MX{&dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 10, Mx: "alpha.beta.gamma.delta"}, &dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 20, Mx: "epsilon.example"}}}, nil, nil},
item{`{"alias":"alpha.beta.gamma.delta"}`, &ncdomain.Value{Alias: "alpha.beta.gamma.delta"}, nil, nil},
item{`{"translate":"alpha.beta.gamma.delta"}`, &ncdomain.Value{Translate: "alpha.beta.gamma.delta"}, nil, nil},
item{`{"txt":"text record"}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}}}, nil, nil},
item{`{"txt":"[text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record]"}`, &ncdomain.Value{TXT: [][]string{[]string{"[text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record]", "[text ... record]"}}}, nil, nil},
item{`{"txt":["text record"]}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}}}, nil, nil},
item{`{"txt":["text record","text record 2"]}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}, []string{"text record 2"}}}, nil, nil},
item{`{"txt":[["text", "record"]]}`, &ncdomain.Value{TXT: [][]string{[]string{"text", "record"}}}, nil, nil},
item{`{"txt":[["text", "record"],["text", "record", "2"]]}`, &ncdomain.Value{TXT: [][]string{[]string{"text", "record"}, []string{"text", "record", "2"}}}, nil, nil},
item{`{"service":[ ["http","tcp",1,2,80,"alpha.beta.gamma.delta"] ]}`, &ncdomain.Value{Service: []*dns.SRV{&dns.SRV{Hdr: dns.RR_Header{Name: "_http._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 80, Target: "alpha.beta.gamma.delta"}}}, nil, nil},
item{`{"service":[ ["http","tcp",1,2,80,"alpha.beta.gamma.delta"], ["https","tcp",1,2,443,"alpha.beta.gamma.delta"] ]}`, &ncdomain.Value{Service: []*dns.SRV{&dns.SRV{Hdr: dns.RR_Header{Name: "_http._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 80, Target: "alpha.beta.gamma.delta"}, &dns.SRV{Hdr: dns.RR_Header{Name: "_https._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 443, Target: "alpha.beta.gamma.delta"}}}, nil, nil},
item{`{"map":{ "": { } }}`, &ncdomain.Value{}, nil, nil},
item{`{"map":{ "": { "ip": "1.2.3.4" } }}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil},
item{`{"map":{ "www": { "ip": "1.2.3.4" } }}`, &ncdomain.Value{Map: map[string]*ncdomain.Value{"www": &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}}}, nil, nil},
item{`{"map":{ "": "1.2.3.4" }}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil},
item{`{"map":{ "www": "1.2.3.4" }}`, &ncdomain.Value{Map: map[string]*ncdomain.Value{"www": &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}}}, nil, nil},
item{`{"ds":[[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]]}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, nil},
item{`{"ds":[[54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="],[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]]}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 54321, Algorithm: 8, DigestType: 1, Digest: "e6c1716cfb6bdc84e84ce1ab5510dac69173b5b2"}, &dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, nil},
item{`{"email":"hostmaster@example.com"}`, &ncdomain.Value{Hostmaster: "hostmaster@example.com"}, nil, nil},
item{`{"ip":["1.2.3.4"],"import":"d/example"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip6":["::beef"]}`}},
item{`{"ip":["1.2.3.4"],"import":"d/example"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip":["2.3.4.5"],"ip6":["::beef"]}`}},
item{`{"ns":["alpha.beta"],"import":"d/example"}`, &ncdomain.Value{NS: []string{"alpha.beta"}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ns":["gamma.delta"],"ip6":["::beef"]}`}},
item{`{"ds":[[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]],"import":"d/example"}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, map[string]string{"d/example": `{"ds":[ [54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="] ]}`}},
item{`{"import":"d/example"}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 54321, Algorithm: 8, DigestType: 1, Digest: "e6c1716cfb6bdc84e84ce1ab5510dac69173b5b2"}}}, nil, map[string]string{"d/example": `{"ds":[ [54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="] ]}`}},
item{`{"ip":["1.2.3.4"],"delegate":"d/example"}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip6":["::beef"]}`}},
item{`{}`, &ncdomain.Value{}, nil, nil, ""},
item{`{"ip":"1.2.3.4"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
item{`{"ip":["1.2.3.4"]}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
item{`{"ip":["1.2.3.4","200.200.200.200"]}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4"), net.ParseIP("200.200.200.200")}}, nil, nil, "bit. 600 IN A 1.2.3.4\nbit. 600 IN A 200.200.200.200"},
item{`{"ip6":"dead:b33f::deca:fbad"}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad")}}, nil, nil, "bit. 600 IN AAAA dead:b33f::deca:fbad"},
item{`{"ip6":["dead:b33f::deca:fbad"]}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad")}}, nil, nil, "bit. 600 IN AAAA dead:b33f::deca:fbad"},
item{`{"ip6":["dead:b33f::deca:fbad","1234:abcd:5678:bcde:9876:fedc:5432:ba98"]}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("dead:b33f::deca:fbad"), net.ParseIP("1234:abcd:5678:bcde:9876:fedc:5432:ba98")}}, nil, nil, "bit. 600 IN AAAA dead:b33f::deca:fbad\nbit. 600 IN AAAA 1234:abcd:5678:bcde:9876:fedc:5432:ba98"},
item{`{"ns":"alpha.beta.gamma.delta"}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta"}}, nil, nil, "bit. 600 IN NS alpha.beta.gamma.delta."},
item{`{"ns":["alpha.beta.gamma.delta"]}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta"}}, nil, nil, "bit. 600 IN NS alpha.beta.gamma.delta."},
item{`{"ns":["alpha.beta.gamma.delta","delta.gamma.beta.alpha"]}`, &ncdomain.Value{NS: []string{"alpha.beta.gamma.delta", "delta.gamma.beta.alpha"}}, nil, nil, "bit. 600 IN NS alpha.beta.gamma.delta.\nbit. 600 IN NS delta.gamma.beta.alpha."},
item{`{"mx":[[10,"alpha.beta.gamma.delta"]]}`, &ncdomain.Value{MX: []*dns.MX{&dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 10, Mx: "alpha.beta.gamma.delta"}}}, nil, nil, "bit. 600 IN MX 10 alpha.beta.gamma.delta."},
item{`{"mx":[[10,"alpha.beta.gamma.delta"],[20,"epsilon.example"]]}`, &ncdomain.Value{MX: []*dns.MX{&dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 10, Mx: "alpha.beta.gamma.delta"}, &dns.MX{Hdr: dns.RR_Header{Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 600}, Preference: 20, Mx: "epsilon.example"}}}, nil, nil, "bit. 600 IN MX 10 alpha.beta.gamma.delta.\nbit. 600 IN MX 20 epsilon.example."},
item{`{"alias":"alpha.beta.gamma.delta"}`, &ncdomain.Value{Alias: "alpha.beta.gamma.delta"}, nil, nil, "bit. 600 IN CNAME alpha.beta.gamma.delta."},
item{`{"translate":"alpha.beta.gamma.delta"}`, &ncdomain.Value{Translate: "alpha.beta.gamma.delta"}, nil, nil, "bit. 600 IN DNAME alpha.beta.gamma.delta."},
item{`{"txt":"text record"}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}}}, nil, nil, "bit. 600 IN TXT \"text record\""},
item{`{"txt":"[text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record]"}`, &ncdomain.Value{TXT: [][]string{[]string{"[text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record][text ... record]", "[text ... record]"}}}, nil, nil, ""},
item{`{"txt":["text record"]}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}}}, nil, nil, "bit. 600 IN TXT \"text record\""},
item{`{"txt":["text record","text record 2"]}`, &ncdomain.Value{TXT: [][]string{[]string{"text record"}, []string{"text record 2"}}}, nil, nil, "bit. 600 IN TXT \"text record\"\nbit. 600 IN TXT \"text record 2\""},
item{`{"txt":[["text", "record"]]}`, &ncdomain.Value{TXT: [][]string{[]string{"text", "record"}}}, nil, nil, "bit. 600 IN TXT \"text\" \"record\""},
item{`{"txt":[["text", "record"],["text", "record", "2"]]}`, &ncdomain.Value{TXT: [][]string{[]string{"text", "record"}, []string{"text", "record", "2"}}}, nil, nil, "bit. 600 IN TXT \"text\" \"record\"\nbit. 600 IN TXT \"text\" \"record\" \"2\""},
item{`{"service":[ ["http","tcp",1,2,80,"alpha.beta.gamma.delta"] ]}`, &ncdomain.Value{Service: []*dns.SRV{&dns.SRV{Hdr: dns.RR_Header{Name: "_http._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 80, Target: "alpha.beta.gamma.delta"}}}, nil, nil, "_http._tcp.bit. IN SRV 1 2 80 alpha.beta.gamma.delta."},
item{`{"service":[ ["http","tcp",1,2,80,"alpha.beta.gamma.delta"], ["https","tcp",1,2,443,"alpha.beta.gamma.delta"] ]}`, &ncdomain.Value{Service: []*dns.SRV{&dns.SRV{Hdr: dns.RR_Header{Name: "_http._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 80, Target: "alpha.beta.gamma.delta"}, &dns.SRV{Hdr: dns.RR_Header{Name: "_https._tcp", Ttl: 600, Rrtype: dns.TypeSRV, Class: dns.ClassINET}, Priority: 1, Weight: 2, Port: 443, Target: "alpha.beta.gamma.delta"}}}, nil, nil, "_http._tcp.bit. 600 IN SRV 1 2 80 alpha.beta.gamma.delta.\n_https._tcp.bit. 600 IN SRV 1 2 443 alpha.beta.gamma.delta."},
item{`{"map":{ "": { } }}`, &ncdomain.Value{}, nil, nil, ""},
item{`{"map":{ "": { "ip": "1.2.3.4" } }}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
item{`{"map":{ "www": { "ip": "1.2.3.4" } }}`, &ncdomain.Value{Map: map[string]*ncdomain.Value{"www": &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}}}, nil, nil, "www.bit. 600 IN A 1.2.3.4"},
item{`{"map":{ "": "1.2.3.4" }}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}, nil, nil, "bit. 600 IN A 1.2.3.4"},
item{`{"map":{ "www": "1.2.3.4" }}`, &ncdomain.Value{Map: map[string]*ncdomain.Value{"www": &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}}}}, nil, nil, "www.bit. 600 IN A 1.2.3.4"},
item{`{"ds":[[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]]}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, nil, "bit. 600 IN DS 12345 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"},
item{`{"ds":[[54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="],[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]]}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 54321, Algorithm: 8, DigestType: 1, Digest: "e6c1716cfb6bdc84e84ce1ab5510dac69173b5b2"}, &dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, nil, "bit. 600 IN DS 54321 8 1 E6C1716CFB6BDC84E84CE1AB5510DAC69173B5B2\nbit. 600 IN DS 12345 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"},
item{`{"email":"hostmaster@example.com"}`, &ncdomain.Value{Hostmaster: "hostmaster@example.com"}, nil, nil, ""},
item{`{"ip":["1.2.3.4"],"import":"d/example"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip6":["::beef"]}`}, "bit. 600 IN A 1.2.3.4\nbit. 600 IN AAAA ::beef"},
item{`{"ip":["1.2.3.4"],"import":"d/example"}`, &ncdomain.Value{IP: []net.IP{net.ParseIP("1.2.3.4")}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip":["2.3.4.5"],"ip6":["::beef"]}`}, "bit. 600 IN A 1.2.3.4\nbit. 600 IN AAAA ::beef"},
item{`{"ns":["alpha.beta"],"import":"d/example"}`, &ncdomain.Value{NS: []string{"alpha.beta"}, IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ns":["gamma.delta"],"ip6":["::beef"]}`}, "bit. 600 IN NS alpha.beta."},
item{`{"ds":[[12345,8,2,"4tPJFvbe6scylOgmj7WIUESoM/xUWViPSpGEz8QaV2Y="]],"import":"d/example"}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 12345, Algorithm: 8, DigestType: 2, Digest: "e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766"}}}, nil, map[string]string{"d/example": `{"ds":[ [54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="] ]}`}, "bit. 600 IN DS 12345 8 2 E2D3C916F6DEEAC73294E8268FB5885044A833FC5459588F4A9184CFC41A5766"},
item{`{"import":"d/example"}`, &ncdomain.Value{DS: []*dns.DS{&dns.DS{Hdr: dns.RR_Header{Rrtype: dns.TypeDS, Class: dns.ClassINET, Ttl: 600}, KeyTag: 54321, Algorithm: 8, DigestType: 1, Digest: "e6c1716cfb6bdc84e84ce1ab5510dac69173b5b2"}}}, nil, map[string]string{"d/example": `{"ds":[ [54321,8,1,"5sFxbPtr3IToTOGrVRDaxpFztbI="] ]}`}, "bit. 600 IN DS 54321 8 1 E6C1716CFB6BDC84E84CE1AB5510DAC69173B5B2"},
item{`{"ip":["1.2.3.4"],"delegate":"d/example"}`, &ncdomain.Value{IP6: []net.IP{net.ParseIP("::beef")}}, nil, map[string]string{"d/example": `{"ip6":["::beef"]}`}, "bit. 600 IN AAAA ::beef"},
}
func TestConversion(t *testing.T) {
@ -72,6 +74,18 @@ func TestConversion(t *testing.T) {
if !equals(v, item.value) {
t.Errorf("Item %d value did not match expected value: got %+v but expected %+v", i, v, item.value)
}
if item.rrstr != "" {
rrstr := ""
rrs, _ := v.RRsRecursive(nil, "bit.")
for _, rr := range rrs {
rrstr += strings.Replace(rr.String(), "\t", " ", -1)
rrstr += "\n"
}
rrstr = strings.Trim(rrstr, "\n")
if item.rrstr != rrstr {
t.Errorf("Item %d rrstr did not match the expected value: got %+v but expected %+v", i, rrstr, item.rrstr)
}
}
}
}
@ -83,10 +97,12 @@ func equals(v1 *ncdomain.Value, v2 *ncdomain.Value) bool {
eqIPArray(v1.IP6, v2.IP6) &&
eqStringArray(v1.NS, v2.NS) &&
v1.Alias == v2.Alias &&
v1.Translate == v2.Translate &&
eqDSArray(v1.DS, v2.DS) &&
eqStringArrayArray(v1.TXT, v2.TXT) &&
eqServiceArray(v1.Service, v2.Service) &&
eqValueMap(v1, v2)
eqValueMap(v1, v2) &&
v1.Hostmaster == v2.Hostmaster
}
func eqIPArray(a []net.IP, b []net.IP) bool {

@ -2,8 +2,12 @@ package util
import "strings"
// Split a domain name a.b.c.d.e into parts a (the head) and b.c.d.e (the rest).
// Split a domain name a.b.c.d.e into parts e (the head) and a.b.c.d (the rest).
func SplitDomainHead(name string) (head string, rest string, err error) {
if len(name) > 0 && name[len(name)-1] == '.' {
name = name[0 : len(name)-1]
}
parts := strings.Split(name, ".")
head = parts[len(parts)-1]

Loading…
Cancel
Save