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

Reply via email to