File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / blockdata.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 16:31:38 2014 UTC (10 years, 1 month ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_71, HEAD
dnsmasq 2.71

    1: /* dnsmasq is Copyright (c) 2000-2014 Simon Kelley
    2: 
    3:    This program is free software; you can redistribute it and/or modify
    4:    it under the terms of the GNU General Public License as published by
    5:    the Free Software Foundation; version 2 dated June, 1991, or
    6:    (at your option) version 3 dated 29 June, 2007.
    7:  
    8:    This program is distributed in the hope that it will be useful,
    9:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   10:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   11:    GNU General Public License for more details.
   12:      
   13:    You should have received a copy of the GNU General Public License
   14:    along with this program.  If not, see <http://www.gnu.org/licenses/>.
   15: */
   16: 
   17: #include "dnsmasq.h"
   18: 
   19: #ifdef HAVE_DNSSEC
   20: 
   21: static struct blockdata *keyblock_free;
   22: static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
   23: 
   24: static void blockdata_expand(int n)
   25: {
   26:   struct blockdata *new = whine_malloc(n * sizeof(struct blockdata));
   27:   
   28:   if (n > 0 && new)
   29:     {
   30:       int i;
   31:       
   32:       new[n-1].next = keyblock_free;
   33:       keyblock_free = new;
   34: 
   35:       for (i = 0; i < n - 1; i++)
   36: 	new[i].next = &new[i+1];
   37: 
   38:       blockdata_alloced += n;
   39:     }
   40: }
   41: 
   42: /* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */
   43: void blockdata_init(void)
   44: {
   45:   keyblock_free = NULL;
   46:   blockdata_alloced = 0;
   47:   blockdata_count = 0;
   48:   blockdata_hwm = 0;
   49: 
   50:   /* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */  
   51:   if (option_bool(OPT_DNSSEC_VALID))
   52:     blockdata_expand((daemon->cachesize * 100) / sizeof(struct blockdata));
   53: }
   54: 
   55: void blockdata_report(void)
   56: {
   57:   if (option_bool(OPT_DNSSEC_VALID))
   58:     my_syslog(LOG_INFO, _("DNSSEC memory in use %u, max %u, allocated %u"), 
   59: 	      blockdata_count * sizeof(struct blockdata),  
   60: 	      blockdata_hwm * sizeof(struct blockdata),  
   61: 	      blockdata_alloced * sizeof(struct blockdata));
   62: } 
   63: 
   64: struct blockdata *blockdata_alloc(char *data, size_t len)
   65: {
   66:   struct blockdata *block, *ret = NULL;
   67:   struct blockdata **prev = &ret;
   68:   size_t blen;
   69: 
   70:   while (len > 0)
   71:     {
   72:       if (!keyblock_free)
   73: 	blockdata_expand(50);
   74:       
   75:       if (keyblock_free)
   76: 	{
   77: 	  block = keyblock_free;
   78: 	  keyblock_free = block->next;
   79: 	  blockdata_count++; 
   80: 	}
   81:       else
   82: 	{
   83: 	  /* failed to alloc, free partial chain */
   84: 	  blockdata_free(ret);
   85: 	  return NULL;
   86: 	}
   87:        
   88:       if (blockdata_hwm < blockdata_count)
   89: 	blockdata_hwm = blockdata_count; 
   90:       
   91:       blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
   92:       memcpy(block->key, data, blen);
   93:       data += blen;
   94:       len -= blen;
   95:       *prev = block;
   96:       prev = &block->next;
   97:       block->next = NULL;
   98:     }
   99:   
  100:   return ret;
  101: }
  102: 
  103: void blockdata_free(struct blockdata *blocks)
  104: {
  105:   struct blockdata *tmp;
  106:   
  107:   if (blocks)
  108:     {
  109:       for (tmp = blocks; tmp->next; tmp = tmp->next)
  110: 	blockdata_count--;
  111:       tmp->next = keyblock_free;
  112:       keyblock_free = blocks; 
  113:       blockdata_count--;
  114:     }
  115: }
  116: 
  117: /* if data == NULL, return pointer to static block of sufficient size */
  118: void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
  119: {
  120:   size_t blen;
  121:   struct  blockdata *b;
  122:   void *new, *d;
  123:   
  124:   static unsigned int buff_len = 0;
  125:   static unsigned char *buff = NULL;
  126:    
  127:   if (!data)
  128:     {
  129:       if (len > buff_len)
  130: 	{
  131: 	  if (!(new = whine_malloc(len)))
  132: 	    return NULL;
  133: 	  if (buff)
  134: 	    free(buff);
  135: 	  buff = new;
  136: 	}
  137:       data = buff;
  138:     }
  139:   
  140:   for (d = data, b = block; len > 0 && b;  b = b->next)
  141:     {
  142:       blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
  143:       memcpy(d, b->key, blen);
  144:       d += blen;
  145:       len -= blen;
  146:     }
  147: 
  148:   return data;
  149: }
  150:  
  151: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>