]> jfr.im git - irc/quakenet/newserv.git/blame - proxyscan/proxyscancache.c
this probably should be the correct new size ;/
[irc/quakenet/newserv.git] / proxyscan / proxyscancache.c
CommitLineData
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
14cachehost *cachetable[HOSTCACHEHASHSIZE];
15time_t cleanscaninterval;
16time_t dirtyscaninterval;
17
18void cachehostinit(time_t ri) {
19 cleanscaninterval=ri;
20 dirtyscaninterval=ri*7;
21 memset(cachetable,0,sizeof(cachetable));
22}
23
24cachehost *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
42void 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
67cachehost *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
96void 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
138void 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,&timestamp,&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
181unsigned 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
196unsigned 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
216void 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}