1 #ifndef __ARES_PRIVATE_H 2 #define __ARES_PRIVATE_H 3 4 5 /* Copyright 1998 by the Massachusetts Institute of Technology. 6 * Copyright (C) 2004-2010 by Daniel Stenberg 7 * 8 * Permission to use, copy, modify, and distribute this 9 * software and its documentation for any purpose and without 10 * fee is hereby granted, provided that the above copyright 11 * notice appear in all copies and that both that copyright 12 * notice and this permission notice appear in supporting 13 * documentation, and that the name of M.I.T. not be used in 14 * advertising or publicity pertaining to distribution of the 15 * software without specific, written prior permission. 16 * M.I.T. makes no representations about the suitability of 17 * this software for any purpose. It is provided "as is" 18 * without express or implied warranty. 19 */ 20 21 /* 22 * Define WIN32 when build target is Win32 API 23 */ 24 25 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) 26 #define WIN32 27 #endif 28 29 #ifdef HAVE_NETINET_IN_H 30 #include <netinet/in.h> 31 #endif 32 33 #ifdef WATT32 34 #include <tcp.h> 35 #include <sys/ioctl.h> 36 #define writev(s,v,c) writev_s(s,v,c) 37 #define HAVE_WRITEV 1 38 #endif 39 40 #define DEFAULT_TIMEOUT 5000 /* milliseconds */ 41 #define DEFAULT_TRIES 4 42 #ifndef INADDR_NONE 43 #define INADDR_NONE 0xffffffff 44 #endif 45 46 #ifdef CARES_EXPOSE_STATICS 47 /* Make some internal functions visible for testing */ 48 #define STATIC_TESTABLE 49 #else 50 #define STATIC_TESTABLE static 51 #endif 52 53 #if defined(WIN32) && !defined(WATT32) 54 55 #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" 56 #define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" 57 #define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient" 58 #define WIN_NT_DNSCLIENT "Software\\Policies\\Microsoft\\Windows NT\\DNSClient" 59 #define NAMESERVER "NameServer" 60 #define DHCPNAMESERVER "DhcpNameServer" 61 #define DATABASEPATH "DatabasePath" 62 #define WIN_PATH_HOSTS "\\hosts" 63 #define SEARCHLIST_KEY "SearchList" 64 #define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix" 65 #define INTERFACES_KEY "Interfaces" 66 #define DOMAIN_KEY "Domain" 67 #define DHCPDOMAIN_KEY "DhcpDomain" 68 69 #elif defined(WATT32) 70 71 #define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf" 72 73 #elif defined(NETWARE) 74 75 #define PATH_RESOLV_CONF "sys:/etc/resolv.cfg" 76 #define PATH_HOSTS "sys:/etc/hosts" 77 78 #elif defined(__riscos__) 79 80 #define PATH_HOSTS "InetDBase:Hosts" 81 82 #else 83 84 #define PATH_RESOLV_CONF "/etc/resolv.conf" 85 #ifdef ETC_INET 86 #define PATH_HOSTS "/etc/inet/hosts" 87 #else 88 #define PATH_HOSTS "/etc/hosts" 89 #endif 90 91 #endif 92 93 #define ARES_ID_KEY_LEN 31 94 95 #include "ares_ipv6.h" 96 #include "ares_llist.h" 97 98 #ifndef HAVE_GETENV 99 # include "ares_getenv.h" 100 # define getenv(ptr) ares_getenv(ptr) 101 #endif 102 103 #include "ares_strdup.h" 104 #include "ares_strsplit.h" 105 106 #ifndef HAVE_STRCASECMP 107 # include "ares_strcasecmp.h" 108 # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2) 109 #endif 110 111 #ifndef HAVE_STRNCASECMP 112 # include "ares_strcasecmp.h" 113 # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n) 114 #endif 115 116 #ifndef HAVE_WRITEV 117 # include "ares_writev.h" 118 # define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) 119 #endif 120 121 /********* EDNS defines section ******/ 122 #define EDNSPACKETSZ 1280 /* Reasonable UDP payload size, as suggested 123 in RFC2671 */ 124 #define MAXENDSSZ 4096 /* Maximum (local) limit for edns packet size */ 125 #define EDNSFIXEDSZ 11 /* Size of EDNS header */ 126 /********* EDNS defines section ******/ 127 128 struct ares_addr { 129 int family; 130 union { 131 struct in_addr addr4; 132 struct ares_in6_addr addr6; 133 } addr; 134 int udp_port; /* stored in network order */ 135 int tcp_port; /* stored in network order */ 136 }; 137 #define addrV4 addr.addr4 138 #define addrV6 addr.addr6 139 140 struct query; 141 142 struct send_request { 143 /* Remaining data to send */ 144 const unsigned char *data; 145 size_t len; 146 147 /* The query for which we're sending this data */ 148 struct query* owner_query; 149 /* The buffer we're using, if we have our own copy of the packet */ 150 unsigned char *data_storage; 151 152 /* Next request in queue */ 153 struct send_request *next; 154 }; 155 156 struct server_state { 157 struct ares_addr addr; 158 ares_socket_t udp_socket; 159 ares_socket_t tcp_socket; 160 161 /* Mini-buffer for reading the length word */ 162 unsigned char tcp_lenbuf[2]; 163 int tcp_lenbuf_pos; 164 int tcp_length; 165 166 /* Buffer for reading actual TCP data */ 167 unsigned char *tcp_buffer; 168 int tcp_buffer_pos; 169 170 /* TCP output queue */ 171 struct send_request *qhead; 172 struct send_request *qtail; 173 174 /* Which incarnation of this connection is this? We don't want to 175 * retransmit requests into the very same socket, but if the server 176 * closes on us and we re-open the connection, then we do want to 177 * re-send. */ 178 int tcp_connection_generation; 179 180 /* Circular, doubly-linked list of outstanding queries to this server */ 181 struct list_node queries_to_server; 182 183 /* Link back to owning channel */ 184 ares_channel channel; 185 186 /* Is this server broken? We mark connections as broken when a 187 * request that is queued for sending times out. 188 */ 189 int is_broken; 190 }; 191 192 /* State to represent a DNS query */ 193 struct query { 194 /* Query ID from qbuf, for faster lookup, and current timeout */ 195 unsigned short qid; 196 struct timeval timeout; 197 198 /* 199 * Links for the doubly-linked lists in which we insert a query. 200 * These circular, doubly-linked lists that are hash-bucketed based 201 * the attributes we care about, help making most important 202 * operations O(1). 203 */ 204 struct list_node queries_by_qid; /* hopefully in same cache line as qid */ 205 struct list_node queries_by_timeout; 206 struct list_node queries_to_server; 207 struct list_node all_queries; 208 209 /* Query buf with length at beginning, for TCP transmission */ 210 unsigned char *tcpbuf; 211 int tcplen; 212 213 /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ 214 const unsigned char *qbuf; 215 int qlen; 216 ares_callback callback; 217 void *arg; 218 219 /* Query status */ 220 int try_count; /* Number of times we tried this query already. */ 221 int server; /* Server this query has last been sent to. */ 222 struct query_server_info *server_info; /* per-server state */ 223 int using_tcp; 224 int error_status; 225 int timeouts; /* number of timeouts we saw for this request */ 226 }; 227 228 /* Per-server state for a query */ 229 struct query_server_info { 230 int skip_server; /* should we skip server, due to errors, etc? */ 231 int tcp_connection_generation; /* into which TCP connection did we send? */ 232 }; 233 234 /* An IP address pattern; matches an IP address X if X & mask == addr */ 235 #define PATTERN_MASK 0x1 236 #define PATTERN_CIDR 0x2 237 238 struct apattern { 239 union 240 { 241 struct in_addr addr4; 242 struct ares_in6_addr addr6; 243 } addr; 244 union 245 { 246 struct in_addr addr4; 247 struct ares_in6_addr addr6; 248 unsigned short bits; 249 } mask; 250 int family; 251 unsigned short type; 252 }; 253 254 typedef struct rc4_key 255 { 256 unsigned char state[256]; 257 unsigned char x; 258 unsigned char y; 259 } rc4_key; 260 261 struct ares_channeldata { 262 /* Configuration data */ 263 int flags; 264 int timeout; /* in milliseconds */ 265 int tries; 266 int ndots; 267 int rotate; /* if true, all servers specified are used */ 268 int udp_port; /* stored in network order */ 269 int tcp_port; /* stored in network order */ 270 int socket_send_buffer_size; 271 int socket_receive_buffer_size; 272 char **domains; 273 int ndomains; 274 struct apattern *sortlist; 275 int nsort; 276 char *lookups; 277 int ednspsz; 278 279 /* For binding to local devices and/or IP addresses. Leave 280 * them null/zero for no binding. 281 */ 282 char local_dev_name[32]; 283 unsigned int local_ip4; 284 unsigned char local_ip6[16]; 285 286 int optmask; /* the option bitfield passed in at init time */ 287 288 /* Server addresses and communications state */ 289 struct server_state *servers; 290 int nservers; 291 292 /* ID to use for next query */ 293 unsigned short next_id; 294 /* key to use when generating new ids */ 295 rc4_key id_key; 296 297 /* Generation number to use for the next TCP socket open/close */ 298 int tcp_connection_generation; 299 300 /* The time at which we last called process_timeouts(). Uses integer seconds 301 just to draw the line somewhere. */ 302 time_t last_timeout_processed; 303 304 /* Last server we sent a query to. */ 305 int last_server; 306 307 /* Circular, doubly-linked list of queries, bucketed various ways.... */ 308 /* All active queries in a single list: */ 309 struct list_node all_queries; 310 /* Queries bucketed by qid, for quickly dispatching DNS responses: */ 311 #define ARES_QID_TABLE_SIZE 2048 312 struct list_node queries_by_qid[ARES_QID_TABLE_SIZE]; 313 /* Queries bucketed by timeout, for quickly handling timeouts: */ 314 #define ARES_TIMEOUT_TABLE_SIZE 1024 315 struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE]; 316 317 ares_sock_state_cb sock_state_cb; 318 void *sock_state_cb_data; 319 320 ares_sock_create_callback sock_create_cb; 321 void *sock_create_cb_data; 322 323 ares_sock_config_callback sock_config_cb; 324 void *sock_config_cb_data; 325 326 const struct ares_socket_functions * sock_funcs; 327 void *sock_func_cb_data; 328 329 /* Path for resolv.conf file, configurable via ares_options */ 330 char *resolvconf_path; 331 }; 332 333 /* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ 334 int ares__is_onion_domain(const char *name); 335 336 /* Memory management functions */ 337 extern void *(*ares_malloc)(size_t size); 338 extern void *(*ares_realloc)(void *ptr, size_t size); 339 extern void (*ares_free)(void *ptr); 340 341 /* return true if now is exactly check time or later */ 342 int ares__timedout(struct timeval *now, 343 struct timeval *check); 344 345 void ares__send_query(ares_channel channel, struct query *query, 346 struct timeval *now); 347 void ares__close_sockets(ares_channel channel, struct server_state *server); 348 int ares__get_hostent(FILE *fp, int family, struct hostent **host); 349 int ares__read_line(FILE *fp, char **buf, size_t *bufsize); 350 void ares__free_query(struct query *query); 351 unsigned short ares__generate_new_id(rc4_key* key); 352 struct timeval ares__tvnow(void); 353 int ares__expand_name_for_response(const unsigned char *encoded, 354 const unsigned char *abuf, int alen, 355 char **s, long *enclen); 356 void ares__init_servers_state(ares_channel channel); 357 void ares__destroy_servers_state(ares_channel channel); 358 #if 0 /* Not used */ 359 long ares__tvdiff(struct timeval t1, struct timeval t2); 360 #endif 361 362 void ares__socket_close(ares_channel, ares_socket_t); 363 364 #define ARES_SWAP_BYTE(a,b) \ 365 { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; } 366 367 #define SOCK_STATE_CALLBACK(c, s, r, w) \ 368 do { \ 369 if ((c)->sock_state_cb) \ 370 (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \ 371 } WHILE_FALSE 372 373 #ifdef CURLDEBUG 374 /* This is low-level hard-hacking memory leak tracking and similar. Using the 375 libcurl lowlevel code from within library is ugly and only works when 376 c-ares is built and linked with a similarly curldebug-enabled libcurl, 377 but we do this anyway for convenience. */ 378 #define HEADER_CURL_SETUP_ONCE_H 379 #include "../lib/memdebug.h" 380 #endif 381 382 #endif /* __ARES_PRIVATE_H */ 383