Commit 5a0a473c authored by Yang Tse's avatar Yang Tse
Browse files

Initial support for the generic ares_free_data() function that will allow

applications to free memory allocated and returned by some c-ares funtions.
parent 5129442e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ CSOURCES = ares__close_sockets.c \
  ares__read_line.c			\
  ares__timeval.c			\
  ares_cancel.c				\
  ares_data.c				\
  ares_destroy.c			\
  ares_expand_name.c			\
  ares_expand_string.c			\
@@ -41,6 +42,7 @@ CSOURCES = ares__close_sockets.c \

HHEADERS = ares.h			\
  ares_build.h				\
  ares_data.h				\
  ares_dns.h				\
  ares_ipv6.h				\
  ares_library_init.h			\
+10 −6
Original line number Diff line number Diff line
@@ -430,15 +430,17 @@ struct addr6ttl {
};

struct ares_srv_reply {
  unsigned short weight;
  struct ares_srv_reply  *next;
  char                   *host;
  unsigned short          priority;
  unsigned short          weight;
  unsigned short          port;
  char *host;
};

struct ares_txt_reply {
  size_t         length;  /* length excludes null termination */
  struct ares_txt_reply  *next;
  unsigned char          *txt;
  size_t                  length;  /* length excludes null termination */
};

/*
@@ -486,6 +488,8 @@ CARES_EXTERN void ares_free_string(void *str);

CARES_EXTERN void ares_free_hostent(struct hostent *host);

CARES_EXTERN void ares_free_data(void *dataptr);

CARES_EXTERN const char *ares_strerror(int code);

#ifdef  __cplusplus

ares/ares_data.c

0 → 100644
+142 −0
Original line number Diff line number Diff line
/* $Id$ */

/* Copyright (C) 2009 by Daniel Stenberg
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 */


#include "ares_setup.h"

#include <stddef.h>

#include "ares.h"
#include "ares_data.h"
#include "ares_private.h"


/*
** ares_free_data() - c-ares external API function.
**
** This function must be used by the application to free data memory that
** has been internally allocated by some c-ares function and for which a
** pointer has already been returned to the calling application. The list
** of c-ares functions returning pointers that must be free'ed using this
** function is:
**
**   FIXME: specify function list.
*/

void ares_free_data(void *dataptr)
{
  struct ares_data *ptr;

  if (!dataptr)
    return;

  ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));

  if (ptr->mark != ARES_DATATYPE_MARK)
    return;

  switch (ptr->type)
    {
      case ARES_DATATYPE_SRV_REPLY:

        if (ptr->data.srv_reply.next)
          ares_free_data(ptr->data.srv_reply.next);
        if (ptr->data.srv_reply.host)
          free(ptr->data.srv_reply.host);
        break;

      case ARES_DATATYPE_TXT_REPLY:

        if (ptr->data.txt_reply.next)
          ares_free_data(ptr->data.txt_reply.next);
        if (ptr->data.txt_reply.txt)
          free(ptr->data.txt_reply.txt);
        break;

      default:
        return;
    }

  free(ptr);
}


/*
** ares_malloc_data() - c-ares internal helper function.
**
** This function allocates memory for a c-ares private ares_data struct
** for the specified ares_datatype, initializes c-ares private fields
** and zero initializes those which later might be used from the public
** API. It returns an interior pointer which can be passed by c-ares
** functions to the calling application, and that must be free'ed using
** c-ares external API function ares_free_data().
*/

void *ares_malloc_data(ares_datatype type)
{
  struct ares_data *ptr;

  ptr = malloc(sizeof(struct ares_data));
  if (!ptr)
    return NULL;

  switch (type)
    {
      case ARES_DATATYPE_SRV_REPLY:
        ptr->data.srv_reply.next = NULL;
        ptr->data.srv_reply.host = NULL;
        ptr->data.srv_reply.priority = 0;
        ptr->data.srv_reply.weight = 0;
        ptr->data.srv_reply.port = 0;
        break;

      case ARES_DATATYPE_TXT_REPLY:
        ptr->data.txt_reply.next = NULL;
        ptr->data.txt_reply.txt = NULL;
        ptr->data.txt_reply.length  = 0;
        break;

      default:
        free(ptr);
        return NULL;
    }

  ptr->mark = ARES_DATATYPE_MARK;
  ptr->type = type;

  return &ptr->data;
}


/*
** ares_get_datatype() - c-ares internal helper function.
**
** This function returns the ares_datatype of the data stored in a
** private ares_data struct when given the public API pointer.
*/

ares_datatype ares_get_datatype(void * dataptr)
{
  struct ares_data *ptr;

  ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));

  if (ptr->mark == ARES_DATATYPE_MARK)
    return ptr->type;

  return ARES_DATATYPE_UNKNOWN;
}

ares/ares_data.h

0 → 100644
+62 −0
Original line number Diff line number Diff line
/* $Id$ */

/* Copyright (C) 2009 by Daniel Stenberg
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 */

typedef enum {
  ARES_DATATYPE_UNKNOWN = 1,   /* unknown data type     */
#if 0
  ARES_DATATYPE_ADDR6TTL,      /* struct ares_addrttl   */
  ARES_DATATYPE_ADDRTTL,       /* struct ares_addr6ttl  */
  ARES_DATATYPE_HOSTENT,       /* struct hostent        */
  ARES_DATATYPE_OPTIONS,       /* struct ares_options   */
#endif
  ARES_DATATYPE_SRV_REPLY,     /* struct ares_srv_reply */
  ARES_DATATYPE_TXT_REPLY,     /* struct ares_txt_reply */
  ARES_DATATYPE_LAST           /* not used              */
} ares_datatype;

#define ARES_DATATYPE_MARK 0xbead

/*
 * ares_data struct definition is internal to c-ares and shall not
 * be exposed by the public API in order to allow future changes
 * and extensions to it without breaking ABI.  This will be used
 * internally by c-ares as the container of multiple types of data
 * dynamically allocated for which a reference will be returned
 * to the calling application.
 *
 * c-ares API functions returning a pointer to c-ares internally
 * allocated data will actually be returning an interior pointer
 * into this ares_data struct.
 *
 * All this is 'invisible' to the calling application, the only
 * requirement is that this kind of data must be free'ed by the
 * calling application using ares_free_data() with the pointer
 * it has received from a previous c-ares function call.
 */

struct ares_data {
  ares_datatype type;  /* Actual data type identifier. */
  unsigned int  mark;  /* Private ares_data signature. */
  union {
    struct ares_txt_reply txt_reply;
    struct ares_srv_reply srv_reply;
  } data;
};

void *ares_malloc_data(ares_datatype type);

ares_datatype ares_get_datatype(void * dataptr);