|
|
|
|
|
|
|
/* 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));
|
|
|
|
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;
|
|
|
|
|
|
|
|
#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;
|
|
|
|
}
|