Enlightenment CVS committal Author : sebastid Project : e17 Module : libs/ecore
Dir : e17/libs/ecore/src/lib/ecore_con Modified Files: ecore_con_dns.c Log Message: Add a small cache. =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore_con/ecore_con_dns.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -3 -r1.13 -r1.14 --- ecore_con_dns.c 25 Aug 2005 15:12:57 -0000 1.13 +++ ecore_con_dns.c 30 Aug 2005 04:35:24 -0000 1.14 @@ -20,6 +20,8 @@ * * Check /etc/hosts * * * Caching + * We should store all names returned when CNAME, might have different ttl. + * Check against search and hostname when querying cache? * * Remember all querys and delete them on shutdown * * * Need more buffer overflow checks. @@ -43,6 +45,8 @@ #define SERVERS 3 typedef struct _Ecore_Con_Dns_Query Ecore_Con_Dns_Query; +typedef struct _Ecore_Con_Dns_Cache Ecore_Con_Dns_Cache; + struct _Ecore_Con_Dns_Query { Ecore_Oldlist list; @@ -65,10 +69,19 @@ }; +struct _Ecore_Con_Dns_Cache { + Ecore_Oldlist list; + + int ttl; + double time; + struct hostent *he; +}; + static void _ecore_con_dns_ghbn(Ecore_Con_Dns_Query *query, const char *hostname); static int _ecore_con_dns_timeout(void *data); static int _ecore_con_cb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); static void _ecore_con_dns_query_free(Ecore_Con_Dns_Query *query); +static void _ecore_con_dns_cache_free(Ecore_Con_Dns_Cache *cache); static int _ecore_con_hostname_get(unsigned char *buf, char *hostname, int pos, int length); @@ -84,11 +97,14 @@ static uint16_t _id = 0; +static Ecore_Con_Dns_Cache *_cache = NULL; + #define SET_16BIT(p, v) \ (((p)[0]) = ((v) >> 8) & 0xff), \ (((p)[1]) = v & 0xff) #define GET_16BIT(p) (((p)[0]) << 8 | ((p)[1])) +#define GET_32BIT(p) (((p)[0]) << 24 | ((p)[1]) << 16 | ((p)[2]) << 8 | ((p)[3])) int ecore_con_dns_init(void) @@ -234,10 +250,51 @@ void *data) { Ecore_Con_Dns_Query *query; + Ecore_Con_Dns_Cache *current; + Ecore_Oldlist *l; if (!_server_count) return 0; if ((!name) || (!*name)) return 0; + for (l = (Ecore_Oldlist *)_cache; l;) + { + double time; + int i; + + current = (Ecore_Con_Dns_Cache *)l; + l = l->next; + + time = ecore_time_get(); + if ((time - current->time) > current->ttl) + { + _cache = _ecore_list_remove(_cache, current); + _ecore_con_dns_cache_free(current); + } + else + { + /* Check if we have a match */ + if (!strcmp(name, current->he->h_name)) + { + if (done_cb) + done_cb(current->he, data); + _cache = _ecore_list_remove(_cache, current); + _cache = _ecore_list_prepend(_cache, current); + return 1; + } + for (i = 0; current->he->h_aliases[i]; i++) + { + if (!strcmp(name, current->he->h_aliases[i])) + { + if (done_cb) + done_cb(current->he, data); + _cache = _ecore_list_remove(_cache, current); + _cache = _ecore_list_prepend(_cache, current); + return 1; + } + } + } + } + query = calloc(1, sizeof(Ecore_Con_Dns_Query)); if (!query) return 0; @@ -392,6 +449,7 @@ _ecore_con_cb_fd_handler(void *data, Ecore_Fd_Handler *fd_handler) { Ecore_Con_Dns_Query *query; + Ecore_Con_Dns_Cache *cache; int i, n, fd, found, len; unsigned int id; unsigned char buf[1024]; @@ -400,8 +458,8 @@ char **aliases = NULL; struct in_addr *addrs = NULL; int naliases = 0, naddrs = 0; - int ancount; - struct hostent he; + int ancount, ttl = INT_MAX; + struct hostent *he; query = data; fd = ecore_main_fd_handler_fd_get(fd_handler); @@ -454,7 +512,7 @@ for (i = 0; i < ancount; i++) { - int rr_type, rr_class, rr_len; + int rr_type, rr_class, rr_len, rr_ttl; char rr_name[1024], rr_data[1024]; /* Get the name */ @@ -467,7 +525,8 @@ /* Get the resource record class */ rr_class = GET_16BIT(p); p += 2; - /* Skip resource record ttl */ + /* Get the resource record ttl */ + rr_ttl = GET_32BIT(p); p += 4; /* Get the resource record length */ rr_len = GET_16BIT(p); @@ -486,6 +545,7 @@ if ((len = _ecore_con_hostname_get(buf, rr_data, p - buf, n)) == -1) goto error; strcpy(hostname, rr_data); p += rr_len; + ttl = MIN(rr_ttl, ttl); } else if ((rr_class == C_IN) && (rr_type == T_A) && (!strcmp(hostname, rr_name))) { @@ -493,32 +553,63 @@ if (rr_len != 4) goto error; memcpy(&addrs[naddrs++], p, sizeof(struct in_addr)); p += rr_len; + ttl = MIN(rr_ttl, ttl); } else p += rr_len; } /* Fill in the hostent and return successfully. */ - he.h_addr_list = malloc((naddrs + 1) * sizeof(char *)); - if (!he.h_addr_list) goto error; - he.h_name = strdup(hostname); + he = malloc(sizeof(struct hostent)); + if (!he) goto error; + he->h_addr_list = malloc((naddrs + 1) * sizeof(char *)); + if (!he->h_addr_list) goto error; + he->h_name = strdup(hostname); aliases[naliases] = NULL; - he.h_aliases = aliases; - he.h_addrtype = AF_INET; - he.h_length = sizeof(struct in_addr); + he->h_aliases = aliases; + he->h_addrtype = AF_INET; + he->h_length = sizeof(struct in_addr); for (i = 0; i < naddrs; i++) - he.h_addr_list[i] = (char *) &addrs[i]; - he.h_addr_list[naddrs] = NULL; + he->h_addr_list[i] = (char *) &addrs[i]; + he->h_addr_list[naddrs] = NULL; if (query->done.cb) - query->done.cb(&he, query->done.data); + query->done.cb(he, query->done.data); - free(he.h_addr_list); - free(he.h_name); - free(addrs); - for (i = 0; i < naliases; i++) - free(aliases[i]); - free(aliases); + cache = malloc(sizeof(Ecore_Con_Dns_Cache)); + if (cache) + { + Ecore_Oldlist *l; + + cache->ttl = ttl; + cache->time = ecore_time_get(); + cache->he = he; + _cache = _ecore_list_prepend(_cache, cache); + + /* Check cache size */ + i = 1; + l = (Ecore_Oldlist *)_cache; + while ((l = l->next)) + i++; + + /* Remove old stuff if cache to big */ + if (i > 16) + { + cache = (Ecore_Con_Dns_Cache *)((Ecore_Oldlist *)_cache)->last; + _cache = _ecore_list_remove(_cache, cache); + _ecore_con_dns_cache_free(cache); + } + } + else + { + free(he->h_addr_list); + free(he->h_name); + free(addrs); + for (i = 0; i < naliases; i++) + free(aliases[i]); + free(aliases); + free(he); + } _ecore_con_dns_query_free(query); return 0; @@ -609,6 +700,24 @@ free(query); } +static void +_ecore_con_dns_cache_free(Ecore_Con_Dns_Cache *cache) +{ + int i; + + free(cache->he->h_addr_list); + free(cache->he->h_name); + i = 0; + while (cache->he->h_addr_list[i]) + free(cache->he->h_addr_list[i++]); + i = 0; + while (cache->he->h_aliases[i]) + free(cache->he->h_aliases[i++]); + free(cache->he->h_aliases); + free(cache->he); + free(cache); +} + static int _ecore_con_hostname_get(unsigned char *buf, char *hostname, int pos, int length) ------------------------------------------------------- SF.Net email is Sponsored by the Better Software Conference & EXPO September 19-22, 2005 * San Francisco, CA * Development Lifecycle Practices Agile & Plan-Driven Development * Managing Projects & Teams * Testing & QA Security * Process Improvement & Measurement * http://www.sqe.com/bsce5sf _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs