1 /* Copyright (c) 2003-2004, Roger Dingledine. 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file dns_structs.h 8 * 9 * \brief Structures used in dns.c. Exposed to dns.c, and to the unit tests 10 * that declare DNS_PRIVATE. 11 */ 12 13 #ifndef TOR_DNS_STRUCTS_H 14 #define TOR_DNS_STRUCTS_H 15 16 #include "ext/ht.h" 17 18 /** Longest hostname we're willing to resolve. */ 19 #define MAX_ADDRESSLEN 256 20 21 /** Linked list of connections waiting for a DNS answer. */ 22 typedef struct pending_connection_t { 23 edge_connection_t *conn; 24 struct pending_connection_t *next; 25 } pending_connection_t; 26 27 /** Value of 'magic' field for cached_resolve_t. Used to try to catch bad 28 * pointers and memory stomping. */ 29 #define CACHED_RESOLVE_MAGIC 0x1234F00D 30 31 /* Possible states for a cached resolve_t */ 32 /** We are waiting for the resolver system to tell us an answer here. 33 * When we get one, or when we time out, the state of this cached_resolve_t 34 * will become "DONE" and we'll possibly add a CACHED 35 * entry. This cached_resolve_t will be in the hash table so that we will 36 * know not to launch more requests for this addr, but rather to add more 37 * connections to the pending list for the addr. */ 38 #define CACHE_STATE_PENDING 0 39 /** This used to be a pending cached_resolve_t, and we got an answer for it. 40 * Now we're waiting for this cached_resolve_t to expire. This should 41 * have no pending connections, and should not appear in the hash table. */ 42 #define CACHE_STATE_DONE 1 43 /** We are caching an answer for this address. This should have no pending 44 * connections, and should appear in the hash table. */ 45 #define CACHE_STATE_CACHED 2 46 47 /** @name status values for a single DNS request. 48 * 49 * @{ */ 50 /** The DNS request is in progress. */ 51 #define RES_STATUS_INFLIGHT 1 52 /** The DNS request finished and gave an answer */ 53 #define RES_STATUS_DONE_OK 2 54 /** The DNS request finished and gave an error */ 55 #define RES_STATUS_DONE_ERR 3 56 /**@}*/ 57 58 /** A DNS request: possibly completed, possibly pending; cached_resolve 59 * structs are stored at the OR side in a hash table, and as a linked 60 * list from oldest to newest. 61 */ 62 typedef struct cached_resolve_t { 63 HT_ENTRY(cached_resolve_t) node; 64 uint32_t magic; /**< Must be CACHED_RESOLVE_MAGIC */ 65 char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */ 66 67 union { 68 uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful. 69 * (In host order.) */ 70 int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */ 71 } result_ipv4; /**< Outcome of IPv4 lookup */ 72 union { 73 struct in6_addr addr_ipv6; /**< IPv6 addr for <b>address</b>, if 74 * successful */ 75 int err_ipv6; /**< One of DNS_ERR_*, if IPv6 lookup failed. */ 76 } result_ipv6; /**< Outcome of IPv6 lookup, if any */ 77 union { 78 char *hostname; /** A hostname, if PTR lookup happened successfully*/ 79 int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */ 80 } result_ptr; 81 /** @name Status fields 82 * 83 * These take one of the RES_STATUS_* values, depending on the state 84 * of the corresponding lookup. 85 * 86 * @{ */ 87 unsigned int res_status_ipv4 : 2; 88 unsigned int res_status_ipv6 : 2; 89 unsigned int res_status_hostname : 2; 90 /**@}*/ 91 uint8_t state; /**< Is this cached entry pending/done/informative? */ 92 93 time_t expire; /**< Remove items from cache after this time. */ 94 uint32_t ttl_ipv4; /**< What TTL did the nameserver tell us? */ 95 uint32_t ttl_ipv6; /**< What TTL did the nameserver tell us? */ 96 uint32_t ttl_hostname; /**< What TTL did the nameserver tell us? */ 97 /** Connections that want to know when we get an answer for this resolve. */ 98 pending_connection_t *pending_connections; 99 /** Position of this element in the heap*/ 100 int minheap_idx; 101 } cached_resolve_t; 102 103 #endif /* !defined(TOR_DNS_STRUCTS_H) */ 104