d_receivedBytes += (uint16_t) len;
- MOADNSParser mdp(false, d_buf.data(), len);
-
- int err = mdp.d_header.rcode;
+ try {
+ MOADNSParser mdp(false, d_buf.data(), len);
- if(err) {
- throw ResolverException("AXFR chunk error: " + RCode::to_s(err));
- }
+ int err = mdp.d_header.rcode;
+ if (err != 0) {
+ throw ResolverException("AXFR chunk error: " + RCode::to_s(err));
+ }
- if(mdp.d_header.tc) {
- throw ResolverException("AXFR chunk had TC bit set");
- }
+ if(mdp.d_header.tc) {
+ throw ResolverException("AXFR chunk had TC bit set");
+ }
- try {
d_tsigVerifier.check(std::string(d_buf.data(), len), mdp);
- }
- catch(const std::runtime_error& re) {
- throw ResolverException(re.what());
- }
- if(!records) {
- err = parseResult(mdp, DNSName(), 0, 0, &res);
-
- if (!err) {
- for(const auto& answer : mdp.d_answers) {
- if (answer.d_type == QType::SOA) {
- d_soacount++;
+ if (records == nullptr) {
+ err = parseResult(mdp, DNSName(), 0, 0, &res);
+ if (err == 0) {
+ for(const auto& answer : mdp.d_answers) {
+ if (answer.d_type == QType::SOA) {
+ d_soacount++;
+ }
}
}
}
- }
- else {
- records->clear();
- records->reserve(mdp.d_answers.size());
+ else {
+ records->clear();
+ records->reserve(mdp.d_answers.size());
- for(auto& r: mdp.d_answers) {
- if (r.d_type == QType::SOA) {
- d_soacount++;
- }
+ for(auto& r: mdp.d_answers) {
+ if (r.d_type == QType::SOA) {
+ d_soacount++;
+ }
- records->push_back(std::move(r));
+ records->push_back(std::move(r));
+ }
}
}
+ catch(const std::runtime_error& re) {
+ throw ResolverException(re.what());
+ }
return true;
}
}
// cout<<g_mtracer->topAllocatorsString(20)<<endl;
}
-catch(PDNSException& pe) {
- cerr<<"Fatal error: "<<pe.reason<<endl;
+catch(const PDNSException& exc) {
+ cerr<<"Fatal error: "<<exc.reason<<endl;
+}
+catch(const std::exception& exc) {
+ cerr<<"Fatal error: "<<exc.what()<<endl;
}
bool DNSPacket::getTSIGDetails(TSIGRecordContent* trc, DNSName* keyname, uint16_t* tsigPosOut) const
{
- MOADNSParser mdp(d_isQuery, d_rawpacket);
- uint16_t tsigPos = mdp.getTSIGPos();
- if(!tsigPos)
- return false;
+ try {
+ MOADNSParser mdp(d_isQuery, d_rawpacket);
+ uint16_t tsigPos = mdp.getTSIGPos();
+ if (tsigPos == 0) {
+ return false;
+ }
- bool gotit=false;
- for(const auto & answer : mdp.d_answers) {
- if(answer.d_type == QType::TSIG && answer.d_class == QType::ANY) {
- // cast can fail, f.e. if d_content is an UnknownRecordContent.
- auto content = getRR<TSIGRecordContent>(answer);
- if (!content) {
- SLOG(g_log<<Logger::Error<<"TSIG record has no or invalid content (invalid packet)"<<endl,
- d_slog->info(Logr::Error, "TSIG record has no or invalid content (invalid packet)"));
- return false;
+ bool gotit=false;
+ for(const auto & answer : mdp.d_answers) {
+ if(answer.d_type == QType::TSIG && answer.d_class == QType::ANY) {
+ // cast can fail, f.e. if d_content is an UnknownRecordContent.
+ auto content = getRR<TSIGRecordContent>(answer);
+ if (!content) {
+ SLOG(g_log<<Logger::Error<<"TSIG record has no or invalid content (invalid packet)"<<endl,
+ d_slog->info(Logr::Error, "TSIG record has no or invalid content (invalid packet)"));
+ return false;
+ }
+ *trc = *content;
+ *keyname = answer.d_name;
+ gotit=true;
}
- *trc = *content;
- *keyname = answer.d_name;
- gotit=true;
}
+ if(!gotit)
+ return false;
+
+ if (tsigPosOut != nullptr) {
+ *tsigPosOut = tsigPos;
+ }
+
+ return true;
}
- if(!gotit)
+ catch (const MOADNSException&) {
+ // If execution has reached this routine, we can reasonably assume that
+ // the packet is good enough to pass the sanity checks of
+ // MOADNSParser::init(). But just in case it doesn't, better handle this.
return false;
-
- if (tsigPosOut) {
- *tsigPosOut = tsigPos;
}
-
- return true;
}
bool DNSPacket::validateTSIG(const TSIGTriplet& tsigTriplet, const TSIGRecordContent& tsigContent, const std::string& previousMAC, const std::string& theirMAC, bool timersOnly) const
{
- MOADNSParser mdp(d_isQuery, d_rawpacket);
- uint16_t tsigPos = mdp.getTSIGPos();
- if (tsigPos == 0) {
+ try {
+ MOADNSParser mdp(d_isQuery, d_rawpacket);
+ uint16_t tsigPos = mdp.getTSIGPos();
+ if (tsigPos == 0) {
+ return false;
+ }
+
+ return ::validateTSIG(d_slog, d_rawpacket, tsigPos, tsigTriplet, tsigContent, previousMAC, theirMAC, timersOnly);
+ }
+ catch (const MOADNSException&) {
+ // If execution has reached this routine, we can reasonably assume that
+ // the packet is good enough to pass the sanity checks of
+ // MOADNSParser::init(). But just in case it doesn't, better handle this.
return false;
}
-
- return ::validateTSIG(d_slog, d_rawpacket, tsigPos, tsigTriplet, tsigContent, previousMAC, theirMAC, timersOnly);
}
bool DNSPacket::getTKEYRecord(TKEYRecordContent *tr, DNSName *keyname) const
{
- MOADNSParser mdp(d_isQuery, d_rawpacket);
- bool gotit=false;
-
- for(const auto & answer : mdp.d_answers) {
- if (gotit) {
- SLOG(g_log<<Logger::Error<<"More than one TKEY record found in query"<<endl,
- d_slog->info(Logr::Error, "More than one TKEY record found in query"));
- return false;
- }
+ try {
+ MOADNSParser mdp(d_isQuery, d_rawpacket);
+ bool gotit=false;
- if(answer.d_type == QType::TKEY) {
- // cast can fail, f.e. if d_content is an UnknownRecordContent.
- auto content = getRR<TKEYRecordContent>(answer);
- if (!content) {
- SLOG(g_log<<Logger::Error<<"TKEY record has no or invalid content (invalid packet)"<<endl,
- d_slog->info(Logr::Error, "TKEY record has no or invalid content (invalid packet)"));
+ for(const auto & answer : mdp.d_answers) {
+ if (gotit) {
+ SLOG(g_log<<Logger::Error<<"More than one TKEY record found in query"<<endl,
+ d_slog->info(Logr::Error, "More than one TKEY record found in query"));
return false;
}
- *tr = *content;
- *keyname = answer.d_name;
- gotit=true;
+
+ if(answer.d_type == QType::TKEY) {
+ // cast can fail, f.e. if d_content is an UnknownRecordContent.
+ auto content = getRR<TKEYRecordContent>(answer);
+ if (!content) {
+ SLOG(g_log<<Logger::Error<<"TKEY record has no or invalid content (invalid packet)"<<endl,
+ d_slog->info(Logr::Error, "TKEY record has no or invalid content (invalid packet)"));
+ return false;
+ }
+ *tr = *content;
+ *keyname = answer.d_name;
+ gotit=true;
+ }
}
- }
- return gotit;
+ return gotit;
+ }
+ catch (const MOADNSException&) {
+ // If execution has reached this routine, we can reasonably assume that
+ // the packet is good enough to pass the sanity checks of
+ // MOADNSParser::init(). But just in case it doesn't, better handle this.
+ return false;
+ }
}
/** This function takes data from the network, possibly received with recvfrom, and parses
throw ResolverException("recvfrom error waiting for answer: "+stringerror());
}
- MOADNSParser mdp(false, (char*)buf, err);
- *id=mdp.d_header.id;
- *domain = mdp.d_qname;
-
- if(domain->empty())
- throw ResolverException("SOA query to '" + remote->toLogString() + "' produced response without domain name (RCode: " + RCode::to_s(mdp.d_header.rcode) + ")");
-
- if(mdp.d_answers.empty())
- throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' produced no results (RCode: " + RCode::to_s(mdp.d_header.rcode) + ")");
-
- if(mdp.d_qtype != QType::SOA)
- throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' returned wrong record type");
-
- if(mdp.d_header.rcode != 0)
- throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' returned Rcode " + RCode::to_s(mdp.d_header.rcode));
-
- *theirInception = *theirExpire = 0;
- bool gotSOA=false;
- for(const MOADNSParser::answers_t::value_type& drc : mdp.d_answers) {
- if(drc.d_type == QType::SOA && drc.d_name == *domain) {
- auto src = getRR<SOARecordContent>(drc);
- if (src) {
- *theirSerial = src->d_st.serial;
- gotSOA = true;
- }
+ bool gotSOA{false};
+ try {
+ MOADNSParser mdp(false, (char*)buf, err);
+ *id=mdp.d_header.id;
+ *domain = mdp.d_qname;
+
+ if(domain->empty()) {
+ throw ResolverException("SOA query to '" + remote->toLogString() + "' produced response without domain name (RCode: " + RCode::to_s(mdp.d_header.rcode) + ")");
+ }
+
+ if(mdp.d_answers.empty()) {
+ throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' produced no results (RCode: " + RCode::to_s(mdp.d_header.rcode) + ")");
+ }
+
+ if(mdp.d_qtype != QType::SOA) {
+ throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' returned wrong record type");
}
- if(drc.d_type == QType::RRSIG && drc.d_name == *domain) {
- auto rrc = getRR<RRSIGRecordContent>(drc);
- if(rrc && rrc->d_type == QType::SOA) {
- *theirInception= std::max(*theirInception, rrc->d_siginception);
- *theirExpire = std::max(*theirExpire, rrc->d_sigexpire);
+
+ if(mdp.d_header.rcode != 0) {
+ throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' returned Rcode " + RCode::to_s(mdp.d_header.rcode));
+ }
+
+ *theirInception = *theirExpire = 0;
+ for(const MOADNSParser::answers_t::value_type& drc : mdp.d_answers) {
+ if(drc.d_type == QType::SOA && drc.d_name == *domain) {
+ auto src = getRR<SOARecordContent>(drc);
+ if (src) {
+ *theirSerial = src->d_st.serial;
+ gotSOA = true;
+ }
+ }
+ if(drc.d_type == QType::RRSIG && drc.d_name == *domain) {
+ auto rrc = getRR<RRSIGRecordContent>(drc);
+ if(rrc && rrc->d_type == QType::SOA) {
+ *theirInception= std::max(*theirInception, rrc->d_siginception);
+ *theirExpire = std::max(*theirExpire, rrc->d_sigexpire);
+ }
}
}
}
- if(!gotSOA)
+ catch (const MOADNSException& exc) {
+ throw ResolverException("SOA Query to '" + remote->toLogString() + "' produced ill-formed response: " + exc.what());
+ }
+ if(!gotSOA) {
throw ResolverException("Query to '" + remote->toLogString() + "' for SOA of '" + domain->toLogString() + "' did not return a SOA");
+ }
return true;
}
catch(ResolverException &re) {
throw ResolverException(re.reason+" from "+to.toLogString());
}
+ catch (const MOADNSException& exc) {
+ throw ResolverException(std::string(exc.what()) + " from " + to.toLogString());
+ }
}
int Resolver::resolve(const ComboAddress& ipport, const DNSName &domain, int type, Resolver::res_t* res) {
catch (...) {
continue;
}
- MOADNSParser mdp(false, reply);
- if (mdp.d_header.rcode == RCode::ServFail) {
- continue;
- }
- for (const auto& answer : mdp.d_answers) {
- if (answer.d_place == 1 && answer.d_type == qtype) {
- DNSZoneRecord zrr;
- zrr.dr = answer;
- zrr.auth = true;
- ret.push_back(std::move(zrr));
+ try {
+ MOADNSParser mdp(false, reply);
+ if (mdp.d_header.rcode == RCode::ServFail) {
+ continue;
+ }
+
+ for (const auto& answer : mdp.d_answers) {
+ if (answer.d_place == 1 && answer.d_type == qtype) {
+ DNSZoneRecord zrr;
+ zrr.dr = answer;
+ zrr.auth = true;
+ ret.push_back(std::move(zrr));
+ }
}
+ SLOG(g_log << Logger::Debug << logPrefix << "Question for '" << queryNameType << "' got answered by " << dest.toString() << endl,
+ slog->info(Logr::Debug, "stub-resolver: got an answer", "query", Logging::Loggable(qname), "type", Logging::Loggable(QType(qtype)), "resolver", Logging::Loggable(dest)));
+ return mdp.d_header.rcode;
+ }
+ catch (const MOADNSException& exc) {
+ SLOG(g_log << Logger::Debug << logPrefix << "Question for '" << queryNameType << "' got ill-formed answer from " << dest.toString() << ": " << exc.what() << endl,
+ slog->error(Logr::Debug, exc.what(), "stub-resolver: got an ill-formed answer", "query", Logging::Loggable(qname), "type", Logging::Loggable(QType(qtype)), "resolver", Logging::Loggable(dest)));
+ continue;
}
- SLOG(g_log << Logger::Debug << logPrefix << "Question for '" << queryNameType << "' got answered by " << dest.toString() << endl,
- slog->info(Logr::Debug, "stub-resolver: got an answer", "query", Logging::Loggable(qname), "type", Logging::Loggable(QType(qtype)), "resolver", Logging::Loggable(dest)));
- return mdp.d_header.rcode;
}
return RCode::ServFail;
}