diff options
-rw-r--r-- | include/dns.h | 31 | ||||
-rw-r--r-- | include/socketengine.h | 1 | ||||
-rw-r--r-- | src/dns.cpp | 98 | ||||
-rw-r--r-- | src/inspircd.cpp | 10 |
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]); |