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 * ---------------------------------------------------
17 #include "inspircd_config.h"
19 #include "configreader.h"
21 #include <sys/errno.h>
22 #include <sys/ioctl.h>
23 #include <sys/utsname.h>
27 #include "inspstring.h"
30 #include "helperfuncs.h"
32 #include "socketengine.h"
35 extern ServerConfig* Config;
36 extern InspIRCd* ServerInstance;
40 Lookup* dnslist[MAX_DESCRIPTORS];
41 Lookup* user_fd_to_dns[MAX_DESCRIPTORS];
42 extern userrec* fd_ref_table[MAX_DESCRIPTORS];
44 //enum LookupState { reverse, forward };
70 bool DoLookup(std::string nick)
73 userrec* usr = Find(nick);
76 resolver1.SetNS(std::string(Config->DNSServer));
77 if (!resolver1.ReverseLookup(std::string(usr->host), true))
81 strlcpy(u,nick.c_str(),NICKMAX-1);
83 /* ASSOCIATE WITH DNS LOOKUP LIST */
84 if (resolver1.GetFD() != -1)
86 dnslist[resolver1.GetFD()] = this;
87 user_fd_to_dns[usr->fd] = this;
94 bool Done(int fdcheck)
98 // doing forward lookup
100 if (resolver2.HasResult(fdcheck))
102 if (resolver2.GetFD() != -1)
104 dnslist[resolver2.GetFD()] = NULL;
105 std::string ip = resolver2.GetResultIP();
109 if (usr->registered > REG_NICKUSER)
111 usr->dns_done = true;
114 if ((hostname != "") && (usr->registered != REG_ALL))
116 if ((std::string(inet_ntoa(usr->ip4)) == ip) && (hostname.length() < 65))
118 if ((hostname.find_last_of(".in-addr.arpa") == hostname.length() - 1) && (hostname.find_last_of(".in-addr.arpa") != std::string::npos))
120 WriteServ(usr->fd,"NOTICE Auth :*** Your ISP are muppets -- reverse resolution resolves back to same reverse .arpa domain (!)");
124 strlcpy(usr->host,hostname.c_str(),64);
125 strlcpy(usr->dhost,hostname.c_str(),64);
126 WriteServ(usr->fd,"NOTICE Auth :*** Found your hostname");
129 usr->dns_done = true;
139 usr->dns_done = true;
148 // doing reverse lookup
150 if (resolver1.HasResult(fdcheck))
153 if ((usr) && (usr->dns_done))
155 if (resolver1.GetFD() != -1)
157 dnslist[resolver1.GetFD()] = NULL;
158 user_fd_to_dns[usr->fd] = NULL;
162 if (resolver1.GetFD() != -1)
164 dnslist[resolver1.GetFD()] = NULL;
165 hostname = resolver1.GetResult();
168 user_fd_to_dns[usr->fd] = NULL;
169 if ((usr->registered > REG_NICKUSER) || (hostname == ""))
171 WriteServ(usr->fd,"NOTICE Auth :*** Could not resolve your hostname -- Using your IP address instead");
172 usr->dns_done = true;
177 resolver2.ForwardLookup(hostname, true);
178 if (resolver2.GetFD() != -1)
180 dnslist[resolver2.GetFD()] = this;
182 user_fd_to_dns[usr->fd] = this;
194 userrec* usr = Find(u);
203 bool lookup_dns(const std::string &nick)
205 /* First attempt to find the nickname */
206 userrec* u = Find(nick);
209 /* Check the cache */
210 /*address_cache::iterator address = addrcache.find(u->ip4);
211 if (address != addrcache.end())
213 WriteServ(u->fd,"NOTICE Auth :*** Found your hostname (cached)");
214 log(DEBUG,"Found cached host");
215 strlcpy(u->host,address->second->c_str(),MAXBUF);
216 strlcpy(u->dhost,address->second->c_str(),MAXBUF);
220 /* If the user exists, create a new
221 * lookup object, and associate it
222 * with the user. The lookup object
223 * will maintain the reference table
224 * which we use for quickly finding
225 * dns results. Please note that we
226 * do not associate a lookup with a
227 * userrec* pointer and we use the
228 * nickname instead because, by the
229 * time the DNS lookup has completed,
230 * the nickname could have quit and
231 * if we then try and access the
232 * pointer we get a nice segfault.
234 Lookup* L = new Lookup();
241 void ZapThisDns(int fd)
244 /* if (fd_ref_table[fd])
246 if (fd_ref_table[fd]->registered >= REG_NICKUSER)
248 log(DEBUG,"Joining thread for user %d",fd);
249 if (pthread_join(fd_ref_table[fd]->dnsthread, NULL))
251 log(DEBUG,"Can't pthread_join(): %s", strerror(errno));
256 if ((fd < 0) || (fd > MAX_DESCRIPTORS))
259 Lookup *x = user_fd_to_dns[fd];
263 if (x->resolver1.GetFD() > 0)
265 log(DEBUG,"Whacked resolver1");
266 dns_close(x->resolver1.GetFD());
269 if (x->resolver2.GetFD() > 0)
271 log(DEBUG,"Whacked resolver2");
272 dns_close(x->resolver2.GetFD());
278 void dns_poll(int fdcheck)
280 /* Check the given file descriptor is in valid range */
281 if ((fdcheck < 0) || (fdcheck > MAX_DESCRIPTORS))
284 /* Try and find the file descriptor in our list of
287 Lookup *x = dnslist[fdcheck];
290 /* If it exists check if its a valid fd still */
291 if (x->GetFD() != -1)
293 /* Check if its done, if it is delete it */
294 if (x->Done(fdcheck))
296 /* We don't need to delete the file descriptor
297 * from the socket engine, as dns.cpp tracks it
298 * for us if we are in single-threaded country.
305 /* its fd is dodgy, the dns code probably
306 * bashed it due to error. Free the class.
310 /* If we got down here, the dns lookup was valid, BUT,
311 * its still in progress. Be patient, and wait for
312 * more socketengine events to complete the lookups.
316 /* This FD doesnt belong here, lets be rid of it,
317 * just to be safe so we dont get any more events
320 if (ServerInstance && ServerInstance->SE)
321 ServerInstance->SE->DelFd(fdcheck);