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