diff --git a/tdns/dns-storage.hh b/tdns/dns-storage.hh index a301fc7..88190e9 100644 --- a/tdns/dns-storage.hh +++ b/tdns/dns-storage.hh @@ -20,24 +20,16 @@ SMARTENUMSTART(RCode) SENUM5(RCode, Noerror, Servfail, Nxdomain, Notimp, Refused) SMARTENUMEND(RCode) - enum class DNSType : uint16_t { - A = 1, NS = 2, CNAME = 5, SOA=6, MX=15, AAAA = 28, IXFR = 251, AXFR = 252, ANY = 255 + A = 1, NS = 2, CNAME = 5, SOA=6, PTR=12, MX=15, TXT=16, AAAA = 28, SRV=33, IXFR = 251, AXFR = 252, ANY = 255 }; SMARTENUMSTART(DNSType) -SENUM11(DNSType, A, NS, CNAME, SOA, MX, AAAA, IXFR, AAAA, IXFR, AXFR, ANY) +SENUM13(DNSType, A, NS, CNAME, SOA, PTR, MX, AAAA, IXFR, AAAA, SRV, IXFR, AXFR, ANY) SMARTENUMEND(DNSType) -enum class DNSSection -{ - Question, Answer, Authority, Additional -}; - -SMARTENUMSTART(DNSSection) -SENUM4(DNSSection, Question, Answer, Authority, Additional) -SMARTENUMEND(DNSSection) +COMBOENUM4(DNSSection, Question, 0, Answer, 1, Authority, 2, Additional,3 ) struct dnsname { @@ -55,9 +47,9 @@ struct dnsname std::deque d_name; }; - std::ostream & operator<<(std::ostream &os, const dnsname& d); dnsname operator+(const dnsname& a, const dnsname& b); + struct RRSet { std::vector contents; diff --git a/tdns/dns-types.hh b/tdns/dns-types.hh new file mode 100644 index 0000000..3c82ee1 --- /dev/null +++ b/tdns/dns-types.hh @@ -0,0 +1,17 @@ +#pragma once +#include "dns-storage.hh" + +struct DNSPacketWriter; + +struct RRGenerator +{ + virtual void toPacket(DNSPacketWriter& dpw) = 0; +}; + +struct AGenerator : RRGenerator +{ + std::unique_ptr make(ComboAddress); + std::unique_ptr make(std::string); + void toPacket(DNSPacketWriter& dpw) override; + uint32_t d_ip; +}; diff --git a/tdns/nenum.hh b/tdns/nenum.hh index 4d87137..4c7b350 100644 --- a/tdns/nenum.hh +++ b/tdns/nenum.hh @@ -7,6 +7,7 @@ #include #include + #define SMARTENUMSTART(x) static constexpr std::pair enumtypemap##x[]= { #define SENUM(x,a1) { x::a1, #a1}, #define SENUM2(x, a1, ...) SENUM(x,a1) SENUM(x, __VA_ARGS__) @@ -19,6 +20,8 @@ #define SENUM9(x, a1, ...) SENUM(x,a1) SENUM8(x, __VA_ARGS__) #define SENUM10(x, a1, ...) SENUM(x,a1) SENUM9(x, __VA_ARGS__) #define SENUM11(x, a1, ...) SENUM(x,a1) SENUM10(x, __VA_ARGS__) +#define SENUM12(x, a1, ...) SENUM(x,a1) SENUM11(x, __VA_ARGS__) +#define SENUM13(x, a1, ...) SENUM(x,a1) SENUM12(x, __VA_ARGS__) #define SMARTENUMEND(x) }; \ inline const char* toString(const x& t) \ @@ -38,3 +41,6 @@ inline std::ostream& operator<<(std::ostream &os, const x& s) { \ os << toString(s); return os; } \ +#define COMBOENUM4(x, a1,b1,a2,b2,a3,b3,a4,b4) enum class x : uint16_t { \ + a1=b1, a2=b2, a3=b3, a4=b4 }; SMARTENUMSTART(x) SENUM4(x, a1, a2, a3,a4) \ + SMARTENUMEND(x) diff --git a/tdns/tdns.cc b/tdns/tdns.cc index 1c00720..a3c9e00 100644 --- a/tdns/tdns.cc +++ b/tdns/tdns.cc @@ -12,6 +12,8 @@ #include "dns.hh" #include "safearray.hh" #include +#include +#include "dns-types.hh" #include "dns-storage.hh" using namespace std; @@ -127,12 +129,9 @@ std::string serializeMXRecord(uint16_t prio, const dnsname& mname) std::string serializeSOARecord(const dnsname& mname, const dnsname& rname, uint32_t serial, uint32_t minimum=3600, uint32_t refresh=10800, uint32_t retry=3600, uint32_t expire=604800) { SafeArray<256> sa; - putName(sa, mname); - putName(sa, rname); - sa.putUInt32(serial); - sa.putUInt32(refresh); - sa.putUInt32(retry); - sa.putUInt32(expire); + putName(sa, mname); putName(sa, rname); + sa.putUInt32(serial); sa.putUInt32(refresh); + sa.putUInt32(retry); sa.putUInt32(expire); sa.putUInt32(minimum); return sa.serialize(); @@ -156,8 +155,6 @@ std::string serializeAAAARecord(const std::string& src) return std::string(p, p+16); } - - bool processQuestion(const DNSNode& zones, DNSMessage& dm, const ComboAddress& local, const ComboAddress& remote, DNSMessage& response) try { @@ -214,7 +211,18 @@ try cout<<"Have delegation"<second; for(const auto& rr : rrset.contents) { - response.putRR(DNSSection::Answer, lastnode+zone, DNSType::NS, rrset.ttl, rr); + response.putRR(DNSSection::Authority, lastnode+zone, DNSType::NS, rrset.ttl, rr); + } + 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); + } } // should do additional processing here } @@ -372,7 +380,6 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo response.payload.rewind(); response.setQuestion(zone, type); - // send all other records node->visit([&response,&sock,&name,&type,&zone](const dnsname& nname, const DNSNode* n) { cout<rrsets[DNSType::SOA].ttl, node->rrsets[DNSType::SOA].contents[0]); writeTCPResponse(sock, response); - return; } else { @@ -421,7 +427,6 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo } } - void loadZones(DNSNode& zones) { auto zone = zones.add({"powerdns", "org"}); @@ -448,6 +453,7 @@ void loadZones(DNSNode& zones) int main(int argc, char** argv) { + signal(SIGPIPE, SIG_IGN); ComboAddress local(argv[1], 53); Socket udplistener(local.sin4.sin_family, SOCK_DGRAM); @@ -459,7 +465,6 @@ int main(int argc, char** argv) SListen(tcplistener, 10); DNSNode zones; - loadZones(zones); thread udpServer(udpThread, local, &udplistener, &zones); @@ -470,5 +475,4 @@ int main(int argc, char** argv) thread t(tcpClientThread, local, remote, client, &zones); t.detach(); } - udpServer.join(); }