1 /* +------------------------------------+
2 * | Inspire Internet Relay Chat Daemon |
3 * +------------------------------------+
5 * InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
7 * <brain@chatspike.net>
8 * <Craig@chatspike.net>
10 * Written by Craig Edwards, Craig McLure, and others.
11 * This program is free but copyrighted software; see
12 * the file COPYING for details.
14 * ---------------------------------------------------
19 #include "inspircd_config.h"
21 #include "inspircd_io.h"
23 #include <sys/errno.h>
24 #include <sys/ioctl.h>
25 #include <sys/utsname.h>
30 #include <ext/hash_map>
40 #include "inspstring.h"
43 #include <sys/types.h>
44 #include <sys/socket.h>
46 #include <netinet/in.h>
49 #include "helperfuncs.h"
51 #include "socketengine.h"
53 extern ServerConfig* Config;
54 extern InspIRCd* ServerInstance;
56 address_cache addrcache;
60 Lookup* dnslist[MAX_DESCRIPTORS];
62 //enum LookupState { reverse, forward };
85 bool DoLookup(std::string nick)
88 userrec* usr = Find(nick);
91 resolver1.SetNS(std::string(Config->DNSServer));
92 if (!resolver1.ReverseLookup(std::string(usr->host)))
96 strlcpy(u,nick.c_str(),NICKMAX);
98 /* ASSOCIATE WITH DNS LOOKUP LIST */
99 if (resolver1.GetFD() != -1)
101 dnslist[resolver1.GetFD()] = this;
108 bool Done(int fdcheck)
112 // doing forward lookup
114 if (resolver2.HasResult(fdcheck))
116 if (resolver2.GetFD() != -1)
118 dnslist[resolver2.GetFD()] = NULL;
119 std::string ip = resolver2.GetResultIP();
123 if (usr->registered > 3)
125 usr->dns_done = true;
128 if ((hostname != "") && (usr->registered != 7))
130 if (std::string((char*)inet_ntoa(usr->ip4)) == ip)
132 strlcpy(usr->host,hostname.c_str(),MAXBUF);
133 strlcpy(usr->dhost,hostname.c_str(),MAXBUF);
134 address_cache::iterator address = addrcache.find(usr->ip4);
135 if (address == addrcache.end())
137 log(DEBUG,"Caching hostname %s -> %s",(char*)inet_ntoa(usr->ip4),hostname.c_str());
138 addrcache[usr->ip4] = new std::string(hostname);
140 WriteServ(usr->fd,"NOTICE Auth :*** Found your hostname");
142 usr->dns_done = true;
152 usr->dns_done = true;
161 // doing reverse lookup
163 if (resolver1.HasResult(fdcheck))
166 if ((usr) && (usr->dns_done))
168 if (resolver1.GetFD() != -1)
169 dnslist[resolver1.GetFD()] = NULL;
172 if (resolver1.GetFD() != -1)
174 dnslist[resolver1.GetFD()] = NULL;
175 hostname = resolver1.GetResult();
178 if ((usr->registered > 3) || (hostname == ""))
180 WriteServ(usr->fd,"NOTICE Auth :*** Could not resolve your hostname -- Using your IP address instead");
181 usr->dns_done = true;
187 resolver2.ForwardLookup(hostname);
188 if (resolver2.GetFD() != -1)
189 dnslist[resolver2.GetFD()] = this;
199 userrec* usr = Find(u);
208 bool lookup_dns(std::string nick)
210 /* First attempt to find the nickname */
211 userrec* u = Find(nick);
214 /* Check the cache */
215 address_cache::iterator address = addrcache.find(u->ip4);
216 if (address != addrcache.end())
218 /* Theyre in the cache, dont waste a lookup */
219 WriteServ(u->fd,"NOTICE Auth :*** Found your hostname (cached)");
220 log(DEBUG,"Found cached host");
221 strlcpy(u->host,address->second->c_str(),MAXBUF);
222 strlcpy(u->dhost,address->second->c_str(),MAXBUF);
226 /* If the user exists, create a new
227 * lookup object, and associate it
228 * with the user. The lookup object
229 * will maintain the reference table
230 * which we use for quickly finding
231 * dns results. Please note that we
232 * do not associate a lookup with a
233 * userrec* pointer and we use the
234 * nickname instead because, by the
235 * time the DNS lookup has completed,
236 * the nickname could have quit and
237 * if we then try and access the
238 * pointer we get a nice segfault.
240 Lookup* L = new Lookup();
247 void dns_poll(int fdcheck)
249 /* Check the given file descriptor is in valid range */
250 if ((fdcheck < 0) || (fdcheck > MAX_DESCRIPTORS))
253 /* Try and find the file descriptor in our list of
256 Lookup *x = dnslist[fdcheck];
259 /* If it exists check if its a valid fd still */
260 if (x->GetFD() != -1)
262 /* Check if its done, if it is delete it */
263 if (x->Done(fdcheck))
265 /* We don't need to delete the file descriptor
266 * from the socket engine, as dns.cpp tracks it
267 * for us if we are in single-threaded country.
274 /* its fd is dodgy, the dns code probably
275 * bashed it due to error. Free the class.
279 /* If we got down here, the dns lookup was valid, BUT,
280 * its still in progress. Be patient, and wait for
281 * more socketengine events to complete the lookups.
285 /* This FD doesnt belong here, lets be rid of it,
286 * just to be safe so we dont get any more events
289 if (ServerInstance && ServerInstance->SE)
290 ServerInstance->SE->DelFd(fdcheck);