summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dns.cpp102
-rw-r--r--src/modules/extra/m_pgsql.cpp13
-rw-r--r--src/modules/m_cgiirc.cpp20
-rw-r--r--src/modules/m_dnsbl.cpp12
-rw-r--r--src/modules/m_http_client.cpp9
-rw-r--r--src/modules/m_spanningtree.cpp20
-rw-r--r--src/modules/m_testcommand.cpp24
-rw-r--r--src/users.cpp22
8 files changed, 172 insertions, 50 deletions
diff --git a/src/dns.cpp b/src/dns.cpp
index d2f08a6e0..385f8639e 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -95,8 +95,9 @@ class DNSRequest
insp_inaddr myserver; /* DNS server address*/
DNS* dnsobj; /* DNS caller (where we get our FD from) */
unsigned long ttl; /* Time to live */
+ std::string orig; /* Original requested name/ip */
- DNSRequest(InspIRCd* Instance, DNS* dns, insp_inaddr server, int id);
+ DNSRequest(InspIRCd* Instance, DNS* dns, insp_inaddr server, int id, const std::string &original);
~DNSRequest();
DNSInfo ResultIsReady(DNSHeader &h, int length);
int SendRequests(const DNSHeader *header, const int length, QueryType qt);
@@ -134,11 +135,12 @@ class RequestTimeout : public InspTimer
};
/* Allocate the processing buffer */
-DNSRequest::DNSRequest(InspIRCd* Instance, DNS* dns, insp_inaddr server, int id) : dnsobj(dns)
+DNSRequest::DNSRequest(InspIRCd* Instance, DNS* dns, insp_inaddr server, int id, const std::string &original) : dnsobj(dns)
{
res = new unsigned char[512];
*res = 0;
memcpy(&myserver, &server, sizeof(insp_inaddr));
+ orig = original;
RequestTimeout* RT = new RequestTimeout(Instance->Config->dns_timeout ? Instance->Config->dns_timeout : 5, Instance, this, id);
Instance->Timers->AddTimer(RT); /* The timer manager frees this */
}
@@ -218,7 +220,7 @@ int DNSRequest::SendRequests(const DNSHeader *header, const int length, QueryTyp
}
/** Add a query with a predefined header, and allocate an ID for it. */
-DNSRequest* DNS::AddQuery(DNSHeader *header, int &id)
+DNSRequest* DNS::AddQuery(DNSHeader *header, int &id, const char* original)
{
/* Is the DNS connection down? */
if (this->GetFd() == -1)
@@ -231,7 +233,7 @@ DNSRequest* DNS::AddQuery(DNSHeader *header, int &id)
while (requests[id])
id = this->PRNG() & DNS::MAX_REQUEST_ID;
- DNSRequest* req = new DNSRequest(ServerInstance, this, this->myserver, id);
+ DNSRequest* req = new DNSRequest(ServerInstance, this, this->myserver, id, original);
header->id[0] = req->id[0] = id >> 8;
header->id[1] = req->id[1] = id & 0xFF;
@@ -263,6 +265,19 @@ void DNS::Rehash()
shutdown(this->GetFd(), 2);
close(this->GetFd());
this->SetFd(-1);
+
+ /* Rehash the cache */
+ dnscache* newcache = new dnscache();
+ for (dnscache::iterator i = this->cache->begin(); i != this->cache->end(); i++)
+ newcache->insert(*i);
+
+ delete this->cache;
+ this->cache = newcache;
+ }
+ else
+ {
+ /* Create initial dns cache */
+ this->cache = new dnscache();
}
if (insp_aton(ServerInstance->Config->DNSServer,&addr) > 0)
@@ -358,9 +373,18 @@ DNS::DNS(InspIRCd* Instance) : ServerInstance(Instance)
/* Set the id of the next request to 0
*/
currid = 0;
+
+ /* DNS::Rehash() sets this to a valid ptr
+ */
+ this->cache = NULL;
+ /* Again, DNS::Rehash() sets this to a
+ * valid value
+ */
this->SetFd(-1);
+ /* Actually read the settings
+ */
this->Rehash();
}
@@ -411,7 +435,7 @@ int DNS::GetIP(const char *name)
if ((length = this->MakePayload(name, DNS_QUERY_A, 1, (unsigned char*)&h.payload)) == -1)
return -1;
- DNSRequest* req = this->AddQuery(&h, id);
+ DNSRequest* req = this->AddQuery(&h, id, name);
if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_A) == -1))
return -1;
@@ -429,7 +453,7 @@ int DNS::GetIP6(const char *name)
if ((length = this->MakePayload(name, DNS_QUERY_AAAA, 1, (unsigned char*)&h.payload)) == -1)
return -1;
- DNSRequest* req = this->AddQuery(&h, id);
+ DNSRequest* req = this->AddQuery(&h, id, name);
if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_AAAA) == -1))
return -1;
@@ -447,7 +471,7 @@ int DNS::GetCName(const char *alias)
if ((length = this->MakePayload(alias, DNS_QUERY_CNAME, 1, (unsigned char*)&h.payload)) == -1)
return -1;
- DNSRequest* req = this->AddQuery(&h, id);
+ DNSRequest* req = this->AddQuery(&h, id, alias);
if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_CNAME) == -1))
return -1;
@@ -479,7 +503,7 @@ int DNS::GetName(const insp_inaddr *ip)
if ((length = this->MakePayload(query, DNS_QUERY_PTR, 1, (unsigned char*)&h.payload)) == -1)
return -1;
- DNSRequest* req = this->AddQuery(&h, id);
+ DNSRequest* req = this->AddQuery(&h, id, insp_ntoa(*ip));
if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_PTR) == -1))
return -1;
@@ -525,7 +549,7 @@ int DNS::GetNameForce(const char *ip, ForceProtocol fp)
if ((length = this->MakePayload(query, DNS_QUERY_PTR, 1, (unsigned char*)&h.payload)) == -1)
return -1;
- DNSRequest* req = this->AddQuery(&h, id);
+ DNSRequest* req = this->AddQuery(&h, id, ip);
if ((!req) || (req->SendRequests(&h, length, DNS_QUERY_PTR) == -1))
return -1;
@@ -577,7 +601,7 @@ DNSResult DNS::GetResult()
{
/* Nope - something screwed up. */
ServerInstance->Log(DEBUG,"Whole header not read!");
- return DNSResult(-1,"",0);
+ return DNSResult(-1,"",0,"");
}
/* Check wether the reply came from a different DNS
@@ -605,7 +629,7 @@ DNSResult DNS::GetResult()
if ((port_from != DNS::QUERY_PORT) || (strcasecmp(ipaddr_from, ServerInstance->Config->DNSServer)))
{
ServerInstance->Log(DEBUG,"port %d is not 53, or %s is not %s",port_from, ipaddr_from, ServerInstance->Config->DNSServer);
- return DNSResult(-1,"",0);
+ return DNSResult(-1,"",0,"");
}
}
@@ -623,7 +647,7 @@ DNSResult DNS::GetResult()
{
/* Somehow we got a DNS response for a request we never made... */
ServerInstance->Log(DEBUG,"DNS: got a response for a query we didnt send with fd=%d queryid=%d",this->GetFd(),this_id);
- return DNSResult(-1,"",0);
+ return DNSResult(-1,"",0,"");
}
else
{
@@ -648,8 +672,9 @@ DNSResult DNS::GetResult()
* an error response and needs to be treated uniquely.
* Put the error message in the second field.
*/
+ std::string ro = req->orig;
delete req;
- return DNSResult(this_id | ERROR_MASK, data.second, 0);
+ return DNSResult(this_id | ERROR_MASK, data.second, 0, ro);
}
else
{
@@ -714,8 +739,9 @@ DNSResult DNS::GetResult()
}
/* Build the reply with the id and hostname/ip in it */
+ std::string ro = req->orig;
delete req;
- return DNSResult(this_id,resultstr,ttl);
+ return DNSResult(this_id,resultstr,ttl,ro);
}
}
@@ -871,11 +897,50 @@ DNS::~DNS()
close(this->GetFd());
}
+CachedQuery* DNS::GetCache(const std::string &source)
+{
+ dnscache::iterator x = cache->find(source.c_str());
+ if (x != cache->end())
+ return &(x->second);
+ else
+ return NULL;
+}
+
+void DNS::DelCache(const std::string &source)
+{
+ cache->erase(source.c_str());
+}
+
+void Resolver::OnLookupComplete(const std::string &result, unsigned int ttl)
+{
+ throw CoreException("Someone didnt define an OnLookupComplete method for their Resolver class!");
+}
+
/** High level abstraction of dns used by application at large */
-Resolver::Resolver(InspIRCd* Instance, const std::string &source, QueryType qt, Module* creator) : ServerInstance(Instance), Creator(creator), input(source), querytype(qt)
+Resolver::Resolver(InspIRCd* Instance, const std::string &source, QueryType qt, bool &cached, Module* creator) : ServerInstance(Instance), Creator(creator), input(source), querytype(qt)
{
ServerInstance->Log(DEBUG,"Instance: %08x %08x",Instance, ServerInstance);
+ cached = false;
+
+ CachedQuery* CQ = ServerInstance->Res->GetCache(source);
+ if (CQ)
+ {
+ int time_left = CQ->CalcTTLRemaining();
+ if (!time_left)
+ {
+ ServerInstance->Log(DEBUG,"Cached but EXPIRED result: %s", CQ->data.c_str());
+ ServerInstance->Res->DelCache(source);
+ }
+ else
+ {
+ cached = true;
+ ServerInstance->Log(DEBUG,"Cached result: %s", CQ->data.c_str());
+ OnLookupComplete(CQ->data, time_left);
+ return;
+ }
+ }
+
insp_inaddr binip;
switch (querytype)
@@ -988,6 +1053,13 @@ void DNS::HandleEvent(EventType et, int errornum)
{
if (ServerInstance && ServerInstance->stats)
ServerInstance->stats->statsDnsGood++;
+
+ if (!this->GetCache(res.original.c_str()))
+ {
+ ServerInstance->Log(DEBUG,"Caching result: %s->%s for %lu secs", res.original.c_str(), res.result.c_str(), res.ttl);
+ this->cache->insert(std::make_pair(res.original.c_str(), CachedQuery(res.result, res.ttl)));
+ }
+
Classes[res.id]->OnLookupComplete(res.result, res.ttl);
delete Classes[res.id];
Classes[res.id] = NULL;
diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp
index 79630d416..d72256a5f 100644
--- a/src/modules/extra/m_pgsql.cpp
+++ b/src/modules/extra/m_pgsql.cpp
@@ -90,8 +90,8 @@ class SQLresolver : public Resolver
SQLhost host;
Module* mod;
public:
- SQLresolver(Module* m, InspIRCd* Instance, const SQLhost& hi)
- : Resolver(Instance, hi.host, DNS_QUERY_FORWARD, (Module*)m), host(hi), mod(m)
+ SQLresolver(Module* m, InspIRCd* Instance, const SQLhost& hi, bool &cached)
+ : Resolver(Instance, hi.host, DNS_QUERY_FORWARD, cached, (Module*)m), host(hi), mod(m)
{
}
@@ -1099,9 +1099,12 @@ public:
try
{
- resolver = new SQLresolver(this, ServerInstance, host);
-
- ServerInstance->AddResolver(resolver);
+ bool cached;
+ resolver = new SQLresolver(this, ServerInstance, host, cached);
+ if (!cached)
+ ServerInstance->AddResolver(resolver);
+ else
+ delete resolver;
}
catch(...)
{
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index dc11ccf96..6df039dce 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -51,8 +51,8 @@ class CGIResolver : public Resolver
userrec* them;
bool notify;
public:
- CGIResolver(Module* me, InspIRCd* ServerInstance, bool NotifyOpers, const std::string &source, bool forward, userrec* u, int userfd, const std::string &type)
- : Resolver(ServerInstance, source, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE, me), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { }
+ CGIResolver(Module* me, InspIRCd* ServerInstance, bool NotifyOpers, const std::string &source, bool forward, userrec* u, int userfd, const std::string &type, bool &cached)
+ : Resolver(ServerInstance, source, forward ? DNS_QUERY_FORWARD : DNS_QUERY_REVERSE, cached, me), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { }
virtual void OnLookupComplete(const std::string &result, unsigned int ttl)
{
@@ -259,8 +259,12 @@ public:
try
{
- CGIResolver* r = new CGIResolver(this, ServerInstance, NotifyOpers, user->password, false, user, user->GetFd(), "PASS");
- ServerInstance->AddResolver(r);
+ bool cached;
+ CGIResolver* r = new CGIResolver(this, ServerInstance, NotifyOpers, user->password, false, user, user->GetFd(), "PASS", cached);
+ if (!cached)
+ ServerInstance->AddResolver(r);
+ else
+ delete r;
}
catch (ModuleException& e)
{
@@ -315,8 +319,12 @@ public:
try
{
ServerInstance->Log(DEBUG,"MAKE RESOLVER: %s %d %s",newip, user->GetFd(), "IDENT");
- CGIResolver* r = new CGIResolver(this, ServerInstance, NotifyOpers, newip, false, user, user->GetFd(), "IDENT");
- ServerInstance->AddResolver(r);
+ bool cached;
+ CGIResolver* r = new CGIResolver(this, ServerInstance, NotifyOpers, newip, false, user, user->GetFd(), "IDENT", cached);
+ if (!cached)
+ ServerInstance->AddResolver(r);
+ else
+ delete r;
}
catch (ModuleException& e)
{
diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp
index 91bfa5131..d6581a7d1 100644
--- a/src/modules/m_dnsbl.cpp
+++ b/src/modules/m_dnsbl.cpp
@@ -46,8 +46,8 @@ class DNSBLResolver : public Resolver
DNSBLConfEntry *ConfEntry;
public:
- DNSBLResolver(Module *me, InspIRCd *ServerInstance, const std::string &hostname, userrec* u, int userfd, DNSBLConfEntry *conf)
- : Resolver(ServerInstance, hostname, DNS_QUERY_A, me)
+ DNSBLResolver(Module *me, InspIRCd *ServerInstance, const std::string &hostname, userrec* u, int userfd, DNSBLConfEntry *conf, bool &cached)
+ : Resolver(ServerInstance, hostname, DNS_QUERY_A, cached, me)
{
theirfd = userfd;
them = u;
@@ -307,8 +307,12 @@ class ModuleDNSBL : public Module
ServerInstance->Log(DEBUG, "m_dnsbl: sending %s for resolution", hostname.c_str());
/* now we'd need to fire off lookups for `hostname'. */
- DNSBLResolver *r = new DNSBLResolver(this, ServerInstance, hostname, user, user->GetFd(), *i);
- ServerInstance->AddResolver(r);
+ bool cached;
+ DNSBLResolver *r = new DNSBLResolver(this, ServerInstance, hostname, user, user->GetFd(), *i, cached);
+ if (!cached)
+ ServerInstance->AddResolver(r);
+ else
+ delete r;
}
}
diff --git a/src/modules/m_http_client.cpp b/src/modules/m_http_client.cpp
index 0ca302ef6..92a9aa348 100644
--- a/src/modules/m_http_client.cpp
+++ b/src/modules/m_http_client.cpp
@@ -56,7 +56,7 @@ class HTTPResolver : public Resolver
private:
HTTPSocket *socket;
public:
- HTTPResolver(HTTPSocket *socket, InspIRCd *Instance, const string &hostname) : Resolver(Instance, hostname, DNS_QUERY_FORWARD), socket(socket)
+ HTTPResolver(HTTPSocket *socket, InspIRCd *Instance, const string &hostname, bool &cached, Module* me) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, cached, me), socket(socket)
{
}
@@ -149,7 +149,12 @@ bool HTTPSocket::DoRequest(HTTPClientRequest *req)
if (!inet_aton(this->host, &this->addy))
{
- new HTTPResolver(this, Server, url.domain);
+ bool cached;
+ HTTPResolver* r = new HTTPResolver(this, Server, url.domain, cached, (Module*)Mod);
+ if (!cached)
+ Instance->AddResolver(r);
+ else
+ delete r;
return true;
}
else
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index 359196990..cbecfa24f 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -3714,7 +3714,7 @@ class ServernameResolver : public Resolver
Link MyLink;
SpanningTreeUtilities* Utils;
public:
- ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, me), MyLink(x), Utils(Util)
+ ServernameResolver(Module* me, SpanningTreeUtilities* Util, InspIRCd* Instance, const std::string &hostname, Link x, bool &cached) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, cached, me), MyLink(x), Utils(Util)
{
/* Nothing in here, folks */
}
@@ -3764,7 +3764,7 @@ class SecurityIPResolver : public Resolver
Link MyLink;
SpanningTreeUtilities* Utils;
public:
- SecurityIPResolver(Module* me, SpanningTreeUtilities* U, InspIRCd* Instance, const std::string &hostname, Link x) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, me), MyLink(x), Utils(U)
+ SecurityIPResolver(Module* me, SpanningTreeUtilities* U, InspIRCd* Instance, const std::string &hostname, Link x, bool &cached) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, cached, me), MyLink(x), Utils(U)
{
}
@@ -4122,8 +4122,12 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
{
try
{
- SecurityIPResolver* sr = new SecurityIPResolver((Module*)this->Creator, this, ServerInstance, L.IPAddr, L);
- ServerInstance->AddResolver(sr);
+ bool cached;
+ SecurityIPResolver* sr = new SecurityIPResolver((Module*)this->Creator, this, ServerInstance, L.IPAddr, L, cached);
+ if (!cached)
+ ServerInstance->AddResolver(sr);
+ else
+ delete sr;
}
catch (ModuleException& e)
{
@@ -4653,8 +4657,12 @@ class ModuleSpanningTree : public Module
{
try
{
- ServernameResolver* snr = new ServernameResolver((Module*)this, Utils, ServerInstance,x->IPAddr, *x);
- ServerInstance->AddResolver(snr);
+ bool cached;
+ ServernameResolver* snr = new ServernameResolver((Module*)this, Utils, ServerInstance,x->IPAddr, *x, cached);
+ if (!cached)
+ ServerInstance->AddResolver(snr);
+ else
+ delete snr;
}
catch (ModuleException& e)
{
diff --git a/src/modules/m_testcommand.cpp b/src/modules/m_testcommand.cpp
index 00988ff96..55632c98e 100644
--- a/src/modules/m_testcommand.cpp
+++ b/src/modules/m_testcommand.cpp
@@ -26,7 +26,7 @@ class MyV6Resolver : public Resolver
{
bool fw;
public:
- MyV6Resolver(InspIRCd* Instance, Module* me, const std::string &source, bool forward) : Resolver(Instance, source, forward ? DNS_QUERY_AAAA : DNS_QUERY_PTR6, me)
+ MyV6Resolver(InspIRCd* Instance, Module* me, const std::string &source, bool forward, bool &cached) : Resolver(Instance, source, forward ? DNS_QUERY_AAAA : DNS_QUERY_PTR6, cached, me)
{
fw = forward;
}
@@ -60,10 +60,24 @@ class cmd_woot : public command_t
* do it for us as required.*/
try
{
- MyV6Resolver* r = new MyV6Resolver(ServerInstance, Creator, "shake.stacken.kth.se", true);
- ServerInstance->AddResolver(r);
- r = new MyV6Resolver(ServerInstance, Creator, "2001:6b0:1:ea:202:a5ff:fecd:13a6", false);
- ServerInstance->AddResolver(r);
+ bool cached1, cached2;
+ MyV6Resolver* r = new MyV6Resolver(ServerInstance, Creator, "shake.stacken.kth.se", true, cached1);
+ if (!cached1)
+ ServerInstance->AddResolver(r);
+ else
+ {
+ ServerInstance->Log(DEBUG,"Result was cached, delete object");
+ delete r;
+ }
+
+ r = new MyV6Resolver(ServerInstance, Creator, "2001:6b0:1:ea:202:a5ff:fecd:13a6", false, cached2);
+ if (!cached2)
+ ServerInstance->AddResolver(r);
+ else
+ {
+ ServerInstance->Log(DEBUG,"Result was cached, delete object");
+ delete r;
+ }
}
catch (ModuleException& e)
{
diff --git a/src/users.cpp b/src/users.cpp
index 0e25f8e55..37664a629 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -151,8 +151,12 @@ void userrec::StartDNSLookup()
try
{
ServerInstance->Log(DEBUG,"Passing instance: %08x",this->ServerInstance);
- res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), DNS_QUERY_REVERSE);
- this->ServerInstance->AddResolver(res_reverse);
+ bool cached;
+ res_reverse = new UserResolver(this->ServerInstance, this, this->GetIPString(), DNS_QUERY_REVERSE, cached);
+ if (!cached)
+ this->ServerInstance->AddResolver(res_reverse);
+ else
+ delete res_reverse;
}
catch (CoreException& e)
{
@@ -160,8 +164,8 @@ void userrec::StartDNSLookup()
}
}
-UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt) :
- Resolver(Instance, to_resolve, qt), bound_user(user)
+UserResolver::UserResolver(InspIRCd* Instance, userrec* user, std::string to_resolve, QueryType qt, bool &cache) :
+ Resolver(Instance, to_resolve, qt, cache), bound_user(user)
{
this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA);
this->bound_fd = user->GetFd();
@@ -178,13 +182,17 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl)
/* Check we didnt time out */
if (this->bound_user->registered != REG_ALL)
{
+ bool cached;
#ifdef IPV6
const char *ip = this->bound_user->GetIPString();
- bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, (strstr(ip,"0::ffff:") == ip ? DNS_QUERY_A : DNS_QUERY_AAAA));
+ bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, (strstr(ip,"0::ffff:") == ip ? DNS_QUERY_A : DNS_QUERY_AAAA), cached);
#else
- bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, DNS_QUERY_A);
+ bound_user->res_forward = new UserResolver(this->ServerInstance, this->bound_user, result, DNS_QUERY_A, cached);
#endif
- this->ServerInstance->AddResolver(bound_user->res_forward);
+ if (!cached)
+ this->ServerInstance->AddResolver(bound_user->res_forward);
+ else
+ delete bound_user->res_forward;
}
}
catch (CoreException& e)