it works again
This commit is contained in:
parent
cc894edba6
commit
ab91a50402
@ -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 '"<<name<<"', last is now '"<<last<<"'"<<endl;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#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<dnslabel> d_name;
|
||||
};
|
||||
|
||||
@ -60,6 +64,10 @@ struct RRGenerator
|
||||
struct RRSet
|
||||
{
|
||||
std::vector<std::unique_ptr<RRGenerator>> contents;
|
||||
void add(std::unique_ptr<RRGenerator>&& rr)
|
||||
{
|
||||
contents.emplace_back(std::move(rr));
|
||||
}
|
||||
uint32_t ttl{3600};
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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<typename... Targs>
|
||||
static std::unique_ptr<RRGenerator> make(Targs&&... fargs)
|
||||
template<typename ... Targs>
|
||||
static std::unique_ptr<RRGenerator> make(const dnsname& mname, const dnsname& rname, Targs&& ... fargs)
|
||||
{
|
||||
return std::move(std::make_unique<SOAGenerator>(std::forward<Targs>(fargs)...));
|
||||
return std::move(std::make_unique<SOAGenerator>(mname, rname, std::forward<Targs>(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<RRGenerator> make(const dnsname& mname)
|
||||
{
|
||||
return std::move(std::make_unique<NameGenerator>(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<RRGenerator> make(uint16_t prio, const dnsname& name)
|
||||
{
|
||||
return std::move(std::make_unique<MXGenerator>(prio, name));
|
||||
}
|
||||
void toMessage(DNSMessageWriter& dpw) override;
|
||||
uint16_t d_prio;
|
||||
dnsname d_name;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#pragma once
|
||||
#include "dns.hh"
|
||||
#include "safearray.hh"
|
||||
#include "dns-storage.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)
|
||||
|
86
tdns/tdns.cc
86
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"<<endl;
|
||||
const auto& rrset = iter->second;
|
||||
vector<dnsname> toresolve;
|
||||
for(const auto& rr : rrset.contents) {
|
||||
response.putRR(DNSSection::Authority, lastnode+zone, DNSType::NS, rrset.ttl, rr);
|
||||
toresolve.push_back(dynamic_cast<NameGenerator*>(rr.get())->d_name);
|
||||
}
|
||||
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);
|
||||
|
||||
for(auto& addname : toresolve ) {
|
||||
if(!addname.makeRelative(zone)) {
|
||||
cout<<addname<<" is not within our zone, not doing glue"<<endl;
|
||||
continue;
|
||||
}
|
||||
dnsname wuh;
|
||||
cout<<"Looking up glue record "<<addname<<" in zone "<<zone<<endl;
|
||||
auto addnode = bestzone->find(addname, wuh);
|
||||
if(!addnode || !addname.empty()) {
|
||||
cout<<"Found nothing, continuing"<<endl;
|
||||
}
|
||||
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
|
||||
}
|
||||
else {
|
||||
cout<<"This is an NXDOMAIN situation"<<endl;
|
||||
@ -128,10 +130,19 @@ try
|
||||
else if(iter = node->rrsets.find(DNSType::CNAME), iter != node->rrsets.end()) {
|
||||
cout<<"We do have a CNAME!"<<endl;
|
||||
const auto& rrset = iter->second;
|
||||
dnsname target;
|
||||
for(const auto& rr : rrset.contents) {
|
||||
response.putRR(DNSSection::Answer, lastnode+zone, DNSType::CNAME, rrset.ttl, rr);
|
||||
target=dynamic_cast<NameGenerator*>(rr.get())->d_name;
|
||||
}
|
||||
cout<<" We should actually follow this, at least within our zone"<<endl;
|
||||
if(target.makeRelative(zone)) {
|
||||
cout<<" Should follow CNAME to "<<target<<" within our zone"<<endl;
|
||||
searchname = target;
|
||||
if(CNAMELoopCount++ < 10)
|
||||
goto loopCNAME;
|
||||
}
|
||||
else
|
||||
cout<<" CNAME points to record "<<target<<" in other zone, good luck"<<endl;
|
||||
}
|
||||
else {
|
||||
cout<<"Node exists, qtype doesn't, NOERROR situation, inserting SOA"<<endl;
|
||||
@ -179,12 +190,11 @@ void udpThread(ComboAddress local, Socket* sock, const DNSNode* zones)
|
||||
void writeTCPResponse(int sock, const DNSMessageWriter& response)
|
||||
{
|
||||
string ser="00"+response.serialize();
|
||||
cout<<"Should send a message of "<<ser.size()<<" bytes in response"<<endl;
|
||||
cout<<"Sending a message of "<<ser.size()<<" bytes in response"<<endl;
|
||||
uint16_t len = htons(ser.length()-2);
|
||||
ser[0] = *((char*)&len);
|
||||
ser[1] = *(((char*)&len) + 1);
|
||||
SWriten(sock, ser);
|
||||
cout<<"Sent!"<<endl;
|
||||
}
|
||||
|
||||
void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNode* zones)
|
||||
@ -210,8 +220,6 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
||||
return;
|
||||
}
|
||||
|
||||
cout<<"Reading "<<len<<" bytes"<<endl;
|
||||
|
||||
message = SRead(sock, len);
|
||||
DNSMessageReader dm;
|
||||
memcpy(&dm, message.c_str(), message.size());
|
||||
@ -305,25 +313,27 @@ void loadZones(DNSNode& zones)
|
||||
{
|
||||
auto zone = zones.add({"powerdns", "org"});
|
||||
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)
|
||||
|
Loading…
Reference in New Issue
Block a user