its a WIP
This commit is contained in:
@ -20,24 +20,16 @@ SMARTENUMSTART(RCode)
|
|||||||
SENUM5(RCode, Noerror, Servfail, Nxdomain, Notimp, Refused)
|
SENUM5(RCode, Noerror, Servfail, Nxdomain, Notimp, Refused)
|
||||||
SMARTENUMEND(RCode)
|
SMARTENUMEND(RCode)
|
||||||
|
|
||||||
|
|
||||||
enum class DNSType : uint16_t
|
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)
|
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)
|
SMARTENUMEND(DNSType)
|
||||||
|
|
||||||
enum class DNSSection
|
COMBOENUM4(DNSSection, Question, 0, Answer, 1, Authority, 2, Additional,3 )
|
||||||
{
|
|
||||||
Question, Answer, Authority, Additional
|
|
||||||
};
|
|
||||||
|
|
||||||
SMARTENUMSTART(DNSSection)
|
|
||||||
SENUM4(DNSSection, Question, Answer, Authority, Additional)
|
|
||||||
SMARTENUMEND(DNSSection)
|
|
||||||
|
|
||||||
struct dnsname
|
struct dnsname
|
||||||
{
|
{
|
||||||
@ -55,9 +47,9 @@ struct dnsname
|
|||||||
std::deque<dnslabel> d_name;
|
std::deque<dnslabel> d_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
std::ostream & operator<<(std::ostream &os, const dnsname& d);
|
std::ostream & operator<<(std::ostream &os, const dnsname& d);
|
||||||
dnsname operator+(const dnsname& a, const dnsname& b);
|
dnsname operator+(const dnsname& a, const dnsname& b);
|
||||||
|
|
||||||
struct RRSet
|
struct RRSet
|
||||||
{
|
{
|
||||||
std::vector<std::string> contents;
|
std::vector<std::string> contents;
|
||||||
|
17
tdns/dns-types.hh
Normal file
17
tdns/dns-types.hh
Normal file
@ -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<RRGenerator> make(ComboAddress);
|
||||||
|
std::unique_ptr<RRGenerator> make(std::string);
|
||||||
|
void toPacket(DNSPacketWriter& dpw) override;
|
||||||
|
uint32_t d_ip;
|
||||||
|
};
|
@ -7,6 +7,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
#define SMARTENUMSTART(x) static constexpr std::pair<x, const char*> enumtypemap##x[]= {
|
#define SMARTENUMSTART(x) static constexpr std::pair<x, const char*> enumtypemap##x[]= {
|
||||||
#define SENUM(x,a1) { x::a1, #a1},
|
#define SENUM(x,a1) { x::a1, #a1},
|
||||||
#define SENUM2(x, a1, ...) SENUM(x,a1) SENUM(x, __VA_ARGS__)
|
#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 SENUM9(x, a1, ...) SENUM(x,a1) SENUM8(x, __VA_ARGS__)
|
||||||
#define SENUM10(x, a1, ...) SENUM(x,a1) SENUM9(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 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) }; \
|
#define SMARTENUMEND(x) }; \
|
||||||
inline const char* toString(const x& t) \
|
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; } \
|
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)
|
||||||
|
34
tdns/tdns.cc
34
tdns/tdns.cc
@ -12,6 +12,8 @@
|
|||||||
#include "dns.hh"
|
#include "dns.hh"
|
||||||
#include "safearray.hh"
|
#include "safearray.hh"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "dns-types.hh"
|
||||||
#include "dns-storage.hh"
|
#include "dns-storage.hh"
|
||||||
|
|
||||||
using namespace std;
|
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)
|
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;
|
SafeArray<256> sa;
|
||||||
putName(sa, mname);
|
putName(sa, mname); putName(sa, rname);
|
||||||
putName(sa, rname);
|
sa.putUInt32(serial); sa.putUInt32(refresh);
|
||||||
sa.putUInt32(serial);
|
sa.putUInt32(retry); sa.putUInt32(expire);
|
||||||
sa.putUInt32(refresh);
|
|
||||||
sa.putUInt32(retry);
|
|
||||||
sa.putUInt32(expire);
|
|
||||||
sa.putUInt32(minimum);
|
sa.putUInt32(minimum);
|
||||||
|
|
||||||
return sa.serialize();
|
return sa.serialize();
|
||||||
@ -156,8 +155,6 @@ std::string serializeAAAARecord(const std::string& src)
|
|||||||
return std::string(p, p+16);
|
return std::string(p, p+16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool processQuestion(const DNSNode& zones, DNSMessage& dm, const ComboAddress& local, const ComboAddress& remote, DNSMessage& response)
|
bool processQuestion(const DNSNode& zones, DNSMessage& dm, const ComboAddress& local, const ComboAddress& remote, DNSMessage& response)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -214,7 +211,18 @@ try
|
|||||||
cout<<"Have delegation"<<endl;
|
cout<<"Have delegation"<<endl;
|
||||||
const auto& rrset = iter->second;
|
const auto& rrset = iter->second;
|
||||||
for(const auto& rr : rrset.contents) {
|
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 "<<addname<<endl;
|
||||||
|
auto addnode = bestzone->find(addname, wuh);
|
||||||
|
auto iter2 = addnode->rrsets.find(DNSType::A);
|
||||||
|
if(iter2 != addnode->rrsets.end()) {
|
||||||
|
cout<<"Lastnode for '"<<addname<<"' glue: "<<wuh<<endl;
|
||||||
|
const auto& rrset = iter2->second;
|
||||||
|
for(const auto& rr : rrset.contents) {
|
||||||
|
response.putRR(DNSSection::Additional, wuh+zone, DNSType::A, rrset.ttl, rr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// should do additional processing here
|
// should do additional processing here
|
||||||
}
|
}
|
||||||
@ -372,7 +380,6 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
|||||||
response.payload.rewind();
|
response.payload.rewind();
|
||||||
response.setQuestion(zone, type);
|
response.setQuestion(zone, type);
|
||||||
|
|
||||||
|
|
||||||
// send all other records
|
// send all other records
|
||||||
node->visit([&response,&sock,&name,&type,&zone](const dnsname& nname, const DNSNode* n) {
|
node->visit([&response,&sock,&name,&type,&zone](const dnsname& nname, const DNSNode* n) {
|
||||||
cout<<nname<<", types: ";
|
cout<<nname<<", types: ";
|
||||||
@ -384,7 +391,7 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
|||||||
try {
|
try {
|
||||||
response.putRR(DNSSection::Answer, nname, p.first, p.second.ttl, rr);
|
response.putRR(DNSSection::Answer, nname, p.first, p.second.ttl, rr);
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) { // exceeded packet size
|
||||||
writeTCPResponse(sock, response);
|
writeTCPResponse(sock, response);
|
||||||
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
||||||
response.payload.rewind();
|
response.payload.rewind();
|
||||||
@ -406,7 +413,6 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
|||||||
response.putRR(DNSSection::Answer, zone, DNSType::SOA, node->rrsets[DNSType::SOA].ttl, node->rrsets[DNSType::SOA].contents[0]);
|
response.putRR(DNSSection::Answer, zone, DNSType::SOA, node->rrsets[DNSType::SOA].ttl, node->rrsets[DNSType::SOA].contents[0]);
|
||||||
|
|
||||||
writeTCPResponse(sock, response);
|
writeTCPResponse(sock, response);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -421,7 +427,6 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void loadZones(DNSNode& zones)
|
void loadZones(DNSNode& zones)
|
||||||
{
|
{
|
||||||
auto zone = zones.add({"powerdns", "org"});
|
auto zone = zones.add({"powerdns", "org"});
|
||||||
@ -448,6 +453,7 @@ void loadZones(DNSNode& zones)
|
|||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
ComboAddress local(argv[1], 53);
|
ComboAddress local(argv[1], 53);
|
||||||
|
|
||||||
Socket udplistener(local.sin4.sin_family, SOCK_DGRAM);
|
Socket udplistener(local.sin4.sin_family, SOCK_DGRAM);
|
||||||
@ -459,7 +465,6 @@ int main(int argc, char** argv)
|
|||||||
SListen(tcplistener, 10);
|
SListen(tcplistener, 10);
|
||||||
|
|
||||||
DNSNode zones;
|
DNSNode zones;
|
||||||
|
|
||||||
loadZones(zones);
|
loadZones(zones);
|
||||||
|
|
||||||
thread udpServer(udpThread, local, &udplistener, &zones);
|
thread udpServer(udpThread, local, &udplistener, &zones);
|
||||||
@ -470,5 +475,4 @@ int main(int argc, char** argv)
|
|||||||
thread t(tcpClientThread, local, remote, client, &zones);
|
thread t(tcpClientThread, local, remote, client, &zones);
|
||||||
t.detach();
|
t.detach();
|
||||||
}
|
}
|
||||||
udpServer.join();
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user