From ab91a50402ecb4c2e5f9b472065a65a8eacb94d5 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Mon, 9 Apr 2018 20:49:37 +0200 Subject: [PATCH] it works again --- tdns/dns-storage.cc | 17 +++++++++ tdns/dns-storage.hh | 8 +++++ tdns/dns-types.cc | 15 ++++---- tdns/dns-types.hh | 29 +++++++++++++-- tdns/dnsmessages.cc | 4 +-- tdns/dnsmessages.hh | 1 + tdns/safearray.hh | 9 ++++- tdns/tdns.cc | 86 +++++++++++++++++++++++++-------------------- 8 files changed, 118 insertions(+), 51 deletions(-) diff --git a/tdns/dns-storage.cc b/tdns/dns-storage.cc index ccd6dba..c9e219e 100644 --- a/tdns/dns-storage.cc +++ b/tdns/dns-storage.cc @@ -1,6 +1,23 @@ #include "dns-storage.hh" using namespace std; +bool dnsname::makeRelative(const dnsname& root) +{ + auto us = d_name, them=root.d_name; + while(!them.empty()) { + if(us.empty()) + return false; + if(us.back() == them.back()) { + us.pop_back(); + them.pop_back(); + } + else + return false; + } + d_name = us; + return true; +} + const DNSNode* DNSNode::find(dnsname& name, dnsname& last, bool* passedZonecut) const { cout<<"find for '"< #include #include +#include #include "nenum.hh" typedef std::string dnslabel; @@ -44,6 +45,9 @@ struct dnsname void pop_back() { d_name.pop_back(); } auto push_front(const dnslabel& dn) { return d_name.push_front(dn); } auto size() { return d_name.size(); } + + bool makeRelative(const dnsname& root); + std::deque d_name; }; @@ -60,6 +64,10 @@ struct RRGenerator struct RRSet { std::vector> contents; + void add(std::unique_ptr&& rr) + { + contents.emplace_back(std::move(rr)); + } uint32_t ttl{3600}; }; diff --git a/tdns/dns-types.cc b/tdns/dns-types.cc index 6a3054a..b59b32c 100644 --- a/tdns/dns-types.cc +++ b/tdns/dns-types.cc @@ -35,14 +35,15 @@ void SOAGenerator::toMessage(DNSMessageWriter& dmw) dmw.payload.putUInt32(d_minimum); } -#if 0 -std::string serializeMXRecord(uint16_t prio, const dnsname& mname) +void NameGenerator::toMessage(DNSMessageWriter& dmw) { - SafeArray<256> sa; - sa.putUInt16(prio); - putName(sa, mname); - return sa.serialize(); + putName(dmw.payload, d_name); +} + +void MXGenerator::toMessage(DNSMessageWriter& dmw) +{ + dmw.payload.putUInt16(d_prio); + putName(dmw.payload, d_name); } -#endif diff --git a/tdns/dns-types.hh b/tdns/dns-types.hh index 1d97b22..2949a9d 100644 --- a/tdns/dns-types.hh +++ b/tdns/dns-types.hh @@ -37,12 +37,35 @@ struct SOAGenerator : RRGenerator d_mname(mname), d_rname(rname), d_serial(serial), d_minimum(minimum), d_refresh(refresh), d_retry(retry), d_expire(expire) {} - template - static std::unique_ptr make(Targs&&... fargs) + template + static std::unique_ptr make(const dnsname& mname, const dnsname& rname, Targs&& ... fargs) { - return std::move(std::make_unique(std::forward(fargs)...)); + return std::move(std::make_unique(mname, rname, std::forward(fargs)...)); } void toMessage(DNSMessageWriter& dpw) override; dnsname d_mname, d_rname; uint32_t d_serial, d_minimum, d_refresh, d_retry, d_expire; }; + +struct NameGenerator : RRGenerator +{ + NameGenerator(const dnsname& name) : d_name(name) {} + static std::unique_ptr make(const dnsname& mname) + { + return std::move(std::make_unique(mname)); + } + void toMessage(DNSMessageWriter& dpw) override; + dnsname d_name; +}; + +struct MXGenerator : RRGenerator +{ + MXGenerator(uint16_t prio, const dnsname& name) : d_prio(prio), d_name(name) {} + static std::unique_ptr make(uint16_t prio, const dnsname& name) + { + return std::move(std::make_unique(prio, name)); + } + void toMessage(DNSMessageWriter& dpw) override; + uint16_t d_prio; + dnsname d_name; +}; diff --git a/tdns/dnsmessages.cc b/tdns/dnsmessages.cc index 89e7c08..ed6c6b4 100644 --- a/tdns/dnsmessages.cc +++ b/tdns/dnsmessages.cc @@ -32,9 +32,9 @@ void DNSMessageWriter::putRR(DNSSection section, const dnsname& name, DNSType ty putName(payload, name); payload.putUInt16((int)type); payload.putUInt16(1); payload.putUInt32(ttl); - payload.putUInt16(0); // XXXX + auto pos = payload.putUInt16(0); // placeholder content->toMessage(*this); - payload.putBlob(content); + payload.putUInt16At(pos, payload.payloadpos-pos-2); } catch(...) { payload.payloadpos = cursize; diff --git a/tdns/dnsmessages.hh b/tdns/dnsmessages.hh index 9531e02..0dab8b9 100644 --- a/tdns/dnsmessages.hh +++ b/tdns/dnsmessages.hh @@ -1,3 +1,4 @@ +#pragma once #include "dns.hh" #include "safearray.hh" #include "dns-storage.hh" diff --git a/tdns/safearray.hh b/tdns/safearray.hh index 439ff66..713386c 100644 --- a/tdns/safearray.hh +++ b/tdns/safearray.hh @@ -35,11 +35,18 @@ struct SafeArray payload.at(payloadpos++)=val; } - void putUInt16(uint16_t val) + uint16_t putUInt16(uint16_t val) { val = htons(val); memcpy(&payload.at(payloadpos+2)-2, &val, 2); payloadpos+=2; + return payloadpos - 2; + } + + void putUInt16At(uint16_t pos, uint16_t val) + { + val = htons(val); + memcpy(&payload.at(pos+2)-2, &val, 2); } void putUInt32(uint32_t val) diff --git a/tdns/tdns.cc b/tdns/tdns.cc index 1079960..168c21c 100644 --- a/tdns/tdns.cc +++ b/tdns/tdns.cc @@ -18,17 +18,6 @@ using namespace std; -std::string serializeDNSName(const dnsname& dn) -{ - std::string ret; - for(const auto & l : dn) { - ret.append(1, l.size()); - ret+=l; - } - ret.append(1, (char)0); - return ret; -} - bool processQuestion(const DNSNode& zones, DNSMessageReader& dm, const ComboAddress& local, const ComboAddress& remote, DNSMessageWriter& response) try { @@ -67,6 +56,8 @@ try auto bestzone = fnd->zone; dnsname searchname(name), lastnode; bool passedZonecut=false; + int CNAMELoopCount = 0; + loopCNAME:; auto node = bestzone->find(searchname, lastnode, &passedZonecut); if(passedZonecut) response.dh.aa = false; @@ -84,21 +75,32 @@ try if(iter != node->rrsets.end() && passedZonecut) { cout<<"Have delegation"<second; + vector toresolve; for(const auto& rr : rrset.contents) { response.putRR(DNSSection::Authority, lastnode+zone, DNSType::NS, rrset.ttl, rr); + toresolve.push_back(dynamic_cast(rr.get())->d_name); } - dnsname addname{"ns1", "fra"}, wuh; - cout<<"Looking up glue record "<find(addname, wuh); - auto iter2 = addnode->rrsets.find(DNSType::A); - if(iter2 != addnode->rrsets.end()) { - cout<<"Lastnode for '"<second; - for(const auto& rr : rrset.contents) { - response.putRR(DNSSection::Additional, wuh+zone, DNSType::A, rrset.ttl, rr); + + for(auto& addname : toresolve ) { + if(!addname.makeRelative(zone)) { + cout<find(addname, wuh); + if(!addnode || !addname.empty()) { + cout<<"Found nothing, continuing"<rrsets.find(DNSType::A); + if(iter2 != addnode->rrsets.end()) { + cout<<"Lastnode for '"<second; + for(const auto& rr : rrset.contents) { + response.putRR(DNSSection::Additional, wuh+zone, DNSType::A, rrset.ttl, rr); + } } } - // should do additional processing here } else { cout<<"This is an NXDOMAIN situation"<rrsets.find(DNSType::CNAME), iter != node->rrsets.end()) { cout<<"We do have a CNAME!"<second; + dnsname target; for(const auto& rr : rrset.contents) { response.putRR(DNSSection::Answer, lastnode+zone, DNSType::CNAME, rrset.ttl, rr); + target=dynamic_cast(rr.get())->d_name; } - cout<<" We should actually follow this, at least within our zone"<zone = new DNSNode(); // XXX ICK - SOAGenerator::make({"ns1", "powerdns", "org"}, {"admin", "powerdns", "org"}, 1); - // zone->zone->rrsets[DNSType::SOA]={{}}; - // zone->zone->rrsets[DNSType::MX]={{serializeMXRecord(25, {"server1", "powerdns", "org"})}}; + + zone->zone->rrsets[DNSType::SOA].add(SOAGenerator::make({"ns1", "powerdns", "org"}, {"admin", "powerdns", "org"}, 1)); + zone->zone->rrsets[DNSType::MX].add(MXGenerator::make(25, {"server1", "powerdns", "org"})); - zone->zone->rrsets[DNSType::A]={{serializeARecord("1.2.3.4")}, 300}; - zone->zone->rrsets[DNSType::AAAA]={{serializeAAAARecord("::1"), serializeAAAARecord("2001::1"), serializeAAAARecord("2a02:a440:b085:1:beee:7bff:fe89:f0fb")}, 900}; - zone->zone->rrsets[DNSType::NS]={{serializeDNSName({"ns1", "powerdns", "org"})}, 300}; + zone->zone->rrsets[DNSType::A].add(AGenerator::make("1.2.3.4")); + zone->zone->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1")); + zone->zone->rrsets[DNSType::AAAA].ttl= 900; + zone->zone->rrsets[DNSType::NS].add(NameGenerator::make({"ns1", "powerdns", "org"})); - zone->zone->add({"www"})->rrsets[DNSType::CNAME]={{serializeDNSName({"server1","powerdns","org"})}}; + zone->zone->add({"www"})->rrsets[DNSType::CNAME].add(NameGenerator::make({"server1","powerdns","org"})); - zone->zone->add({"server1"})->rrsets[DNSType::A]={{serializeARecord("213.244.168.210")}}; - zone->zone->add({"server1"})->rrsets[DNSType::AAAA]={{serializeAAAARecord("::1")}}; + zone->zone->add({"server1"})->rrsets[DNSType::A].add(AGenerator::make("213.244.168.210")); + zone->zone->add({"server1"})->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1")); // zone->zone->add({"*"})->rrsets[(dnstype)DNSType::A]={"\x05\x06\x07\x08"}; - zone->zone->add({"fra"})->rrsets[DNSType::NS]={{serializeDNSName({"ns1","fra","powerdns","org"})}}; + zone->zone->add({"fra"})->rrsets[DNSType::NS].add(NameGenerator::make({"ns1","fra","powerdns","org"})); + zone->zone->add({"fra"})->rrsets[DNSType::NS].add(NameGenerator::make({"ns2","fra","powerdns","org"})); - zone->zone->add({"ns1", "fra"})->rrsets[DNSType::A]={{serializeARecord("12.13.14.15")}, 86400}; - zone->zone->add({"NS2", "fra"})->rrsets[DNSType::A]={{serializeARecord("12.13.14.16")}, 86400}; + zone->zone->add({"ns1", "fra"})->rrsets[DNSType::A].add(AGenerator::make("12.13.14.15")); + zone->zone->add({"NS2", "fra"})->rrsets[DNSType::A].add(AGenerator::make("12.13.14.16")); } int main(int argc, char** argv)