"Fossies" - the Fresh Open Source Software Archive

Member "etherape-0.9.18/src/names/ip-cache.c" (14 Apr 2018, 3894 Bytes) of package /linux/privat/etherape-0.9.18.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ip-cache.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.9.17_vs_0.9.18.

    1 /*
    2    $Id$
    3 
    4    This program is free software; you can redistribute it and/or modify
    5    it under the terms of the GNU General Public License as published by
    6    the Free Software Foundation; either version 2 of the License, or
    7    (at your option) any later version.
    8 
    9    This program is distributed in the hope that it will be useful,
   10    but WITHOUT ANY WARRANTY; without even the implied warranty of
   11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12    GNU General Public License for more details.
   13 
   14    You should have received a copy of the GNU General Public License
   15    along with this program; if not, write to the Free Software
   16    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   17 
   18    ----------------------------------------------------------------
   19 
   20    A simple cache of ipaddr->hostname lookups.  The cache is pruned
   21    periodically, removing entries whose expiry times have passed.  Negative
   22    caching is also performed.
   23 
   24    Copyright (C) 2014 Zev Weiss <zev@bewilderbeest.net>
   25 */
   26 
   27 
   28 #ifdef HAVE_CONFIG_H
   29 #include <config.h>
   30 #endif
   31 
   32 #include <glib.h>
   33 
   34 #include "common.h"
   35 #include "preferences.h"
   36 #include "stats/util.h"
   37 #include "ip-cache.h"
   38 
   39 static GTree *ipcache_tree;
   40 
   41 static int addr_tree_cmp(gconstpointer a, gconstpointer b, gpointer unused)
   42 {
   43   return address_cmp(a, b);
   44 }
   45 
   46 struct prune_ctx
   47 {
   48   time_t now;
   49   GSList *to_free;
   50 };
   51 
   52 static gboolean
   53 find_expired(gpointer key, gpointer value, gpointer data)
   54 {
   55   struct ipcache_item *item = value;
   56   struct prune_ctx *ctx = data;
   57 
   58   /* Don't prune items that are still being resolved */
   59   if (item && item->expiry != 0 && item->state != ICS_RESOLVING && item->expiry < ctx->now)
   60       ctx->to_free = g_slist_prepend(ctx->to_free, item);
   61 
   62   return FALSE; /* don't terminate traversal */
   63 }
   64 
   65 static void
   66 del_expired(gpointer data, gpointer unused)
   67 {
   68   struct ipcache_item *item = data;
   69   gboolean found = g_tree_remove(ipcache_tree, &item->ip);
   70   g_assert(found);
   71 }
   72 
   73 static gboolean
   74 ipcache_prune(gpointer data)
   75 {
   76   struct prune_ctx ctx = { .now = time(NULL), .to_free = NULL, };
   77 
   78   g_tree_foreach(ipcache_tree, find_expired, &ctx);
   79 
   80   g_slist_foreach(ctx.to_free, del_expired, NULL);
   81   g_slist_free(ctx.to_free);
   82 
   83   return TRUE;
   84 }
   85 
   86 static void
   87 free_ipcache_item(gpointer data)
   88 {
   89   struct ipcache_item *item = data;
   90   g_free(item->hostname);
   91   g_free(item);
   92 }
   93 
   94 void
   95 ipcache_init(void)
   96 {
   97   g_timeout_add_seconds(10, ipcache_prune, NULL);
   98   ipcache_tree = g_tree_new_full(addr_tree_cmp, NULL, NULL, free_ipcache_item);
   99 }
  100 
  101 void
  102 ipcache_clear(void)
  103 {
  104   g_tree_destroy(ipcache_tree);
  105 }
  106 
  107 long
  108 ipcache_active_entries(void)
  109 {
  110   return g_tree_nnodes(ipcache_tree);
  111 }
  112 
  113 const char *
  114 ipcache_lookup(const address_t *addr)
  115 {
  116   struct ipcache_item *item;
  117 
  118   if (!pref.name_res)
  119     return address_to_str(addr); /* name resolution globally disabled */
  120 
  121   item = g_tree_lookup(ipcache_tree, addr);
  122   if (item)
  123     {
  124       if (item->state == ICS_RESOLVED)
  125         return item->hostname;
  126       else
  127         return address_to_str(&item->ip);
  128     }
  129   else
  130     return NULL;
  131 }
  132 
  133 static struct ipcache_item *
  134 ipcache_alloc_item(const address_t *ip)
  135 {
  136   struct ipcache_item *item;
  137 
  138   item = g_malloc0(sizeof(*item));
  139 
  140   item->state = ICS_RESOLVING;
  141   address_copy(&item->ip, ip);
  142 
  143   return item;
  144 }
  145 
  146 struct ipcache_item *
  147 ipcache_prepare_request(const address_t *ip)
  148 {
  149   struct ipcache_item *item;
  150 
  151   g_assert(ip);
  152 
  153   item = g_tree_lookup(ipcache_tree, ip);
  154   g_assert(!item);
  155   item = ipcache_alloc_item(ip);
  156 
  157   g_tree_insert(ipcache_tree, &item->ip, item);
  158 
  159   return item;
  160 }
  161 
  162 void
  163 ipcache_request_succeeded(struct ipcache_item *rp, long ttl, const char *ipname)
  164 {
  165   rp->hostname = g_strdup(ipname);
  166   rp->expiry = time(NULL) + ttl;
  167   rp->state = ICS_RESOLVED;
  168 }
  169 
  170 void
  171 ipcache_request_failed(struct ipcache_item *rp)
  172 {
  173   /* Arbitrary default negative cache timeout of 5 minutes */
  174   rp->expiry = time(NULL) + 300;
  175   rp->state = ICS_FAILED;
  176 }