mirror of https://github.com/c-ares/c-ares.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
4.7 KiB
189 lines
4.7 KiB
|
|
/* Copyright (C) 2009-2010 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: |
|
** |
|
** ares_get_servers() |
|
** ares_parse_srv_reply() |
|
** ares_parse_txt_reply() |
|
*/ |
|
|
|
void ares_free_data(void *dataptr) |
|
{ |
|
struct ares_data *ptr; |
|
|
|
if (!dataptr) |
|
return; |
|
|
|
#ifdef __INTEL_COMPILER |
|
# pragma warning(push) |
|
# pragma warning(disable:1684) |
|
/* 1684: conversion from pointer to same-sized integral type */ |
|
#endif |
|
|
|
ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); |
|
|
|
#ifdef __INTEL_COMPILER |
|
# pragma warning(pop) |
|
#endif |
|
|
|
if (ptr->mark != ARES_DATATYPE_MARK) |
|
return; |
|
|
|
switch (ptr->type) |
|
{ |
|
case ARES_DATATYPE_MX_REPLY: |
|
|
|
if (ptr->data.mx_reply.next) |
|
ares_free_data(ptr->data.mx_reply.next); |
|
if (ptr->data.mx_reply.host) |
|
free(ptr->data.mx_reply.host); |
|
break; |
|
|
|
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; |
|
|
|
case ARES_DATATYPE_ADDR_NODE: |
|
|
|
if (ptr->data.addr_node.next) |
|
ares_free_data(ptr->data.addr_node.next); |
|
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_MX_REPLY: |
|
ptr->data.mx_reply.next = NULL; |
|
ptr->data.mx_reply.host = NULL; |
|
ptr->data.mx_reply.priority = 0; |
|
break; |
|
|
|
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; |
|
|
|
case ARES_DATATYPE_ADDR_NODE: |
|
ptr->data.addr_node.next = NULL; |
|
ptr->data.addr_node.family = 0; |
|
memset(&ptr->data.addr_node.addrV6, 0, |
|
sizeof(ptr->data.addr_node.addrV6)); |
|
|
|
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; |
|
|
|
#ifdef __INTEL_COMPILER |
|
# pragma warning(push) |
|
# pragma warning(disable:1684) |
|
/* 1684: conversion from pointer to same-sized integral type */ |
|
#endif |
|
|
|
ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); |
|
|
|
#ifdef __INTEL_COMPILER |
|
# pragma warning(pop) |
|
#endif |
|
|
|
if (ptr->mark == ARES_DATATYPE_MARK) |
|
return ptr->type; |
|
|
|
return ARES_DATATYPE_UNKNOWN; |
|
}
|
|
|