]>
Commit | Line | Data |
---|---|---|
905c2ba2 | 1 | /* |
2 | * proxyscancache.c: | |
3 | * This file deals with the cache of known hosts, clean or otherwise. | |
4 | */ | |
5 | ||
6 | #include "proxyscan.h" | |
7 | #include <time.h> | |
8 | #include <stdio.h> | |
9 | #include "../core/error.h" | |
10 | #include <string.h> | |
11 | ||
12 | #define HOSTCACHEHASHSIZE 50000 | |
13 | ||
14 | cachehost *cachetable[HOSTCACHEHASHSIZE]; | |
15 | time_t cleanscaninterval; | |
16 | time_t dirtyscaninterval; | |
17 | ||
18 | void cachehostinit(time_t ri) { | |
19 | cleanscaninterval=ri; | |
20 | dirtyscaninterval=ri*7; | |
21 | memset(cachetable,0,sizeof(cachetable)); | |
22 | } | |
23 | ||
24 | cachehost *addcleanhost(unsigned long IP, time_t timestamp) { | |
25 | cachehost *chp; | |
26 | int hash; | |
27 | ||
28 | hash=(IP%HOSTCACHEHASHSIZE); | |
29 | ||
30 | chp=getcachehost(); | |
31 | chp->IP=IP; | |
32 | chp->lastscan=timestamp; | |
33 | chp->proxies=NULL; | |
34 | chp->glineid=0; | |
35 | chp->next=cachetable[hash]; | |
36 | ||
37 | cachetable[hash]=chp; | |
38 | ||
39 | return chp; | |
40 | } | |
41 | ||
42 | void delcachehost(cachehost *chp) { | |
43 | cachehost **chh; | |
44 | foundproxy *fpp, *nfpp; | |
45 | int hash; | |
46 | ||
47 | hash=(chp->IP%HOSTCACHEHASHSIZE); | |
48 | ||
49 | for (chh=&(cachetable[hash]);*chh;chh=&((*chh)->next)) { | |
50 | if (*chh==chp) { | |
51 | *chh=chp->next; | |
52 | break; | |
53 | } | |
54 | } | |
55 | ||
56 | for (fpp=chp->proxies;fpp;fpp=nfpp) { | |
57 | nfpp=fpp->next; | |
58 | freefoundproxy(fpp); | |
59 | } | |
60 | freecachehost(chp); | |
61 | } | |
62 | ||
63 | /* | |
64 | * Returns a cachehost * for the named IP | |
65 | */ | |
66 | ||
67 | cachehost *findcachehost(unsigned long IP) { | |
68 | int hash; | |
69 | cachehost *chp; | |
70 | ||
71 | hash=(IP%HOSTCACHEHASHSIZE); | |
72 | ||
73 | for (chp=cachetable[hash];chp;chp=chp->next) { | |
74 | if (chp->IP==IP) { | |
75 | /* match */ | |
76 | if(chp->lastscan < (time(NULL)-(chp->proxies ? dirtyscaninterval : cleanscaninterval))) { | |
77 | /* Needs rescan; delete and return 1 */ | |
78 | delcachehost(chp); | |
79 | return NULL; | |
80 | } else { | |
81 | /* valid: return it */ | |
82 | return chp; | |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | /* Not found: return NULL */ | |
88 | return NULL; | |
89 | } | |
90 | ||
91 | /* | |
92 | * dumpcleanhosts: | |
93 | * Dumps all cached hosts to a savefile. Expires hosts as it goes along | |
94 | */ | |
95 | ||
96 | void dumpcachehosts(void *arg) { | |
97 | int i; | |
98 | FILE *fp; | |
99 | cachehost *chp,*nchp; | |
100 | time_t now=time(NULL); | |
101 | foundproxy *fpp; | |
102 | ||
103 | if ((fp=fopen("cleanhosts","w"))==NULL) { | |
104 | Error("proxyscan",ERR_ERROR,"Unable to open cleanhosts file for writing!"); | |
105 | return; | |
106 | } | |
107 | ||
108 | for(i=0;i<HOSTCACHEHASHSIZE;i++) { | |
109 | for(chp=cachetable[i];chp;chp=nchp) { | |
110 | nchp=chp->next; | |
111 | if (chp->proxies) { | |
112 | if (chp->lastscan < (now-dirtyscaninterval)) { | |
113 | delcachehost(chp); | |
114 | continue; | |
115 | } | |
116 | ||
117 | for (fpp=chp->proxies;fpp;fpp=fpp->next) | |
118 | fprintf(fp, "%lu %lu %u %i %u\n",chp->IP,chp->lastscan,chp->glineid,fpp->type,fpp->port); | |
119 | } else { | |
120 | if (chp->lastscan < (now-cleanscaninterval)) { | |
121 | /* Needs rescan anyway, so delete it */ | |
122 | delcachehost(chp); | |
123 | continue; | |
124 | } | |
125 | fprintf(fp,"%lu %lu\n",chp->IP,chp->lastscan); | |
126 | } | |
127 | } | |
128 | } | |
129 | ||
130 | fclose(fp); | |
131 | } | |
132 | ||
133 | /* | |
134 | * loadcleanhosts: | |
135 | * Loads clean hosts in from database. | |
136 | */ | |
137 | ||
138 | void loadcachehosts() { | |
139 | FILE *fp; | |
140 | unsigned long IP,timestamp,glineid,ptype,pport; | |
141 | char buf[512]; | |
142 | cachehost *chp=NULL; | |
143 | foundproxy *fpp; | |
144 | int res; | |
145 | ||
146 | if ((fp=fopen("cleanhosts","r"))==NULL) { | |
147 | Error("proxyscan",ERR_ERROR,"Unable to open cleanhosts file for reading!"); | |
148 | return; | |
149 | } | |
150 | ||
151 | while (!feof(fp)) { | |
152 | fgets(buf,512,fp); | |
153 | if (feof(fp)) { | |
154 | break; | |
155 | } | |
156 | ||
157 | res=sscanf(buf,"%lu %lu %lu %lu %lu",&IP,×tamp,&glineid,&ptype,&pport); | |
158 | ||
159 | if (res<2) | |
160 | continue; | |
161 | ||
162 | if (!chp || (chp->IP != IP)) | |
163 | chp=addcleanhost(IP, timestamp); | |
164 | ||
165 | if (res==5) { | |
166 | chp->glineid=glineid; | |
167 | fpp=getfoundproxy(); | |
168 | fpp->type=ptype; | |
169 | fpp->port=pport; | |
170 | fpp->next=chp->proxies; | |
171 | chp->proxies=fpp; | |
172 | } | |
173 | } | |
174 | } | |
175 | ||
176 | /* | |
177 | * cleancount: | |
178 | * Returns the number of "clean" host entries present | |
179 | */ | |
180 | ||
181 | unsigned int cleancount() { | |
182 | int i; | |
183 | unsigned int total=0; | |
184 | cachehost *chp; | |
185 | ||
186 | for(i=0;i<HOSTCACHEHASHSIZE;i++) { | |
187 | for (chp=cachetable[i];chp;chp=chp->next) { | |
188 | if (!chp->proxies) | |
189 | total++; | |
190 | } | |
191 | } | |
192 | ||
193 | return total; | |
194 | } | |
195 | ||
196 | unsigned int dirtycount() { | |
197 | int i; | |
198 | unsigned int total=0; | |
199 | cachehost *chp; | |
200 | ||
201 | for(i=0;i<HOSTCACHEHASHSIZE;i++) { | |
202 | for (chp=cachetable[i];chp;chp=chp->next) { | |
203 | if (chp->proxies) | |
204 | total++; | |
205 | } | |
206 | } | |
207 | ||
208 | return total; | |
209 | } | |
210 | ||
211 | /* | |
212 | * scanall: | |
213 | * Scans all hosts on the network for a given proxy, and updates the cache accordingly | |
214 | */ | |
215 | ||
216 | void scanall(int type, int port) { | |
217 | int i; | |
218 | cachehost *chp, *nchp; | |
219 | nick *np; | |
220 | unsigned int hostmarker; | |
221 | ||
222 | hostmarker=nexthostmarker(); | |
223 | ||
224 | for (i=0;i<HOSTCACHEHASHSIZE;i++) | |
225 | for (chp=cachetable[i];chp;chp=chp->next) | |
226 | chp->marker=0; | |
227 | ||
228 | for (i=0;i<NICKHASHSIZE;i++) { | |
229 | for (np=nicktable[i];np;np=np->next) { | |
230 | if (np->host->marker==hostmarker) | |
231 | continue; | |
232 | ||
233 | np->host->marker=hostmarker; | |
234 | ||
c9db668b P |
235 | if (!irc_in_addr_is_ipv4(&np->p_ipaddr)) |
236 | continue; | |
237 | ||
238 | unsigned int ip2 = irc_in_addr_v4_to_int(&np->p_ipaddr); | |
239 | ||
240 | if ((chp=findcachehost(ip2))) | |
905c2ba2 | 241 | chp->marker=1; |
242 | ||
c9db668b | 243 | queuescan(ip2, type, port, SCLASS_NORMAL, 0); |
905c2ba2 | 244 | } |
245 | } | |
246 | ||
247 | for (i=0;i<HOSTCACHEHASHSIZE;i++) { | |
248 | for (chp=cachetable[i];chp;chp=nchp) { | |
249 | nchp=chp->next; | |
250 | if (!chp->proxies && !chp->marker) | |
251 | delcachehost(chp); | |
252 | } | |
253 | } | |
254 | } |