d_wasVariable=false;
d_wasOutOfBand=false;
+ if (doSpecialNamesResolve(qname, qtype, qclass, ret))
+ return 0;
+
if( (qtype.getCode() == QType::AXFR))
return -1;
- static const DNSName arpa("1.0.0.127.in-addr.arpa."), localhost("localhost."),
- versionbind("version.bind."), idserver("id.server."), versionpdns("version.pdns.");
+ if(qclass==QClass::ANY)
+ qclass=QClass::IN;
+ else if(qclass!=QClass::IN)
+ return -1;
- if( (qtype.getCode()==QType::PTR && qname==arpa) ||
- (qtype.getCode()==QType::A && qname==localhost)) {
- ret.clear();
- DNSRecord dr;
- dr.d_name=qname;
- dr.d_place = DNSResourceRecord::ANSWER;
- dr.d_type=qtype.getCode();
- dr.d_class=QClass::IN;
- dr.d_ttl=86400;
- if(qtype.getCode()==QType::PTR)
- dr.d_content=shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::PTR, 1, "localhost."));
+ set<GetBestNSAnswer> beenthere;
+ int res=doResolve(qname, qtype, ret, 0, beenthere);
+ return res;
+}
+
+/*! Handles all special, built-in names
+ * Fills ret with an answer and returns true if it handled the query.
+ *
+ * Handles the following queries:
+ *
+ * - localhost. IN A
+ * - localhost. IN AAAA
+ * - 1.0.0.127.in-addr.arpa. IN PTR
+ * - 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. IN PTR
+ * - version.bind. CH TXT
+ * - version.pdns. CH TXT
+ * - id.server. CH TXT
+ *
+ * TODO handle ANY
+ */
+bool SyncRes::doSpecialNamesResolve(const DNSName &qname, const QType &qtype, const uint16_t &qclass, vector<DNSRecord> &ret)
+{
+ static const DNSName arpa("1.0.0.127.in-addr.arpa."), ip6_arpa("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa."),
+ localhost("localhost."), versionbind("version.bind."), idserver("id.server."), versionpdns("version.pdns.");
+
+ bool handled = false;
+ string content;
+
+ if (qtype.getCode()==QType::PTR && (qname==arpa || qname==ip6_arpa)) {
+ handled = true;
+ content = "localhost.";
+ }
+
+ if (qname == localhost) {
+ handled = true;
+ if (qtype==QType::A)
+ content = "127.0.0.1";
+ if (qtype==QType::AAAA)
+ content = "::1";
+ }
+
+ if (qclass==QClass::CHAOS && qtype==QType::TXT && (qname==versionbind || qname==idserver || qname==versionpdns)) {
+ handled = true;
+ if(qname==versionbind || qname==versionpdns)
+ content = "\""+::arg()["version-string"]+"\"";
else
- dr.d_content=shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::A, 1, "127.0.0.1"));
- ret.push_back(dr);
- d_wasOutOfBand=true;
- return 0;
+ content = "\""+s_serverID+"\"";
}
- if(qclass==QClass::CHAOS && qtype.getCode()==QType::TXT &&
- (qname==versionbind || qname==idserver || qname==versionpdns )
- ) {
+ if (handled && !content.empty()) {
ret.clear();
+ d_wasOutOfBand=true;
+
DNSRecord dr;
- dr.d_name=qname;
- dr.d_type=qtype.getCode();
- dr.d_class=qclass;
- dr.d_ttl=86400;
+ dr.d_name = qname;
dr.d_place = DNSResourceRecord::ANSWER;
- if(qname==versionbind || qname==versionpdns)
- dr.d_content=shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::TXT, 3, "\""+::arg()["version-string"]+"\""));
- else
- dr.d_content=shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(QType::TXT, 3, "\""+s_serverID+"\""));
-
+ dr.d_type = qtype.getCode();
+ dr.d_class = qclass;
+ dr.d_ttl = 86400;
+ dr.d_content=shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(qtype.getCode(), qclass, content));
ret.push_back(dr);
- d_wasOutOfBand=true;
- return 0;
}
- if(qclass==QClass::ANY)
- qclass=QClass::IN;
- else if(qclass!=QClass::IN)
- return -1;
-
- set<GetBestNSAnswer> beenthere;
- int res=doResolve(qname, qtype, ret, 0, beenthere);
- return res;
+ return handled;
}
+
//! This is the 'out of band resolver', in other words, the authoritative server
bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, int& res)
{
RCode::rcodes_ updateCacheFromRecords(const std::string& prefix, LWResult& lwr, const DNSName& qname, const DNSName& auth, NsSet& nameservers, const DNSName& tns, const boost::optional<Netmask>);
bool processRecords(const std::string& prefix, const DNSName& qname, const QType& qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector<DNSRecord>& ret, set<DNSName>& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, bool& sawDS);
-private:
+ bool doSpecialNamesResolve(const DNSName &qname, const QType &qtype, const uint16_t &qclass, vector<DNSRecord> &ret);
+
ostringstream d_trace;
shared_ptr<RecursorLua4> d_pdl;
string d_prefix;