LWResult::Result arecvfrom(std::string& packet, int flags, const ComboAddress& fromaddr, size_t *d_len,
uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval* now)
{
- static boost::optional<unsigned int> nearMissLimit;
- if(!nearMissLimit)
- nearMissLimit=::arg().asNum("spoof-nearmiss-max");
+ static const boost::optional<unsigned int> nearMissLimit = ::arg().asNum("spoof-nearmiss-max");
PacketID pident;
pident.fd=fd;
if (*nearMissLimit && pident.nearMisses > *nearMissLimit) {
g_log<<Logger::Error<<"Too many ("<<pident.nearMisses<<" > "<<*nearMissLimit<<") bogus answers for '"<<domain<<"' from "<<fromaddr.toString()<<", assuming spoof attempt."<<endl;
g_stats.spoofCount++;
- return LWResult::Result::PermanentError;
+ return LWResult::Result::Spoofed;
}
return LWResult::Result::Success;
// ednsstatus might be cleared, so do a new lookup
ednsstatus = t_sstorage.ednsstatus.insert(ip).first;
mode = &ednsstatus->mode;
- if (ret == LWResult::Result::PermanentError || ret == LWResult::Result::OSLimitError) {
+ if (ret == LWResult::Result::PermanentError || ret == LWResult::Result::OSLimitError || ret == LWResult::Result::Spoofed) {
return ret; // transport error, nothing to learn here
}
- if(ret == LWResult::Result::Timeout) { // timeout, not doing anything with it now
+ if (ret == LWResult::Result::Timeout) { // timeout, not doing anything with it now
return ret;
}
else if (*mode == EDNSStatus::UNKNOWN || *mode == EDNSStatus::EDNSOK || *mode == EDNSStatus::EDNSIGNORANT ) {
return done;
}
-bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const bool wasForwarded, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool* truncated)
+bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const bool wasForwarded, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool& truncated, bool& spoofed)
{
bool chained = false;
LWResult::Result resolveret = LWResult::Result::Success;
if(t_timeouts)
t_timeouts->push_back(remoteIP);
}
- else if(resolveret == LWResult::Result::OSLimitError) {
+ else if (resolveret == LWResult::Result::OSLimitError) {
/* OS resource limit reached */
LOG(prefix<<qname<<": hit a local resource limit resolving"<< (doTCP ? " over TCP" : "")<<", probable error: "<<stringerror()<<endl);
g_stats.resourceLimits++;
}
+ else if (resolveret == LWResult::Result::Spoofed) {
+ spoofed = true;
+ }
else {
/* -1 means server unreachable */
s_unreachables++;
t_sstorage.fails.clear(remoteIP);
}
- if(lwr.d_tcbit) {
- *truncated = true;
+ if (lwr.d_tcbit) {
+ truncated = true;
if (doTCP) {
LOG(prefix<<qname<<": truncated bit set, over TCP?"<<endl);
}
bool truncated = false;
+ bool spoofed = false;
bool gotAnswer = doResolveAtThisIP(prefix, qname, qtype, lwr, ednsmask, auth, sendRDQuery, wasForwarded,
- tns->first, *remoteIP, false, &truncated);
- if (gotAnswer && truncated ) {
+ tns->first, *remoteIP, false, truncated, spoofed);
+ if (spoofed || (gotAnswer && truncated) ) {
/* retry, over TCP this time */
gotAnswer = doResolveAtThisIP(prefix, qname, qtype, lwr, ednsmask, auth, sendRDQuery, wasForwarded,
- tns->first, *remoteIP, true, &truncated);
+ tns->first, *remoteIP, true, truncated, spoofed);
}
if (!gotAnswer) {
int doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret,
unsigned int depth, set<GetBestNSAnswer>&beenthere, vState& state, StopAtDelegation* stopAtDelegation);
- bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const bool wasForwarded, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool* truncated);
+ bool doResolveAtThisIP(const std::string& prefix, const DNSName& qname, const QType& qtype, LWResult& lwr, boost::optional<Netmask>& ednsmask, const DNSName& auth, bool const sendRDQuery, const bool wasForwarded, const DNSName& nsName, const ComboAddress& remoteIP, bool doTCP, bool& truncated, bool& spoofed);
bool processAnswer(unsigned int depth, LWResult& lwr, const DNSName& qname, const QType& qtype, DNSName& auth, bool wasForwarded, const boost::optional<Netmask> ednsmask, bool sendRDQuery, NsSet &nameservers, std::vector<DNSRecord>& ret, const DNSFilterEngine& dfe, bool* gotNewServers, int* rcode, vState& state);
int doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, vState& state);