1 /* 2 * services/cache/infra.h - infrastructure cache, server rtt and capabilities 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * Redistributions of source code must retain the above copyright notice, 13 * this list of conditions and the following disclaimer. 14 * 15 * Redistributions in binary form must reproduce the above copyright notice, 16 * this list of conditions and the following disclaimer in the documentation 17 * and/or other materials provided with the distribution. 18 * 19 * Neither the name of the NLNET LABS nor the names of its contributors may 20 * be used to endorse or promote products derived from this software without 21 * specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36 /** 37 * \file 38 * 39 * This file contains the infrastructure cache. 40 */ 41 42 #ifndef SERVICES_CACHE_INFRA_H 43 #define SERVICES_CACHE_INFRA_H 44 #include "util/storage/lruhash.h" 45 #include "util/rtt.h" 46 struct slabhash; 47 struct config_file; 48 49 /** 50 * Host information kept for every server, per zone. 51 */ 52 struct infra_key { 53 /** the host address. */ 54 struct sockaddr_storage addr; 55 /** length of addr. */ 56 socklen_t addrlen; 57 /** zone name in wireformat */ 58 uint8_t* zonename; 59 /** length of zonename */ 60 size_t namelen; 61 /** hash table entry, data of type infra_data. */ 62 struct lruhash_entry entry; 63 }; 64 65 /** 66 * Host information encompasses host capabilities and retransmission timeouts. 67 * And lameness information (notAuthoritative, noEDNS, Recursive) 68 */ 69 struct infra_data { 70 /** TTL value for this entry. absolute time. */ 71 time_t ttl; 72 73 /** time in seconds (absolute) when probing re-commences, 0 disabled */ 74 time_t probedelay; 75 /** round trip times for timeout calculation */ 76 struct rtt_info rtt; 77 78 /** edns version that the host supports, -1 means no EDNS */ 79 int edns_version; 80 /** if the EDNS lameness is already known or not. 81 * EDNS lame is when EDNS queries or replies are dropped, 82 * and cause a timeout */ 83 uint8_t edns_lame_known; 84 85 /** is the host lame (does not serve the zone authoritatively), 86 * or is the host dnssec lame (does not serve DNSSEC data) */ 87 uint8_t isdnsseclame; 88 /** is the host recursion lame (not AA, but RA) */ 89 uint8_t rec_lame; 90 /** the host is lame (not authoritative) for A records */ 91 uint8_t lame_type_A; 92 /** the host is lame (not authoritative) for other query types */ 93 uint8_t lame_other; 94 95 /** timeouts counter for type A */ 96 uint8_t timeout_A; 97 /** timeouts counter for type AAAA */ 98 uint8_t timeout_AAAA; 99 /** timeouts counter for others */ 100 uint8_t timeout_other; 101 }; 102 103 /** 104 * Infra cache 105 */ 106 struct infra_cache { 107 /** The hash table with hosts */ 108 struct slabhash* hosts; 109 /** TTL value for host information, in seconds */ 110 int host_ttl; 111 }; 112 113 /** infra host cache default hash lookup size */ 114 #define INFRA_HOST_STARTSIZE 32 115 /** bytes per zonename reserved in the hostcache, dnamelen(zonename.com.) */ 116 #define INFRA_BYTES_NAME 14 117 118 /** 119 * Create infra cache. 120 * @param cfg: config parameters or NULL for defaults. 121 * @return: new infra cache, or NULL. 122 */ 123 struct infra_cache* infra_create(struct config_file* cfg); 124 125 /** 126 * Delete infra cache. 127 * @param infra: infrastructure cache to delete. 128 */ 129 void infra_delete(struct infra_cache* infra); 130 131 /** 132 * Adjust infra cache to use updated configuration settings. 133 * This may clean the cache. Operates a bit like realloc. 134 * There may be no threading or use by other threads. 135 * @param infra: existing cache. If NULL a new infra cache is returned. 136 * @param cfg: config options. 137 * @return the new infra cache pointer or NULL on error. 138 */ 139 struct infra_cache* infra_adjust(struct infra_cache* infra, 140 struct config_file* cfg); 141 142 /** 143 * Plain find infra data function (used by the the other functions) 144 * @param infra: infrastructure cache. 145 * @param addr: host address. 146 * @param addrlen: length of addr. 147 * @param name: domain name of zone. 148 * @param namelen: length of domain name. 149 * @param wr: if true, writelock, else readlock. 150 * @return the entry, could be expired (this is not checked) or NULL. 151 */ 152 struct lruhash_entry* infra_lookup_nottl(struct infra_cache* infra, 153 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, 154 size_t namelen, int wr); 155 156 /** 157 * Find host information to send a packet. Creates new entry if not found. 158 * Lameness is empty. EDNS is 0 (try with first), and rtt is returned for 159 * the first message to it. 160 * Use this to send a packet only, because it also locks out others when 161 * probing is restricted. 162 * @param infra: infrastructure cache. 163 * @param addr: host address. 164 * @param addrlen: length of addr. 165 * @param name: domain name of zone. 166 * @param namelen: length of domain name. 167 * @param timenow: what time it is now. 168 * @param edns_vs: edns version it supports, is returned. 169 * @param edns_lame_known: if EDNS lame (EDNS is dropped in transit) has 170 * already been probed, is returned. 171 * @param to: timeout to use, is returned. 172 * @return: 0 on error. 173 */ 174 int infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, 175 socklen_t addrlen, uint8_t* name, size_t namelen, 176 time_t timenow, int* edns_vs, uint8_t* edns_lame_known, int* to); 177 178 /** 179 * Set a host to be lame for the given zone. 180 * @param infra: infrastructure cache. 181 * @param addr: host address. 182 * @param addrlen: length of addr. 183 * @param name: domain name of zone apex. 184 * @param namelen: length of domain name. 185 * @param timenow: what time it is now. 186 * @param dnsseclame: if true the host is set dnssec lame. 187 * if false, the host is marked lame (not serving the zone). 188 * @param reclame: if true host is a recursor not AA server. 189 * if false, dnsseclame or marked lame. 190 * @param qtype: the query type for which it is lame. 191 * @return: 0 on error. 192 */ 193 int infra_set_lame(struct infra_cache* infra, 194 struct sockaddr_storage* addr, socklen_t addrlen, 195 uint8_t* name, size_t namelen, time_t timenow, int dnsseclame, 196 int reclame, uint16_t qtype); 197 198 /** 199 * Update rtt information for the host. 200 * @param infra: infrastructure cache. 201 * @param addr: host address. 202 * @param addrlen: length of addr. 203 * @param name: zone name 204 * @param namelen: zone name length 205 * @param qtype: query type. 206 * @param roundtrip: estimate of roundtrip time in milliseconds or -1 for 207 * timeout. 208 * @param orig_rtt: original rtt for the query that timed out (roundtrip==-1). 209 * ignored if roundtrip != -1. 210 * @param timenow: what time it is now. 211 * @return: 0 on error. new rto otherwise. 212 */ 213 int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, 214 socklen_t addrlen, uint8_t* name, size_t namelen, int qtype, 215 int roundtrip, int orig_rtt, time_t timenow); 216 217 /** 218 * Update information for the host, store that a TCP transaction works. 219 * @param infra: infrastructure cache. 220 * @param addr: host address. 221 * @param addrlen: length of addr. 222 * @param name: name of zone 223 * @param namelen: length of name 224 */ 225 void infra_update_tcp_works(struct infra_cache* infra, 226 struct sockaddr_storage* addr, socklen_t addrlen, 227 uint8_t* name, size_t namelen); 228 229 /** 230 * Update edns information for the host. 231 * @param infra: infrastructure cache. 232 * @param addr: host address. 233 * @param addrlen: length of addr. 234 * @param name: name of zone 235 * @param namelen: length of name 236 * @param edns_version: the version that it publishes. 237 * If it is known to support EDNS then no-EDNS is not stored over it. 238 * @param timenow: what time it is now. 239 * @return: 0 on error. 240 */ 241 int infra_edns_update(struct infra_cache* infra, 242 struct sockaddr_storage* addr, socklen_t addrlen, 243 uint8_t* name, size_t namelen, int edns_version, time_t timenow); 244 245 /** 246 * Get Lameness information and average RTT if host is in the cache. 247 * This information is to be used for server selection. 248 * @param infra: infrastructure cache. 249 * @param addr: host address. 250 * @param addrlen: length of addr. 251 * @param name: zone name. 252 * @param namelen: zone name length. 253 * @param qtype: the query to be made. 254 * @param lame: if function returns true, this returns lameness of the zone. 255 * @param dnsseclame: if function returns true, this returns if the zone 256 * is dnssec-lame. 257 * @param reclame: if function returns true, this is if it is recursion lame. 258 * @param rtt: if function returns true, this returns avg rtt of the server. 259 * The rtt value is unclamped and reflects recent timeouts. 260 * @param timenow: what time it is now. 261 * @return if found in cache, or false if not (or TTL bad). 262 */ 263 int infra_get_lame_rtt(struct infra_cache* infra, 264 struct sockaddr_storage* addr, socklen_t addrlen, 265 uint8_t* name, size_t namelen, uint16_t qtype, 266 int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow); 267 268 /** 269 * Get additional (debug) info on timing. 270 * @param infra: infra cache. 271 * @param addr: host address. 272 * @param addrlen: length of addr. 273 * @param name: zone name 274 * @param namelen: zone name length 275 * @param rtt: the rtt_info is copied into here (caller alloced return struct). 276 * @param delay: probe delay (if any). 277 * @param timenow: what time it is now. 278 * @param tA: timeout counter on type A. 279 * @param tAAAA: timeout counter on type AAAA. 280 * @param tother: timeout counter on type other. 281 * @return TTL the infra host element is valid for. If -1: not found in cache. 282 * TTL -2: found but expired. 283 */ 284 long long infra_get_host_rto(struct infra_cache* infra, 285 struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, 286 size_t namelen, struct rtt_info* rtt, int* delay, time_t timenow, 287 int* tA, int* tAAAA, int* tother); 288 289 /** 290 * Get memory used by the infra cache. 291 * @param infra: infrastructure cache. 292 * @return memory in use in bytes. 293 */ 294 size_t infra_get_mem(struct infra_cache* infra); 295 296 /** calculate size for the hashtable, does not count size of lameness, 297 * so the hashtable is a fixed number of items */ 298 size_t infra_sizefunc(void* k, void* d); 299 300 /** compare two addresses, returns -1, 0, or +1 */ 301 int infra_compfunc(void* key1, void* key2); 302 303 /** delete key, and destroy the lock */ 304 void infra_delkeyfunc(void* k, void* arg); 305 306 /** delete data and destroy the lameness hashtable */ 307 void infra_deldatafunc(void* d, void* arg); 308 309 #endif /* SERVICES_CACHE_INFRA_H */ 310