Query() : error(ERROR_NONE), cached(false) { }
Query(const Question& q) : question(q), error(ERROR_NONE), cached(false) { }
+
+ const ResourceRecord* FindAnswerOfType(QueryType qtype) const
+ {
+ for (std::vector<DNS::ResourceRecord>::const_iterator i = answers.begin(); i != answers.end(); ++i)
+ {
+ const DNS::ResourceRecord& rr = *i;
+ if (rr.type == qtype)
+ return &rr;
+ }
+
+ return NULL;
+ }
};
class ReplySocket;
/** A DNS query.
*/
- class Request : public Timer, public Question
+ class Request : public Timer
{
protected:
Manager* const manager;
public:
+ Question question;
/* Use result cache if available */
bool use_cache;
/* Request id */
Request(Manager* mgr, Module* mod, const std::string& addr, QueryType qt, bool usecache = true)
: Timer((ServerInstance->Config->dns_timeout ? ServerInstance->Config->dns_timeout : 5))
- , Question(addr, qt)
, manager(mgr)
+ , question(addr, qt)
, use_cache(usecache)
, id(0)
, creator(mod)
*/
bool Tick(time_t now)
{
- Query rr(*this);
+ Query rr(this->question);
rr.error = ERROR_TIMEDOUT;
this->OnError(&rr);
delete this;
if (!request)
continue;
- Query rr(*request);
+ Query rr(request->question);
rr.error = ERROR_UNKNOWN;
request->OnError(&rr);
void Process(DNS::Request* req)
{
- ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Processing request to lookup " + req->name + " of type " + ConvToStr(req->type) + " to " + this->myserver.addr());
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Processing request to lookup " + req->question.name + " of type " + ConvToStr(req->question.type) + " to " + this->myserver.addr());
/* Create an id */
unsigned int tries = 0;
Packet p;
p.flags = QUERYFLAGS_RD;
p.id = req->id;
- p.question = *req;
+ p.question = req->question;
unsigned char buffer[524];
unsigned short len = p.Pack(buffer, sizeof(buffer));
}
// Update name in the original request so question checking works for PTR queries
- req->name = p.question.name;
+ req->question.name = p.question.name;
if (SocketEngine::SendTo(this, buffer, len, 0, &this->myserver.sa, this->myserver.sa_size()) != len)
throw Exception("DNS: Unable to send query");
return;
}
- if (static_cast<Question&>(*request) != recv_packet.question)
+ if (request->question != recv_packet.question)
{
// This can happen under high latency, drop it silently, do not fail the request
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Received an answer that isn't for a question we asked");
}
else
{
- ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Lookup complete for " + request->name);
+ ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Lookup complete for " + request->question.name);
ServerInstance->stats.DnsGood++;
request->OnLookupComplete(&recv_packet);
this->AddCache(recv_packet);
if (req->creator == mod)
{
- Query rr(*req);
+ Query rr(req->question);
rr.error = ERROR_UNLOADED;
req->OnError(&rr);
*/
const bool fwd;
- const DNS::ResourceRecord* FindAnswerOfType(const DNS::Query* response, DNS::QueryType qtype)
- {
- for (std::vector<DNS::ResourceRecord>::const_iterator it = response->answers.begin(); it != response->answers.end(); ++it)
- {
- const DNS::ResourceRecord& rr = *it;
-
- if (rr.type == qtype)
- {
- return &rr;
- }
- }
-
- return NULL;
- }
-
public:
/** Create a resolver.
* @param mgr DNS Manager
return;
}
- const DNS::ResourceRecord* ans_record = FindAnswerOfType(r, this->type);
+ const DNS::ResourceRecord* ans_record = r->FindAnswerOfType(this->question.type);
if (ans_record == NULL)
{
- ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "DNS result for %s: no record of type %d", uuid.c_str(), this->type);
+ OnError(r);
return;
}
void ServernameResolver::OnLookupComplete(const DNS::Query *r)
{
- const DNS::ResourceRecord &ans_record = r->answers[0];
+ const DNS::ResourceRecord* const ans_record = r->FindAnswerOfType(this->question.type);
+ if (!ans_record)
+ {
+ OnError(r);
+ return;
+ }
/* Initiate the connection, now that we have an IP to use.
* Passing a hostname directly to BufferedSocket causes it to
TreeServer* CheckDupe = Utils->FindServer(MyLink->Name.c_str());
if (!CheckDupe) /* Check that nobody tried to connect it successfully while we were resolving */
{
- TreeSocket* newsocket = new TreeSocket(MyLink, myautoconnect, ans_record.rdata);
+ TreeSocket* newsocket = new TreeSocket(MyLink, myautoconnect, ans_record->rdata);
if (newsocket->GetFd() > -1)
{
/* We're all OK */