X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fdnsqueue.cpp;h=73d80d11d02804b3fc526979d49dc7e560a7dc60;hb=84a19a9ab6129deb71cdc24b216b74dd8eb80978;hp=e949ddab95c0269b8df92ac80c910e3897b9e293;hpb=e8da3ac2c037f645b0f29f12304e8b4c6c2988e0;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/dnsqueue.cpp b/src/dnsqueue.cpp index e949ddab9..73d80d11d 100644 --- a/src/dnsqueue.cpp +++ b/src/dnsqueue.cpp @@ -2,7 +2,7 @@ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * - * Inspire is copyright (C) 2002-2004 ChatSpike-Dev. + * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev. * E-mail: * * @@ -14,171 +14,50 @@ * --------------------------------------------------- */ -/* Now with added unF! ;) */ - -using namespace std; - -#include "inspircd.h" -#include "inspircd_io.h" -#include "inspircd_util.h" #include "inspircd_config.h" +#include "inspircd.h" +#include "configreader.h" #include -#include #include #include #include -#include -#include #include -#ifdef GCC3 -#include -#else -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include "connection.h" #include "users.h" -#include "servers.h" -#include "ctables.h" #include "globals.h" -#include "modules.h" -#include "dynamic.h" -#include "wildcard.h" -#include "message.h" -#include "mode.h" -#include "commands.h" -#include "xline.h" #include "inspstring.h" #include "dnsqueue.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include "dns.h" +#include "helperfuncs.h" +#include "hashcomp.h" +#include "socketengine.h" +#include "socket.h" -#ifdef GCC3 -#define nspace __gnu_cxx -#else -#define nspace std -#endif - -extern int MaxWhoResults; - -extern std::vector modules; -extern std::vector module_names; -extern std::vector factory; -extern std::vector fd_reap; - -extern int MODCOUNT; - -namespace nspace -{ -#ifdef GCC34 - template<> struct hash -#else - template<> struct nspace::hash -#endif - { - size_t operator()(const struct in_addr &a) const - { - size_t q; - memcpy(&q,&a,sizeof(size_t)); - return q; - } - }; -#ifdef GCC34 - template<> struct hash -#else - template<> struct nspace::hash -#endif - { - size_t operator()(const string &s) const - { - char a[MAXBUF]; - static struct hash strhash; - strlcpy(a,s.c_str(),MAXBUF); - strlower(a); - return strhash(a); - } - }; -} - - -struct StrHashComp -{ - - bool operator()(const string& s1, const string& s2) const - { - char a[MAXBUF],b[MAXBUF]; - strlcpy(a,s1.c_str(),MAXBUF); - strlcpy(b,s2.c_str(),MAXBUF); - return (strcasecmp(a,b) == 0); - } - -}; - -struct InAddr_HashComp -{ - - bool operator()(const in_addr &s1, const in_addr &s2) const - { - size_t q; - size_t p; - - memcpy(&q,&s1,sizeof(size_t)); - memcpy(&p,&s2,sizeof(size_t)); - - return (q == p); - } - -}; - - -typedef nspace::hash_map, StrHashComp> user_hash; -typedef nspace::hash_map, StrHashComp> chan_hash; -typedef nspace::hash_map, InAddr_HashComp> address_cache; -typedef std::deque command_table; - -extern user_hash clientlist; -extern chan_hash chanlist; -extern user_hash whowas; -extern command_table cmdlist; +extern ServerConfig* Config; +extern InspIRCd* ServerInstance; -extern ClassVector Classes; +class Lookup; -extern char DNSServer[MAXBUF]; -long max_fd_alloc = 0; +Lookup* dnslist[MAX_DESCRIPTORS]; -extern time_t TIME; +//enum LookupState { reverse, forward }; class Lookup { private: - DNS resolver; + DNS resolver1; + DNS resolver2; char u[NICKMAX]; + std::string hostname; public: Lookup() { - strcpy(u,""); + *u = 0; + hostname = ""; } void Reset() { - strcpy(u,""); + *u = 0; + hostname = ""; } ~Lookup() @@ -187,53 +66,111 @@ public: bool DoLookup(std::string nick) { + hostname = ""; userrec* usr = Find(nick); if (usr) { - log(DEBUG,"New Lookup class for %s with DNSServer set to '%s'",nick.c_str(),DNSServer); - resolver.SetNS(std::string(DNSServer)); - if (!resolver.ReverseLookup(std::string(usr->host))) + resolver1.SetNS(std::string(Config->DNSServer)); + if (!resolver1.ReverseLookup(std::string(usr->host))) + { return false; - strlcpy(u,nick.c_str(),NICKMAX); - return true; + } + strlcpy(u,nick.c_str(),NICKMAX-1); + + /* ASSOCIATE WITH DNS LOOKUP LIST */ + if (resolver1.GetFD() != -1) + { + dnslist[resolver1.GetFD()] = this; + return true; + } } return false; } - bool Done() + bool Done(int fdcheck) { - userrec* usr = NULL; - if (resolver.HasResult()) + if (hostname != "") { - if (resolver.GetFD() != 0) + // doing forward lookup + userrec* usr = NULL; + if (resolver2.HasResult(fdcheck)) { - std::string hostname = resolver.GetResult(); - usr = Find(u); - if (usr) + if (resolver2.GetFD() != -1) { - if (usr->registered > 3) + dnslist[resolver2.GetFD()] = NULL; + std::string ip = resolver2.GetResultIP(); + usr = Find(u); + if (usr) { - usr->dns_done = true; - return true; + if (usr->registered > 3) + { + usr->dns_done = true; + return true; + } + if ((hostname != "") && (usr->registered != 7)) + { + if ((std::string((char*)inet_ntoa(usr->ip4)) == ip) && (hostname.length() < 65)) + { + strlcpy(usr->host,hostname.c_str(),MAXBUF); + strlcpy(usr->dhost,hostname.c_str(),MAXBUF); + /*address_cache::iterator address = addrcache.find(usr->ip4); + if (address == addrcache.end()) + { + log(DEBUG,"Caching hostname %s -> %s",(char*)inet_ntoa(usr->ip4),hostname.c_str()); + addrcache[usr->ip4] = new std::string(hostname); + }*/ + WriteServ(usr->fd,"NOTICE Auth :*** Found your hostname"); + } + usr->dns_done = true; + return true; + } } - if ((hostname != "") && (usr->registered != 7)) + } + else + { + usr = Find(u); + if (usr) { - strlcpy(usr->host,hostname.c_str(),MAXBUF); - strlcpy(usr->dhost,hostname.c_str(),MAXBUF); - WriteServ(usr->fd,"NOTICE Auth :Resolved your hostname: %s",hostname.c_str()); usr->dns_done = true; - return true; } - usr->dns_done = true; return true; } } - else + return false; + } + else + { + // doing reverse lookup + userrec* usr = NULL; + if (resolver1.HasResult(fdcheck)) { usr = Find(u); - if (usr) - usr->dns_done = true; - return true; + if ((usr) && (usr->dns_done)) + { + if (resolver1.GetFD() != -1) + dnslist[resolver1.GetFD()] = NULL; + return true; + } + if (resolver1.GetFD() != -1) + { + dnslist[resolver1.GetFD()] = NULL; + hostname = resolver1.GetResult(); + if (usr) + { + if ((usr->registered > 3) || (hostname == "")) + { + WriteServ(usr->fd,"NOTICE Auth :*** Could not resolve your hostname -- Using your IP address instead"); + usr->dns_done = true; + return true; + } + } + if (hostname != "") + { + resolver2.ForwardLookup(hostname); + if (resolver2.GetFD() != -1) + dnslist[resolver2.GetFD()] = this; + } + } } } return false; @@ -250,59 +187,86 @@ public: } }; -Lookup dnsq[MAXBUF]; - -bool lookup_dns(std::string nick) +bool lookup_dns(const std::string &nick) { + /* First attempt to find the nickname */ userrec* u = Find(nick); if (u) { - // place a new user into the queue... - log(DEBUG,"Queueing DNS lookup for %s",u->nick); - WriteServ(u->fd,"NOTICE Auth :Looking up your hostname..."); - Lookup L; - if (L.DoLookup(nick)) - { - for (int j = 0; j < MAXBUF; j++) - { - if (!dnsq[j].GetFD()) - { - dnsq[j] = L; - return true; - } - } - // calculate the maximum value, this saves cpu time later - for (int p = 0; p < MAXBUF; p++) - if (dnsq[p].GetFD()) - max_fd_alloc = p; - } - else + /* Check the cache */ + /*address_cache::iterator address = addrcache.find(u->ip4); + if (address != addrcache.end()) { - return false; - } + WriteServ(u->fd,"NOTICE Auth :*** Found your hostname (cached)"); + log(DEBUG,"Found cached host"); + strlcpy(u->host,address->second->c_str(),MAXBUF); + strlcpy(u->dhost,address->second->c_str(),MAXBUF); + u->dns_done = true; + return true; + }*/ + /* If the user exists, create a new + * lookup object, and associate it + * with the user. The lookup object + * will maintain the reference table + * which we use for quickly finding + * dns results. Please note that we + * do not associate a lookup with a + * userrec* pointer and we use the + * nickname instead because, by the + * time the DNS lookup has completed, + * the nickname could have quit and + * if we then try and access the + * pointer we get a nice segfault. + */ + Lookup* L = new Lookup(); + L->DoLookup(nick); + return true; } return false; } -void dns_poll() +void dns_poll(int fdcheck) { - // do we have items in the queue? - for (int j = 0; j <= max_fd_alloc; j++) + /* Check the given file descriptor is in valid range */ + if ((fdcheck < 0) || (fdcheck > MAX_DESCRIPTORS)) + return; + + /* Try and find the file descriptor in our list of + * active DNS lookups + */ + Lookup *x = dnslist[fdcheck]; + if (x) { - // are any ready, or stale? - if (dnsq[j].GetFD()) + /* If it exists check if its a valid fd still */ + if (x->GetFD() != -1) { - if (dnsq[j].Done()) + /* Check if its done, if it is delete it */ + if (x->Done(fdcheck)) { - dnsq[j].Reset(); + /* We don't need to delete the file descriptor + * from the socket engine, as dns.cpp tracks it + * for us if we are in single-threaded country. + */ + delete x; } } + else + { + /* its fd is dodgy, the dns code probably + * bashed it due to error. Free the class. + */ + delete x; + } + /* If we got down here, the dns lookup was valid, BUT, + * its still in progress. Be patient, and wait for + * more socketengine events to complete the lookups. + */ + return; } - // looks like someones freed an item, recalculate end of list. - if ((!dnsq[max_fd_alloc].GetFD()) && (max_fd_alloc != 0)) - for (int p = 0; p < MAXBUF; p++) - if (dnsq[p].GetFD()) - max_fd_alloc = p; - + /* This FD doesnt belong here, lets be rid of it, + * just to be safe so we dont get any more events + * about it. + */ + if (ServerInstance && ServerInstance->SE) + ServerInstance->SE->DelFd(fdcheck); } -