Loading src/or/connection.c +2 −2 Original line number Diff line number Diff line Loading @@ -654,8 +654,8 @@ connection_free_(connection_t *conn) /** Make sure <b>conn</b> isn't in any of the global conn lists; then free it. */ void connection_free(connection_t *conn) MOCK_IMPL(void, connection_free,(connection_t *conn)) { if (!conn) return; Loading src/or/connection.h +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ listener_connection_t *listener_connection_new(int type, int socket_family); connection_t *connection_new(int type, int socket_family); void connection_link_connections(connection_t *conn_a, connection_t *conn_b); void connection_free(connection_t *conn); MOCK_DECL(void,connection_free,(connection_t *conn)); void connection_free_all(void); void connection_about_to_close_connection(connection_t *conn); void connection_close_immediate(connection_t *conn); Loading src/or/dns.c +14 −102 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ * be nonblocking.) **/ #define DNS_PRIVATE #include "or.h" #include "circuitlist.h" #include "circuituse.h" Loading Loading @@ -81,9 +83,6 @@ struct evdns_request; #endif /** Longest hostname we're willing to resolve. */ #define MAX_ADDRESSLEN 256 /** How long will we wait for an answer from the resolver before we decide * that the resolver is wedged? */ #define RESOLVE_MAX_TIMEOUT 300 Loading @@ -102,104 +101,16 @@ static char *resolv_conf_fname = NULL; * the nameservers? Used to check whether we need to reconfigure. */ static time_t resolv_conf_mtime = 0; /** Linked list of connections waiting for a DNS answer. */ typedef struct pending_connection_t { edge_connection_t *conn; struct pending_connection_t *next; } pending_connection_t; /** Value of 'magic' field for cached_resolve_t. Used to try to catch bad * pointers and memory stomping. */ #define CACHED_RESOLVE_MAGIC 0x1234F00D /* Possible states for a cached resolve_t */ /** We are waiting for the resolver system to tell us an answer here. * When we get one, or when we time out, the state of this cached_resolve_t * will become "DONE" and we'll possibly add a CACHED * entry. This cached_resolve_t will be in the hash table so that we will * know not to launch more requests for this addr, but rather to add more * connections to the pending list for the addr. */ #define CACHE_STATE_PENDING 0 /** This used to be a pending cached_resolve_t, and we got an answer for it. * Now we're waiting for this cached_resolve_t to expire. This should * have no pending connections, and should not appear in the hash table. */ #define CACHE_STATE_DONE 1 /** We are caching an answer for this address. This should have no pending * connections, and should appear in the hash table. */ #define CACHE_STATE_CACHED 2 /** @name status values for a single DNS request. * * @{ */ /** The DNS request is in progress. */ #define RES_STATUS_INFLIGHT 1 /** The DNS request finished and gave an answer */ #define RES_STATUS_DONE_OK 2 /** The DNS request finished and gave an error */ #define RES_STATUS_DONE_ERR 3 /**@}*/ /** A DNS request: possibly completed, possibly pending; cached_resolve * structs are stored at the OR side in a hash table, and as a linked * list from oldest to newest. */ typedef struct cached_resolve_t { HT_ENTRY(cached_resolve_t) node; uint32_t magic; /**< Must be CACHED_RESOLVE_MAGIC */ char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */ union { uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful. * (In host order.) */ int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */ } result_ipv4; /**< Outcome of IPv4 lookup */ union { struct in6_addr addr_ipv6; /**< IPv6 addr for <b>address</b>, if * successful */ int err_ipv6; /**< One of DNS_ERR_*, if IPv6 lookup failed. */ } result_ipv6; /**< Outcome of IPv6 lookup, if any */ union { char *hostname; /** A hostname, if PTR lookup happened successfully*/ int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */ } result_ptr; /** @name Status fields * * These take one of the RES_STATUS_* values, depending on the state * of the corresponding lookup. * * @{ */ unsigned int res_status_ipv4 : 2; unsigned int res_status_ipv6 : 2; unsigned int res_status_hostname : 2; /**@}*/ uint8_t state; /**< Is this cached entry pending/done/informative? */ time_t expire; /**< Remove items from cache after this time. */ uint32_t ttl_ipv4; /**< What TTL did the nameserver tell us? */ uint32_t ttl_ipv6; /**< What TTL did the nameserver tell us? */ uint32_t ttl_hostname; /**< What TTL did the nameserver tell us? */ /** Connections that want to know when we get an answer for this resolve. */ pending_connection_t *pending_connections; /** Position of this element in the heap*/ int minheap_idx; } cached_resolve_t; static void purge_expired_resolves(time_t now); static void dns_found_answer(const char *address, uint8_t query_type, int dns_answer, const tor_addr_t *addr, const char *hostname, uint32_t ttl); static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type, const cached_resolve_t *resolve); static int launch_resolve(cached_resolve_t *resolve); static void add_wildcarded_test_address(const char *address); static int configure_nameservers(int force); static int answer_is_wildcarded(const char *ip); static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, or_circuit_t *oncirc, char **resolved_to_hostname, int *made_connection_pending_out, cached_resolve_t **resolve_out); static int set_exitconn_info_from_resolve(edge_connection_t *exitconn, const cached_resolve_t *resolve, char **hostname_out); Loading Loading @@ -367,7 +278,7 @@ dns_clip_ttl(uint32_t ttl) /** Helper: Given a TTL from a DNS response, determine how long to hold it in * our cache. */ static uint32_t STATIC uint32_t dns_get_expiry_ttl(uint32_t ttl) { if (ttl < MIN_DNS_TTL) Loading Loading @@ -605,9 +516,9 @@ purge_expired_resolves(time_t now) * answer back along circ; otherwise, send the answer back along * <b>conn</b>'s attached circuit. */ static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type, const cached_resolve_t *resolved) MOCK_IMPL(STATIC void, send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type, const cached_resolve_t *resolved)) { char buf[RELAY_PAYLOAD_SIZE], *cp = buf; size_t buflen = 0; Loading Loading @@ -671,8 +582,9 @@ send_resolved_cell(edge_connection_t *conn, uint8_t answer_type, * answer back along circ; otherwise, send the answer back along * <b>conn</b>'s attached circuit. */ static void send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname) MOCK_IMPL(STATIC void, send_resolved_hostname_cell,(edge_connection_t *conn, const char *hostname)) { char buf[RELAY_PAYLOAD_SIZE]; size_t buflen; Loading Loading @@ -800,11 +712,11 @@ dns_resolve(edge_connection_t *exitconn) * * Set *<b>resolve_out</b> to a cached resolve, if we found one. */ static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, MOCK_IMPL(STATIC int, dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve, or_circuit_t *oncirc, char **hostname_out, int *made_connection_pending_out, cached_resolve_t **resolve_out) cached_resolve_t **resolve_out)) { cached_resolve_t *resolve; cached_resolve_t search; Loading Loading @@ -1145,8 +1057,8 @@ connection_dns_remove(edge_connection_t *conn) * the resolve for <b>address</b> itself, and remove any cached results for * <b>address</b> from the cache. */ void dns_cancel_pending_resolve(const char *address) MOCK_IMPL(void, dns_cancel_pending_resolve,(const char *address)) { pending_connection_t *pend; cached_resolve_t search; Loading src/or/dns.h +17 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ int dns_reset(void); void connection_dns_remove(edge_connection_t *conn); void assert_connection_edge_not_dns_pending(edge_connection_t *conn); void assert_all_pending_dns_resolves_ok(void); void dns_cancel_pending_resolve(const char *question); MOCK_DECL(void,dns_cancel_pending_resolve,(const char *question)); int dns_resolve(edge_connection_t *exitconn); void dns_launch_correctness_checks(void); int dns_seems_to_be_broken(void); Loading @@ -28,5 +28,21 @@ int dns_seems_to_be_broken_for_ipv6(void); void dns_reset_correctness_checks(void); void dump_dns_mem_usage(int severity); #ifdef DNS_PRIVATE #include "dns_structs.h" STATIC uint32_t dns_get_expiry_ttl(uint32_t ttl); MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve,or_circuit_t *oncirc, char **hostname_out, int *made_connection_pending_out, cached_resolve_t **resolve_out)); MOCK_DECL(STATIC void,send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type,const cached_resolve_t *resolved)); MOCK_DECL(STATIC void,send_resolved_hostname_cell,(edge_connection_t *conn, const char *hostname)); #endif #endif src/or/dns_structs.h 0 → 100644 +90 −0 Original line number Diff line number Diff line #ifndef TOR_DNS_STRUCTS_H #define TOR_DNS_STRUCTS_H /** Longest hostname we're willing to resolve. */ #define MAX_ADDRESSLEN 256 /** Linked list of connections waiting for a DNS answer. */ typedef struct pending_connection_t { edge_connection_t *conn; struct pending_connection_t *next; } pending_connection_t; /** Value of 'magic' field for cached_resolve_t. Used to try to catch bad * pointers and memory stomping. */ #define CACHED_RESOLVE_MAGIC 0x1234F00D /* Possible states for a cached resolve_t */ /** We are waiting for the resolver system to tell us an answer here. * When we get one, or when we time out, the state of this cached_resolve_t * will become "DONE" and we'll possibly add a CACHED * entry. This cached_resolve_t will be in the hash table so that we will * know not to launch more requests for this addr, but rather to add more * connections to the pending list for the addr. */ #define CACHE_STATE_PENDING 0 /** This used to be a pending cached_resolve_t, and we got an answer for it. * Now we're waiting for this cached_resolve_t to expire. This should * have no pending connections, and should not appear in the hash table. */ #define CACHE_STATE_DONE 1 /** We are caching an answer for this address. This should have no pending * connections, and should appear in the hash table. */ #define CACHE_STATE_CACHED 2 /** @name status values for a single DNS request. * * @{ */ /** The DNS request is in progress. */ #define RES_STATUS_INFLIGHT 1 /** The DNS request finished and gave an answer */ #define RES_STATUS_DONE_OK 2 /** The DNS request finished and gave an error */ #define RES_STATUS_DONE_ERR 3 /**@}*/ /** A DNS request: possibly completed, possibly pending; cached_resolve * structs are stored at the OR side in a hash table, and as a linked * list from oldest to newest. */ typedef struct cached_resolve_t { HT_ENTRY(cached_resolve_t) node; uint32_t magic; /**< Must be CACHED_RESOLVE_MAGIC */ char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */ union { uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful. * (In host order.) */ int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */ } result_ipv4; /**< Outcome of IPv4 lookup */ union { struct in6_addr addr_ipv6; /**< IPv6 addr for <b>address</b>, if * successful */ int err_ipv6; /**< One of DNS_ERR_*, if IPv6 lookup failed. */ } result_ipv6; /**< Outcome of IPv6 lookup, if any */ union { char *hostname; /** A hostname, if PTR lookup happened successfully*/ int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */ } result_ptr; /** @name Status fields * * These take one of the RES_STATUS_* values, depending on the state * of the corresponding lookup. * * @{ */ unsigned int res_status_ipv4 : 2; unsigned int res_status_ipv6 : 2; unsigned int res_status_hostname : 2; /**@}*/ uint8_t state; /**< Is this cached entry pending/done/informative? */ time_t expire; /**< Remove items from cache after this time. */ uint32_t ttl_ipv4; /**< What TTL did the nameserver tell us? */ uint32_t ttl_ipv6; /**< What TTL did the nameserver tell us? */ uint32_t ttl_hostname; /**< What TTL did the nameserver tell us? */ /** Connections that want to know when we get an answer for this resolve. */ pending_connection_t *pending_connections; /** Position of this element in the heap*/ int minheap_idx; } cached_resolve_t; #endif Loading
src/or/connection.c +2 −2 Original line number Diff line number Diff line Loading @@ -654,8 +654,8 @@ connection_free_(connection_t *conn) /** Make sure <b>conn</b> isn't in any of the global conn lists; then free it. */ void connection_free(connection_t *conn) MOCK_IMPL(void, connection_free,(connection_t *conn)) { if (!conn) return; Loading
src/or/connection.h +1 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ listener_connection_t *listener_connection_new(int type, int socket_family); connection_t *connection_new(int type, int socket_family); void connection_link_connections(connection_t *conn_a, connection_t *conn_b); void connection_free(connection_t *conn); MOCK_DECL(void,connection_free,(connection_t *conn)); void connection_free_all(void); void connection_about_to_close_connection(connection_t *conn); void connection_close_immediate(connection_t *conn); Loading
src/or/dns.c +14 −102 Original line number Diff line number Diff line Loading @@ -11,6 +11,8 @@ * be nonblocking.) **/ #define DNS_PRIVATE #include "or.h" #include "circuitlist.h" #include "circuituse.h" Loading Loading @@ -81,9 +83,6 @@ struct evdns_request; #endif /** Longest hostname we're willing to resolve. */ #define MAX_ADDRESSLEN 256 /** How long will we wait for an answer from the resolver before we decide * that the resolver is wedged? */ #define RESOLVE_MAX_TIMEOUT 300 Loading @@ -102,104 +101,16 @@ static char *resolv_conf_fname = NULL; * the nameservers? Used to check whether we need to reconfigure. */ static time_t resolv_conf_mtime = 0; /** Linked list of connections waiting for a DNS answer. */ typedef struct pending_connection_t { edge_connection_t *conn; struct pending_connection_t *next; } pending_connection_t; /** Value of 'magic' field for cached_resolve_t. Used to try to catch bad * pointers and memory stomping. */ #define CACHED_RESOLVE_MAGIC 0x1234F00D /* Possible states for a cached resolve_t */ /** We are waiting for the resolver system to tell us an answer here. * When we get one, or when we time out, the state of this cached_resolve_t * will become "DONE" and we'll possibly add a CACHED * entry. This cached_resolve_t will be in the hash table so that we will * know not to launch more requests for this addr, but rather to add more * connections to the pending list for the addr. */ #define CACHE_STATE_PENDING 0 /** This used to be a pending cached_resolve_t, and we got an answer for it. * Now we're waiting for this cached_resolve_t to expire. This should * have no pending connections, and should not appear in the hash table. */ #define CACHE_STATE_DONE 1 /** We are caching an answer for this address. This should have no pending * connections, and should appear in the hash table. */ #define CACHE_STATE_CACHED 2 /** @name status values for a single DNS request. * * @{ */ /** The DNS request is in progress. */ #define RES_STATUS_INFLIGHT 1 /** The DNS request finished and gave an answer */ #define RES_STATUS_DONE_OK 2 /** The DNS request finished and gave an error */ #define RES_STATUS_DONE_ERR 3 /**@}*/ /** A DNS request: possibly completed, possibly pending; cached_resolve * structs are stored at the OR side in a hash table, and as a linked * list from oldest to newest. */ typedef struct cached_resolve_t { HT_ENTRY(cached_resolve_t) node; uint32_t magic; /**< Must be CACHED_RESOLVE_MAGIC */ char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */ union { uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful. * (In host order.) */ int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */ } result_ipv4; /**< Outcome of IPv4 lookup */ union { struct in6_addr addr_ipv6; /**< IPv6 addr for <b>address</b>, if * successful */ int err_ipv6; /**< One of DNS_ERR_*, if IPv6 lookup failed. */ } result_ipv6; /**< Outcome of IPv6 lookup, if any */ union { char *hostname; /** A hostname, if PTR lookup happened successfully*/ int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */ } result_ptr; /** @name Status fields * * These take one of the RES_STATUS_* values, depending on the state * of the corresponding lookup. * * @{ */ unsigned int res_status_ipv4 : 2; unsigned int res_status_ipv6 : 2; unsigned int res_status_hostname : 2; /**@}*/ uint8_t state; /**< Is this cached entry pending/done/informative? */ time_t expire; /**< Remove items from cache after this time. */ uint32_t ttl_ipv4; /**< What TTL did the nameserver tell us? */ uint32_t ttl_ipv6; /**< What TTL did the nameserver tell us? */ uint32_t ttl_hostname; /**< What TTL did the nameserver tell us? */ /** Connections that want to know when we get an answer for this resolve. */ pending_connection_t *pending_connections; /** Position of this element in the heap*/ int minheap_idx; } cached_resolve_t; static void purge_expired_resolves(time_t now); static void dns_found_answer(const char *address, uint8_t query_type, int dns_answer, const tor_addr_t *addr, const char *hostname, uint32_t ttl); static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type, const cached_resolve_t *resolve); static int launch_resolve(cached_resolve_t *resolve); static void add_wildcarded_test_address(const char *address); static int configure_nameservers(int force); static int answer_is_wildcarded(const char *ip); static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, or_circuit_t *oncirc, char **resolved_to_hostname, int *made_connection_pending_out, cached_resolve_t **resolve_out); static int set_exitconn_info_from_resolve(edge_connection_t *exitconn, const cached_resolve_t *resolve, char **hostname_out); Loading Loading @@ -367,7 +278,7 @@ dns_clip_ttl(uint32_t ttl) /** Helper: Given a TTL from a DNS response, determine how long to hold it in * our cache. */ static uint32_t STATIC uint32_t dns_get_expiry_ttl(uint32_t ttl) { if (ttl < MIN_DNS_TTL) Loading Loading @@ -605,9 +516,9 @@ purge_expired_resolves(time_t now) * answer back along circ; otherwise, send the answer back along * <b>conn</b>'s attached circuit. */ static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type, const cached_resolve_t *resolved) MOCK_IMPL(STATIC void, send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type, const cached_resolve_t *resolved)) { char buf[RELAY_PAYLOAD_SIZE], *cp = buf; size_t buflen = 0; Loading Loading @@ -671,8 +582,9 @@ send_resolved_cell(edge_connection_t *conn, uint8_t answer_type, * answer back along circ; otherwise, send the answer back along * <b>conn</b>'s attached circuit. */ static void send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname) MOCK_IMPL(STATIC void, send_resolved_hostname_cell,(edge_connection_t *conn, const char *hostname)) { char buf[RELAY_PAYLOAD_SIZE]; size_t buflen; Loading Loading @@ -800,11 +712,11 @@ dns_resolve(edge_connection_t *exitconn) * * Set *<b>resolve_out</b> to a cached resolve, if we found one. */ static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve, MOCK_IMPL(STATIC int, dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve, or_circuit_t *oncirc, char **hostname_out, int *made_connection_pending_out, cached_resolve_t **resolve_out) cached_resolve_t **resolve_out)) { cached_resolve_t *resolve; cached_resolve_t search; Loading Loading @@ -1145,8 +1057,8 @@ connection_dns_remove(edge_connection_t *conn) * the resolve for <b>address</b> itself, and remove any cached results for * <b>address</b> from the cache. */ void dns_cancel_pending_resolve(const char *address) MOCK_IMPL(void, dns_cancel_pending_resolve,(const char *address)) { pending_connection_t *pend; cached_resolve_t search; Loading
src/or/dns.h +17 −1 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ int dns_reset(void); void connection_dns_remove(edge_connection_t *conn); void assert_connection_edge_not_dns_pending(edge_connection_t *conn); void assert_all_pending_dns_resolves_ok(void); void dns_cancel_pending_resolve(const char *question); MOCK_DECL(void,dns_cancel_pending_resolve,(const char *question)); int dns_resolve(edge_connection_t *exitconn); void dns_launch_correctness_checks(void); int dns_seems_to_be_broken(void); Loading @@ -28,5 +28,21 @@ int dns_seems_to_be_broken_for_ipv6(void); void dns_reset_correctness_checks(void); void dump_dns_mem_usage(int severity); #ifdef DNS_PRIVATE #include "dns_structs.h" STATIC uint32_t dns_get_expiry_ttl(uint32_t ttl); MOCK_DECL(STATIC int,dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve,or_circuit_t *oncirc, char **hostname_out, int *made_connection_pending_out, cached_resolve_t **resolve_out)); MOCK_DECL(STATIC void,send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type,const cached_resolve_t *resolved)); MOCK_DECL(STATIC void,send_resolved_hostname_cell,(edge_connection_t *conn, const char *hostname)); #endif #endif
src/or/dns_structs.h 0 → 100644 +90 −0 Original line number Diff line number Diff line #ifndef TOR_DNS_STRUCTS_H #define TOR_DNS_STRUCTS_H /** Longest hostname we're willing to resolve. */ #define MAX_ADDRESSLEN 256 /** Linked list of connections waiting for a DNS answer. */ typedef struct pending_connection_t { edge_connection_t *conn; struct pending_connection_t *next; } pending_connection_t; /** Value of 'magic' field for cached_resolve_t. Used to try to catch bad * pointers and memory stomping. */ #define CACHED_RESOLVE_MAGIC 0x1234F00D /* Possible states for a cached resolve_t */ /** We are waiting for the resolver system to tell us an answer here. * When we get one, or when we time out, the state of this cached_resolve_t * will become "DONE" and we'll possibly add a CACHED * entry. This cached_resolve_t will be in the hash table so that we will * know not to launch more requests for this addr, but rather to add more * connections to the pending list for the addr. */ #define CACHE_STATE_PENDING 0 /** This used to be a pending cached_resolve_t, and we got an answer for it. * Now we're waiting for this cached_resolve_t to expire. This should * have no pending connections, and should not appear in the hash table. */ #define CACHE_STATE_DONE 1 /** We are caching an answer for this address. This should have no pending * connections, and should appear in the hash table. */ #define CACHE_STATE_CACHED 2 /** @name status values for a single DNS request. * * @{ */ /** The DNS request is in progress. */ #define RES_STATUS_INFLIGHT 1 /** The DNS request finished and gave an answer */ #define RES_STATUS_DONE_OK 2 /** The DNS request finished and gave an error */ #define RES_STATUS_DONE_ERR 3 /**@}*/ /** A DNS request: possibly completed, possibly pending; cached_resolve * structs are stored at the OR side in a hash table, and as a linked * list from oldest to newest. */ typedef struct cached_resolve_t { HT_ENTRY(cached_resolve_t) node; uint32_t magic; /**< Must be CACHED_RESOLVE_MAGIC */ char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */ union { uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful. * (In host order.) */ int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */ } result_ipv4; /**< Outcome of IPv4 lookup */ union { struct in6_addr addr_ipv6; /**< IPv6 addr for <b>address</b>, if * successful */ int err_ipv6; /**< One of DNS_ERR_*, if IPv6 lookup failed. */ } result_ipv6; /**< Outcome of IPv6 lookup, if any */ union { char *hostname; /** A hostname, if PTR lookup happened successfully*/ int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */ } result_ptr; /** @name Status fields * * These take one of the RES_STATUS_* values, depending on the state * of the corresponding lookup. * * @{ */ unsigned int res_status_ipv4 : 2; unsigned int res_status_ipv6 : 2; unsigned int res_status_hostname : 2; /**@}*/ uint8_t state; /**< Is this cached entry pending/done/informative? */ time_t expire; /**< Remove items from cache after this time. */ uint32_t ttl_ipv4; /**< What TTL did the nameserver tell us? */ uint32_t ttl_ipv6; /**< What TTL did the nameserver tell us? */ uint32_t ttl_hostname; /**< What TTL did the nameserver tell us? */ /** Connections that want to know when we get an answer for this resolve. */ pending_connection_t *pending_connections; /** Position of this element in the heap*/ int minheap_idx; } cached_resolve_t; #endif