Skip to content

Commit

Permalink
added ns record support
Browse files Browse the repository at this point in the history
  • Loading branch information
256dpi committed Jan 30, 2020
1 parent c9692d9 commit 5cea949
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 1 deletion.
7 changes: 7 additions & 0 deletions record.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,12 @@ func (r *Record) Validate(typ Type) error {
}
}

// validate NS addresses
if typ == NS {
if !IsDomain(r.Address, true) {
return errors.Errorf("invalid ns name: %s", r.Address)
}
}

return nil
}
9 changes: 9 additions & 0 deletions record_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ func TestRecordValidate(t *testing.T) {
typ: TXT,
rec: Record{Data: []string{"foo"}},
},
{
typ: NS,
rec: Record{Address: "foo.com"},
err: "invalid ns name: foo.com",
},
{
typ: NS,
rec: Record{Address: "foo.com."},
},
}

for i, item := range table {
Expand Down
17 changes: 17 additions & 0 deletions server.go
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ func (s *Server) handler(w dns.ResponseWriter, rq *dns.Msg) {
// prepare extra set
var extra []Set

// TODO: Lookup glue records for NS records?

// lookup extra sets
for _, set := range answer {
for _, record := range set.Records {
Expand Down Expand Up @@ -323,6 +325,16 @@ func (s *Server) handler(w dns.ResponseWriter, rq *dns.Msg) {
})
}

// check if NS query
if typ == NS {
// move answers
rs.Ns = rs.Answer
rs.Answer = nil

// no authoritative response for other zone in NS queries
rs.Authoritative = false
}

// write message
s.writeMessage(w, rq, rs)
}
Expand Down Expand Up @@ -490,6 +502,11 @@ func (s *Server) convert(query string, zone *Zone, set Set) []dns.RR {
Hdr: header,
Txt: record.Data,
})
case NS:
list = append(list, &dns.NS{
Hdr: header,
Ns: dns.Fqdn(record.Address),
})
}
}

Expand Down
52 changes: 52 additions & 0 deletions server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,20 @@ func TestServer(t *testing.T) {
}, nil
}

// handle other
if name == "other" {
return []Set{
{
Name: "other.newdns.256dpi.com.",
Type: NS,
Records: []Record{
{Address: "ns1.example.com."},
{Address: "ns2.example.com."},
},
},
}, nil
}

return nil, nil
},
}
Expand Down Expand Up @@ -1016,13 +1030,50 @@ func conformanceTests(t *testing.T, proto, addr string) {
}, ret)
})

t.Run("SubNS", func(t *testing.T) {
ret, err := Query(proto, addr, "other.newdns.256dpi.com.", "NS", nil)
assert.NoError(t, err)
equalJSON(t, &dns.Msg{
MsgHdr: dns.MsgHdr{
Response: true,
Authoritative: false,
},
Question: []dns.Question{
{Name: "other.newdns.256dpi.com.", Qtype: dns.TypeNS, Qclass: dns.ClassINET},
},
Ns: []dns.RR{
&dns.NS{
Hdr: dns.RR_Header{
Name: "other.newdns.256dpi.com.",
Rrtype: dns.TypeNS,
Class: dns.ClassINET,
Ttl: 300,
Rdlength: 14,
},
Ns: "ns1.example.com.",
},
&dns.NS{
Hdr: dns.RR_Header{
Name: "other.newdns.256dpi.com.",
Rrtype: dns.TypeNS,
Class: dns.ClassINET,
Ttl: 300,
Rdlength: 6,
},
Ns: "ns2.example.com.",
},
},
}, ret)
})

t.Run("NoExactRecord", func(t *testing.T) {
assertMissing(t, proto, addr, "ip4.newdns.256dpi.com.", "CNAME", dns.RcodeSuccess)
assertMissing(t, proto, addr, "ip6.newdns.256dpi.com.", "CNAME", dns.RcodeSuccess)
assertMissing(t, proto, addr, "ip4.newdns.256dpi.com.", "AAAA", dns.RcodeSuccess)
assertMissing(t, proto, addr, "ip6.newdns.256dpi.com.", "A", dns.RcodeSuccess)
assertMissing(t, proto, addr, "mail.newdns.256dpi.com.", "A", dns.RcodeSuccess)
assertMissing(t, proto, addr, "text.newdns.256dpi.com.", "A", dns.RcodeSuccess)
assertMissing(t, proto, addr, "ip4.newdns.256dpi.com.", "NS", dns.RcodeSuccess)
})

t.Run("NoExistingRecord", func(t *testing.T) {
Expand All @@ -1031,6 +1082,7 @@ func conformanceTests(t *testing.T, proto, addr string) {
assertMissing(t, proto, addr, "missing.newdns.256dpi.com.", "CNAME", dns.RcodeNameError)
assertMissing(t, proto, addr, "missing.newdns.256dpi.com.", "MX", dns.RcodeNameError)
assertMissing(t, proto, addr, "missing.newdns.256dpi.com.", "TXT", dns.RcodeNameError)
assertMissing(t, proto, addr, "missing.newdns.256dpi.com.", "NS", dns.RcodeNameError)
})

t.Run("TruncatedResponse", func(t *testing.T) {
Expand Down
5 changes: 4 additions & 1 deletion type.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ const (

// TXT records return arbitrary text data.
TXT = Type(dns.TypeTXT)

// NS records delegate names to other name servers.
NS = Type(dns.TypeNS)
)

func (t Type) valid() bool {
switch t {
case A, AAAA, CNAME, MX, TXT:
case A, AAAA, CNAME, MX, TXT, NS:
return true
default:
return false
Expand Down

0 comments on commit 5cea949

Please sign in to comment.