diff options
| author | Yang Tse <yangsita@gmail.com> | 2009-11-20 08:50:03 +0000 | 
|---|---|---|
| committer | Yang Tse <yangsita@gmail.com> | 2009-11-20 08:50:03 +0000 | 
| commit | 5a0a473c30925d63e1695a7b8b1cee8f73ad6e68 (patch) | |
| tree | ead0cabfa58c70b8241855cf743f38d37819eebc | |
| parent | 5129442ee7074e24f097a389ddb789c9996bb42a (diff) | |
Initial support for the generic ares_free_data() function that will allow
applications to free memory allocated and returned by some c-ares funtions.
| -rw-r--r-- | ares/Makefile.inc | 2 | ||||
| -rw-r--r-- | ares/ares.h | 16 | ||||
| -rw-r--r-- | ares/ares_data.c | 142 | ||||
| -rw-r--r-- | ares/ares_data.h | 62 | 
4 files changed, 216 insertions, 6 deletions
diff --git a/ares/Makefile.inc b/ares/Makefile.inc index 8d99afdcb..bf249344b 100644 --- a/ares/Makefile.inc +++ b/ares/Makefile.inc @@ -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			\ diff --git a/ares/ares.h b/ares/ares.h index 63eb6810e..d2b6cecc5 100644 --- a/ares/ares.h +++ b/ares/ares.h @@ -430,15 +430,17 @@ struct addr6ttl {  };  struct ares_srv_reply { -  unsigned short weight; -  unsigned short priority; -  unsigned short port; -  char *host; +  struct ares_srv_reply  *next; +  char                   *host; +  unsigned short          priority; +  unsigned short          weight; +  unsigned short          port;  };  struct ares_txt_reply { -  size_t         length;  /* length excludes null termination */ -  unsigned char *txt; +  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 diff --git a/ares/ares_data.c b/ares/ares_data.c new file mode 100644 index 000000000..5d710ee65 --- /dev/null +++ b/ares/ares_data.c @@ -0,0 +1,142 @@ +/* $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; +} diff --git a/ares/ares_data.h b/ares/ares_data.h new file mode 100644 index 000000000..ffe2aebb0 --- /dev/null +++ b/ares/ares_data.h @@ -0,0 +1,62 @@ +/* $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);  | 
