1933707f3Ssthen /* 2933707f3Ssthen * services/outside_network.h - listen to answers from the network 3933707f3Ssthen * 4933707f3Ssthen * Copyright (c) 2007, NLnet Labs. All rights reserved. 5933707f3Ssthen * 6933707f3Ssthen * This software is open source. 7933707f3Ssthen * 8933707f3Ssthen * Redistribution and use in source and binary forms, with or without 9933707f3Ssthen * modification, are permitted provided that the following conditions 10933707f3Ssthen * are met: 11933707f3Ssthen * 12933707f3Ssthen * Redistributions of source code must retain the above copyright notice, 13933707f3Ssthen * this list of conditions and the following disclaimer. 14933707f3Ssthen * 15933707f3Ssthen * Redistributions in binary form must reproduce the above copyright notice, 16933707f3Ssthen * this list of conditions and the following disclaimer in the documentation 17933707f3Ssthen * and/or other materials provided with the distribution. 18933707f3Ssthen * 19933707f3Ssthen * Neither the name of the NLNET LABS nor the names of its contributors may 20933707f3Ssthen * be used to endorse or promote products derived from this software without 21933707f3Ssthen * specific prior written permission. 22933707f3Ssthen * 23933707f3Ssthen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 245d76a658Ssthen * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 255d76a658Ssthen * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 265d76a658Ssthen * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 275d76a658Ssthen * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 285d76a658Ssthen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 295d76a658Ssthen * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 305d76a658Ssthen * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 315d76a658Ssthen * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 325d76a658Ssthen * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 335d76a658Ssthen * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34933707f3Ssthen */ 35933707f3Ssthen 36933707f3Ssthen /** 37933707f3Ssthen * \file 38933707f3Ssthen * 39933707f3Ssthen * This file has functions to send queries to authoritative servers, 40933707f3Ssthen * and wait for the pending answer, with timeouts. 41933707f3Ssthen */ 42933707f3Ssthen 43933707f3Ssthen #ifndef OUTSIDE_NETWORK_H 44933707f3Ssthen #define OUTSIDE_NETWORK_H 45933707f3Ssthen 46933707f3Ssthen #include "util/rbtree.h" 47933707f3Ssthen #include "util/netevent.h" 4898f3ca02Sbrad #include "dnstap/dnstap_config.h" 49933707f3Ssthen struct pending; 50933707f3Ssthen struct pending_timeout; 51933707f3Ssthen struct ub_randstate; 52933707f3Ssthen struct pending_tcp; 53933707f3Ssthen struct waiting_tcp; 54933707f3Ssthen struct waiting_udp; 55933707f3Ssthen struct infra_cache; 56933707f3Ssthen struct port_comm; 57933707f3Ssthen struct port_if; 585d76a658Ssthen struct sldns_buffer; 5998f3ca02Sbrad struct serviced_query; 6098f3ca02Sbrad struct dt_env; 61*2ee382b6Ssthen struct edns_option; 62933707f3Ssthen 63933707f3Ssthen /** 64933707f3Ssthen * Send queries to outside servers and wait for answers from servers. 65933707f3Ssthen * Contains answer-listen sockets. 66933707f3Ssthen */ 67933707f3Ssthen struct outside_network { 68933707f3Ssthen /** Base for select calls */ 69933707f3Ssthen struct comm_base* base; 70933707f3Ssthen /** pointer to time in seconds */ 71229e174cSsthen time_t* now_secs; 72933707f3Ssthen /** pointer to time in microseconds */ 73933707f3Ssthen struct timeval* now_tv; 74933707f3Ssthen 75933707f3Ssthen /** buffer shared by UDP connections, since there is only one 76933707f3Ssthen datagram at any time. */ 775d76a658Ssthen struct sldns_buffer* udp_buff; 78933707f3Ssthen /** serviced_callbacks malloc overhead when processing multiple 79933707f3Ssthen * identical serviced queries to the same server. */ 80933707f3Ssthen size_t svcd_overhead; 81933707f3Ssthen /** use x20 bits to encode additional ID random bits */ 82933707f3Ssthen int use_caps_for_id; 83933707f3Ssthen /** outside network wants to quit. Stop queued msgs from sent. */ 84933707f3Ssthen int want_to_quit; 85933707f3Ssthen 86933707f3Ssthen /** number of unwanted replies received (for statistics) */ 87933707f3Ssthen size_t unwanted_replies; 88933707f3Ssthen /** cumulative total of unwanted replies (for defense) */ 89933707f3Ssthen size_t unwanted_total; 90933707f3Ssthen /** threshold when to take defensive action. If 0 then never. */ 91933707f3Ssthen size_t unwanted_threshold; 92933707f3Ssthen /** what action to take, called when defensive action is needed */ 93933707f3Ssthen void (*unwanted_action)(void*); 94933707f3Ssthen /** user param for action */ 95933707f3Ssthen void* unwanted_param; 96933707f3Ssthen 97933707f3Ssthen /** linked list of available commpoints, unused file descriptors, 98933707f3Ssthen * for use as outgoing UDP ports. cp.fd=-1 in them. */ 99933707f3Ssthen struct port_comm* unused_fds; 100933707f3Ssthen /** if udp is done */ 101933707f3Ssthen int do_udp; 1025d76a658Ssthen /** if udp is delay-closed (delayed answers do not meet closed port)*/ 1035d76a658Ssthen int delayclose; 1045d76a658Ssthen /** timeout for delayclose */ 1055d76a658Ssthen struct timeval delay_tv; 106933707f3Ssthen 107933707f3Ssthen /** array of outgoing IP4 interfaces */ 108933707f3Ssthen struct port_if* ip4_ifs; 109933707f3Ssthen /** number of outgoing IP4 interfaces */ 110933707f3Ssthen int num_ip4; 111933707f3Ssthen 112933707f3Ssthen /** array of outgoing IP6 interfaces */ 113933707f3Ssthen struct port_if* ip6_ifs; 114933707f3Ssthen /** number of outgoing IP6 interfaces */ 115933707f3Ssthen int num_ip6; 116933707f3Ssthen 117933707f3Ssthen /** pending udp queries waiting to be sent out, waiting for fd */ 118933707f3Ssthen struct pending* udp_wait_first; 119933707f3Ssthen /** last pending udp query in list */ 120933707f3Ssthen struct pending* udp_wait_last; 121933707f3Ssthen 122933707f3Ssthen /** pending udp answers. sorted by id, addr */ 123933707f3Ssthen rbtree_t* pending; 124933707f3Ssthen /** serviced queries, sorted by qbuf, addr, dnssec */ 125933707f3Ssthen rbtree_t* serviced; 126933707f3Ssthen /** host cache, pointer but not owned by outnet. */ 127933707f3Ssthen struct infra_cache* infra; 128933707f3Ssthen /** where to get random numbers */ 129933707f3Ssthen struct ub_randstate* rnd; 130933707f3Ssthen /** ssl context to create ssl wrapped TCP with DNS connections */ 131933707f3Ssthen void* sslctx; 13298f3ca02Sbrad #ifdef USE_DNSTAP 13398f3ca02Sbrad /** dnstap environment */ 13498f3ca02Sbrad struct dt_env* dtenv; 13598f3ca02Sbrad #endif 13632e31f52Ssthen /** maximum segment size of tcp socket */ 13732e31f52Ssthen int tcp_mss; 138933707f3Ssthen 139933707f3Ssthen /** 140933707f3Ssthen * Array of tcp pending used for outgoing TCP connections. 141933707f3Ssthen * Each can be used to establish a TCP connection with a server. 142933707f3Ssthen * The file descriptors are -1 if they are free, and need to be 143933707f3Ssthen * opened for the tcp connection. Can be used for ip4 and ip6. 144933707f3Ssthen */ 145933707f3Ssthen struct pending_tcp **tcp_conns; 146933707f3Ssthen /** number of tcp communication points. */ 147933707f3Ssthen size_t num_tcp; 14898f3ca02Sbrad /** number of tcp communication points in use. */ 14998f3ca02Sbrad size_t num_tcp_outgoing; 150933707f3Ssthen /** list of tcp comm points that are free for use */ 151933707f3Ssthen struct pending_tcp* tcp_free; 152933707f3Ssthen /** list of tcp queries waiting for a buffer */ 153933707f3Ssthen struct waiting_tcp* tcp_wait_first; 154933707f3Ssthen /** last of waiting query list */ 155933707f3Ssthen struct waiting_tcp* tcp_wait_last; 156933707f3Ssthen }; 157933707f3Ssthen 158933707f3Ssthen /** 159933707f3Ssthen * Outgoing interface. Ports available and currently used are tracked 160933707f3Ssthen * per interface 161933707f3Ssthen */ 162933707f3Ssthen struct port_if { 163933707f3Ssthen /** address ready to allocate new socket (except port no). */ 164933707f3Ssthen struct sockaddr_storage addr; 165933707f3Ssthen /** length of addr field */ 166933707f3Ssthen socklen_t addrlen; 167933707f3Ssthen 168933707f3Ssthen /** the available ports array. These are unused. 169933707f3Ssthen * Only the first total-inuse part is filled. */ 170933707f3Ssthen int* avail_ports; 171933707f3Ssthen /** the total number of available ports (size of the array) */ 172933707f3Ssthen int avail_total; 173933707f3Ssthen 174933707f3Ssthen /** array of the commpoints currently in use. 175933707f3Ssthen * allocated for max number of fds, first part in use. */ 176933707f3Ssthen struct port_comm** out; 177933707f3Ssthen /** max number of fds, size of out array */ 178933707f3Ssthen int maxout; 179933707f3Ssthen /** number of commpoints (and thus also ports) in use */ 180933707f3Ssthen int inuse; 181933707f3Ssthen }; 182933707f3Ssthen 183933707f3Ssthen /** 184933707f3Ssthen * Outgoing commpoint for UDP port. 185933707f3Ssthen */ 186933707f3Ssthen struct port_comm { 187933707f3Ssthen /** next in free list */ 188933707f3Ssthen struct port_comm* next; 189933707f3Ssthen /** which port number (when in use) */ 190933707f3Ssthen int number; 191933707f3Ssthen /** interface it is used in */ 192933707f3Ssthen struct port_if* pif; 193933707f3Ssthen /** index in the out array of the interface */ 194933707f3Ssthen int index; 195933707f3Ssthen /** number of outstanding queries on this port */ 196933707f3Ssthen int num_outstanding; 197933707f3Ssthen /** UDP commpoint, fd=-1 if not in use */ 198933707f3Ssthen struct comm_point* cp; 199933707f3Ssthen }; 200933707f3Ssthen 201933707f3Ssthen /** 202933707f3Ssthen * A query that has an answer pending for it. 203933707f3Ssthen */ 204933707f3Ssthen struct pending { 205933707f3Ssthen /** redblacktree entry, key is the pending struct(id, addr). */ 206933707f3Ssthen rbnode_t node; 207933707f3Ssthen /** the ID for the query. int so that a value out of range can 208933707f3Ssthen * be used to signify a pending that is for certain not present in 209933707f3Ssthen * the rbtree. (and for which deletion is safe). */ 210933707f3Ssthen unsigned int id; 211933707f3Ssthen /** remote address. */ 212933707f3Ssthen struct sockaddr_storage addr; 213933707f3Ssthen /** length of addr field in use. */ 214933707f3Ssthen socklen_t addrlen; 215933707f3Ssthen /** comm point it was sent on (and reply must come back on). */ 216933707f3Ssthen struct port_comm* pc; 217933707f3Ssthen /** timeout event */ 218933707f3Ssthen struct comm_timer* timer; 219933707f3Ssthen /** callback for the timeout, error or reply to the message */ 220933707f3Ssthen comm_point_callback_t* cb; 221933707f3Ssthen /** callback user argument */ 222933707f3Ssthen void* cb_arg; 223933707f3Ssthen /** the outside network it is part of */ 224933707f3Ssthen struct outside_network* outnet; 22598f3ca02Sbrad /** the corresponding serviced_query */ 22698f3ca02Sbrad struct serviced_query* sq; 227933707f3Ssthen 228933707f3Ssthen /*---- filled if udp pending is waiting -----*/ 229933707f3Ssthen /** next in waiting list. */ 230933707f3Ssthen struct pending* next_waiting; 231933707f3Ssthen /** timeout in msec */ 232933707f3Ssthen int timeout; 233933707f3Ssthen /** The query itself, the query packet to send. */ 234933707f3Ssthen uint8_t* pkt; 235933707f3Ssthen /** length of query packet. */ 236933707f3Ssthen size_t pkt_len; 237933707f3Ssthen }; 238933707f3Ssthen 239933707f3Ssthen /** 240933707f3Ssthen * Pending TCP query to server. 241933707f3Ssthen */ 242933707f3Ssthen struct pending_tcp { 243933707f3Ssthen /** next in list of free tcp comm points, or NULL. */ 244933707f3Ssthen struct pending_tcp* next_free; 245933707f3Ssthen /** the ID for the query; checked in reply */ 246933707f3Ssthen uint16_t id; 247933707f3Ssthen /** tcp comm point it was sent on (and reply must come back on). */ 248933707f3Ssthen struct comm_point* c; 249933707f3Ssthen /** the query being serviced, NULL if the pending_tcp is unused. */ 250933707f3Ssthen struct waiting_tcp* query; 251933707f3Ssthen }; 252933707f3Ssthen 253933707f3Ssthen /** 254933707f3Ssthen * Query waiting for TCP buffer. 255933707f3Ssthen */ 256933707f3Ssthen struct waiting_tcp { 257933707f3Ssthen /** 258933707f3Ssthen * next in waiting list. 259933707f3Ssthen * if pkt==0, this points to the pending_tcp structure. 260933707f3Ssthen */ 261933707f3Ssthen struct waiting_tcp* next_waiting; 262933707f3Ssthen /** timeout event; timer keeps running whether the query is 263933707f3Ssthen * waiting for a buffer or the tcp reply is pending */ 264933707f3Ssthen struct comm_timer* timer; 265933707f3Ssthen /** the outside network it is part of */ 266933707f3Ssthen struct outside_network* outnet; 267933707f3Ssthen /** remote address. */ 268933707f3Ssthen struct sockaddr_storage addr; 269933707f3Ssthen /** length of addr field in use. */ 270933707f3Ssthen socklen_t addrlen; 271933707f3Ssthen /** 272933707f3Ssthen * The query itself, the query packet to send. 273933707f3Ssthen * allocated after the waiting_tcp structure. 274933707f3Ssthen * set to NULL when the query is serviced and it part of pending_tcp. 275933707f3Ssthen * if this is NULL, the next_waiting points to the pending_tcp. 276933707f3Ssthen */ 277933707f3Ssthen uint8_t* pkt; 278933707f3Ssthen /** length of query packet. */ 279933707f3Ssthen size_t pkt_len; 280933707f3Ssthen /** callback for the timeout, error or reply to the message */ 281933707f3Ssthen comm_point_callback_t* cb; 282933707f3Ssthen /** callback user argument */ 283933707f3Ssthen void* cb_arg; 284933707f3Ssthen /** if it uses ssl upstream */ 285933707f3Ssthen int ssl_upstream; 286933707f3Ssthen }; 287933707f3Ssthen 288933707f3Ssthen /** 289933707f3Ssthen * Callback to party interested in serviced query results. 290933707f3Ssthen */ 291933707f3Ssthen struct service_callback { 292933707f3Ssthen /** next in callback list */ 293933707f3Ssthen struct service_callback* next; 294933707f3Ssthen /** callback function */ 295933707f3Ssthen comm_point_callback_t* cb; 296933707f3Ssthen /** user argument for callback function */ 297933707f3Ssthen void* cb_arg; 298933707f3Ssthen }; 299933707f3Ssthen 300933707f3Ssthen /** fallback size for fragmentation for EDNS in IPv4 */ 301229e174cSsthen #define EDNS_FRAG_SIZE_IP4 1472 302933707f3Ssthen /** fallback size for EDNS in IPv6, fits one fragment with ip6-tunnel-ids */ 303229e174cSsthen #define EDNS_FRAG_SIZE_IP6 1232 304933707f3Ssthen 305933707f3Ssthen /** 306933707f3Ssthen * Query service record. 307933707f3Ssthen * Contains query and destination. UDP, TCP, EDNS are all tried. 308933707f3Ssthen * complete with retries and timeouts. A number of interested parties can 309933707f3Ssthen * receive a callback. 310933707f3Ssthen */ 311933707f3Ssthen struct serviced_query { 312933707f3Ssthen /** The rbtree node, key is this record */ 313933707f3Ssthen rbnode_t node; 314933707f3Ssthen /** The query that needs to be answered. Starts with flags u16, 315933707f3Ssthen * then qdcount, ..., including qname, qtype, qclass. Does not include 316933707f3Ssthen * EDNS record. */ 317933707f3Ssthen uint8_t* qbuf; 318933707f3Ssthen /** length of qbuf. */ 319933707f3Ssthen size_t qbuflen; 320933707f3Ssthen /** If an EDNS section is included, the DO/CD bit will be turned on. */ 321933707f3Ssthen int dnssec; 322933707f3Ssthen /** We want signatures, or else the answer is likely useless */ 323933707f3Ssthen int want_dnssec; 32498f3ca02Sbrad /** ignore capsforid */ 32598f3ca02Sbrad int nocaps; 326933707f3Ssthen /** tcp upstream used, use tcp, or ssl_upstream for SSL */ 327933707f3Ssthen int tcp_upstream, ssl_upstream; 328933707f3Ssthen /** where to send it */ 329933707f3Ssthen struct sockaddr_storage addr; 330933707f3Ssthen /** length of addr field in use. */ 331933707f3Ssthen socklen_t addrlen; 332933707f3Ssthen /** zone name, uncompressed domain name in wireformat */ 333933707f3Ssthen uint8_t* zone; 334933707f3Ssthen /** length of zone name */ 335933707f3Ssthen size_t zonelen; 336d8d14d0cSsthen /** qtype */ 337d8d14d0cSsthen int qtype; 338933707f3Ssthen /** current status */ 339933707f3Ssthen enum serviced_query_status { 340933707f3Ssthen /** initial status */ 341933707f3Ssthen serviced_initial, 342933707f3Ssthen /** UDP with EDNS sent */ 343933707f3Ssthen serviced_query_UDP_EDNS, 344933707f3Ssthen /** UDP without EDNS sent */ 345933707f3Ssthen serviced_query_UDP, 346933707f3Ssthen /** TCP with EDNS sent */ 347933707f3Ssthen serviced_query_TCP_EDNS, 348933707f3Ssthen /** TCP without EDNS sent */ 349933707f3Ssthen serviced_query_TCP, 350933707f3Ssthen /** probe to test EDNS lameness (EDNS is dropped) */ 351933707f3Ssthen serviced_query_PROBE_EDNS, 352933707f3Ssthen /** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */ 353933707f3Ssthen serviced_query_UDP_EDNS_fallback, 354933707f3Ssthen /** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */ 355933707f3Ssthen serviced_query_TCP_EDNS_fallback, 356933707f3Ssthen /** send UDP query with EDNS1480 (or 1280) */ 357933707f3Ssthen serviced_query_UDP_EDNS_FRAG 358933707f3Ssthen } 359933707f3Ssthen /** variable with current status */ 360933707f3Ssthen status; 361933707f3Ssthen /** true if serviced_query is scheduled for deletion already */ 362933707f3Ssthen int to_be_deleted; 363933707f3Ssthen /** number of UDP retries */ 364933707f3Ssthen int retry; 365933707f3Ssthen /** time last UDP was sent */ 366933707f3Ssthen struct timeval last_sent_time; 367933707f3Ssthen /** rtt of last (UDP) message */ 368933707f3Ssthen int last_rtt; 369933707f3Ssthen /** do we know edns probe status already, for UDP_EDNS queries */ 370933707f3Ssthen int edns_lame_known; 371*2ee382b6Ssthen /** edns options to use for sending upstream packet */ 372*2ee382b6Ssthen struct edns_option* opt_list; 373933707f3Ssthen /** outside network this is part of */ 374933707f3Ssthen struct outside_network* outnet; 375933707f3Ssthen /** list of interested parties that need callback on results. */ 376933707f3Ssthen struct service_callback* cblist; 377933707f3Ssthen /** the UDP or TCP query that is pending, see status which */ 378933707f3Ssthen void* pending; 379933707f3Ssthen }; 380933707f3Ssthen 381933707f3Ssthen /** 382933707f3Ssthen * Create outside_network structure with N udp ports. 383933707f3Ssthen * @param base: the communication base to use for event handling. 384933707f3Ssthen * @param bufsize: size for network buffers. 385933707f3Ssthen * @param num_ports: number of udp ports to open per interface. 386933707f3Ssthen * @param ifs: interface names (or NULL for default interface). 387933707f3Ssthen * These interfaces must be able to access all authoritative servers. 388933707f3Ssthen * @param num_ifs: number of names in array ifs. 389933707f3Ssthen * @param do_ip4: service IP4. 390933707f3Ssthen * @param do_ip6: service IP6. 391933707f3Ssthen * @param num_tcp: number of outgoing tcp buffers to preallocate. 392933707f3Ssthen * @param infra: pointer to infra cached used for serviced queries. 393933707f3Ssthen * @param rnd: stored to create random numbers for serviced queries. 394933707f3Ssthen * @param use_caps_for_id: enable to use 0x20 bits to encode id randomness. 395933707f3Ssthen * @param availports: array of available ports. 396933707f3Ssthen * @param numavailports: number of available ports in array. 397933707f3Ssthen * @param unwanted_threshold: when to take defensive action. 398933707f3Ssthen * @param unwanted_action: the action to take. 399933707f3Ssthen * @param unwanted_param: user parameter to action. 40032e31f52Ssthen * @param tcp_mss: maximum segment size of tcp socket. 401933707f3Ssthen * @param do_udp: if udp is done. 402933707f3Ssthen * @param sslctx: context to create outgoing connections with (if enabled). 4035d76a658Ssthen * @param delayclose: if not 0, udp sockets are delayed before timeout closure. 4045d76a658Ssthen * msec to wait on timeouted udp sockets. 40598f3ca02Sbrad * @param dtenv: environment to send dnstap events with (if enabled). 406933707f3Ssthen * @return: the new structure (with no pending answers) or NULL on error. 407933707f3Ssthen */ 408933707f3Ssthen struct outside_network* outside_network_create(struct comm_base* base, 409933707f3Ssthen size_t bufsize, size_t num_ports, char** ifs, int num_ifs, 410933707f3Ssthen int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra, 411933707f3Ssthen struct ub_randstate* rnd, int use_caps_for_id, int* availports, 41232e31f52Ssthen int numavailports, size_t unwanted_threshold, int tcp_mss, 413933707f3Ssthen void (*unwanted_action)(void*), void* unwanted_param, int do_udp, 41498f3ca02Sbrad void* sslctx, int delayclose, struct dt_env *dtenv); 415933707f3Ssthen 416933707f3Ssthen /** 417933707f3Ssthen * Delete outside_network structure. 418933707f3Ssthen * @param outnet: object to delete. 419933707f3Ssthen */ 420933707f3Ssthen void outside_network_delete(struct outside_network* outnet); 421933707f3Ssthen 422933707f3Ssthen /** 423933707f3Ssthen * Prepare for quit. Sends no more queries, even if queued up. 424933707f3Ssthen * @param outnet: object to prepare for removal 425933707f3Ssthen */ 426933707f3Ssthen void outside_network_quit_prepare(struct outside_network* outnet); 427933707f3Ssthen 428933707f3Ssthen /** 429933707f3Ssthen * Send UDP query, create pending answer. 430933707f3Ssthen * Changes the ID for the query to be random and unique for that destination. 43198f3ca02Sbrad * @param sq: serviced query. 432933707f3Ssthen * @param packet: wireformat query to send to destination. 433933707f3Ssthen * @param timeout: in milliseconds from now. 434933707f3Ssthen * @param callback: function to call on error, timeout or reply. 435933707f3Ssthen * @param callback_arg: user argument for callback function. 436933707f3Ssthen * @return: NULL on error for malloc or socket. Else the pending query object. 437933707f3Ssthen */ 43898f3ca02Sbrad struct pending* pending_udp_query(struct serviced_query* sq, 43998f3ca02Sbrad struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback, 440933707f3Ssthen void* callback_arg); 441933707f3Ssthen 442933707f3Ssthen /** 443933707f3Ssthen * Send TCP query. May wait for TCP buffer. Selects ID to be random, and 444933707f3Ssthen * checks id. 44598f3ca02Sbrad * @param sq: serviced query. 446933707f3Ssthen * @param packet: wireformat query to send to destination. copied from. 447933707f3Ssthen * @param timeout: in seconds from now. 448933707f3Ssthen * Timer starts running now. Timer may expire if all buffers are used, 449933707f3Ssthen * without any query been sent to the server yet. 450933707f3Ssthen * @param callback: function to call on error, timeout or reply. 451933707f3Ssthen * @param callback_arg: user argument for callback function. 452933707f3Ssthen * @return: false on error for malloc or socket. Else the pending TCP object. 453933707f3Ssthen */ 45498f3ca02Sbrad struct waiting_tcp* pending_tcp_query(struct serviced_query* sq, 45598f3ca02Sbrad struct sldns_buffer* packet, int timeout, comm_point_callback_t* callback, 45698f3ca02Sbrad void* callback_arg); 457933707f3Ssthen 458933707f3Ssthen /** 459933707f3Ssthen * Delete pending answer. 460933707f3Ssthen * @param outnet: outside network the pending query is part of. 461933707f3Ssthen * Internal feature: if outnet is NULL, p is not unlinked from rbtree. 462933707f3Ssthen * @param p: deleted 463933707f3Ssthen */ 464933707f3Ssthen void pending_delete(struct outside_network* outnet, struct pending* p); 465933707f3Ssthen 466933707f3Ssthen /** 467933707f3Ssthen * Perform a serviced query to the authoritative servers. 468933707f3Ssthen * Duplicate efforts are detected, and EDNS, TCP and UDP retry is performed. 469933707f3Ssthen * @param outnet: outside network, with rbtree of serviced queries. 470933707f3Ssthen * @param qname: what qname to query. 471933707f3Ssthen * @param qnamelen: length of qname in octets including 0 root label. 472933707f3Ssthen * @param qtype: rrset type to query (host format) 473933707f3Ssthen * @param qclass: query class. (host format) 474933707f3Ssthen * @param flags: flags u16 (host format), includes opcode, CD bit. 475933707f3Ssthen * @param dnssec: if set, DO bit is set in EDNS queries. 476933707f3Ssthen * If the value includes BIT_CD, CD bit is set when in EDNS queries. 477933707f3Ssthen * If the value includes BIT_DO, DO bit is set when in EDNS queries. 478933707f3Ssthen * @param want_dnssec: signatures are needed, without EDNS the answer is 479933707f3Ssthen * likely to be useless. 48098f3ca02Sbrad * @param nocaps: ignore use_caps_for_id and use unperturbed qname. 481933707f3Ssthen * @param tcp_upstream: use TCP for upstream queries. 482933707f3Ssthen * @param ssl_upstream: use SSL for upstream queries. 483*2ee382b6Ssthen * @param opt_list: pass edns option list (deep copied into serviced query) 484*2ee382b6Ssthen * these options are set on the outgoing packets. 485933707f3Ssthen * @param callback: callback function. 486933707f3Ssthen * @param callback_arg: user argument to callback function. 487933707f3Ssthen * @param addr: to which server to send the query. 488933707f3Ssthen * @param addrlen: length of addr. 489933707f3Ssthen * @param zone: name of the zone of the delegation point. wireformat dname. 490933707f3Ssthen This is the delegation point name for which the server is deemed 491933707f3Ssthen authoritative. 492933707f3Ssthen * @param zonelen: length of zone. 493933707f3Ssthen * @param buff: scratch buffer to create query contents in. Empty on exit. 494933707f3Ssthen * @return 0 on error, or pointer to serviced query that is used to answer 495933707f3Ssthen * this serviced query may be shared with other callbacks as well. 496933707f3Ssthen */ 497933707f3Ssthen struct serviced_query* outnet_serviced_query(struct outside_network* outnet, 498933707f3Ssthen uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, 49998f3ca02Sbrad uint16_t flags, int dnssec, int want_dnssec, int nocaps, 500*2ee382b6Ssthen int tcp_upstream, int ssl_upstream, struct edns_option* opt_list, 501*2ee382b6Ssthen struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, 502*2ee382b6Ssthen size_t zonelen, comm_point_callback_t* callback, void* callback_arg, 50398f3ca02Sbrad struct sldns_buffer* buff); 504933707f3Ssthen 505933707f3Ssthen /** 506933707f3Ssthen * Remove service query callback. 507933707f3Ssthen * If that leads to zero callbacks, the query is completely cancelled. 508933707f3Ssthen * @param sq: serviced query to adjust. 509933707f3Ssthen * @param cb_arg: callback argument of callback that needs removal. 510933707f3Ssthen * same as the callback_arg to outnet_serviced_query(). 511933707f3Ssthen */ 512933707f3Ssthen void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg); 513933707f3Ssthen 514933707f3Ssthen /** 515933707f3Ssthen * Get memory size in use by outside network. 516933707f3Ssthen * Counts buffers and outstanding query (serviced queries) malloced data. 517933707f3Ssthen * @param outnet: outside network structure. 518933707f3Ssthen * @return size in bytes. 519933707f3Ssthen */ 520933707f3Ssthen size_t outnet_get_mem(struct outside_network* outnet); 521933707f3Ssthen 522933707f3Ssthen /** 523933707f3Ssthen * Get memory size in use by serviced query while it is servicing callbacks. 524933707f3Ssthen * This takes into account the pre-deleted status of it; it will be deleted 525933707f3Ssthen * when the callbacks are done. 526933707f3Ssthen * @param sq: serviced query. 527933707f3Ssthen * @return size in bytes. 528933707f3Ssthen */ 529933707f3Ssthen size_t serviced_get_mem(struct serviced_query* sq); 530933707f3Ssthen 531933707f3Ssthen /** callback for incoming udp answers from the network */ 532933707f3Ssthen int outnet_udp_cb(struct comm_point* c, void* arg, int error, 533933707f3Ssthen struct comm_reply *reply_info); 534933707f3Ssthen 535933707f3Ssthen /** callback for pending tcp connections */ 536933707f3Ssthen int outnet_tcp_cb(struct comm_point* c, void* arg, int error, 537933707f3Ssthen struct comm_reply *reply_info); 538933707f3Ssthen 539933707f3Ssthen /** callback for udp timeout */ 540933707f3Ssthen void pending_udp_timer_cb(void *arg); 541933707f3Ssthen 5425d76a658Ssthen /** callback for udp delay for timeout */ 5435d76a658Ssthen void pending_udp_timer_delay_cb(void *arg); 5445d76a658Ssthen 545933707f3Ssthen /** callback for outgoing TCP timer event */ 546933707f3Ssthen void outnet_tcptimer(void* arg); 547933707f3Ssthen 548933707f3Ssthen /** callback for serviced query UDP answers */ 549933707f3Ssthen int serviced_udp_callback(struct comm_point* c, void* arg, int error, 550933707f3Ssthen struct comm_reply* rep); 551933707f3Ssthen 552933707f3Ssthen /** TCP reply or error callback for serviced queries */ 553933707f3Ssthen int serviced_tcp_callback(struct comm_point* c, void* arg, int error, 554933707f3Ssthen struct comm_reply* rep); 555933707f3Ssthen 556933707f3Ssthen /** compare function of pending rbtree */ 557933707f3Ssthen int pending_cmp(const void* key1, const void* key2); 558933707f3Ssthen 559933707f3Ssthen /** compare function of serviced query rbtree */ 560933707f3Ssthen int serviced_cmp(const void* key1, const void* key2); 561933707f3Ssthen 562933707f3Ssthen #endif /* OUTSIDE_NETWORK_H */ 563