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 W32_FUNC const char *_w32_GetHostsFile (void); 78 79 #elif defined(NETWARE) 80 81 #define PATH_RESOLV_CONF "sys:/etc/resolv.cfg" 82 #define PATH_HOSTS "sys:/etc/hosts" 83 84 #elif defined(__riscos__) 85 86 #define PATH_HOSTS "InetDBase:Hosts" 87 88 #elif defined(__HAIKU__) 89 90 #define PATH_RESOLV_CONF "/system/settings/network/resolv.conf" 91 #define PATH_HOSTS "/system/settings/network/hosts" 92 93 #else 94 95 #define PATH_RESOLV_CONF "/etc/resolv.conf" 96 #ifdef ETC_INET 97 #define PATH_HOSTS "/etc/inet/hosts" 98 #else 99 #define PATH_HOSTS "/etc/hosts" 100 #endif 101 102 #endif 103 104 #include "ares_ipv6.h" 105 #include "ares_llist.h" 106 107 #ifndef HAVE_GETENV 108 # include "ares_getenv.h" 109 # define getenv(ptr) ares_getenv(ptr) 110 #endif 111 112 #include "ares_strdup.h" 113 #include "ares_strsplit.h" 114 115 #ifndef HAVE_STRCASECMP 116 # include "ares_strcasecmp.h" 117 # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2) 118 #endif 119 120 #ifndef HAVE_STRNCASECMP 121 # include "ares_strcasecmp.h" 122 # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n) 123 #endif 124 125 #ifndef HAVE_WRITEV 126 # include "ares_writev.h" 127 # define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) 128 #endif 129 130 /********* EDNS defines section ******/ 131 #define EDNSPACKETSZ 1280 /* Reasonable UDP payload size, as suggested 132 in RFC2671 */ 133 #define MAXENDSSZ 4096 /* Maximum (local) limit for edns packet size */ 134 #define EDNSFIXEDSZ 11 /* Size of EDNS header */ 135 /********* EDNS defines section ******/ 136 137 struct ares_addr { 138 int family; 139 union { 140 struct in_addr addr4; 141 struct ares_in6_addr addr6; 142 } addr; 143 int udp_port; /* stored in network order */ 144 int tcp_port; /* stored in network order */ 145 }; 146 #define addrV4 addr.addr4 147 #define addrV6 addr.addr6 148 149 struct query; 150 151 struct send_request { 152 /* Remaining data to send */ 153 const unsigned char *data; 154 size_t len; 155 156 /* The query for which we're sending this data */ 157 struct query* owner_query; 158 /* The buffer we're using, if we have our own copy of the packet */ 159 unsigned char *data_storage; 160 161 /* Next request in queue */ 162 struct send_request *next; 163 }; 164 165 struct server_state { 166 struct ares_addr addr; 167 ares_socket_t udp_socket; 168 ares_socket_t tcp_socket; 169 170 /* Mini-buffer for reading the length word */ 171 unsigned char tcp_lenbuf[2]; 172 int tcp_lenbuf_pos; 173 int tcp_length; 174 175 /* Buffer for reading actual TCP data */ 176 unsigned char *tcp_buffer; 177 int tcp_buffer_pos; 178 179 /* TCP output queue */ 180 struct send_request *qhead; 181 struct send_request *qtail; 182 183 /* Which incarnation of this connection is this? We don't want to 184 * retransmit requests into the very same socket, but if the server 185 * closes on us and we re-open the connection, then we do want to 186 * re-send. */ 187 int tcp_connection_generation; 188 189 /* Circular, doubly-linked list of outstanding queries to this server */ 190 struct list_node queries_to_server; 191 192 /* Link back to owning channel */ 193 ares_channel channel; 194 195 /* Is this server broken? We mark connections as broken when a 196 * request that is queued for sending times out. 197 */ 198 int is_broken; 199 }; 200 201 /* State to represent a DNS query */ 202 struct query { 203 /* Query ID from qbuf, for faster lookup, and current timeout */ 204 unsigned short qid; 205 struct timeval timeout; 206 207 /* 208 * Links for the doubly-linked lists in which we insert a query. 209 * These circular, doubly-linked lists that are hash-bucketed based 210 * the attributes we care about, help making most important 211 * operations O(1). 212 */ 213 struct list_node queries_by_qid; /* hopefully in same cache line as qid */ 214 struct list_node queries_by_timeout; 215 struct list_node queries_to_server; 216 struct list_node all_queries; 217 218 /* Query buf with length at beginning, for TCP transmission */ 219 unsigned char *tcpbuf; 220 int tcplen; 221 222 /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ 223 const unsigned char *qbuf; 224 int qlen; 225 ares_callback callback; 226 void *arg; 227 228 /* Query status */ 229 int try_count; /* Number of times we tried this query already. */ 230 int server; /* Server this query has last been sent to. */ 231 struct query_server_info *server_info; /* per-server state */ 232 int using_tcp; 233 int error_status; 234 int timeouts; /* number of timeouts we saw for this request */ 235 }; 236 237 /* Per-server state for a query */ 238 struct query_server_info { 239 int skip_server; /* should we skip server, due to errors, etc? */ 240 int tcp_connection_generation; /* into which TCP connection did we send? */ 241 }; 242 243 /* An IP address pattern; matches an IP address X if X & mask == addr */ 244 #define PATTERN_MASK 0x1 245 #define PATTERN_CIDR 0x2 246 247 struct apattern { 248 union 249 { 250 struct in_addr addr4; 251 struct ares_in6_addr addr6; 252 } addr; 253 union 254 { 255 struct in_addr addr4; 256 struct ares_in6_addr addr6; 257 unsigned short bits; 258 } mask; 259 int family; 260 unsigned short type; 261 }; 262 263 struct ares_rand_state; 264 typedef struct ares_rand_state ares_rand_state; 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 /* random state to use when generating new ids */ 300 ares_rand_state *rand_state; 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 /* Path for hosts file, configurable via ares_options */ 338 char *hosts_path; 339 }; 340 341 /* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ 342 int ares__is_onion_domain(const char *name); 343 344 /* Memory management functions */ 345 extern void *(*ares_malloc)(size_t size); 346 extern void *(*ares_realloc)(void *ptr, size_t size); 347 extern void (*ares_free)(void *ptr); 348 349 /* return true if now is exactly check time or later */ 350 int ares__timedout(struct timeval *now, 351 struct timeval *check); 352 353 void ares__send_query(ares_channel channel, struct query *query, 354 struct timeval *now); 355 void ares__close_sockets(ares_channel channel, struct server_state *server); 356 int ares__get_hostent(FILE *fp, int family, struct hostent **host); 357 int ares__read_line(FILE *fp, char **buf, size_t *bufsize); 358 void ares__free_query(struct query *query); 359 360 ares_rand_state *ares__init_rand_state(void); 361 void ares__destroy_rand_state(ares_rand_state *state); 362 unsigned short ares__generate_new_id(ares_rand_state *state); 363 struct timeval ares__tvnow(void); 364 int ares__expand_name_validated(const unsigned char *encoded, 365 const unsigned char *abuf, 366 int alen, char **s, long *enclen, 367 int is_hostname); 368 int ares__expand_name_for_response(const unsigned char *encoded, 369 const unsigned char *abuf, int alen, 370 char **s, long *enclen, int is_hostname); 371 void ares__init_servers_state(ares_channel channel); 372 void ares__destroy_servers_state(ares_channel channel); 373 int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype); 374 int ares__single_domain(ares_channel channel, const char *name, char **s); 375 int ares__cat_domain(const char *name, const char *domain, char **s); 376 int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *ai_node); 377 int ares__readaddrinfo(FILE *fp, const char *name, unsigned short port, 378 const struct ares_addrinfo_hints *hints, 379 struct ares_addrinfo *ai); 380 381 struct ares_addrinfo *ares__malloc_addrinfo(void); 382 383 struct ares_addrinfo_node *ares__malloc_addrinfo_node(void); 384 void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node); 385 386 struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node); 387 void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head, 388 struct ares_addrinfo_node *tail); 389 390 struct ares_addrinfo_cname *ares__malloc_addrinfo_cname(void); 391 void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname); 392 393 struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname); 394 395 int ares_append_ai_node(int aftype, unsigned short port, int ttl, 396 const void *adata, 397 struct ares_addrinfo_node **nodes); 398 399 void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head, 400 struct ares_addrinfo_cname *tail); 401 402 int ares__parse_into_addrinfo(const unsigned char *abuf, 403 int alen, int cname_only_is_enodata, 404 unsigned short port, 405 struct ares_addrinfo *ai); 406 407 int ares__addrinfo2hostent(const struct ares_addrinfo *ai, int family, 408 struct hostent **host); 409 int ares__addrinfo2addrttl(const struct ares_addrinfo *ai, int family, 410 int req_naddrttls, struct ares_addrttl *addrttls, 411 struct ares_addr6ttl *addr6ttls, int *naddrttls); 412 int ares__addrinfo_localhost(const char *name, unsigned short port, 413 const struct ares_addrinfo_hints *hints, 414 struct ares_addrinfo *ai); 415 416 #if 0 /* Not used */ 417 long ares__tvdiff(struct timeval t1, struct timeval t2); 418 #endif 419 420 ares_socket_t ares__open_socket(ares_channel channel, 421 int af, int type, int protocol); 422 void ares__close_socket(ares_channel, ares_socket_t); 423 int ares__connect_socket(ares_channel channel, 424 ares_socket_t sockfd, 425 const struct sockaddr *addr, 426 ares_socklen_t addrlen); 427 428 #define ARES_SWAP_BYTE(a,b) \ 429 { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; } 430 431 #define SOCK_STATE_CALLBACK(c, s, r, w) \ 432 do { \ 433 if ((c)->sock_state_cb) \ 434 (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \ 435 } WHILE_FALSE 436 437 #endif /* __ARES_PRIVATE_H */ 438