#include "../core/error.h"
#include <string.h>
-#define HOSTCACHEHASHSIZE 50000
-
-cachehost *cachetable[HOSTCACHEHASHSIZE];
time_t cleanscaninterval;
time_t dirtyscaninterval;
void cachehostinit(time_t ri) {
cleanscaninterval=ri;
dirtyscaninterval=ri*7;
- memset(cachetable,0,sizeof(cachetable));
}
-cachehost *addcleanhost(unsigned long IP, time_t timestamp) {
+cachehost *addcleanhost(time_t timestamp) {
cachehost *chp;
- int hash;
-
- hash=(IP%HOSTCACHEHASHSIZE);
chp=getcachehost();
- chp->IP=IP;
chp->lastscan=timestamp;
chp->proxies=NULL;
chp->glineid=0;
- chp->next=cachetable[hash];
-
- cachetable[hash]=chp;
+ chp->lastgline=0;
return chp;
}
void delcachehost(cachehost *chp) {
- cachehost **chh;
foundproxy *fpp, *nfpp;
- int hash;
-
- hash=(chp->IP%HOSTCACHEHASHSIZE);
- for (chh=&(cachetable[hash]);*chh;chh=&((*chh)->next)) {
- if (*chh==chp) {
- *chh=chp->next;
- break;
- }
- }
-
for (fpp=chp->proxies;fpp;fpp=nfpp) {
nfpp=fpp->next;
freefoundproxy(fpp);
* Returns a cachehost * for the named IP
*/
-cachehost *findcachehost(unsigned long IP) {
- int hash;
+cachehost *findcachehost(patricia_node_t *node) {
cachehost *chp;
- hash=(IP%HOSTCACHEHASHSIZE);
-
- for (chp=cachetable[hash];chp;chp=chp->next) {
- if (chp->IP==IP) {
- /* match */
- if(chp->lastscan < (time(NULL)-(chp->proxies ? dirtyscaninterval : cleanscaninterval))) {
- /* Needs rescan; delete and return 1 */
- delcachehost(chp);
- return NULL;
- } else {
- /* valid: return it */
- return chp;
- }
+ if( (cachehost *)node->exts[ps_cache_ext] ) {
+ chp = (cachehost *)node->exts[ps_cache_ext];
+ if(chp->lastscan < (time(NULL)-(chp->proxies ? dirtyscaninterval : cleanscaninterval))) {
+ /* Needs rescan; delete and return 1 */
+ delcachehost(chp);
+ derefnode(iptree,node);
+ node->exts[ps_cache_ext] = NULL;
+ return NULL;
+ } else {
+ /* valid: return it */
+ return chp;
}
}
*/
void dumpcachehosts(void *arg) {
- int i;
FILE *fp;
- cachehost *chp,*nchp;
+ cachehost *chp;
time_t now=time(NULL);
foundproxy *fpp;
+ patricia_node_t *node;
- if ((fp=fopen("cleanhosts","w"))==NULL) {
+ if ((fp=fopen("data/cleanhosts","w"))==NULL) {
Error("proxyscan",ERR_ERROR,"Unable to open cleanhosts file for writing!");
return;
}
- for(i=0;i<HOSTCACHEHASHSIZE;i++) {
- for(chp=cachetable[i];chp;chp=nchp) {
- nchp=chp->next;
- if (chp->proxies) {
- if (chp->lastscan < (now-dirtyscaninterval)) {
- delcachehost(chp);
- continue;
- }
+ PATRICIA_WALK_CLEAR (iptree->head, node) {
+ if (node->exts[ps_cache_ext] ) {
+ chp = (cachehost *) node->exts[ps_cache_ext];
+ if (chp) {
+ if (chp->proxies) {
+ if (chp->lastscan < (now-dirtyscaninterval)) {
+ derefnode(iptree,node);
+ delcachehost(chp);
+ node->exts[ps_cache_ext] = NULL;
+ } else
- for (fpp=chp->proxies;fpp;fpp=fpp->next)
- fprintf(fp, "%lu %lu %u %i %u\n",chp->IP,chp->lastscan,chp->glineid,fpp->type,fpp->port);
- } else {
- if (chp->lastscan < (now-cleanscaninterval)) {
- /* Needs rescan anyway, so delete it */
- delcachehost(chp);
- continue;
+ for (fpp=chp->proxies;fpp;fpp=fpp->next)
+ fprintf(fp, "%s %lu %u %i %u %lu\n",IPtostr(node->prefix->sin),chp->lastscan,chp->glineid,fpp->type,fpp->port,chp->lastgline);
+ } else {
+ if (chp->lastscan < (now-cleanscaninterval)) {
+ /* Needs rescan anyway, so delete it */
+ derefnode(iptree,node);
+ delcachehost(chp);
+ node->exts[ps_cache_ext] = NULL;
+ } else
+ fprintf(fp,"%s %lu\n",IPtostr(node->prefix->sin),chp->lastscan);
}
- fprintf(fp,"%lu %lu\n",chp->IP,chp->lastscan);
}
}
- }
+ } PATRICIA_WALK_CLEAR_END;
+
+// patricia_tidy_tree(iptree);
fclose(fp);
}
void loadcachehosts() {
FILE *fp;
- unsigned long IP,timestamp,glineid,ptype,pport;
+ unsigned long timestamp,glineid,ptype,pport,lastgline;
char buf[512];
cachehost *chp=NULL;
foundproxy *fpp;
+ char ip[512];
int res;
-
- if ((fp=fopen("cleanhosts","r"))==NULL) {
+ struct irc_in_addr sin;
+ unsigned char bits;
+ patricia_node_t *node;
+ int i=0;
+
+ if ((fp=fopen("data/cleanhosts","r"))==NULL) {
Error("proxyscan",ERR_ERROR,"Unable to open cleanhosts file for reading!");
return;
}
+
while (!feof(fp)) {
fgets(buf,512,fp);
if (feof(fp)) {
break;
}
- res=sscanf(buf,"%lu %lu %lu %lu %lu",&IP,×tamp,&glineid,&ptype,&pport);
+ res=sscanf(buf,"%s %lu %lu %lu %lu %lu",ip,×tamp,&glineid,&ptype,&pport,&lastgline);
if (res<2)
continue;
- if (!chp || (chp->IP != IP))
- chp=addcleanhost(IP, timestamp);
+ if (0 == ipmask_parse(ip,&sin, &bits)) {
+ /* invalid mask */
+ } else {
+ node = refnode(iptree, &sin, bits);
+ if( node ) {
+ i++;
+ chp=addcleanhost(timestamp);
+ node->exts[ps_cache_ext] = chp;
- if (res==5) {
- chp->glineid=glineid;
- fpp=getfoundproxy();
- fpp->type=ptype;
- fpp->port=pport;
- fpp->next=chp->proxies;
- chp->proxies=fpp;
+ if (res==6) {
+ chp->glineid=glineid;
+ chp->lastgline=lastgline;
+ fpp=getfoundproxy();
+ fpp->type=ptype;
+ fpp->port=pport;
+ fpp->next=chp->proxies;
+ chp->proxies=fpp;
+ }
+ }
}
}
+
+ Error("proxyscan",ERR_INFO, "Loaded %d entries from cache", i);
}
/*
*/
unsigned int cleancount() {
- int i;
unsigned int total=0;
cachehost *chp;
+ patricia_node_t *head, *node;
+ head = iptree->head;
+ PATRICIA_WALK (head, node) {
+ if ( node->exts[ps_cache_ext] ) {
+ chp = (cachehost *) node->exts[ps_cache_ext];
- for(i=0;i<HOSTCACHEHASHSIZE;i++) {
- for (chp=cachetable[i];chp;chp=chp->next) {
if (!chp->proxies)
total++;
}
- }
+ } PATRICIA_WALK_END;
return total;
}
unsigned int dirtycount() {
- int i;
unsigned int total=0;
cachehost *chp;
+ patricia_node_t *node;
- for(i=0;i<HOSTCACHEHASHSIZE;i++) {
- for (chp=cachetable[i];chp;chp=chp->next) {
+ PATRICIA_WALK (iptree->head, node) {
+ if ( node->exts[ps_cache_ext] ) {
+ chp = (cachehost *) node->exts[ps_cache_ext];
if (chp->proxies)
total++;
}
- }
+ } PATRICIA_WALK_END;
return total;
}
void scanall(int type, int port) {
int i;
- cachehost *chp, *nchp;
+ cachehost *chp;
nick *np;
unsigned int hostmarker;
+ patricia_node_t *node;
hostmarker=nexthostmarker();
- for (i=0;i<HOSTCACHEHASHSIZE;i++)
- for (chp=cachetable[i];chp;chp=chp->next)
+ PATRICIA_WALK (iptree->head, node) {
+ if ( node->exts[ps_cache_ext] ) {
+ chp = (cachehost *) node->exts[ps_cache_ext];
chp->marker=0;
+ }
+ } PATRICIA_WALK_END;
for (i=0;i<NICKHASHSIZE;i++) {
for (np=nicktable[i];np;np=np->next) {
if (!irc_in_addr_is_ipv4(&np->p_ipaddr))
continue;
- unsigned int ip2 = irc_in_addr_v4_to_int(&np->p_ipaddr);
-
- if ((chp=findcachehost(ip2)))
+ if ((chp=findcachehost(np->ipnode)))
chp->marker=1;
- queuescan(ip2, type, port, SCLASS_NORMAL, 0);
- }
- }
-
- for (i=0;i<HOSTCACHEHASHSIZE;i++) {
- for (chp=cachetable[i];chp;chp=nchp) {
- nchp=chp->next;
- if (!chp->proxies && !chp->marker)
- delcachehost(chp);
+ queuescan(np->ipnode, type, port, SCLASS_NORMAL, 0);
}
}
}