From: Frédéric Marchal Date: Sun, 26 Feb 2012 19:12:12 +0000 (+0100) Subject: Add a cache to store the resolved IP addresses X-Git-Tag: v2.3.3-pre1~20 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0326d73b47a57d65c26d4d333db96f394252abfc;p=thirdparty%2Fsarg.git Add a cache to store the resolved IP addresses The cache is based on a dichotomic search in an array. I plan to compare the speed of the dichotomic search with the btree. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index e17d313..cb05c77 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,7 +51,7 @@ SET(SRC util.c log.c report.c topuser.c email.c sort.c html.c index.c getconf.c usage.c decomp.c ip2name.c ip2name_dns.c useragent.c exclude.c convlog.c totday.c repday.c datafile.c indexonly.c splitlog.c lastlog.c topsites.c siteuser.c css.c - smartfilter.c denied.c authfail.c charset.c + smartfilter.c denied.c authfail.c charset.c dichotomic.c redirector.c auth.c download.c grepday.c dansguardian_log.c dansguardian_report.c realtime.c btree_cache.c usertab.c userinfo.c longline.c url.c) diff --git a/Makefile.in b/Makefile.in index 16d3ea5..4595f81 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,7 +35,7 @@ SRCS = util.c log.c report.c topuser.c email.c sort.c html.c \ index.c getconf.c usage.c decomp.c ip2name.c ip2name_dns.c \ useragent.c exclude.c convlog.c totday.c repday.c datafile.c\ indexonly.c splitlog.c lastlog.c topsites.c siteuser.c css.c \ - smartfilter.c denied.c authfail.c charset.c \ + smartfilter.c denied.c authfail.c charset.c dichotomic.c \ redirector.c auth.c download.c grepday.c \ dansguardian_log.c dansguardian_report.c realtime.c btree_cache.c \ usertab.c userinfo.c longline.c url.c diff --git a/dichotomic.c b/dichotomic.c new file mode 100644 index 0000000..b81129e --- /dev/null +++ b/dichotomic.c @@ -0,0 +1,202 @@ +/* + * SARG Squid Analysis Report Generator http://sarg.sourceforge.net + * 1998, 2012 + * + * SARG donations: + * please look at http://sarg.sourceforge.net/donations.php + * Support: + * http://sourceforge.net/projects/sarg/forums/forum/363374 + * --------------------------------------------------------------------- + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. + * + */ + +#include "include/conf.h" +#include "include/defs.h" +#include "include/dichotomic.h" + +/*! +One key/value pair stored in the sorted list. +*/ +struct DichotomicItemStruct +{ + //! The key. + const char *Key; + //! The value. + const char *Value; +}; + +struct DichotomicStruct +{ + //! The array containing the sorted pairs. + struct DichotomicItemStruct *Items; + //! The number of pairs in the array. + int NItems; + //! The size of the array. + int NAllocated; +}; + +/*! +Create an object to store key/value pairs and +retrieve them. + +\return The object to pass to the functions in this module. +The returned pointer is NULL if there is not enough memory +to allocate the object. The object must be freed with a call +to Dichotomic_Destroy(). +*/ +DichotomicObject Dichotomic_Create(void) +{ + DichotomicObject Obj; + + Obj=malloc(sizeof(*Obj)); + if (!Obj) + { + return(NULL); + } + memset(Obj,0,sizeof(*Obj)); + return(Obj); +} + +/*! +Destroy an object created by Dichotomic_Create(). + +\param ObjPtr The pointer to the variable containing +the object to destroy. The pointer is reset to NULL +by this function. It is safe to pass NULL or a NULL +pointer. +*/ +void Dichotomic_Destroy(DichotomicObject *ObjPtr) +{ + DichotomicObject Obj; + int i; + + if (!ObjPtr || !*ObjPtr) return; + Obj=*ObjPtr; + *ObjPtr=NULL; + if (Obj->Items) + { + for (i=0 ; iNItems ; i++) + { + free((void*)Obj->Items[i].Key); + free((void*)Obj->Items[i].Value); + } + free(Obj->Items); + } + free(Obj); +} + +static int Dichotomic_FindKeyPos(DichotomicObject Obj,const char *key,bool *Found) +{ + int down,up; + int middle=0; + int cmp=0; + + down=0; + up=Obj->NItems-1; + while (up>=down) + { + middle=(down+up)/2; + cmp=strcasecmp(key,Obj->Items[middle].Key); + if (!cmp) + { + *Found=true; + return(middle); + } + if (cmp<0) + up=middle-1; + else + down=middle+1; + } + *Found=false; + if (cmp>0) middle++; + return(middle); +} + +/*! +Insert a key/value pair into the array. + +\param Obj The object created by Dichotomic_Create(). +\param key The key of the pair. +\param value The value of the pair. + +\return \c True if the pair was inserted or \c false if +it failed. +*/ +bool Dichotomic_Insert(DichotomicObject Obj,const char *key, const char *value) +{ + int Position; + bool Found; + int i; + + if (!Obj) return(false); + if (Obj->Items) + { + Position=Dichotomic_FindKeyPos(Obj,key,&Found); + if (Found) return(false); + } + else + Position=0; + + if (Obj->NItems>=Obj->NAllocated) + { + struct DichotomicItemStruct *Items; + Obj->NAllocated+=25; + Items=realloc(Obj->Items,Obj->NAllocated*sizeof(*Items)); + if (!Items) + { + debuga(_("Not enough memory to store the key/value pair %s/%s\n"),key,value); + exit(EXIT_FAILURE); + } + Obj->Items=Items; + } + + for (i=Obj->NItems ; i>Position ; i--) + { + Obj->Items[i].Key=Obj->Items[i-1].Key; + Obj->Items[i].Value=Obj->Items[i-1].Value; + } + Obj->Items[Position].Key=strdup(key); + Obj->Items[Position].Value=strdup(value); + if (!Obj->Items[Position].Key || !Obj->Items[Position].Value) + { + debuga(_("Not enough memory to store the key/value pair %s/%s\n"),key,value); + exit(EXIT_FAILURE); + } + Obj->NItems++; + + return(true); +} + +/*! +Search for the value of a key. + +\param Obj The object created by Dichotomic_Create(). +\param key The key to search for. + +\return The value of the key or NULL if the key was not found. +*/ +const char *Dichotomic_Search(DichotomicObject Obj,const char *key) +{ + int Position; + bool Found; + + if (!Obj) return(NULL); + if (Obj->NItems==0 || !Obj->Items) return(NULL); + Position=Dichotomic_FindKeyPos(Obj,key,&Found); + if (!Found) return(NULL); + return(Obj->Items[Position].Value); +} diff --git a/include/defs.h b/include/defs.h index 8e3fdf3..69acaca 100755 --- a/include/defs.h +++ b/include/defs.h @@ -153,6 +153,7 @@ void index_only(const char *dirname,int debug); int ip2name_config(const char *param); void ip2name_forcedns(void); void ip2name(char *ip,int ip_len); +void ip2name_cleanup(void); void name2ip(char *name,int name_size); // lastlog.c diff --git a/include/dichotomic.h b/include/dichotomic.h new file mode 100644 index 0000000..48c14de --- /dev/null +++ b/include/dichotomic.h @@ -0,0 +1,26 @@ +#ifndef DICHOTOMIC_HEADER +#define DICHOTOMIC_HEADER + +#ifdef HAVE_STDBOOL_H +#include +#else +typedef int bool; +#ifndef true +#define true 1 +#endif +#ifndef false +#define false 0 +#endif +#endif + +//! The object to store key/value pairs +typedef struct DichotomicStruct *DichotomicObject; + +DichotomicObject Dichotomic_Create(void); +void Dichotomic_Destroy(DichotomicObject *ObjPtr); + +const char *Dichotomic_Search(DichotomicObject Obj,const char *key); +bool Dichotomic_Insert(DichotomicObject Obj,const char *key, const char *value); + + +#endif //DICHOTOMIC_HEADER diff --git a/ip2name.c b/ip2name.c index 205574e..5e7825e 100644 --- a/ip2name.c +++ b/ip2name.c @@ -27,6 +27,7 @@ #include "include/conf.h" #include "include/defs.h" #include "include/ip2name.h" +#include "include/dichotomic.h" //! Associate a name or alias to a module. struct Ip2NameModules @@ -49,6 +50,8 @@ static const struct Ip2NameModules ModulesList[]= //! The chain of the configured modules to try to resolve an IP. static struct Ip2NameProcess *FirstModule=NULL; +//! The list of the names found so far. +static DichotomicObject KnownIp=NULL; /*! Add a new module to the list of the configured modules. @@ -182,13 +185,40 @@ void ip2name(char *ip,int ip_len) { struct Ip2NameProcess *Module; enum ip2name_retcode Status; + const char *Name; + char OrigIp[80]; + if (!KnownIp) { + KnownIp=Dichotomic_Create(); + if (!KnownIp) { + debuga(_("Not enough memory to store the names corresponding to the IP address\n")); + exit(EXIT_FAILURE); + } + } + + Name=Dichotomic_Search(KnownIp,ip); + if (Name) { + safe_strcpy(ip,Name,ip_len); + return; + } + + safe_strcpy(OrigIp,ip,sizeof(OrigIp)); for (Module=FirstModule ; Module ; Module=Module->Next) { if (Module->Resolve) { Status=Module->Resolve(ip,ip_len); - if (Status==INRC_Found) return; + if (Status==INRC_Found) break; } } + Dichotomic_Insert(KnownIp,OrigIp,ip); +} + +/*! +Release the memory allocated to resolve the IP addresses +into names. +*/ +void ip2name_cleanup(void) +{ + Dichotomic_Destroy(&KnownIp); } void name2ip(char *name,int name_size) diff --git a/log.c b/log.c index e2172e6..5913241 100644 --- a/log.c +++ b/log.c @@ -1708,6 +1708,7 @@ int main(int argc,char *argv[]) unlinkdir(tmp,0); } + ip2name_cleanup(); free_hostalias(); userinfo_free(); if(userfile)