outside_network.h revision 256281
1/* 2 * services/outside_network.h - listen to answers from the network 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 LIMITED 25 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 * POSSIBILITY OF SUCH DAMAGE. 34 */ 35 36/** 37 * \file 38 * 39 * This file has functions to send queries to authoritative servers, 40 * and wait for the pending answer, with timeouts. 41 */ 42 43#ifndef OUTSIDE_NETWORK_H 44#define OUTSIDE_NETWORK_H 45 46#include "util/rbtree.h" 47#include "util/netevent.h" 48struct pending; 49struct pending_timeout; 50struct ub_randstate; 51struct pending_tcp; 52struct waiting_tcp; 53struct waiting_udp; 54struct infra_cache; 55struct port_comm; 56struct port_if; 57 58/** 59 * Send queries to outside servers and wait for answers from servers. 60 * Contains answer-listen sockets. 61 */ 62struct outside_network { 63 /** Base for select calls */ 64 struct comm_base* base; 65 /** pointer to time in seconds */ 66 uint32_t* now_secs; 67 /** pointer to time in microseconds */ 68 struct timeval* now_tv; 69 70 /** buffer shared by UDP connections, since there is only one 71 datagram at any time. */ 72 ldns_buffer* udp_buff; 73 /** serviced_callbacks malloc overhead when processing multiple 74 * identical serviced queries to the same server. */ 75 size_t svcd_overhead; 76 /** use x20 bits to encode additional ID random bits */ 77 int use_caps_for_id; 78 /** outside network wants to quit. Stop queued msgs from sent. */ 79 int want_to_quit; 80 81 /** number of unwanted replies received (for statistics) */ 82 size_t unwanted_replies; 83 /** cumulative total of unwanted replies (for defense) */ 84 size_t unwanted_total; 85 /** threshold when to take defensive action. If 0 then never. */ 86 size_t unwanted_threshold; 87 /** what action to take, called when defensive action is needed */ 88 void (*unwanted_action)(void*); 89 /** user param for action */ 90 void* unwanted_param; 91 92 /** linked list of available commpoints, unused file descriptors, 93 * for use as outgoing UDP ports. cp.fd=-1 in them. */ 94 struct port_comm* unused_fds; 95 /** if udp is done */ 96 int do_udp; 97 98 /** array of outgoing IP4 interfaces */ 99 struct port_if* ip4_ifs; 100 /** number of outgoing IP4 interfaces */ 101 int num_ip4; 102 103 /** array of outgoing IP6 interfaces */ 104 struct port_if* ip6_ifs; 105 /** number of outgoing IP6 interfaces */ 106 int num_ip6; 107 108 /** pending udp queries waiting to be sent out, waiting for fd */ 109 struct pending* udp_wait_first; 110 /** last pending udp query in list */ 111 struct pending* udp_wait_last; 112 113 /** pending udp answers. sorted by id, addr */ 114 rbtree_t* pending; 115 /** serviced queries, sorted by qbuf, addr, dnssec */ 116 rbtree_t* serviced; 117 /** host cache, pointer but not owned by outnet. */ 118 struct infra_cache* infra; 119 /** where to get random numbers */ 120 struct ub_randstate* rnd; 121 /** ssl context to create ssl wrapped TCP with DNS connections */ 122 void* sslctx; 123 124 /** 125 * Array of tcp pending used for outgoing TCP connections. 126 * Each can be used to establish a TCP connection with a server. 127 * The file descriptors are -1 if they are free, and need to be 128 * opened for the tcp connection. Can be used for ip4 and ip6. 129 */ 130 struct pending_tcp **tcp_conns; 131 /** number of tcp communication points. */ 132 size_t num_tcp; 133 /** list of tcp comm points that are free for use */ 134 struct pending_tcp* tcp_free; 135 /** list of tcp queries waiting for a buffer */ 136 struct waiting_tcp* tcp_wait_first; 137 /** last of waiting query list */ 138 struct waiting_tcp* tcp_wait_last; 139}; 140 141/** 142 * Outgoing interface. Ports available and currently used are tracked 143 * per interface 144 */ 145struct port_if { 146 /** address ready to allocate new socket (except port no). */ 147 struct sockaddr_storage addr; 148 /** length of addr field */ 149 socklen_t addrlen; 150 151 /** the available ports array. These are unused. 152 * Only the first total-inuse part is filled. */ 153 int* avail_ports; 154 /** the total number of available ports (size of the array) */ 155 int avail_total; 156 157 /** array of the commpoints currently in use. 158 * allocated for max number of fds, first part in use. */ 159 struct port_comm** out; 160 /** max number of fds, size of out array */ 161 int maxout; 162 /** number of commpoints (and thus also ports) in use */ 163 int inuse; 164}; 165 166/** 167 * Outgoing commpoint for UDP port. 168 */ 169struct port_comm { 170 /** next in free list */ 171 struct port_comm* next; 172 /** which port number (when in use) */ 173 int number; 174 /** interface it is used in */ 175 struct port_if* pif; 176 /** index in the out array of the interface */ 177 int index; 178 /** number of outstanding queries on this port */ 179 int num_outstanding; 180 /** UDP commpoint, fd=-1 if not in use */ 181 struct comm_point* cp; 182}; 183 184/** 185 * A query that has an answer pending for it. 186 */ 187struct pending { 188 /** redblacktree entry, key is the pending struct(id, addr). */ 189 rbnode_t node; 190 /** the ID for the query. int so that a value out of range can 191 * be used to signify a pending that is for certain not present in 192 * the rbtree. (and for which deletion is safe). */ 193 unsigned int id; 194 /** remote address. */ 195 struct sockaddr_storage addr; 196 /** length of addr field in use. */ 197 socklen_t addrlen; 198 /** comm point it was sent on (and reply must come back on). */ 199 struct port_comm* pc; 200 /** timeout event */ 201 struct comm_timer* timer; 202 /** callback for the timeout, error or reply to the message */ 203 comm_point_callback_t* cb; 204 /** callback user argument */ 205 void* cb_arg; 206 /** the outside network it is part of */ 207 struct outside_network* outnet; 208 209 /*---- filled if udp pending is waiting -----*/ 210 /** next in waiting list. */ 211 struct pending* next_waiting; 212 /** timeout in msec */ 213 int timeout; 214 /** The query itself, the query packet to send. */ 215 uint8_t* pkt; 216 /** length of query packet. */ 217 size_t pkt_len; 218}; 219 220/** 221 * Pending TCP query to server. 222 */ 223struct pending_tcp { 224 /** next in list of free tcp comm points, or NULL. */ 225 struct pending_tcp* next_free; 226 /** the ID for the query; checked in reply */ 227 uint16_t id; 228 /** tcp comm point it was sent on (and reply must come back on). */ 229 struct comm_point* c; 230 /** the query being serviced, NULL if the pending_tcp is unused. */ 231 struct waiting_tcp* query; 232}; 233 234/** 235 * Query waiting for TCP buffer. 236 */ 237struct waiting_tcp { 238 /** 239 * next in waiting list. 240 * if pkt==0, this points to the pending_tcp structure. 241 */ 242 struct waiting_tcp* next_waiting; 243 /** timeout event; timer keeps running whether the query is 244 * waiting for a buffer or the tcp reply is pending */ 245 struct comm_timer* timer; 246 /** the outside network it is part of */ 247 struct outside_network* outnet; 248 /** remote address. */ 249 struct sockaddr_storage addr; 250 /** length of addr field in use. */ 251 socklen_t addrlen; 252 /** 253 * The query itself, the query packet to send. 254 * allocated after the waiting_tcp structure. 255 * set to NULL when the query is serviced and it part of pending_tcp. 256 * if this is NULL, the next_waiting points to the pending_tcp. 257 */ 258 uint8_t* pkt; 259 /** length of query packet. */ 260 size_t pkt_len; 261 /** callback for the timeout, error or reply to the message */ 262 comm_point_callback_t* cb; 263 /** callback user argument */ 264 void* cb_arg; 265 /** if it uses ssl upstream */ 266 int ssl_upstream; 267}; 268 269/** 270 * Callback to party interested in serviced query results. 271 */ 272struct service_callback { 273 /** next in callback list */ 274 struct service_callback* next; 275 /** callback function */ 276 comm_point_callback_t* cb; 277 /** user argument for callback function */ 278 void* cb_arg; 279}; 280 281/** fallback size for fragmentation for EDNS in IPv4 */ 282#define EDNS_FRAG_SIZE_IP4 1472 283/** fallback size for EDNS in IPv6, fits one fragment with ip6-tunnel-ids */ 284#define EDNS_FRAG_SIZE_IP6 1232 285 286/** 287 * Query service record. 288 * Contains query and destination. UDP, TCP, EDNS are all tried. 289 * complete with retries and timeouts. A number of interested parties can 290 * receive a callback. 291 */ 292struct serviced_query { 293 /** The rbtree node, key is this record */ 294 rbnode_t node; 295 /** The query that needs to be answered. Starts with flags u16, 296 * then qdcount, ..., including qname, qtype, qclass. Does not include 297 * EDNS record. */ 298 uint8_t* qbuf; 299 /** length of qbuf. */ 300 size_t qbuflen; 301 /** If an EDNS section is included, the DO/CD bit will be turned on. */ 302 int dnssec; 303 /** We want signatures, or else the answer is likely useless */ 304 int want_dnssec; 305 /** tcp upstream used, use tcp, or ssl_upstream for SSL */ 306 int tcp_upstream, ssl_upstream; 307 /** where to send it */ 308 struct sockaddr_storage addr; 309 /** length of addr field in use. */ 310 socklen_t addrlen; 311 /** zone name, uncompressed domain name in wireformat */ 312 uint8_t* zone; 313 /** length of zone name */ 314 size_t zonelen; 315 /** qtype */ 316 int qtype; 317 /** current status */ 318 enum serviced_query_status { 319 /** initial status */ 320 serviced_initial, 321 /** UDP with EDNS sent */ 322 serviced_query_UDP_EDNS, 323 /** UDP without EDNS sent */ 324 serviced_query_UDP, 325 /** TCP with EDNS sent */ 326 serviced_query_TCP_EDNS, 327 /** TCP without EDNS sent */ 328 serviced_query_TCP, 329 /** probe to test EDNS lameness (EDNS is dropped) */ 330 serviced_query_PROBE_EDNS, 331 /** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */ 332 serviced_query_UDP_EDNS_fallback, 333 /** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */ 334 serviced_query_TCP_EDNS_fallback, 335 /** send UDP query with EDNS1480 (or 1280) */ 336 serviced_query_UDP_EDNS_FRAG 337 } 338 /** variable with current status */ 339 status; 340 /** true if serviced_query is scheduled for deletion already */ 341 int to_be_deleted; 342 /** number of UDP retries */ 343 int retry; 344 /** time last UDP was sent */ 345 struct timeval last_sent_time; 346 /** rtt of last (UDP) message */ 347 int last_rtt; 348 /** do we know edns probe status already, for UDP_EDNS queries */ 349 int edns_lame_known; 350 /** outside network this is part of */ 351 struct outside_network* outnet; 352 /** list of interested parties that need callback on results. */ 353 struct service_callback* cblist; 354 /** the UDP or TCP query that is pending, see status which */ 355 void* pending; 356}; 357 358/** 359 * Create outside_network structure with N udp ports. 360 * @param base: the communication base to use for event handling. 361 * @param bufsize: size for network buffers. 362 * @param num_ports: number of udp ports to open per interface. 363 * @param ifs: interface names (or NULL for default interface). 364 * These interfaces must be able to access all authoritative servers. 365 * @param num_ifs: number of names in array ifs. 366 * @param do_ip4: service IP4. 367 * @param do_ip6: service IP6. 368 * @param num_tcp: number of outgoing tcp buffers to preallocate. 369 * @param infra: pointer to infra cached used for serviced queries. 370 * @param rnd: stored to create random numbers for serviced queries. 371 * @param use_caps_for_id: enable to use 0x20 bits to encode id randomness. 372 * @param availports: array of available ports. 373 * @param numavailports: number of available ports in array. 374 * @param unwanted_threshold: when to take defensive action. 375 * @param unwanted_action: the action to take. 376 * @param unwanted_param: user parameter to action. 377 * @param do_udp: if udp is done. 378 * @param sslctx: context to create outgoing connections with (if enabled). 379 * @return: the new structure (with no pending answers) or NULL on error. 380 */ 381struct outside_network* outside_network_create(struct comm_base* base, 382 size_t bufsize, size_t num_ports, char** ifs, int num_ifs, 383 int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra, 384 struct ub_randstate* rnd, int use_caps_for_id, int* availports, 385 int numavailports, size_t unwanted_threshold, 386 void (*unwanted_action)(void*), void* unwanted_param, int do_udp, 387 void* sslctx); 388 389/** 390 * Delete outside_network structure. 391 * @param outnet: object to delete. 392 */ 393void outside_network_delete(struct outside_network* outnet); 394 395/** 396 * Prepare for quit. Sends no more queries, even if queued up. 397 * @param outnet: object to prepare for removal 398 */ 399void outside_network_quit_prepare(struct outside_network* outnet); 400 401/** 402 * Send UDP query, create pending answer. 403 * Changes the ID for the query to be random and unique for that destination. 404 * @param outnet: provides the event handling 405 * @param packet: wireformat query to send to destination. 406 * @param addr: address to send to. 407 * @param addrlen: length of addr. 408 * @param timeout: in milliseconds from now. 409 * @param callback: function to call on error, timeout or reply. 410 * @param callback_arg: user argument for callback function. 411 * @return: NULL on error for malloc or socket. Else the pending query object. 412 */ 413struct pending* pending_udp_query(struct outside_network* outnet, 414 ldns_buffer* packet, struct sockaddr_storage* addr, 415 socklen_t addrlen, int timeout, comm_point_callback_t* callback, 416 void* callback_arg); 417 418/** 419 * Send TCP query. May wait for TCP buffer. Selects ID to be random, and 420 * checks id. 421 * @param outnet: provides the event handling. 422 * @param packet: wireformat query to send to destination. copied from. 423 * @param addr: address to send to. 424 * @param addrlen: length of addr. 425 * @param timeout: in seconds from now. 426 * Timer starts running now. Timer may expire if all buffers are used, 427 * without any query been sent to the server yet. 428 * @param callback: function to call on error, timeout or reply. 429 * @param callback_arg: user argument for callback function. 430 * @param ssl_upstream: if the tcp connection must use SSL. 431 * @return: false on error for malloc or socket. Else the pending TCP object. 432 */ 433struct waiting_tcp* pending_tcp_query(struct outside_network* outnet, 434 ldns_buffer* packet, struct sockaddr_storage* addr, 435 socklen_t addrlen, int timeout, comm_point_callback_t* callback, 436 void* callback_arg, int ssl_upstream); 437 438/** 439 * Delete pending answer. 440 * @param outnet: outside network the pending query is part of. 441 * Internal feature: if outnet is NULL, p is not unlinked from rbtree. 442 * @param p: deleted 443 */ 444void pending_delete(struct outside_network* outnet, struct pending* p); 445 446/** 447 * Perform a serviced query to the authoritative servers. 448 * Duplicate efforts are detected, and EDNS, TCP and UDP retry is performed. 449 * @param outnet: outside network, with rbtree of serviced queries. 450 * @param qname: what qname to query. 451 * @param qnamelen: length of qname in octets including 0 root label. 452 * @param qtype: rrset type to query (host format) 453 * @param qclass: query class. (host format) 454 * @param flags: flags u16 (host format), includes opcode, CD bit. 455 * @param dnssec: if set, DO bit is set in EDNS queries. 456 * If the value includes BIT_CD, CD bit is set when in EDNS queries. 457 * If the value includes BIT_DO, DO bit is set when in EDNS queries. 458 * @param want_dnssec: signatures are needed, without EDNS the answer is 459 * likely to be useless. 460 * @param tcp_upstream: use TCP for upstream queries. 461 * @param ssl_upstream: use SSL for upstream queries. 462 * @param callback: callback function. 463 * @param callback_arg: user argument to callback function. 464 * @param addr: to which server to send the query. 465 * @param addrlen: length of addr. 466 * @param zone: name of the zone of the delegation point. wireformat dname. 467 This is the delegation point name for which the server is deemed 468 authoritative. 469 * @param zonelen: length of zone. 470 * @param buff: scratch buffer to create query contents in. Empty on exit. 471 * @return 0 on error, or pointer to serviced query that is used to answer 472 * this serviced query may be shared with other callbacks as well. 473 */ 474struct serviced_query* outnet_serviced_query(struct outside_network* outnet, 475 uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 476 uint16_t flags, int dnssec, int want_dnssec, int tcp_upstream, 477 int ssl_upstream, struct sockaddr_storage* addr, socklen_t addrlen, 478 uint8_t* zone, size_t zonelen, comm_point_callback_t* callback, 479 void* callback_arg, ldns_buffer* buff); 480 481/** 482 * Remove service query callback. 483 * If that leads to zero callbacks, the query is completely cancelled. 484 * @param sq: serviced query to adjust. 485 * @param cb_arg: callback argument of callback that needs removal. 486 * same as the callback_arg to outnet_serviced_query(). 487 */ 488void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg); 489 490/** 491 * Get memory size in use by outside network. 492 * Counts buffers and outstanding query (serviced queries) malloced data. 493 * @param outnet: outside network structure. 494 * @return size in bytes. 495 */ 496size_t outnet_get_mem(struct outside_network* outnet); 497 498/** 499 * Get memory size in use by serviced query while it is servicing callbacks. 500 * This takes into account the pre-deleted status of it; it will be deleted 501 * when the callbacks are done. 502 * @param sq: serviced query. 503 * @return size in bytes. 504 */ 505size_t serviced_get_mem(struct serviced_query* sq); 506 507/** callback for incoming udp answers from the network */ 508int outnet_udp_cb(struct comm_point* c, void* arg, int error, 509 struct comm_reply *reply_info); 510 511/** callback for pending tcp connections */ 512int outnet_tcp_cb(struct comm_point* c, void* arg, int error, 513 struct comm_reply *reply_info); 514 515/** callback for udp timeout */ 516void pending_udp_timer_cb(void *arg); 517 518/** callback for outgoing TCP timer event */ 519void outnet_tcptimer(void* arg); 520 521/** callback for serviced query UDP answers */ 522int serviced_udp_callback(struct comm_point* c, void* arg, int error, 523 struct comm_reply* rep); 524 525/** TCP reply or error callback for serviced queries */ 526int serviced_tcp_callback(struct comm_point* c, void* arg, int error, 527 struct comm_reply* rep); 528 529/** compare function of pending rbtree */ 530int pending_cmp(const void* key1, const void* key2); 531 532/** compare function of serviced query rbtree */ 533int serviced_cmp(const void* key1, const void* key2); 534 535#endif /* OUTSIDE_NETWORK_H */ 536