]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dnsqueue.cpp
Removed deprecated direct reference to file_cache MOTD, RULES
[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/time.h>
47 #include <netinet/in.h>
48 #include <string.h>
49 #include "dns.h"
50 #include "helperfuncs.h"
51 #include "hashcomp.h"
52 #include "socketengine.h"
53
54 extern SocketEngine* SE;
55 extern ServerConfig* Config;
56
57 class Lookup;
58
59 Lookup* dnslist[65535];
60
61 //enum LookupState { reverse, forward };
62
63 class Lookup {
64 private:
65         DNS resolver1;
66         DNS resolver2;
67         char u[NICKMAX];
68         std::string hostname;
69 public:
70         Lookup()
71         {
72                 strcpy(u,"");
73         }
74
75         void Reset()
76         {
77                 strcpy(u,"");
78         }
79
80         ~Lookup()
81         {
82         }
83
84         bool DoLookup(std::string nick)
85         {
86                 hostname = "";
87                 userrec* usr = Find(nick);
88                 if (usr)
89                 {
90                         resolver1.SetNS(std::string(Config->DNSServer));
91                         if (!resolver1.ReverseLookup(std::string(usr->host)))
92                         {
93                                 return false;
94                         }
95                         strlcpy(u,nick.c_str(),NICKMAX);
96
97                         /* ASSOCIATE WITH DNS LOOKUP LIST */
98                         if (resolver1.GetFD() != -1)
99                         {
100                                 dnslist[resolver1.GetFD()] = this;
101                                 return true;
102                         }
103                 }
104                 return false;
105         }
106
107         bool Done(int fdcheck)
108         {
109                 if (hostname != "")
110                 {
111                         // doing forward lookup
112                         userrec* usr = NULL;
113                         if (resolver2.HasResult(fdcheck))
114                         {
115                                 if (resolver2.GetFD() != -1)
116                                 {
117                                         dnslist[resolver2.GetFD()] = NULL;
118                                         std::string ip = resolver2.GetResultIP();
119                                         usr = Find(u);
120                                         if (usr)
121                                         {
122                                                 if (usr->registered > 3)
123                                                 {
124                                                         usr->dns_done = true;
125                                                         return true;
126                                                 }
127                                                 if ((hostname != "") && (usr->registered != 7))
128                                                 {
129                                                         if (std::string(usr->ip) == ip)
130                                                         {
131                                                                 strlcpy(usr->host,hostname.c_str(),MAXBUF);
132                                                                 strlcpy(usr->dhost,hostname.c_str(),MAXBUF);
133                                                         }
134                                                         usr->dns_done = true;
135                                                         return true;
136                                                 }
137                                         }
138                                 }
139                                 else
140                                 {
141                                         usr = Find(u);
142                                         if (usr)
143                                         {
144                                                 usr->dns_done = true;
145                                         }
146                                         return true;
147                                 }
148                         }
149                         return false;
150                 }
151                 else
152                 {
153                         // doing reverse lookup
154                         userrec* usr = NULL;
155                         if (resolver1.HasResult(fdcheck))
156                         {
157                                 usr = Find(u);
158                                 if ((usr) && (usr->dns_done))
159                                 {
160                                         if (resolver1.GetFD() != -1)
161                                                 dnslist[resolver1.GetFD()] = NULL;
162                                         return true;
163                                 }
164                                 if (resolver1.GetFD() != -1)
165                                 {
166                                         dnslist[resolver1.GetFD()] = NULL;
167                                         hostname = resolver1.GetResult();
168                                         if (usr)
169                                         {
170                                                 if ((usr->registered > 3) || (hostname == ""))
171                                                 {
172                                                         usr->dns_done = true;
173                                                         return true;
174                                                 }
175                                         }
176                                         if (hostname != "")
177                                         {
178                                                 resolver2.ForwardLookup(hostname);
179                                                 if (resolver2.GetFD() != -1)
180                                                         dnslist[resolver2.GetFD()] = this;
181                                         }
182                                 }
183                         }
184                 }
185                 return false;
186         }
187
188         int GetFD()
189         {
190                 userrec* usr = Find(u);
191                 if (!usr)
192                         return 0;
193                 if (usr->dns_done)
194                         return 0;
195                 return usr->fd;
196         }
197 };
198
199 bool lookup_dns(std::string nick)
200 {
201         /* First attempt to find the nickname */
202         userrec* u = Find(nick);
203         if (u)
204         {
205                 /* If the user exists, create a new
206                  * lookup object, and associate it
207                  * with the user. The lookup object
208                  * will maintain the reference table
209                  * which we use for quickly finding
210                  * dns results. Please note that we
211                  * do not associate a lookup with a
212                  * userrec* pointer and we use the
213                  * nickname instead because, by the
214                  * time the DNS lookup has completed,
215                  * the nickname could have quit and
216                  * if we then try and access the
217                  * pointer we get a nice segfault.
218                  */
219                 Lookup* L = new Lookup();
220                 L->DoLookup(nick);
221                 return true;
222         }
223         return false;
224 }
225
226 void dns_poll(int fdcheck)
227 {
228         /* Check the given file descriptor is in valid range */
229         if ((fdcheck < 0) || (fdcheck > 65535))
230                 return;
231
232         /* Try and find the file descriptor in our list of
233          * active DNS lookups
234          */
235         Lookup *x = dnslist[fdcheck];
236         if (x)
237         {
238                 /* If it exists check if its a valid fd still */
239                 if (x->GetFD() != -1)
240                 {
241                         /* Check if its done, if it is delete it */
242                         if (x->Done(fdcheck))
243                         {
244                                 /* We don't need to delete the file descriptor
245                                  * from the socket engine, as dns.cpp tracks it
246                                  * for us if we are in single-threaded country.
247                                  */
248                                 delete x;
249                         }
250                 }
251                 else
252                 {
253                         /* its fd is dodgy, the dns code probably
254                          * bashed it due to error. Free the class.
255                          */
256                         delete x;
257                 }
258                 /* If we got down here, the dns lookup was valid, BUT,
259                  * its still in progress. Be patient, and wait for
260                  * more socketengine events to complete the lookups.
261                  */
262                 return;
263         }
264         /* This FD doesnt belong here, lets be rid of it,
265          * just to be safe so we dont get any more events
266          * about it.
267          */
268         SE->DelFd(fdcheck);
269 }
270