/* Copyright (C) 2004-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library 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
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */

#include <assert.h>
#include <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <not-cancel.h>

#include "nscd-client.h"
#include "nscd_proto.h"


/* Define in nscd_gethst_r.c.  */
extern int __nss_not_use_nscd_hosts;


/* We use the mapping from nscd_gethst.  */
libc_locked_map_ptr (extern, __hst_map_handle) attribute_hidden;

/* Defined in nscd_gethst_r.c.  */
extern int __nss_have_localdomain attribute_hidden;


int
__nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop)
{
  if (__builtin_expect (__nss_have_localdomain >= 0, 0))
    {
      if (__nss_have_localdomain == 0)
	__nss_have_localdomain = getenv ("LOCALDOMAIN") != NULL ? 1 : -1;
      if (__nss_have_localdomain > 0)
	{
	  __nss_not_use_nscd_hosts = 1;
	  return -1;
	}
    }

  size_t keylen = strlen (key) + 1;
  int gc_cycle;
  int nretries = 0;

  /* If the mapping is available, try to search there instead of
     communicating with the nscd.  */
  struct mapped_database *mapped;
  mapped = __nscd_get_map_ref (GETFDHST, "hosts", &__hst_map_handle,
			       &gc_cycle);

 retry:;
  struct nscd_ai_result *resultbuf = NULL;
  const char *recend = (const char *) ~UINTMAX_C (0);
  char *respdata = NULL;
  int retval = -1;
  int sock = -1;
  ai_response_header ai_resp;

  if (mapped != NO_MAPPING)
    {
      struct datahead *found = __nscd_cache_search (GETAI, key, keylen,
						    mapped, sizeof ai_resp);
      if (found != NULL)
	{
	  respdata = (char *) (&found->data[0].aidata + 1);
	  ai_resp = found->data[0].aidata;
	  recend = (const char *) found->data + found->recsize;
	  /* Now check if we can trust ai_resp fields.  If GC is
	     in progress, it can contain anything.  */
	  if (mapped->head->gc_cycle != gc_cycle)
	    {
	      retval = -2;
	      goto out;
	    }
	}
    }

  /* If we do not have the cache mapped, try to get the data over the
     socket.  */
  if (respdata == NULL)
    {
      sock = __nscd_open_socket (key, keylen, GETAI, &ai_resp,
				 sizeof (ai_resp));
      if (sock == -1)
	{
	  /* nscd not running or wrong version.  */
	  __nss_not_use_nscd_hosts = 1;
	  goto out;
	}
    }

  if (ai_resp.found == 1)
    {
      size_t datalen = ai_resp.naddrs + ai_resp.addrslen + ai_resp.canonlen;

      /* This check really only affects the case where the data
	 comes from the mapped cache.  */
      if (respdata + datalen > recend)
	{
	  assert (sock == -1);
	  goto out;
	}

      /* Create result.  */
      resultbuf = (struct nscd_ai_result *) malloc (sizeof (*resultbuf)
						    + datalen);
      if (resultbuf == NULL)
	{
	  *h_errnop = NETDB_INTERNAL;
	  goto out_close;
	}

      /* Set up the data structure, including pointers.  */
      resultbuf->naddrs = ai_resp.naddrs;
      resultbuf->addrs = (char *) (resultbuf + 1);
      resultbuf->family = (uint8_t *) (resultbuf->addrs + ai_resp.addrslen);
      if (ai_resp.canonlen != 0)
	resultbuf->canon = (char *) (resultbuf->family + resultbuf->naddrs);
      else
	resultbuf->canon = NULL;

      if (respdata == NULL)
	{
	  /* Read the data from the socket.  */
	  if ((size_t) __readall (sock, resultbuf + 1, datalen) == datalen)
	    {
	      retval = 0;
	      *result = resultbuf;
	    }
	  else
	    {
	      free (resultbuf);
	      *h_errnop = NETDB_INTERNAL;
	    }
	}
      else
	{
	  /* Copy the data in the block.  */
	  memcpy (resultbuf + 1, respdata, datalen);

	  /* Try to detect corrupt databases.  */
	  if (resultbuf->canon != NULL
	      && resultbuf->canon[ai_resp.canonlen - 1] != '\0')
	    /* We cannot use the database.  */
	    {
	      if (mapped->head->gc_cycle != gc_cycle)
		retval = -2;
	      else
		free (resultbuf);
	      goto out_close;
	    }

	  retval = 0;
	  *result = resultbuf;
	}
    }
  else
    {
      if (__builtin_expect (ai_resp.found == -1, 0))
	{
	  /* The daemon does not cache this database.  */
	  __nss_not_use_nscd_hosts = 1;
	  goto out_close;
	}

      /* Store the error number.  */
      *h_errnop = ai_resp.error;

      /* Set errno to 0 to indicate no error, just no found record.  */
      __set_errno (0);
      /* Even though we have not found anything, the result is zero.  */
      retval = 0;
    }

 out_close:
  if (sock != -1)
    close_not_cancel_no_status (sock);
 out:
  if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0)
    {
      /* When we come here this means there has been a GC cycle while we
	 were looking for the data.  This means the data might have been
	 inconsistent.  Retry if possible.  */
      if ((gc_cycle & 1) != 0 || ++nretries == 5 || retval == -1)
	{
	  /* nscd is just running gc now.  Disable using the mapping.  */
	  if (atomic_decrement_val (&mapped->counter) == 0)
	    __nscd_unmap (mapped);
	  mapped = NO_MAPPING;
	}

      if (retval != -1)
	{
	  *result = NULL;
	  free (resultbuf);
	  goto retry;
	}
    }

  return retval;
}
