+class DNSRequest
+{
+ public:
+ unsigned char id[2]; /* Request id */
+ unsigned char* res; /* Result processing buffer */
+ unsigned int rr_class; /* Request class */
+ QueryType type; /* Request type */
+ DNS* dnsobj; /* DNS caller (where we get our FD from) */
+ unsigned long ttl; /* Time to live */
+ std::string orig; /* Original requested name/ip */
+ InspIRCd* ServerInstance;
+
+ DNSRequest(InspIRCd* Instance, DNS* dns, int id, const std::string &original);
+ ~DNSRequest();
+ DNSInfo ResultIsReady(DNSHeader &h, int length);
+ int SendRequests(const DNSHeader *header, const int length, QueryType qt);
+};
+
+class CacheTimer : public Timer
+{
+ private:
+ InspIRCd* ServerInstance;
+ DNS* dns;
+ public:
+ CacheTimer(InspIRCd* Instance, DNS* thisdns)
+ : Timer(3600, Instance->Time(), true), ServerInstance(Instance), dns(thisdns) { }
+
+ virtual void Tick(time_t)
+ {
+ dns->PruneCache();
+ }
+};
+
+class RequestTimeout : public Timer
+{
+ InspIRCd* ServerInstance;
+ DNSRequest* watch;
+ int watchid;
+ public:
+ RequestTimeout(unsigned long n, InspIRCd* SI, DNSRequest* watching, int id) : Timer(n, SI->Time()), ServerInstance(SI), watch(watching), watchid(id)
+ {
+ }
+ ~RequestTimeout()
+ {
+ if (ServerInstance->Res)
+ Tick(0);
+ }
+
+ void Tick(time_t)
+ {
+ if (ServerInstance->Res->requests[watchid] == watch)
+ {
+ /* Still exists, whack it */
+ if (ServerInstance->Res->Classes[watchid])
+ {
+ ServerInstance->Res->Classes[watchid]->OnError(RESOLVER_TIMEOUT, "Request timed out");
+ delete ServerInstance->Res->Classes[watchid];
+ ServerInstance->Res->Classes[watchid] = NULL;
+ }
+ ServerInstance->Res->requests[watchid] = NULL;
+ delete watch;
+ }
+ }
+};
+
+/* Allocate the processing buffer */
+DNSRequest::DNSRequest(InspIRCd* Instance, DNS* dns, int rid, const std::string &original) : dnsobj(dns), ServerInstance(Instance)
+{
+ res = new unsigned char[512];
+ *res = 0;
+ orig = original;
+ RequestTimeout* RT = new RequestTimeout(Instance->Config->dns_timeout ? Instance->Config->dns_timeout : 5, Instance, this, rid);
+ Instance->Timers->AddTimer(RT); /* The timer manager frees this */