]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dnsqueue.cpp
78be4d8f18f0ada51384ebb5587470220eb483a2
[user/henk/code/inspircd.git] / src / dnsqueue.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 using namespace std;
18
19 #include "inspircd_config.h"
20 #include "inspircd.h"
21 #include "inspircd_io.h"
22 #include "inspircd_util.h"
23 #include <unistd.h>
24 #include <sys/errno.h>
25 #include <sys/ioctl.h>
26 #include <sys/utsname.h>
27 #include <cstdio>
28 #include <time.h>
29 #include <string>
30 #ifdef GCC3
31 #include <ext/hash_map>
32 #else
33 #include <hash_map>
34 #endif
35 #include <map>
36 #include <sstream>
37 #include <vector>
38 #include <deque>
39 #include "users.h"
40 #include "globals.h"
41 #include "inspstring.h"
42 #include "dnsqueue.h"
43 #include <time.h>
44 #include <sys/types.h>
45 #include <sys/socket.h>
46 #include <sys/poll.h>
47 #include <sys/time.h>
48 #include <netinet/in.h>
49 #include <string.h>
50 #include "dns.h"
51 #include "helperfuncs.h"
52 #include "hashcomp.h"
53 #include "socketengine.h"
54
55 extern SocketEngine* SE;
56 typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, irc::StrHashComp> user_hash;
57 extern user_hash clientlist;
58 extern char DNSServer[MAXBUF];
59
60 class Lookup;
61
62 Lookup* dnslist[65535];
63
64 //enum LookupState { reverse, forward };
65
66 class Lookup {
67 private:
68         DNS resolver1;
69         DNS resolver2;
70         char u[NICKMAX];
71         std::string hostname;
72 public:
73         Lookup()
74         {
75                 strcpy(u,"");
76         }
77
78         void Reset()
79         {
80                 strcpy(u,"");
81         }
82
83         ~Lookup()
84         {
85         }
86
87         bool DoLookup(std::string nick)
88         {
89                 hostname = "";
90                 userrec* usr = Find(nick);
91                 if (usr)
92                 {
93                         resolver1.SetNS(std::string(DNSServer));
94                         if (!resolver1.ReverseLookup(std::string(usr->host)))
95                         {
96                                 return false;
97                         }
98                         strlcpy(u,nick.c_str(),NICKMAX);
99
100                         /* ASSOCIATE WITH DNS LOOKUP LIST */
101                         if (resolver1.GetFD() != -1)
102                         {
103                                 dnslist[resolver1.GetFD()] = this;
104                                 return true;
105                         }
106                 }
107                 return false;
108         }
109
110         bool Done(int fdcheck)
111         {
112                 if (hostname != "")
113                 {
114                         // doing forward lookup
115                         userrec* usr = NULL;
116                         if (resolver2.HasResult(fdcheck))
117                         {
118                                 if (resolver2.GetFD() != -1)
119                                 {
120                                         dnslist[resolver2.GetFD()] = NULL;
121                                         std::string ip = resolver2.GetResultIP();
122                                         usr = Find(u);
123                                         if (usr)
124                                         {
125                                                 if (usr->registered > 3)
126                                                 {
127                                                         usr->dns_done = true;
128                                                         return true;
129                                                 }
130                                                 if ((hostname != "") && (usr->registered != 7))
131                                                 {
132                                                         if (std::string(usr->ip) == ip)
133                                                         {
134                                                                 strlcpy(usr->host,hostname.c_str(),MAXBUF);
135                                                                 strlcpy(usr->dhost,hostname.c_str(),MAXBUF);
136                                                         }
137                                                         usr->dns_done = true;
138                                                         return true;
139                                                 }
140                                         }
141                                 }
142                                 else
143                                 {
144                                         usr = Find(u);
145                                         if (usr)
146                                         {
147                                                 usr->dns_done = true;
148                                         }
149                                         return true;
150                                 }
151                         }
152                         return false;
153                 }
154                 else
155                 {
156                         // doing reverse lookup
157                         userrec* usr = NULL;
158                         if (resolver1.HasResult(fdcheck))
159                         {
160                                 usr = Find(u);
161                                 if ((usr) && (usr->dns_done))
162                                 {
163                                         if (resolver1.GetFD() != -1)
164                                                 dnslist[resolver1.GetFD()] = NULL;
165                                         return true;
166                                 }
167                                 if (resolver1.GetFD() != -1)
168                                 {
169                                         dnslist[resolver1.GetFD()] = NULL;
170                                         hostname = resolver1.GetResult();
171                                         if (usr)
172                                         {
173                                                 if ((usr->registered > 3) || (hostname == ""))
174                                                 {
175                                                         usr->dns_done = true;
176                                                         return true;
177                                                 }
178                                         }
179                                         if (hostname != "")
180                                         {
181                                                 resolver2.ForwardLookup(hostname);
182                                                 if (resolver2.GetFD() != -1)
183                                                         dnslist[resolver2.GetFD()] = this;
184                                         }
185                                 }
186                         }
187                 }
188                 return false;
189         }
190
191         int GetFD()
192         {
193                 userrec* usr = Find(u);
194                 if (!usr)
195                         return 0;
196                 if (usr->dns_done)
197                         return 0;
198                 return usr->fd;
199         }
200 };
201
202 bool lookup_dns(std::string nick)
203 {
204         /* First attempt to find the nickname */
205         userrec* u = Find(nick);
206         if (u)
207         {
208                 /* If the user exists, create a new
209                  * lookup object, and associate it
210                  * with the user. The lookup object
211                  * will maintain the reference table
212                  * which we use for quickly finding
213                  * dns results. Please note that we
214                  * do not associate a lookup with a
215                  * userrec* pointer and we use the
216                  * nickname instead because, by the
217                  * time the DNS lookup has completed,
218                  * the nickname could have quit and
219                  * if we then try and access the
220                  * pointer we get a nice segfault.
221                  */
222                 Lookup* L = new Lookup();
223                 L->DoLookup(nick);
224                 return true;
225         }
226         return false;
227 }
228
229 void dns_poll(int fdcheck)
230 {
231         /* Check the given file descriptor is in valid range */
232         if ((fdcheck < 0) || (fdcheck > 65535))
233                 return;
234
235         /* Try and find the file descriptor in our list of
236          * active DNS lookups
237          */
238         Lookup *x = dnslist[fdcheck];
239         if (x)
240         {
241                 /* If it exists check if its a valid fd still */
242                 if (x->GetFD() != -1)
243                 {
244                         /* Check if its done, if it is delete it */
245                         if (x->Done(fdcheck))
246                         {
247                                 /* We don't need to delete the file descriptor
248                                  * from the socket engine, as dns.cpp tracks it
249                                  * for us if we are in single-threaded country.
250                                  */
251                                 delete x;
252                         }
253                 }
254                 else
255                 {
256                         /* its fd is dodgy, the dns code probably
257                          * bashed it due to error. Free the class.
258                          */
259                         delete x;
260                 }
261                 /* If we got down here, the dns lookup was valid, BUT,
262                  * its still in progress. Be patient, and wait for
263                  * more socketengine events to complete the lookups.
264                  */
265                 return;
266         }
267         /* This FD doesnt belong here, lets be rid of it,
268          * just to be safe so we dont get any more events
269          * about it.
270          */
271         SE->DelFd(fdcheck);
272 }
273