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 #define ARES_ID_KEY_LEN 31 105 106 #include "ares_ipv6.h" 107 #include "ares_llist.h" 108 109 #ifndef HAVE_GETENV 110 # include "ares_getenv.h" 111 # define getenv(ptr) ares_getenv(ptr) 112 #endif 113 114 #include "ares_strdup.h" 115 #include "ares_strsplit.h" 116 117 #ifndef HAVE_STRCASECMP 118 # include "ares_strcasecmp.h" 119 # define strcasecmp(p1,p2) ares_strcasecmp(p1,p2) 120 #endif 121 122 #ifndef HAVE_STRNCASECMP 123 # include "ares_strcasecmp.h" 124 # define strncasecmp(p1,p2,n) ares_strncasecmp(p1,p2,n) 125 #endif 126 127 #ifndef HAVE_WRITEV 128 # include "ares_writev.h" 129 # define writev(s,ptr,cnt) ares_writev(s,ptr,cnt) 130 #endif 131 132 /********* EDNS defines section ******/ 133 #define EDNSPACKETSZ 1280 /* Reasonable UDP payload size, as suggested 134 in RFC2671 */ 135 #define MAXENDSSZ 4096 /* Maximum (local) limit for edns packet size */ 136 #define EDNSFIXEDSZ 11 /* Size of EDNS header */ 137 /********* EDNS defines section ******/ 138 139 struct ares_addr { 140 int family; 141 union { 142 struct in_addr addr4; 143 struct ares_in6_addr addr6; 144 } addr; 145 int udp_port; /* stored in network order */ 146 int tcp_port; /* stored in network order */ 147 }; 148 #define addrV4 addr.addr4 149 #define addrV6 addr.addr6 150 151 struct query; 152 153 struct send_request { 154 /* Remaining data to send */ 155 const unsigned char *data; 156 size_t len; 157 158 /* The query for which we're sending this data */ 159 struct query* owner_query; 160 /* The buffer we're using, if we have our own copy of the packet */ 161 unsigned char *data_storage; 162 163 /* Next request in queue */ 164 struct send_request *next; 165 }; 166 167 struct server_state { 168 struct ares_addr addr; 169 ares_socket_t udp_socket; 170 ares_socket_t tcp_socket; 171 172 /* Mini-buffer for reading the length word */ 173 unsigned char tcp_lenbuf[2]; 174 int tcp_lenbuf_pos; 175 int tcp_length; 176 177 /* Buffer for reading actual TCP data */ 178 unsigned char *tcp_buffer; 179 int tcp_buffer_pos; 180 181 /* TCP output queue */ 182 struct send_request *qhead; 183 struct send_request *qtail; 184 185 /* Which incarnation of this connection is this? We don't want to 186 * retransmit requests into the very same socket, but if the server 187 * closes on us and we re-open the connection, then we do want to 188 * re-send. */ 189 int tcp_connection_generation; 190 191 /* Circular, doubly-linked list of outstanding queries to this server */ 192 struct list_node queries_to_server; 193 194 /* Link back to owning channel */ 195 ares_channel channel; 196 197 /* Is this server broken? We mark connections as broken when a 198 * request that is queued for sending times out. 199 */ 200 int is_broken; 201 }; 202 203 /* State to represent a DNS query */ 204 struct query { 205 /* Query ID from qbuf, for faster lookup, and current timeout */ 206 unsigned short qid; 207 struct timeval timeout; 208 209 /* 210 * Links for the doubly-linked lists in which we insert a query. 211 * These circular, doubly-linked lists that are hash-bucketed based 212 * the attributes we care about, help making most important 213 * operations O(1). 214 */ 215 struct list_node queries_by_qid; /* hopefully in same cache line as qid */ 216 struct list_node queries_by_timeout; 217 struct list_node queries_to_server; 218 struct list_node all_queries; 219 220 /* Query buf with length at beginning, for TCP transmission */ 221 unsigned char *tcpbuf; 222 int tcplen; 223 224 /* Arguments passed to ares_send() (qbuf points into tcpbuf) */ 225 const unsigned char *qbuf; 226 int qlen; 227 ares_callback callback; 228 void *arg; 229 230 /* Query status */ 231 int try_count; /* Number of times we tried this query already. */ 232 int server; /* Server this query has last been sent to. */ 233 struct query_server_info *server_info; /* per-server state */ 234 int using_tcp; 235 int error_status; 236 int timeouts; /* number of timeouts we saw for this request */ 237 }; 238 239 /* Per-server state for a query */ 240 struct query_server_info { 241 int skip_server; /* should we skip server, due to errors, etc? */ 242 int tcp_connection_generation; /* into which TCP connection did we send? */ 243 }; 244 245 /* An IP address pattern; matches an IP address X if X & mask == addr */ 246 #define PATTERN_MASK 0x1 247 #define PATTERN_CIDR 0x2 248 249 struct apattern { 250 union 251 { 252 struct in_addr addr4; 253 struct ares_in6_addr addr6; 254 } addr; 255 union 256 { 257 struct in_addr addr4; 258 struct ares_in6_addr addr6; 259 unsigned short bits; 260 } mask; 261 int family; 262 unsigned short type; 263 }; 264 265 typedef struct rc4_key 266 { 267 unsigned char state[256]; 268 unsigned char x; 269 unsigned char y; 270 } rc4_key; 271 272 struct ares_channeldata { 273 /* Configuration data */ 274 int flags; 275 int timeout; /* in milliseconds */ 276 int tries; 277 int ndots; 278 int rotate; /* if true, all servers specified are used */ 279 int udp_port; /* stored in network order */ 280 int tcp_port; /* stored in network order */ 281 int socket_send_buffer_size; 282 int socket_receive_buffer_size; 283 char **domains; 284 int ndomains; 285 struct apattern *sortlist; 286 int nsort; 287 char *lookups; 288 int ednspsz; 289 290 /* For binding to local devices and/or IP addresses. Leave 291 * them null/zero for no binding. 292 */ 293 char local_dev_name[32]; 294 unsigned int local_ip4; 295 unsigned char local_ip6[16]; 296 297 int optmask; /* the option bitfield passed in at init time */ 298 299 /* Server addresses and communications state */ 300 struct server_state *servers; 301 int nservers; 302 303 /* ID to use for next query */ 304 unsigned short next_id; 305 /* key to use when generating new ids */ 306 rc4_key id_key; 307 308 /* Generation number to use for the next TCP socket open/close */ 309 int tcp_connection_generation; 310 311 /* The time at which we last called process_timeouts(). Uses integer seconds 312 just to draw the line somewhere. */ 313 time_t last_timeout_processed; 314 315 /* Last server we sent a query to. */ 316 int last_server; 317 318 /* Circular, doubly-linked list of queries, bucketed various ways.... */ 319 /* All active queries in a single list: */ 320 struct list_node all_queries; 321 /* Queries bucketed by qid, for quickly dispatching DNS responses: */ 322 #define ARES_QID_TABLE_SIZE 2048 323 struct list_node queries_by_qid[ARES_QID_TABLE_SIZE]; 324 /* Queries bucketed by timeout, for quickly handling timeouts: */ 325 #define ARES_TIMEOUT_TABLE_SIZE 1024 326 struct list_node queries_by_timeout[ARES_TIMEOUT_TABLE_SIZE]; 327 328 ares_sock_state_cb sock_state_cb; 329 void *sock_state_cb_data; 330 331 ares_sock_create_callback sock_create_cb; 332 void *sock_create_cb_data; 333 334 ares_sock_config_callback sock_config_cb; 335 void *sock_config_cb_data; 336 337 const struct ares_socket_functions * sock_funcs; 338 void *sock_func_cb_data; 339 340 /* Path for resolv.conf file, configurable via ares_options */ 341 char *resolvconf_path; 342 }; 343 344 /* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ 345 int ares__is_onion_domain(const char *name); 346 347 /* Memory management functions */ 348 extern void *(*ares_malloc)(size_t size); 349 extern void *(*ares_realloc)(void *ptr, size_t size); 350 extern void (*ares_free)(void *ptr); 351 352 /* return true if now is exactly check time or later */ 353 int ares__timedout(struct timeval *now, 354 struct timeval *check); 355 356 void ares__send_query(ares_channel channel, struct query *query, 357 struct timeval *now); 358 void ares__close_sockets(ares_channel channel, struct server_state *server); 359 int ares__get_hostent(FILE *fp, int family, struct hostent **host); 360 int ares__read_line(FILE *fp, char **buf, size_t *bufsize); 361 void ares__free_query(struct query *query); 362 unsigned short ares__generate_new_id(rc4_key* key); 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