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