Home | History | Annotate | Download | only in c-ares
      1 
      2 /* Copyright (C) 2009-2010 by Daniel Stenberg
      3  *
      4  * Permission to use, copy, modify, and distribute this
      5  * software and its documentation for any purpose and without
      6  * fee is hereby granted, provided that the above copyright
      7  * notice appear in all copies and that both that copyright
      8  * notice and this permission notice appear in supporting
      9  * documentation, and that the name of M.I.T. not be used in
     10  * advertising or publicity pertaining to distribution of the
     11  * software without specific, written prior permission.
     12  * M.I.T. makes no representations about the suitability of
     13  * this software for any purpose.  It is provided "as is"
     14  * without express or implied warranty.
     15  */
     16 
     17 
     18 #include "ares_setup.h"
     19 
     20 #include <stddef.h>
     21 
     22 #include "ares.h"
     23 #include "ares_data.h"
     24 #include "ares_private.h"
     25 
     26 
     27 /*
     28 ** ares_free_data() - c-ares external API function.
     29 **
     30 ** This function must be used by the application to free data memory that
     31 ** has been internally allocated by some c-ares function and for which a
     32 ** pointer has already been returned to the calling application. The list
     33 ** of c-ares functions returning pointers that must be free'ed using this
     34 ** function is:
     35 **
     36 **   ares_get_servers()
     37 **   ares_parse_srv_reply()
     38 **   ares_parse_txt_reply()
     39 */
     40 
     41 void ares_free_data(void *dataptr)
     42 {
     43   struct ares_data *ptr;
     44 
     45   if (!dataptr)
     46     return;
     47 
     48 #ifdef __INTEL_COMPILER
     49 #  pragma warning(push)
     50 #  pragma warning(disable:1684)
     51    /* 1684: conversion from pointer to same-sized integral type */
     52 #endif
     53 
     54   ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
     55 
     56 #ifdef __INTEL_COMPILER
     57 #  pragma warning(pop)
     58 #endif
     59 
     60   if (ptr->mark != ARES_DATATYPE_MARK)
     61     return;
     62 
     63   switch (ptr->type)
     64     {
     65       case ARES_DATATYPE_MX_REPLY:
     66 
     67         if (ptr->data.mx_reply.next)
     68           ares_free_data(ptr->data.mx_reply.next);
     69         if (ptr->data.mx_reply.host)
     70           free(ptr->data.mx_reply.host);
     71         break;
     72 
     73       case ARES_DATATYPE_SRV_REPLY:
     74 
     75         if (ptr->data.srv_reply.next)
     76           ares_free_data(ptr->data.srv_reply.next);
     77         if (ptr->data.srv_reply.host)
     78           free(ptr->data.srv_reply.host);
     79         break;
     80 
     81       case ARES_DATATYPE_TXT_REPLY:
     82 
     83         if (ptr->data.txt_reply.next)
     84           ares_free_data(ptr->data.txt_reply.next);
     85         if (ptr->data.txt_reply.txt)
     86           free(ptr->data.txt_reply.txt);
     87         break;
     88 
     89       case ARES_DATATYPE_ADDR_NODE:
     90 
     91         if (ptr->data.addr_node.next)
     92           ares_free_data(ptr->data.addr_node.next);
     93         break;
     94 
     95       default:
     96         return;
     97     }
     98 
     99   free(ptr);
    100 }
    101 
    102 
    103 /*
    104 ** ares_malloc_data() - c-ares internal helper function.
    105 **
    106 ** This function allocates memory for a c-ares private ares_data struct
    107 ** for the specified ares_datatype, initializes c-ares private fields
    108 ** and zero initializes those which later might be used from the public
    109 ** API. It returns an interior pointer which can be passed by c-ares
    110 ** functions to the calling application, and that must be free'ed using
    111 ** c-ares external API function ares_free_data().
    112 */
    113 
    114 void *ares_malloc_data(ares_datatype type)
    115 {
    116   struct ares_data *ptr;
    117 
    118   ptr = malloc(sizeof(struct ares_data));
    119   if (!ptr)
    120     return NULL;
    121 
    122   switch (type)
    123     {
    124       case ARES_DATATYPE_MX_REPLY:
    125         ptr->data.mx_reply.next = NULL;
    126         ptr->data.mx_reply.host = NULL;
    127         ptr->data.mx_reply.priority = 0;
    128         break;
    129 
    130       case ARES_DATATYPE_SRV_REPLY:
    131         ptr->data.srv_reply.next = NULL;
    132         ptr->data.srv_reply.host = NULL;
    133         ptr->data.srv_reply.priority = 0;
    134         ptr->data.srv_reply.weight = 0;
    135         ptr->data.srv_reply.port = 0;
    136         break;
    137 
    138       case ARES_DATATYPE_TXT_REPLY:
    139         ptr->data.txt_reply.next = NULL;
    140         ptr->data.txt_reply.txt = NULL;
    141         ptr->data.txt_reply.length  = 0;
    142         break;
    143 
    144       case ARES_DATATYPE_ADDR_NODE:
    145         ptr->data.addr_node.next = NULL;
    146         ptr->data.addr_node.family = 0;
    147         memset(&ptr->data.addr_node.addrV6, 0,
    148                sizeof(ptr->data.addr_node.addrV6));
    149         break;
    150 
    151       default:
    152         free(ptr);
    153         return NULL;
    154     }
    155 
    156   ptr->mark = ARES_DATATYPE_MARK;
    157   ptr->type = type;
    158 
    159   return &ptr->data;
    160 }
    161 
    162 
    163 /*
    164 ** ares_get_datatype() - c-ares internal helper function.
    165 **
    166 ** This function returns the ares_datatype of the data stored in a
    167 ** private ares_data struct when given the public API pointer.
    168 */
    169 
    170 ares_datatype ares_get_datatype(void * dataptr)
    171 {
    172   struct ares_data *ptr;
    173 
    174 #ifdef __INTEL_COMPILER
    175 #  pragma warning(push)
    176 #  pragma warning(disable:1684)
    177    /* 1684: conversion from pointer to same-sized integral type */
    178 #endif
    179 
    180   ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data));
    181 
    182 #ifdef __INTEL_COMPILER
    183 #  pragma warning(pop)
    184 #endif
    185 
    186   if (ptr->mark == ARES_DATATYPE_MARK)
    187     return ptr->type;
    188 
    189   return ARES_DATATYPE_UNKNOWN;
    190 }
    191