mirror of https://github.com/c-ares/c-ares.git
applications to free memory allocated and returned by some c-ares funtions.pull/1/head
parent
10461d1414
commit
2a916ce6e5
4 changed files with 216 additions and 6 deletions
@ -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; |
||||
} |
@ -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); |
Loading…
Reference in new issue