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