lots of work, starting to look useful
This commit is contained in:
@ -45,10 +45,14 @@ const DNSNode* DNSNode::find(dnsname& name, dnsname& last, bool* passedZonecut)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cout<<"Had wildcard match, following"<<endl;
|
cout<<" Had wildcard match, picking that, matching all labels"<<endl;
|
||||||
|
while(name.size() > 1) {
|
||||||
|
last.push_front(name.back());
|
||||||
|
name.pop_back();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout<<"Had match, continuing to child '"<<iter->first<<"'"<<endl;
|
cout<<" Had match, continuing to child '"<<iter->first<<"'"<<endl;
|
||||||
last.push_front(name.back());
|
last.push_front(name.back());
|
||||||
name.pop_back();
|
name.pop_back();
|
||||||
return iter->second.find(name, last, passedZonecut);
|
return iter->second.find(name, last, passedZonecut);
|
||||||
@ -56,9 +60,9 @@ const DNSNode* DNSNode::find(dnsname& name, dnsname& last, bool* passedZonecut)
|
|||||||
|
|
||||||
DNSNode* DNSNode::add(dnsname name)
|
DNSNode* DNSNode::add(dnsname name)
|
||||||
{
|
{
|
||||||
cout<<"Add for '"<<name<<"'"<<endl;
|
cout<<"Add called for '"<<name<<"'"<<endl;
|
||||||
if(name.size() == 1) {
|
if(name.size() == 1) {
|
||||||
cout<<"Last label, adding "<<name.front()<<endl;
|
cout<<" Last label, possibly addding, already present="<<children.count(name.front())<<endl;
|
||||||
return &children[name.front()];
|
return &children[name.front()];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +71,7 @@ DNSNode* DNSNode::add(dnsname name)
|
|||||||
auto iter = children.find(back);
|
auto iter = children.find(back);
|
||||||
|
|
||||||
if(iter == children.end()) {
|
if(iter == children.end()) {
|
||||||
cout<<"Inserting new child for "<<back<<endl;
|
cout<<"Inserting new child for "<<back<<", continuing add there"<<endl;
|
||||||
return children[back].add(name);
|
return children[back].add(name);
|
||||||
}
|
}
|
||||||
return iter->second.add(name);
|
return iter->second.add(name);
|
||||||
@ -91,8 +95,7 @@ void DNSNode::visit(std::function<void(const dnsname& name, const DNSNode*)> vis
|
|||||||
// this should perform escaping rules!
|
// this should perform escaping rules!
|
||||||
std::ostream & operator<<(std::ostream &os, const dnsname& d)
|
std::ostream & operator<<(std::ostream &os, const dnsname& d)
|
||||||
{
|
{
|
||||||
for(const auto& l : d.d_name) {
|
for(const auto& l : d.d_name)
|
||||||
os<<l<<".";
|
os<<l<<".";
|
||||||
}
|
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,11 @@ enum class DNSType : uint16_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
SMARTENUMSTART(DNSType)
|
SMARTENUMSTART(DNSType)
|
||||||
SENUM13(DNSType, A, NS, CNAME, SOA, PTR, MX, AAAA, IXFR, AAAA, SRV, IXFR, AXFR, ANY)
|
SENUM13(DNSType, A, NS, CNAME, SOA, PTR, MX, TXT, AAAA, IXFR, AAAA, SRV, IXFR, AXFR)
|
||||||
|
SENUM(DNSType, ANY)
|
||||||
SMARTENUMEND(DNSType)
|
SMARTENUMEND(DNSType)
|
||||||
|
|
||||||
COMBOENUM4(DNSSection, Question, 0, Answer, 1, Authority, 2, Additional,3 )
|
COMBOENUM4(DNSSection, Question, 0, Answer, 1, Authority, 2, Additional, 3)
|
||||||
|
|
||||||
struct dnsname
|
struct dnsname
|
||||||
{
|
{
|
||||||
@ -45,7 +46,7 @@ struct dnsname
|
|||||||
void pop_back() { d_name.pop_back(); }
|
void pop_back() { d_name.pop_back(); }
|
||||||
auto push_front(const dnslabel& dn) { return d_name.push_front(dn); }
|
auto push_front(const dnslabel& dn) { return d_name.push_front(dn); }
|
||||||
auto size() { return d_name.size(); }
|
auto size() { return d_name.size(); }
|
||||||
|
void clear() { d_name.clear(); }
|
||||||
bool makeRelative(const dnsname& root);
|
bool makeRelative(const dnsname& root);
|
||||||
|
|
||||||
std::deque<dnslabel> d_name;
|
std::deque<dnslabel> d_name;
|
||||||
@ -60,7 +61,6 @@ struct RRGenerator
|
|||||||
virtual void toMessage(DNSMessageWriter& dpw) = 0;
|
virtual void toMessage(DNSMessageWriter& dpw) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct RRSet
|
struct RRSet
|
||||||
{
|
{
|
||||||
std::vector<std::unique_ptr<RRGenerator>> contents;
|
std::vector<std::unique_ptr<RRGenerator>> contents;
|
||||||
|
@ -10,7 +10,6 @@ void AGenerator::toMessage(DNSMessageWriter& dmw)
|
|||||||
dmw.payload.putUInt32(d_ip);
|
dmw.payload.putUInt32(d_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<RRGenerator> AAAAGenerator::make(const ComboAddress& ca)
|
std::unique_ptr<RRGenerator> AAAAGenerator::make(const ComboAddress& ca)
|
||||||
{
|
{
|
||||||
if(ca.sin4.sin_family != AF_INET6)
|
if(ca.sin4.sin_family != AF_INET6)
|
||||||
@ -46,4 +45,9 @@ void MXGenerator::toMessage(DNSMessageWriter& dmw)
|
|||||||
putName(dmw.payload, d_name);
|
putName(dmw.payload, d_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TXTGenerator::toMessage(DNSMessageWriter& dmw)
|
||||||
|
{
|
||||||
|
// XXX should autosplit
|
||||||
|
dmw.payload.putUInt8(d_txt.length());
|
||||||
|
dmw.payload.putBlob(d_txt);
|
||||||
|
}
|
||||||
|
@ -69,3 +69,14 @@ struct MXGenerator : RRGenerator
|
|||||||
uint16_t d_prio;
|
uint16_t d_prio;
|
||||||
dnsname d_name;
|
dnsname d_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TXTGenerator : RRGenerator
|
||||||
|
{
|
||||||
|
TXTGenerator(const std::string& txt) : d_txt(txt) {}
|
||||||
|
static std::unique_ptr<RRGenerator> make(const std::string& txt)
|
||||||
|
{
|
||||||
|
return std::move(std::make_unique<TXTGenerator>(txt));
|
||||||
|
}
|
||||||
|
void toMessage(DNSMessageWriter& dpw) override;
|
||||||
|
std::string d_txt;
|
||||||
|
};
|
||||||
|
@ -57,6 +57,7 @@ void DNSMessageWriter::putRR(DNSSection section, const dnsname& name, DNSType ty
|
|||||||
|
|
||||||
void DNSMessageWriter::setQuestion(const dnsname& name, DNSType type)
|
void DNSMessageWriter::setQuestion(const dnsname& name, DNSType type)
|
||||||
{
|
{
|
||||||
|
dh.ancount = dh.arcount = dh.nscount = 0;
|
||||||
payload.rewind();
|
payload.rewind();
|
||||||
putName(payload, name);
|
putName(payload, name);
|
||||||
payload.putUInt16((uint16_t)type);
|
payload.putUInt16((uint16_t)type);
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -7,7 +6,6 @@
|
|||||||
#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__)
|
||||||
@ -40,7 +38,6 @@ for(const auto& a : enumtypemap##x) \
|
|||||||
inline std::ostream& operator<<(std::ostream &os, const x& s) { \
|
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 { \
|
#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) \
|
a1=b1, a2=b2, a3=b3, a4=b4 }; SMARTENUMSTART(x) SENUM4(x, a1, a2, a3,a4) \
|
||||||
SMARTENUMEND(x)
|
SMARTENUMEND(x)
|
||||||
|
134
tdns/tdns.cc
134
tdns/tdns.cc
@ -1,11 +1,9 @@
|
|||||||
/* Goal: a fully standards compliant basic authoritative server. In <500 lines.
|
/* Goal: a fully standards compliant basic authoritative server. In <1000 lines.
|
||||||
Non-goals: notifications, slaving zones, name compression, edns,
|
Non-goals: notifications, slaving zones, name compression, edns,
|
||||||
performance
|
performance
|
||||||
*/
|
*/
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include "sclasses.hh"
|
#include "sclasses.hh"
|
||||||
@ -18,6 +16,33 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
void addAdditional(const DNSNode* bestzone, const dnsname& zone, const vector<dnsname>& toresolve, DNSMessageWriter& response)
|
||||||
|
{
|
||||||
|
for(auto addname : toresolve ) {
|
||||||
|
cout<<"Doing additional or glue lookup for "<<addname<<endl;
|
||||||
|
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;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for(auto& type : {DNSType::A, DNSType::AAAA}) {
|
||||||
|
auto iter2 = addnode->rrsets.find(type);
|
||||||
|
if(iter2 != addnode->rrsets.end()) {
|
||||||
|
const auto& rrset = iter2->second;
|
||||||
|
for(const auto& rr : rrset.contents) {
|
||||||
|
response.putRR(DNSSection::Additional, wuh+zone, type, rrset.ttl, rr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool processQuestion(const DNSNode& zones, DNSMessageReader& dm, const ComboAddress& local, const ComboAddress& remote, DNSMessageWriter& response)
|
bool processQuestion(const DNSNode& zones, DNSMessageReader& dm, const ComboAddress& local, const ComboAddress& remote, DNSMessageWriter& response)
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -27,14 +52,11 @@ try
|
|||||||
cout<<"Received a query from "<<remote.toStringWithPort()<<" for "<<name<<" and type "<<type<<endl;
|
cout<<"Received a query from "<<remote.toStringWithPort()<<" for "<<name<<" and type "<<type<<endl;
|
||||||
|
|
||||||
response.dh = dm.dh;
|
response.dh = dm.dh;
|
||||||
response.dh.ad = 0;
|
response.dh.ad = response.dh.ra = response.dh.aa = 0;
|
||||||
response.dh.ra = 0;
|
|
||||||
response.dh.aa = 0;
|
|
||||||
response.dh.qr = 1;
|
response.dh.qr = 1;
|
||||||
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
|
||||||
response.setQuestion(name, type);
|
response.setQuestion(name, type);
|
||||||
|
|
||||||
if(type == DNSType::AXFR) {
|
if(type == DNSType::AXFR || type == DNSType::IXFR) {
|
||||||
cout<<"Query was for AXFR or IXFR over UDP, can't do that"<<endl;
|
cout<<"Query was for AXFR or IXFR over UDP, can't do that"<<endl;
|
||||||
response.dh.rcode = (int)RCode::Servfail;
|
response.dh.rcode = (int)RCode::Servfail;
|
||||||
return true;
|
return true;
|
||||||
@ -58,6 +80,8 @@ try
|
|||||||
bool passedZonecut=false;
|
bool passedZonecut=false;
|
||||||
int CNAMELoopCount = 0;
|
int CNAMELoopCount = 0;
|
||||||
loopCNAME:;
|
loopCNAME:;
|
||||||
|
passedZonecut=false;
|
||||||
|
lastnode.clear();
|
||||||
auto node = bestzone->find(searchname, lastnode, &passedZonecut);
|
auto node = bestzone->find(searchname, lastnode, &passedZonecut);
|
||||||
if(passedZonecut)
|
if(passedZonecut)
|
||||||
response.dh.aa = false;
|
response.dh.aa = false;
|
||||||
@ -81,26 +105,7 @@ try
|
|||||||
toresolve.push_back(dynamic_cast<NameGenerator*>(rr.get())->d_name);
|
toresolve.push_back(dynamic_cast<NameGenerator*>(rr.get())->d_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& addname : toresolve ) {
|
addAdditional(bestzone, zone, toresolve, response);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cout<<"This is an NXDOMAIN situation"<<endl;
|
cout<<"This is an NXDOMAIN situation"<<endl;
|
||||||
@ -123,9 +128,13 @@ try
|
|||||||
}
|
}
|
||||||
else if(iter = node->rrsets.find(type), iter != node->rrsets.end()) {
|
else if(iter = node->rrsets.find(type), iter != node->rrsets.end()) {
|
||||||
const auto& rrset = iter->second;
|
const auto& rrset = iter->second;
|
||||||
|
vector<dnsname> additional;
|
||||||
for(const auto& rr : rrset.contents) {
|
for(const auto& rr : rrset.contents) {
|
||||||
response.putRR(DNSSection::Answer, lastnode+zone, type, rrset.ttl, rr);
|
response.putRR(DNSSection::Answer, lastnode+zone, type, rrset.ttl, rr);
|
||||||
|
if(type == DNSType::MX)
|
||||||
|
additional.push_back(dynamic_cast<MXGenerator*>(rr.get())->d_name);
|
||||||
}
|
}
|
||||||
|
addAdditional(bestzone, zone, additional, response);
|
||||||
}
|
}
|
||||||
else if(iter = node->rrsets.find(DNSType::CNAME), iter != node->rrsets.end()) {
|
else if(iter = node->rrsets.find(DNSType::CNAME), iter != node->rrsets.end()) {
|
||||||
cout<<"We do have a CNAME!"<<endl;
|
cout<<"We do have a CNAME!"<<endl;
|
||||||
@ -137,8 +146,9 @@ try
|
|||||||
}
|
}
|
||||||
if(target.makeRelative(zone)) {
|
if(target.makeRelative(zone)) {
|
||||||
cout<<" Should follow CNAME to "<<target<<" within our zone"<<endl;
|
cout<<" Should follow CNAME to "<<target<<" within our zone"<<endl;
|
||||||
searchname = target;
|
// XXX we need to change our behaviour on NXDOMAIN I think depending on if you've followed a CNAME
|
||||||
if(CNAMELoopCount++ < 10)
|
searchname = target;
|
||||||
|
if(CNAMELoopCount++ < 10)
|
||||||
goto loopCNAME;
|
goto loopCNAME;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -239,17 +249,14 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
|||||||
|
|
||||||
dnsname zone;
|
dnsname zone;
|
||||||
auto fnd = zones->find(name, zone);
|
auto fnd = zones->find(name, zone);
|
||||||
if(!fnd || !fnd->zone || !name.empty()) {
|
if(!fnd || !fnd->zone || !name.empty() || !fnd->zone->rrsets.count(DNSType::SOA)) {
|
||||||
cout<<" This was not a zone"<<endl;
|
cout<<" This was not a zone, or zone had no SOA"<<endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cout<<"Have zone, walking it"<<endl;
|
cout<<"Have zone, walking it"<<endl;
|
||||||
response.dh = dm.dh;
|
response.dh = dm.dh;
|
||||||
response.dh.ad = 0;
|
response.dh.ad = response.dh.ra = response.dh.aa = 0;
|
||||||
response.dh.ra = 0;
|
|
||||||
response.dh.aa = 0;
|
|
||||||
response.dh.qr = 1;
|
response.dh.qr = 1;
|
||||||
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
|
||||||
response.setQuestion(zone, type);
|
response.setQuestion(zone, type);
|
||||||
|
|
||||||
auto node = fnd->zone;
|
auto node = fnd->zone;
|
||||||
@ -258,13 +265,10 @@ 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);
|
||||||
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
|
||||||
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: ";
|
|
||||||
for(const auto& p : n->rrsets) {
|
for(const auto& p : n->rrsets) {
|
||||||
if(p.first == DNSType::SOA)
|
if(p.first == DNSType::SOA)
|
||||||
continue;
|
continue;
|
||||||
@ -275,20 +279,14 @@ void tcpClientThread(ComboAddress local, ComboAddress remote, int s, const DNSNo
|
|||||||
}
|
}
|
||||||
catch(...) { // exceeded packet size
|
catch(...) { // exceeded packet size
|
||||||
writeTCPResponse(sock, response);
|
writeTCPResponse(sock, response);
|
||||||
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
|
||||||
response.payload.rewind();
|
|
||||||
response.setQuestion(zone, type);
|
response.setQuestion(zone, type);
|
||||||
goto retry;
|
goto retry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cout<<p.first<<" ";
|
|
||||||
}
|
}
|
||||||
cout<<endl;
|
|
||||||
}, zone);
|
}, zone);
|
||||||
|
|
||||||
writeTCPResponse(sock, response);
|
writeTCPResponse(sock, response);
|
||||||
response.dh.ancount = response.dh.arcount = response.dh.nscount = 0;
|
|
||||||
response.payload.rewind();
|
|
||||||
response.setQuestion(zone, type);
|
response.setQuestion(zone, type);
|
||||||
|
|
||||||
// send SOA again
|
// send SOA again
|
||||||
@ -312,32 +310,43 @@ 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"});
|
||||||
zone->zone = new DNSNode(); // XXX ICK
|
auto newzone = zone->zone = new DNSNode(); // XXX ICK
|
||||||
|
|
||||||
zone->zone->rrsets[DNSType::SOA].add(SOAGenerator::make({"ns1", "powerdns", "org"}, {"admin", "powerdns", "org"}, 1));
|
newzone->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"}));
|
newzone->rrsets[DNSType::MX].add(MXGenerator::make(25, {"server1", "powerdns", "org"}));
|
||||||
|
|
||||||
zone->zone->rrsets[DNSType::A].add(AGenerator::make("1.2.3.4"));
|
newzone->rrsets[DNSType::A].add(AGenerator::make("1.2.3.4"));
|
||||||
zone->zone->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1"));
|
newzone->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1"));
|
||||||
zone->zone->rrsets[DNSType::AAAA].ttl= 900;
|
newzone->rrsets[DNSType::AAAA].ttl= 900;
|
||||||
zone->zone->rrsets[DNSType::NS].add(NameGenerator::make({"ns1", "powerdns", "org"}));
|
newzone->rrsets[DNSType::NS].add(NameGenerator::make({"ns1", "powerdns", "org"}));
|
||||||
|
newzone->rrsets[DNSType::TXT].add(TXTGenerator::make("Proudly served by tdns " __DATE__ " " __TIME__));
|
||||||
|
|
||||||
zone->zone->add({"www"})->rrsets[DNSType::CNAME].add(NameGenerator::make({"server1","powerdns","org"}));
|
newzone->add({"www"})->rrsets[DNSType::CNAME].add(NameGenerator::make({"server1","powerdns","org"}));
|
||||||
|
newzone->add({"www2"})->rrsets[DNSType::CNAME].add(NameGenerator::make({"nosuchserver1","powerdns","org"}));
|
||||||
|
|
||||||
zone->zone->add({"server1"})->rrsets[DNSType::A].add(AGenerator::make("213.244.168.210"));
|
newzone->add({"server1"})->rrsets[DNSType::A].add(AGenerator::make("213.244.168.210"));
|
||||||
zone->zone->add({"server1"})->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1"));
|
newzone->add({"server1"})->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1"));
|
||||||
|
|
||||||
|
newzone->add({"server2"})->rrsets[DNSType::A].add(AGenerator::make("213.244.168.210"));
|
||||||
|
newzone->add({"server2"})->rrsets[DNSType::AAAA].add(AAAAGenerator::make("::1"));
|
||||||
|
|
||||||
// zone->zone->add({"*"})->rrsets[(dnstype)DNSType::A]={"\x05\x06\x07\x08"};
|
newzone->add({"*", "nl"})->rrsets[DNSType::A].add(AGenerator::make("5.6.7.8"));
|
||||||
|
newzone->add({"*", "fr"})->rrsets[DNSType::CNAME].add(NameGenerator::make({"server2", "powerdns", "org"}));
|
||||||
|
|
||||||
zone->zone->add({"fra"})->rrsets[DNSType::NS].add(NameGenerator::make({"ns1","fra","powerdns","org"}));
|
newzone->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"}));
|
newzone->add({"fra"})->rrsets[DNSType::NS].add(NameGenerator::make({"ns2","fra","powerdns","org"}));
|
||||||
|
|
||||||
zone->zone->add({"ns1", "fra"})->rrsets[DNSType::A].add(AGenerator::make("12.13.14.15"));
|
newzone->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"));
|
newzone->add({"NS2", "fra"})->rrsets[DNSType::A].add(AGenerator::make("12.13.14.16"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
|
try
|
||||||
{
|
{
|
||||||
|
if(argc != 2) {
|
||||||
|
cerr<<"Syntax: tdns ipaddress:port"<<endl;
|
||||||
|
return(EXIT_FAILURE);
|
||||||
|
}
|
||||||
signal(SIGPIPE, SIG_IGN);
|
signal(SIGPIPE, SIG_IGN);
|
||||||
ComboAddress local(argv[1], 53);
|
ComboAddress local(argv[1], 53);
|
||||||
|
|
||||||
@ -361,3 +370,8 @@ int main(int argc, char** argv)
|
|||||||
t.detach();
|
t.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(std::exception& e)
|
||||||
|
{
|
||||||
|
cerr<<"Fatal error: "<<e.what()<<endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user