/* +------------------------------------+ * | Inspire Internet Relay Chat Daemon | * +------------------------------------+ * * Inspire is copyright (C) 2002-2004 ChatSpike-Dev. * E-mail: * * * * Written by Craig Edwards, Craig McLure, and others. * This program is free but copyrighted software; see * the file COPYING for details. * * --------------------------------------------------- */ /* 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 #include #include #include #include #ifdef GCC3 #include #else #include #endif #include #include #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" 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 ClassVector Classes; extern char DNSServer[MAXBUF]; long max_fd_alloc = 0; extern time_t TIME; //enum LookupState { reverse, forward }; class Lookup { private: DNS resolver1; DNS resolver2; char u[NICKMAX]; std::string hostname; public: Lookup() { strcpy(u,""); log(DEBUG,"Create class Lookup"); } void Reset() { strcpy(u,""); log(DEBUG,"Reset class Lookup"); } ~Lookup() { log(DEBUG,"Delete class Lookup"); } 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); resolver1.SetNS(std::string(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; } log(DEBUG,"We couldnt find that user"); return false; } bool Done() { if (hostname != "") { log(DEBUG,"Doing forward lookup here with host %s",hostname.c_str()); // doing forward lookup userrec* usr = NULL; if (resolver2.HasResult()) { log(DEBUG,"resolver2 has result"); if (resolver2.GetFD() != 0) { 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) { 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); } usr->dns_done = true; return true; } } } else { 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()) { usr = Find(u); if ((usr) && (usr->dns_done)) return true; if (resolver1.GetFD() != 0) { hostname = resolver1.GetResult(); if (usr) { if ((usr->registered > 3) || (hostname == "")) { log(DEBUG,"Hostname is blank and user->registered > 3, returning true and setting done"); usr->dns_done = true; return true; } } log(DEBUG,"Starting forwardlookup now for host '%s'...",hostname.c_str()); if ((resolver2.GetFD() <= 0) && (hostname != "")) { resolver2.ForwardLookup(hostname); } } } } log(DEBUG,"Returning false"); return false; } int GetFD() { userrec* usr = Find(u); if (!usr) return 0; if (usr->dns_done) return 0; return usr->fd; } }; Lookup dnsq[255]; bool lookup_dns(std::string nick) { 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 < 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; } } return false; } void dns_poll() { // do we have items in the queue? for (int j = 0; j <= max_fd_alloc; j++) { // are any ready, or stale? if (dnsq[j].GetFD()) { if (dnsq[j].Done()) { dnsq[j].Reset(); } } } // 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; }