X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fdnsqueue.cpp;h=8be3ea99b0b742a3312866e5b5c80aca0f6cf6f3;hb=59b1a8955142935b02af6446005ab47fc7c3fc8c;hp=99f32988e55f382d60f1a2aaee2fbcc37ed9c843;hpb=2d821f2980825be73e3f90b47ffff365b0ec5ecb;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/dnsqueue.cpp b/src/dnsqueue.cpp index 99f32988e..8be3ea99b 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,14 +14,11 @@ * --------------------------------------------------- */ -/* Now with added unF! ;) */ - using namespace std; #include "inspircd_config.h" #include "inspircd.h" #include "inspircd_io.h" -#include "inspircd_util.h" #include #include #include @@ -39,53 +36,28 @@ using namespace std; #include #include #include "users.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 "dns.h" #include "helperfuncs.h" #include "hashcomp.h" +#include "socketengine.h" -extern int MaxWhoResults; - -extern std::vector modules; -extern std::vector module_names; -extern std::vector factory; - -extern int MODCOUNT; - -typedef nspace::hash_map, irc::StrHashComp> user_hash; -typedef nspace::hash_map, irc::StrHashComp> chan_hash; -typedef nspace::hash_map, irc::InAddr_HashComp> address_cache; -typedef nspace::hash_map, irc::StrHashComp> whowas_hash; -typedef std::deque command_table; - -extern user_hash clientlist; -extern chan_hash chanlist; -extern whowas_hash whowas; -extern command_table cmdlist; +extern ServerConfig* Config; +extern InspIRCd* ServerInstance; -extern ClassVector Classes; +address_cache addrcache; -extern char DNSServer[MAXBUF]; -long max_fd_alloc = 0; +class Lookup; -extern time_t TIME; +Lookup* dnslist[MAX_DESCRIPTORS]; //enum LookupState { reverse, forward }; @@ -98,13 +70,14 @@ private: public: Lookup() { - strcpy(u,""); + *u = 0; + hostname = ""; } void Reset() { - strcpy(u,""); - log(DEBUG,"Reset class Lookup"); + *u = 0; + hostname = ""; } ~Lookup() @@ -117,55 +90,56 @@ public: userrec* usr = Find(nick); if (usr) { - log(DEBUG,"New Lookup class for %s with DNSServer set to '%s'",nick.c_str(),DNSServer); - resolver1.SetNS(std::string(DNSServer)); + resolver1.SetNS(std::string(Config->DNSServer)); if (!resolver1.ReverseLookup(std::string(usr->host))) { - log(DEBUG,"ReverseLookup didnt return true, we're outta here"); 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; + } } - log(DEBUG,"We couldnt find that user"); return false; } - bool Done() + bool Done(int fdcheck) { if (hostname != "") { - log(DEBUG,"Doing forward lookup here with host %s",hostname.c_str()); // doing forward lookup userrec* usr = NULL; - if (resolver2.HasResult()) + if (resolver2.HasResult(fdcheck)) { - log(DEBUG,"resolver2 has result"); - if (resolver2.GetFD() != 0) + if (resolver2.GetFD() != -1) { + dnslist[resolver2.GetFD()] = NULL; std::string ip = resolver2.GetResultIP(); - log(DEBUG,"FORWARD RESULT! %s",ip.c_str()); - usr = Find(u); if (usr) { if (usr->registered > 3) { - log(DEBUG,"Point 1: Returning true as usr->dns_done is true"); usr->dns_done = true; return true; } if ((hostname != "") && (usr->registered != 7)) { - if (std::string(usr->ip) == ip) + if (std::string((char*)inet_ntoa(usr->ip4)) == ip) { strlcpy(usr->host,hostname.c_str(),MAXBUF); strlcpy(usr->dhost,hostname.c_str(),MAXBUF); - log(DEBUG,"Forward and reverse match, assigning hostname"); - } - else - { - log(DEBUG,"AWOOGA! Forward lookup doesn't match reverse: R='%s',F='%s',IP='%s'",hostname.c_str(),ip.c_str(),usr->ip); + /*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; @@ -177,45 +151,48 @@ public: usr = Find(u); if (usr) { - log(DEBUG,"Point 2: Returning true"); usr->dns_done = true; } return true; } } - log(DEBUG,"Returning false in forward"); return false; } else { // doing reverse lookup userrec* usr = NULL; - if (resolver1.HasResult()) + if (resolver1.HasResult(fdcheck)) { usr = Find(u); if ((usr) && (usr->dns_done)) + { + if (resolver1.GetFD() != -1) + dnslist[resolver1.GetFD()] = NULL; return true; - if (resolver1.GetFD() != 0) + } + if (resolver1.GetFD() != -1) { + dnslist[resolver1.GetFD()] = NULL; hostname = resolver1.GetResult(); if (usr) { if ((usr->registered > 3) || (hostname == "")) { - log(DEBUG,"Hostname is blank and user->registered > 3, returning true and setting done"); + WriteServ(usr->fd,"NOTICE Auth :*** Could not resolve your hostname -- Using your IP address instead"); usr->dns_done = true; return true; } } if (hostname != "") { - log(DEBUG,"Starting forwardlookup now for host '%s'...",hostname.c_str()); resolver2.ForwardLookup(hostname); + if (resolver2.GetFD() != -1) + dnslist[resolver2.GetFD()] = this; } } } } - log(DEBUG,"Returning false"); return false; } @@ -230,58 +207,87 @@ public: } }; -Lookup dnsq[255]; - bool lookup_dns(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)) + /* Check the cache */ + /*address_cache::iterator address = addrcache.find(u->ip4); + if (address != addrcache.end()) { - for (int j = 0; j < 255; j++) - { - if (!dnsq[j].GetFD()) - { - dnsq[j] = L; - return true; - } - } - // calculate the maximum value, this saves cpu time later - for (int p = 0; p < 255; p++) - if (dnsq[p].GetFD()) - max_fd_alloc = p; - } - else - { - 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 < 255; 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); } +