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 41void 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 114void *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 170ares_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