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