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 /* By using a double cast, we can get rid of the bogus warning of 54 * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align] 55 */ 56 #define CARES_INADDR_CAST(type, var) ((type)((void *)var)) 57 58 #if defined(WIN32) && !defined(WATT32) 59 60 #define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" 61 #define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" 62 #define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient" 63 #define WIN_NT_DNSCLIENT "Software\\Policies\\Microsoft\\Windows NT\\DNSClient" 64 #define NAMESERVER "NameServer" 65 #define DHCPNAMESERVER "DhcpNameServer" 66 #define DATABASEPATH "DatabasePath" 67 #define WIN_PATH_HOSTS "\\hosts" 68 #define SEARCHLIST_KEY "SearchList" 69 #define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix" 70 #define INTERFACES_KEY "Interfaces" 71 #define DOMAIN_KEY "Domain" 72 #define DHCPDOMAIN_KEY "DhcpDomain" 73 74 #elif defined(WATT32) 75 76 #define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf" 77 78 #elif defined(NETWARE) 79 80 #define PATH_RESOLV_CONF "sys:/etc/resolv.cfg" 81 #define PATH_HOSTS "sys:/etc/hosts" 82 83 #elif defined(__riscos__) 84 85 #define PATH_HOSTS "InetDBase:Hosts" 86 87 #else 88 89 #define PATH_RESOLV_CONF "/etc/resolv.conf" 90 #ifdef ETC_INET 91 #define PATH_HOSTS "/etc/inet/hosts" 92 #else 93 #define PATH_HOSTS "/etc/hosts" 94 #endif 95 96 #endif 97 98 #define ARES_ID_KEY_LEN 31 99 100 #include "ares_ipv6.h" 101 #include "ares_llist.h" 102 103 #ifndef HAVE_GETENV 104 # include "ares_getenv.h" 105 # define getenv(ptr) ares_getenv(ptr) 106 #endif 107 108 #include "ares_strdup.h" 109 #include "ares_strsplit.h" 110 111 #ifndef HAVE_STRCASECMP 112 # include "ares_strcasecmp.h" 113 # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2) 114 #endif 115 116 #ifndef HAVE_STRNCASECMP 117 # include "ares_strcasecmp.h" 118 # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n) 119 #endif 120 121 #ifndef HAVE_WRITEV 122 # include "ares_writev.h" 123 # define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) 124 #endif 125 126 /********* EDNS defines section ******/ 127 #define EDNSPACKETSZ 1280 /* Reasonable UDP payload size, as suggested 128 in RFC2671 */ 129 #define MAXENDSSZ 4096 /* Maximum (local) limit for edns packet size */ 130 #define EDNSFIXEDSZ 11 /* Size of EDNS header */ 131 /********* EDNS defines section ******/ 132 133 struct ares_addr { 134 int family; 135 union { 136 struct in_addr addr4; 137 struct ares_in6_addr addr6; 138 } addr; 139 int udp_port; /* stored in network order */ 140 int tcp_port; /* stored in network order */ 141 }; 142 #define addrV4 addr.addr4 143 #define addrV6 addr.addr6 144 145 struct query; 146 147 struct send_request { 148 /* Remaining data to send */ 149 const unsigned char *data; 150 size_t len; 151 152 /* The query for which we're sending this data */ 153 struct query* owner_query; 154 /* The buffer we're using, if we have our own copy of the packet */ 155 unsigned char *data_storage; 156 157 /* Next request in queue */ 158 struct send_request *next; 159 }; 160 161 struct server_state { 162 struct ares_addr addr; 163 ares_socket_t udp_socket; 164 ares_socket_t tcp_socket; 165 166 /* Mini-buffer for reading the length word */ 167 unsigned char tcp_lenbuf[2]; 168 int tcp_lenbuf_pos; 169 int tcp_length; 170 171 /* Buffer for reading actual TCP data */ 172 unsigned char *tcp_buffer; 173 int tcp_buffer_pos; 174 175 /* TCP output queue */ 176 struct send_request *qhead; 177 struct send_request *qtail; 178 179 /* Which incarnation of this connection is this? We don't want to 180 * retransmit requests into the very same socket, but if the server 181 * closes on us and we re-open the connection, then we do want to 182 * re-send. */ 183 int tcp_connection_generation; 184 185 /* Circular, doubly-linked list of outstanding queries to this server */ 186 struct list_node queries_to_server; 187 188 /* Link back to owning channel */ 189 ares_channel channel; 190 191 /* Is this server broken? We mark connections as broken when a 192 * request that is queued for sending times out. 193 */ 194 int is_broken; 195 }; 196 197 /* State to represent a DNS query */ 198 struct query { 199 /* Query ID from qbuf, for faster lookup, and current timeout */ 200 unsigned short qid; 201 struct timeval timeout; 202 203 /* 204 * Links for the doubly-linked lists in which we insert a query. 205 * These circular, doubly-linked lists that are hash-bucketed based 206 * the attributes we care about, help making most important 207 * operations O(1). 208 */ 209 struct list_node queries_by_qid; /* hopefully in same cache line as qid */ 210 struct list_node queries_by_timeout; 211 struct list_node queries_to_server; 212 struct list_node all_queries; 213 214 /* Query buf with length at beginning, for TCP transmission */ 215 unsigned char *tcpbuf; 216 int tcplen; 217 218 /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ 219 const unsigned char *qbuf; 220 int qlen; 221 ares_callback callback; 222 void *arg; 223 224 /* Query status */ 225 int try_count; /* Number of times we tried this query already. */ 226 int server; /* Server this query has last been sent to. */ 227 struct query_server_info *server_info; /* per-server state */ 228 int using_tcp; 229 int error_status; 230 int timeouts; /* number of timeouts we saw for this request */ 231 }; 232 233 /* Per-server state for a query */ 234 struct query_server_info { 235 int skip_server; /* should we skip server, due to errors, etc? */ 236 int tcp_connection_generation; /* into which TCP connection did we send? */ 237 }; 238 239 /* An IP address pattern; matches an IP address X if X & mask == addr */ 240 #define PATTERN_MASK 0x1 241 #define PATTERN_CIDR 0x2 242 243 struct apattern { 244 union 245 { 246 struct in_addr addr4; 247 struct ares_in6_addr addr6; 248 } addr; 249 union 250 { 251 struct in_addr addr4; 252 struct ares_in6_addr addr6; 253 unsigned short bits; 254 } mask; 255 int family; 256 unsigned short type; 257 }; 258 259 typedef struct rc4_key 260 { 261 unsigned char state[256]; 262 unsigned char x; 263 unsigned char y; 264 } rc4_key; 265 266 struct ares_channeldata { 267 /* Configuration data */ 268 int flags; 269 int timeout; /* in milliseconds */ 270 int tries; 271 int ndots; 272 int rotate; /* if true, all servers specified are used */ 273 int udp_port; /* stored in network order */ 274 int tcp_port; /* stored in network order */ 275 int socket_send_buffer_size; 276 int socket_receive_buffer_size; 277 char **domains; 278 int ndomains; 279 struct apattern *sortlist; 280 int nsort; 281 char *lookups; 282 int ednspsz; 283 284 /* For binding to local devices and/or IP addresses. Leave 285 * them null/zero for no binding. 286 */ 287 char local_dev_name[32]; 288 unsigned int local_ip4; 289 unsigned char local_ip6[16]; 290 291 int optmask; /* the option bitfield passed in at init time */ 292 293 /* Server addresses and communications state */ 294 struct server_state *servers; 295 int nservers; 296 297 /* ID to use for next query */ 298 unsigned short next_id; 299 /* key to use when generating new ids */ 300 rc4_key id_key; 301 302 /* Generation number to use for the next TCP socket open/close */ 303 int tcp_connection_generation; 304 305 /* The time at which we last called process_timeouts(). Uses integer seconds 306 just to draw the line somewhere. */ 307 time_t last_timeout_processed; 308 309 /* Last server we sent a query to. */ 310 int last_server; 311 312 /* Circular, doubly-linked list of queries, bucketed various ways.... */ 313 /* All active queries in a single list: */ 314 struct list_node all_queries; 315 /* Queries bucketed by qid, for quickly dispatching DNS responses: */ 316 #define ARES_QID_TABLE_SIZE 2048 317 struct list_node queries_by_qid[ARES_QID_TABLE_SIZE]; 318 /* Queries bucketed by timeout, for quickly handling timeouts: */ 319 #define ARES_TIMEOUT_TABLE_SIZE 1024 320 struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE]; 321 322 ares_sock_state_cb sock_state_cb; 323 void *sock_state_cb_data; 324 325 ares_sock_create_callback sock_create_cb; 326 void *sock_create_cb_data; 327 328 ares_sock_config_callback sock_config_cb; 329 void *sock_config_cb_data; 330 331 const struct ares_socket_functions * sock_funcs; 332 void *sock_func_cb_data; 333 334 /* Path for resolv.conf file, configurable via ares_options */ 335 char *resolvconf_path; 336 }; 337 338 /* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ 339 int ares__is_onion_domain(const char *name); 340 341 /* Memory management functions */ 342 extern void *(*ares_malloc)(size_t size); 343 extern void *(*ares_realloc)(void *ptr, size_t size); 344 extern void (*ares_free)(void *ptr); 345 346 /* return true if now is exactly check time or later */ 347 int ares__timedout(struct timeval *now, 348 struct timeval *check); 349 350 void ares__send_query(ares_channel channel, struct query *query, 351 struct timeval *now); 352 void ares__close_sockets(ares_channel channel, struct server_state *server); 353 int ares__get_hostent(FILE *fp, int family, struct hostent **host); 354 int ares__read_line(FILE *fp, char **buf, size_t *bufsize); 355 void ares__free_query(struct query *query); 356 unsigned short ares__generate_new_id(rc4_key* key); 357 struct timeval ares__tvnow(void); 358 int ares__expand_name_for_response(const unsigned char *encoded, 359 const unsigned char *abuf, int alen, 360 char **s, long *enclen); 361 void ares__init_servers_state(ares_channel channel); 362 void ares__destroy_servers_state(ares_channel channel); 363 int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype); 364 int ares__single_domain(ares_channel channel, const char *name, char **s); 365 int ares__cat_domain(const char *name, const char *domain, char **s); 366 int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *ai_node); 367 int ares__readaddrinfo(FILE *fp, const char *name, unsigned short port, 368 const struct ares_addrinfo_hints *hints, 369 struct ares_addrinfo *ai); 370 371 struct ares_addrinfo *ares__malloc_addrinfo(void); 372 373 struct ares_addrinfo_node *ares__malloc_addrinfo_node(void); 374 void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node); 375 376 struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node); 377 void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head, 378 struct ares_addrinfo_node *tail); 379 380 struct ares_addrinfo_cname *ares__malloc_addrinfo_cname(void); 381 void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname); 382 383 struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname); 384 385 void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head, 386 struct ares_addrinfo_cname *tail); 387 388 int ares__parse_into_addrinfo(const unsigned char *abuf, 389 int alen, 390 struct ares_addrinfo *ai); 391 392 int ares__parse_into_addrinfo2(const unsigned char *abuf, 393 int alen, 394 char **question_hostname, 395 struct ares_addrinfo *ai); 396 397 #if 0 /* Not used */ 398 long ares__tvdiff(struct timeval t1, struct timeval t2); 399 #endif 400 401 ares_socket_t ares__open_socket(ares_channel channel, 402 int af, int type, int protocol); 403 void ares__close_socket(ares_channel, ares_socket_t); 404 int ares__connect_socket(ares_channel channel, 405 ares_socket_t sockfd, 406 const struct sockaddr *addr, 407 ares_socklen_t addrlen); 408 409 #define ARES_SWAP_BYTE(a,b) \ 410 { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; } 411 412 #define SOCK_STATE_CALLBACK(c, s, r, w) \ 413 do { \ 414 if ((c)->sock_state_cb) \ 415 (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \ 416 } WHILE_FALSE 417 418 #ifdef CURLDEBUG 419 /* This is low-level hard-hacking memory leak tracking and similar. Using the 420 libcurl lowlevel code from within library is ugly and only works when 421 c-ares is built and linked with a similarly curldebug-enabled libcurl, 422 but we do this anyway for convenience. */ 423 #define HEADER_CURL_SETUP_ONCE_H 424 #include "../lib/memdebug.h" 425 #endif 426 427 #endif /* __ARES_PRIVATE_H */ 428