/* dnsmasq is Copyright (c) 2000-2024 Simon Kelley

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 dated June, 1991, or
   (at your option) version 3 dated 29 June, 2007.
 
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
     
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "dnsmasq.h"

static struct blockdata *keyblock_free;
static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;

static void add_blocks(int n)
{
  struct blockdata *new = whine_malloc(n * sizeof(struct blockdata));
  
  if (new)
    {
      int i;
      
      new[n-1].next = keyblock_free;
      keyblock_free = new;

      for (i = 0; i < n - 1; i++)
	new[i].next = &new[i+1];

      blockdata_alloced += n;
    }
}

/* Preallocate some blocks, proportional to cachesize, to reduce heap fragmentation. */
void blockdata_init(void)
{
  keyblock_free = NULL;
  blockdata_alloced = 0;
  blockdata_count = 0;
  blockdata_hwm = 0;

  /* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */  
  if (option_bool(OPT_DNSSEC_VALID))
    add_blocks(daemon->cachesize);
}

void blockdata_report(void)
{
  my_syslog(LOG_INFO, _("pool memory in use %zu, max %zu, allocated %zu"), 
	    blockdata_count * sizeof(struct blockdata),  
	    blockdata_hwm * sizeof(struct blockdata),  
	    blockdata_alloced * sizeof(struct blockdata));
} 

static struct blockdata *new_block(void)
{
  struct blockdata *block;

  if (!keyblock_free)
    add_blocks(50);
  
  if (keyblock_free)
    {
      block = keyblock_free;
      keyblock_free = block->next;
      blockdata_count++;
      if (blockdata_hwm < blockdata_count)
	blockdata_hwm = blockdata_count;
      block->next = NULL;
      return block;
    }
  
  return NULL;
}

static struct blockdata *blockdata_alloc_real(int fd, char *data, size_t len)
{
  struct blockdata *block, *ret = NULL;
  struct blockdata **prev = &ret;
  size_t blen;

  do
    {
      if (!(block = new_block()))
	{
	  /* failed to alloc, free partial chain */
	  blockdata_free(ret);
	  return NULL;
	}

      if ((blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len) > 0)
	{
	  if (data)
	    {
	      memcpy(block->key, data, blen);
	      data += blen;
	    }
	  else if (!read_write(fd, block->key, blen, 1))
	    {
	      /* failed read free partial chain */
	      blockdata_free(ret);
	      return NULL;
	    }
	}
      
      len -= blen;
      *prev = block;
      prev = &block->next;
    } while (len != 0);
  
  return ret;
}

struct blockdata *blockdata_alloc(char *data, size_t len)
{
  return blockdata_alloc_real(0, data, len);
}

/* Add data to the end of the block. 
   newlen is length of new data, NOT total new length. 
   Use blockdata_alloc(NULL, 0) to make empty block to add to. */
int blockdata_expand(struct blockdata *block, size_t oldlen, char *data, size_t newlen)
{
  struct blockdata *b;
  
  /* find size of current final block */
  for (b = block; oldlen > KEYBLOCK_LEN && b;  b = b->next, oldlen -= KEYBLOCK_LEN);

  /* chain to short for length, something is broken */
  if (oldlen > KEYBLOCK_LEN)
    {
      blockdata_free(block);
      return 0;
    }

  while (1)
    {
      struct blockdata *new;
      size_t blocksize = KEYBLOCK_LEN - oldlen;
      size_t size = (newlen <= blocksize) ? newlen : blocksize;
      
      if (size != 0)
	{
	  memcpy(&b->key[oldlen], data, size);
	  data += size;
	  newlen -= size;
	}
      
      /* full blocks from now on. */
      oldlen = 0;

      if (newlen == 0)
	break;

      if ((new = new_block()))
	{
	  b->next = new;
	  b = new;
	}
      else
	{
	  /* failed to alloc, free partial chain */
	  blockdata_free(block);
	  return 0;
	}
    }

  return 1;
}

void blockdata_free(struct blockdata *blocks)
{
  struct blockdata *tmp;
  
  if (blocks)
    {
      for (tmp = blocks; tmp->next; tmp = tmp->next)
	blockdata_count--;
      tmp->next = keyblock_free;
      keyblock_free = blocks; 
      blockdata_count--;
    }
}

/* if data == NULL, return pointer to static block of sufficient size */
void *blockdata_retrieve(struct blockdata *block, size_t len, void *data)
{
  size_t blen;
  struct  blockdata *b;
  void *new, *d;
  
  static unsigned int buff_len = 0;
  static unsigned char *buff = NULL;
   
  if (!data)
    {
      if (len > buff_len)
	{
	  if (!(new = whine_malloc(len)))
	    return NULL;
	  if (buff)
	    free(buff);
	  buff = new;
	}
      data = buff;
    }
  
  for (d = data, b = block; len > 0 && b;  b = b->next)
    {
      blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
      memcpy(d, b->key, blen);
      d += blen;
      len -= blen;
    }

  return data;
}


void blockdata_write(struct blockdata *block, size_t len, int fd)
{
  for (; len > 0 && block; block = block->next)
    {
      size_t blen = len > KEYBLOCK_LEN ? KEYBLOCK_LEN : len;
      read_write(fd, block->key, blen, 0);
      len -= blen;
    }
}

struct blockdata *blockdata_read(int fd, size_t len)
{
  return blockdata_alloc_real(fd, NULL, len);
}
