File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / dnsmasq / src / blockdata.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:56:46 2021 UTC (3 years, 4 months ago) by misho
Branches: elwix, dnsmasq, MAIN
CVS tags: v2_84, HEAD
dnsmasq 2.84

    1: /* dnsmasq is Copyright (c) 2000-2021 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: static struct blockdata *keyblock_free;
   20: static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
   21: 
   22: static void blockdata_expand(int n)
   23: {
   24:   struct blockdata *new = whine_malloc(n * sizeof(struct blockdata));
   25:   
   26:   if (new)
   27:     {
   28:       int i;
   29:       
   30:       new[n-1].next = keyblock_free;
   31:       keyblock_free = new;
   32: 
   33:       for (i = 0; i < n - 1; i++)
   34: 	new[i].next = &new[i+1];
   35: 
   36:       blockdata_alloced += n;
   37:     }
   38: }
   39: 
   40: /* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */
   41: void blockdata_init(void)
   42: {
   43:   keyblock_free = NULL;
   44:   blockdata_alloced = 0;
   45:   blockdata_count = 0;
   46:   blockdata_hwm = 0;
   47: 
   48:   /* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */  
   49:   if (option_bool(OPT_DNSSEC_VALID))
   50:     blockdata_expand(daemon->cachesize);
   51: }
   52: 
   53: void blockdata_report(void)
   54: {
   55:   my_syslog(LOG_INFO, _("pool memory in use %u, max %u, allocated %u"), 
   56: 	    blockdata_count * sizeof(struct blockdata),  
   57: 	    blockdata_hwm * sizeof(struct blockdata),  
   58: 	    blockdata_alloced * sizeof(struct blockdata));
   59: } 
   60: 
   61: static struct blockdata *blockdata_alloc_real(int fd, char *data, size_t len)
   62: {
   63:   struct blockdata *block, *ret = NULL;
   64:   struct blockdata **prev = &ret;
   65:   size_t blen;
   66: 
   67:   while (len > 0)
   68:     {
   69:       if (!keyblock_free)
   70: 	blockdata_expand(50);
   71:       
   72:       if (keyblock_free)
   73: 	{
   74: 	  block = keyblock_free;
   75: 	  keyblock_free = block->next;
   76: 	  blockdata_count++; 
   77: 	}
   78:       else
   79: 	{
   80: 	  /* failed to alloc, free partial chain */
   81: 	  blockdata_free(ret);
   82: 	  return NULL;
   83: 	}
   84:        
   85:       if (blockdata_hwm < blockdata_count)
   86: 	blockdata_hwm = blockdata_count; 
   87:       
   88:       blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
   89:       if (data)
   90: 	{
   91: 	  memcpy(block->key, data, blen);
   92: 	  data += blen;
   93: 	}
   94:       else if (!read_write(fd, block->key, blen, 1))
   95: 	{
   96: 	  /* failed read free partial chain */
   97: 	  blockdata_free(ret);
   98: 	  return NULL;
   99: 	}
  100:       len -= blen;
  101:       *prev = block;
  102:       prev = &block->next;
  103:       block->next = NULL;
  104:     }
  105:   
  106:   return ret;
  107: }
  108: 
  109: struct blockdata *blockdata_alloc(char *data, size_t len)
  110: {
  111:   return blockdata_alloc_real(0, data, len);
  112: }
  113: 
  114: void blockdata_free(struct blockdata *blocks)
  115: {
  116:   struct blockdata *tmp;
  117:   
  118:   if (blocks)
  119:     {
  120:       for (tmp = blocks; tmp->next; tmp = tmp->next)
  121: 	blockdata_count--;
  122:       tmp->next = keyblock_free;
  123:       keyblock_free = blocks; 
  124:       blockdata_count--;
  125:     }
  126: }
  127: 
  128: /* if data == NULL, return pointer to static block of sufficient size */
  129: void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
  130: {
  131:   size_t blen;
  132:   struct  blockdata *b;
  133:   void *new, *d;
  134:   
  135:   static unsigned int buff_len = 0;
  136:   static unsigned char *buff = NULL;
  137:    
  138:   if (!data)
  139:     {
  140:       if (len > buff_len)
  141: 	{
  142: 	  if (!(new = whine_malloc(len)))
  143: 	    return NULL;
  144: 	  if (buff)
  145: 	    free(buff);
  146: 	  buff = new;
  147: 	}
  148:       data = buff;
  149:     }
  150:   
  151:   for (d = data, b = block; len > 0 && b;  b = b->next)
  152:     {
  153:       blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
  154:       memcpy(d, b->key, blen);
  155:       d += blen;
  156:       len -= blen;
  157:     }
  158: 
  159:   return data;
  160: }
  161: 
  162: 
  163: void blockdata_write(struct blockdata *block, size_t len, int fd)
  164: {
  165:   for (; len > 0 && block; block = block->next)
  166:     {
  167:       size_t blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
  168:       read_write(fd, block->key, blen, 0);
  169:       len -= blen;
  170:     }
  171: }
  172: 
  173: struct blockdata *blockdata_read(int fd, size_t len)
  174: {
  175:   return blockdata_alloc_real(fd, NULL, len);
  176: }
  177: 

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