summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/dns.h31
-rw-r--r--include/socketengine.h1
-rw-r--r--src/dns.cpp98
-rw-r--r--src/inspircd.cpp10
4 files changed, 140 insertions, 0 deletions
diff --git a/include/dns.h b/include/dns.h
index b0dc3636f..89dd4e270 100644
--- a/include/dns.h
+++ b/include/dns.h
@@ -29,6 +29,14 @@ struct dns_ip4list
dns_ip4list *next;
};
+enum ResolverError
+{
+ RESOLVER_NOERROR = 0,
+ RESOLVER_NSDOWN = 1,
+ RESOLVER_NXDOMAIN = 2,
+ RESOLVER_NOTREADY = 3
+};
+
/** The DNS class allows fast nonblocking resolution of hostnames
* and ip addresses. It is based heavily upon firedns by Ian Gulliver.
@@ -101,6 +109,29 @@ public:
void SetNS(const std::string &dnsserver);
};
+class Resolver : public Extensible
+{
+ private:
+ DNS Query;
+ std::string input;
+ bool fwd;
+ std::string server;
+ int fd;
+ std::string result;
+ public:
+ Resolver(const std::string &source, bool forward, const std::string &dnsserver);
+ virtual ~Resolver();
+ virtual void OnLookupComplete(const std::string &result);
+ virtual void OnError(ResolverError e);
+
+ bool ProcessResult();
+ int GetFd();
+};
+
+void init_dns();
+void dns_deal_with_classes(int fd);
+bool dns_add_class(Resolver* r);
+
/** This is the handler function for multi-threaded DNS.
* It cannot be a class member as pthread will not let us
* create a thread whos handler function is a member of
diff --git a/include/socketengine.h b/include/socketengine.h
index bbd34a302..e07642fa1 100644
--- a/include/socketengine.h
+++ b/include/socketengine.h
@@ -44,6 +44,7 @@ const char X_LISTEN = 1;
const char X_ESTAB_CLIENT = 2;
const char X_ESTAB_MODULE = 3;
const char X_ESTAB_DNS = 4;
+const char X_ESTAB_CLASSDNS = 5;
/**
* To indicate that a socket is readable, we
diff --git a/src/dns.cpp b/src/dns.cpp
index ab244a049..06cff0757 100644
--- a/src/dns.cpp
+++ b/src/dns.cpp
@@ -50,6 +50,7 @@ using namespace std;
#include "inspircd.h"
#include "helperfuncs.h"
#include "socketengine.h"
+#include "configreader.h"
extern InspIRCd* ServerInstance;
extern ServerConfig* Config;
@@ -65,6 +66,8 @@ typedef std::map<int,s_connection*> connlist;
typedef connlist::iterator connlist_iter;
connlist connections;
+Resolver* dns_classes[MAX_DESCRIPTORS];
+
struct in_addr servers4[8];
int i4;
int initdone = 0;
@@ -875,3 +878,98 @@ void* dns_task(void* arg)
return NULL;
}
#endif
+
+Resolver::Resolver(const std::string &source, bool forward, const std::string &dnsserver = "") : input(source), fwd(forward), server(dnsserver)
+{
+ if (this->server != "")
+ Query.SetNS(this->server);
+ else
+ Query.SetNS(Config->DNSServer);
+
+ if (forward)
+ this->fd = Query.ForwardLookup(input.c_str());
+ else
+ this->fd = Query.ReverseLookup(input.c_str());
+ if (fd < 0)
+ this->OnError(RESOLVER_NSDOWN);
+
+ if (ServerInstance && ServerInstance->SE)
+ ServerInstance->SE->AddFd(this->fd,true,X_ESTAB_CLASSDNS);
+ else
+ this->OnError(RESOLVER_NOTREADY);
+}
+
+Resolver::~Resolver()
+{
+ if (ServerInstance && ServerInstance->SE)
+ ServerInstance->SE->DelFd(this->fd);
+}
+
+int Resolver::GetFd()
+{
+ return this->fd;
+}
+
+bool Resolver::ProcessResult()
+{
+ if (this->fwd)
+ result = Query.GetResultIP();
+ else
+ result = Query.GetResult();
+
+ if (result != "")
+ {
+ this->OnLookupComplete(result);
+ return true;
+ }
+ else
+ {
+ this->OnError(RESOLVER_NXDOMAIN);
+ return false;
+ }
+}
+
+void Resolver::OnLookupComplete(const std::string &result)
+{
+}
+
+void Resolver::OnError(ResolverError e)
+{
+}
+
+void dns_deal_with_classes(int fd)
+{
+ if ((fd > -1) && (dns_classes[fd]))
+ {
+ dns_classes[fd]->ProcessResult();
+ delete dns_classes[fd];
+ dns_classes[fd] = NULL;
+ }
+}
+
+bool dns_add_class(Resolver* r)
+{
+ if ((r) && (r->GetFd() > -1))
+ {
+ if (!dns_classes[r->GetFd()])
+ {
+ dns_classes[r->GetFd()] = r;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ delete r;
+ return true;
+ }
+}
+
+void init_dns()
+{
+ memset(dns_classes,0,sizeof(dns_classes));
+}
+
diff --git a/src/inspircd.cpp b/src/inspircd.cpp
index 61c59a6b5..66f15e872 100644
--- a/src/inspircd.cpp
+++ b/src/inspircd.cpp
@@ -240,6 +240,7 @@ InspIRCd::InspIRCd(int argc, char** argv)
{
this->Start();
module_sockets.clear();
+ init_dns();
this->startup_time = time(NULL);
srand(time(NULL));
log(DEBUG,"*** InspIRCd starting up!");
@@ -836,6 +837,15 @@ void InspIRCd::DoOneIteration(bool process_module_sockets)
#endif
break;
+ case X_ESTAB_CLASSDNS:
+ /* Handles instances of the Resolver class,
+ * a simple class extended by modules for
+ * nonblocking resolving of addresses.
+ */
+
+ dns_deal_with_classes(activefds[activefd]);
+ break;
+
case X_LISTEN:
log(DEBUG,"Type: X_LISTEN_MODULE: fd=%d",activefds[activefd]);