]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/dnsqueue.cpp
Moved a ton of functions into helperfuncs.h to speed up recompiles
[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 /* Now with added unF! ;) */
18
19 using namespace std;
20
21 #include "inspircd.h"
22 #include "inspircd_io.h"
23 #include "inspircd_util.h"
24 #include "inspircd_config.h"
25 #include <unistd.h>
26 #include <fcntl.h>
27 #include <sys/errno.h>
28 #include <sys/ioctl.h>
29 #include <sys/utsname.h>
30 #include <cstdio>
31 #include <time.h>
32 #include <string>
33 #ifdef GCC3
34 #include <ext/hash_map>
35 #else
36 #include <hash_map>
37 #endif
38 #include <map>
39 #include <sstream>
40 #include <vector>
41 #include <errno.h>
42 #include <deque>
43 #include <errno.h>
44 #include <unistd.h>
45 #include <sched.h>
46 #include "connection.h"
47 #include "users.h"
48 #include "servers.h"
49 #include "ctables.h"
50 #include "globals.h"
51 #include "modules.h"
52 #include "dynamic.h"
53 #include "wildcard.h"
54 #include "message.h"
55 #include "mode.h"
56 #include "commands.h"
57 #include "xline.h"
58 #include "inspstring.h"
59 #include "dnsqueue.h"
60 #include <stdlib.h>
61 #include <time.h>
62 #include <sys/types.h>
63 #include <sys/socket.h>
64 #include <sys/poll.h>
65 #include <sys/time.h>
66 #include <netinet/in.h>
67 #include <string.h>
68 #include <unistd.h>
69 #include <stdio.h>
70 #include <errno.h>
71 #include <fcntl.h>
72 #include "dns.h"
73 #include "helperfuncs.h"
74 #include "hashcomp.h"
75
76 extern int MaxWhoResults;
77
78 extern std::vector<Module*> modules;
79 extern std::vector<std::string> module_names;
80 extern std::vector<ircd_module*> factory;
81 extern std::vector<int> fd_reap;
82
83 extern int MODCOUNT;
84
85 typedef nspace::hash_map<std::string, userrec*, nspace::hash<string>, StrHashComp> user_hash;
86 typedef nspace::hash_map<std::string, chanrec*, nspace::hash<string>, StrHashComp> chan_hash;
87 typedef nspace::hash_map<in_addr,string*, nspace::hash<in_addr>, InAddr_HashComp> address_cache;
88 typedef nspace::hash_map<std::string, WhoWasUser*, nspace::hash<string>, StrHashComp> whowas_hash;
89 typedef std::deque<command_t> command_table;
90
91 extern user_hash clientlist;
92 extern chan_hash chanlist;
93 extern whowas_hash whowas;
94 extern command_table cmdlist;
95
96 extern ClassVector Classes;
97
98 extern char DNSServer[MAXBUF];
99 long max_fd_alloc = 0;
100
101 extern time_t TIME;
102
103 class Lookup {
104 private:
105         DNS resolver;
106         char u[NICKMAX];
107 public:
108         Lookup()
109         {
110                 strcpy(u,"");
111         }
112
113         void Reset()
114         {
115                 strcpy(u,"");
116         }
117
118         ~Lookup()
119         {
120         }
121
122         bool DoLookup(std::string nick)
123         {
124                 userrec* usr = Find(nick);
125                 if (usr)
126                 {
127                         log(DEBUG,"New Lookup class for %s with DNSServer set to '%s'",nick.c_str(),DNSServer);
128                         resolver.SetNS(std::string(DNSServer));
129                         if (!resolver.ReverseLookup(std::string(usr->host)))
130                                 return false;
131                         strlcpy(u,nick.c_str(),NICKMAX);
132                         return true;
133                 }
134                 return false;
135         }
136
137         bool Done()
138         {
139                 userrec* usr = NULL;
140                 if (resolver.HasResult())
141                 {
142                         if (resolver.GetFD() != 0)
143                         {
144                                 std::string hostname = resolver.GetResult();
145                                 log(DEBUG,"RESULT! %s",hostname.c_str());
146                                 usr = Find(u);
147                                 if (usr)
148                                 {
149                                         if (usr->registered > 3)
150                                         {
151                                                 usr->dns_done = true;
152                                                 return true;
153                                         }
154                                         if ((hostname != "") && (usr->registered != 7))
155                                         {
156                                                 strlcpy(usr->host,hostname.c_str(),MAXBUF);
157                                                 strlcpy(usr->dhost,hostname.c_str(),MAXBUF);
158                                                 WriteServ(usr->fd,"NOTICE Auth :Resolved your hostname: %s",hostname.c_str());
159                                                 usr->dns_done = true;
160                                                 return true;
161                                         }
162                                         usr->dns_done = true;
163                                         return true;
164                                 }
165                         }
166                         else
167                         {
168                                 usr = Find(u);
169                                 if (usr)
170                                         usr->dns_done = true;
171                                 return true;
172                         }
173                 }
174                 return false;
175         }
176
177         int GetFD()
178         {
179                 userrec* usr = Find(u);
180                 if (!usr)
181                         return 0;
182                 if (usr->dns_done)
183                         return 0;
184                 return usr->fd;
185         }
186 };
187
188 Lookup dnsq[255];
189
190 bool lookup_dns(std::string nick)
191 {
192         userrec* u = Find(nick);
193         if (u)
194         {
195                 // place a new user into the queue...
196                 log(DEBUG,"Queueing DNS lookup for %s",u->nick);
197                 WriteServ(u->fd,"NOTICE Auth :Looking up your hostname...");
198                 Lookup L;
199                 if (L.DoLookup(nick))
200                 {
201                         for (int j = 0; j < 255; j++)
202                         {
203                                 if (!dnsq[j].GetFD())
204                                 {
205                                         dnsq[j] = L;
206                                         return true;
207                                 }
208                         }
209                         // calculate the maximum value, this saves cpu time later
210                         for (int p = 0; p < 255; p++)
211                                 if (dnsq[p].GetFD())
212                                         max_fd_alloc = p;
213                 }
214                 else
215                 {
216                         return false;
217                 }
218         }
219         return false;
220 }
221
222 void dns_poll()
223 {
224         // do we have items in the queue?
225         for (int j = 0; j <= max_fd_alloc; j++)
226         {
227                 // are any ready, or stale?
228                 if (dnsq[j].GetFD())
229                 {
230                         if (dnsq[j].Done())
231                         {
232                                 dnsq[j].Reset();
233                         }
234                 }
235         }
236         // looks like someones freed an item, recalculate end of list.
237         if ((!dnsq[max_fd_alloc].GetFD()) && (max_fd_alloc != 0))
238                 for (int p = 0; p < 255; p++)
239                         if (dnsq[p].GetFD())
240                                 max_fd_alloc = p;
241
242 }