1238106Sdes/* 2238106Sdes * services/mesh.h - deal with mesh of query states and handle events for that. 3238106Sdes * 4238106Sdes * Copyright (c) 2007, NLnet Labs. All rights reserved. 5238106Sdes * 6238106Sdes * This software is open source. 7238106Sdes * 8238106Sdes * Redistribution and use in source and binary forms, with or without 9238106Sdes * modification, are permitted provided that the following conditions 10238106Sdes * are met: 11238106Sdes * 12238106Sdes * Redistributions of source code must retain the above copyright notice, 13238106Sdes * this list of conditions and the following disclaimer. 14238106Sdes * 15238106Sdes * Redistributions in binary form must reproduce the above copyright notice, 16238106Sdes * this list of conditions and the following disclaimer in the documentation 17238106Sdes * and/or other materials provided with the distribution. 18238106Sdes * 19238106Sdes * Neither the name of the NLNET LABS nor the names of its contributors may 20238106Sdes * be used to endorse or promote products derived from this software without 21238106Sdes * specific prior written permission. 22238106Sdes * 23238106Sdes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24269257Sdes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25269257Sdes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26269257Sdes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27269257Sdes * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28269257Sdes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29269257Sdes * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30269257Sdes * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31269257Sdes * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32269257Sdes * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33269257Sdes * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34238106Sdes */ 35238106Sdes 36238106Sdes/** 37238106Sdes * \file 38238106Sdes * 39238106Sdes * This file contains functions to assist in dealing with a mesh of 40238106Sdes * query states. This mesh is supposed to be thread-specific. 41238106Sdes * It consists of query states (per qname, qtype, qclass) and connections 42238106Sdes * between query states and the super and subquery states, and replies to 43238106Sdes * send back to clients. 44238106Sdes */ 45238106Sdes 46238106Sdes#ifndef SERVICES_MESH_H 47238106Sdes#define SERVICES_MESH_H 48238106Sdes 49238106Sdes#include "util/rbtree.h" 50238106Sdes#include "util/netevent.h" 51238106Sdes#include "util/data/msgparse.h" 52238106Sdes#include "util/module.h" 53238106Sdes#include "services/modstack.h" 54269257Sdesstruct sldns_buffer; 55238106Sdesstruct mesh_state; 56238106Sdesstruct mesh_reply; 57238106Sdesstruct mesh_cb; 58238106Sdesstruct query_info; 59238106Sdesstruct reply_info; 60238106Sdesstruct outbound_entry; 61238106Sdesstruct timehist; 62238106Sdes 63238106Sdes/** 64238106Sdes * Maximum number of mesh state activations. Any more is likely an 65238106Sdes * infinite loop in the module. It is then terminated. 66238106Sdes */ 67238106Sdes#define MESH_MAX_ACTIVATION 3000 68238106Sdes 69238106Sdes/** 70238106Sdes * Max number of references-to-references-to-references.. search size. 71238106Sdes * Any more is treated like 'too large', and the creation of a new 72238106Sdes * dependency is failed (so that no loops can be created). 73238106Sdes */ 74238106Sdes#define MESH_MAX_SUBSUB 1024 75238106Sdes 76238106Sdes/** 77238106Sdes * Mesh of query states 78238106Sdes */ 79238106Sdesstruct mesh_area { 80238106Sdes /** active module stack */ 81238106Sdes struct module_stack mods; 82238106Sdes /** environment for new states */ 83238106Sdes struct module_env* env; 84238106Sdes 85238106Sdes /** set of runnable queries (mesh_state.run_node) */ 86238106Sdes rbtree_t run; 87238106Sdes /** rbtree of all current queries (mesh_state.node)*/ 88238106Sdes rbtree_t all; 89238106Sdes 90238106Sdes /** count of the total number of mesh_reply entries */ 91238106Sdes size_t num_reply_addrs; 92238106Sdes /** count of the number of mesh_states that have mesh_replies 93238106Sdes * Because a state can send results to multiple reply addresses, 94238106Sdes * this number must be equal or lower than num_reply_addrs. */ 95238106Sdes size_t num_reply_states; 96238106Sdes /** number of mesh_states that have no mesh_replies, and also 97238106Sdes * an empty set of super-states, thus are 'toplevel' or detached 98238106Sdes * internal opportunistic queries */ 99238106Sdes size_t num_detached_states; 100238106Sdes /** number of reply states in the forever list */ 101238106Sdes size_t num_forever_states; 102238106Sdes 103238106Sdes /** max total number of reply states to have */ 104238106Sdes size_t max_reply_states; 105238106Sdes /** max forever number of reply states to have */ 106238106Sdes size_t max_forever_states; 107238106Sdes 108238106Sdes /** stats, cumulative number of reply states jostled out */ 109238106Sdes size_t stats_jostled; 110238106Sdes /** stats, cumulative number of incoming client msgs dropped */ 111238106Sdes size_t stats_dropped; 112238106Sdes /** number of replies sent */ 113238106Sdes size_t replies_sent; 114238106Sdes /** sum of waiting times for the replies */ 115238106Sdes struct timeval replies_sum_wait; 116238106Sdes /** histogram of time values */ 117238106Sdes struct timehist* histogram; 118238106Sdes /** (extended stats) secure replies */ 119238106Sdes size_t ans_secure; 120238106Sdes /** (extended stats) bogus replies */ 121238106Sdes size_t ans_bogus; 122238106Sdes /** (extended stats) rcodes in replies */ 123238106Sdes size_t ans_rcode[16]; 124238106Sdes /** (extended stats) rcode nodata in replies */ 125238106Sdes size_t ans_nodata; 126238106Sdes 127238106Sdes /** backup of query if other operations recurse and need the 128238106Sdes * network buffers */ 129269257Sdes struct sldns_buffer* qbuf_bak; 130238106Sdes 131238106Sdes /** double linked list of the run-to-completion query states. 132238106Sdes * These are query states with a reply */ 133238106Sdes struct mesh_state* forever_first; 134238106Sdes /** last entry in run forever list */ 135238106Sdes struct mesh_state* forever_last; 136238106Sdes 137238106Sdes /** double linked list of the query states that can be jostled out 138238106Sdes * by new queries if too old. These are query states with a reply */ 139238106Sdes struct mesh_state* jostle_first; 140238106Sdes /** last entry in jostle list - this is the entry that is newest */ 141238106Sdes struct mesh_state* jostle_last; 142238106Sdes /** timeout for jostling. if age is lower, it does not get jostled. */ 143238106Sdes struct timeval jostle_max; 144238106Sdes}; 145238106Sdes 146238106Sdes/** 147238106Sdes * A mesh query state 148238106Sdes * Unique per qname, qtype, qclass (from the qstate). 149238106Sdes * And RD / CD flag; in case a client turns it off. 150238106Sdes * And priming queries are different from ordinary queries (because of hints). 151238106Sdes * 152238106Sdes * The entire structure is allocated in a region, this region is the qstate 153238106Sdes * region. All parts (rbtree nodes etc) are also allocated in the region. 154238106Sdes */ 155238106Sdesstruct mesh_state { 156238106Sdes /** node in mesh_area all tree, key is this struct. Must be first. */ 157238106Sdes rbnode_t node; 158238106Sdes /** node in mesh_area runnable tree, key is this struct */ 159238106Sdes rbnode_t run_node; 160238106Sdes /** the query state. Note that the qinfo and query_flags 161238106Sdes * may not change. */ 162238106Sdes struct module_qstate s; 163238106Sdes /** the list of replies to clients for the results */ 164238106Sdes struct mesh_reply* reply_list; 165238106Sdes /** the list of callbacks for the results */ 166238106Sdes struct mesh_cb* cb_list; 167238106Sdes /** set of superstates (that want this state's result) 168238106Sdes * contains struct mesh_state_ref* */ 169238106Sdes rbtree_t super_set; 170238106Sdes /** set of substates (that this state needs to continue) 171238106Sdes * contains struct mesh_state_ref* */ 172238106Sdes rbtree_t sub_set; 173238106Sdes /** number of activations for the mesh state */ 174238106Sdes size_t num_activated; 175238106Sdes 176238106Sdes /** previous in linked list for reply states */ 177238106Sdes struct mesh_state* prev; 178238106Sdes /** next in linked list for reply states */ 179238106Sdes struct mesh_state* next; 180238106Sdes /** if this state is in the forever list, jostle list, or neither */ 181238106Sdes enum mesh_list_select { mesh_no_list, mesh_forever_list, 182238106Sdes mesh_jostle_list } list_select; 183238106Sdes 184238106Sdes /** true if replies have been sent out (at end for alignment) */ 185238106Sdes uint8_t replies_sent; 186238106Sdes}; 187238106Sdes 188238106Sdes/** 189238106Sdes * Rbtree reference to a mesh_state. 190238106Sdes * Used in super_set and sub_set. 191238106Sdes */ 192238106Sdesstruct mesh_state_ref { 193238106Sdes /** node in rbtree for set, key is this structure */ 194238106Sdes rbnode_t node; 195238106Sdes /** the mesh state */ 196238106Sdes struct mesh_state* s; 197238106Sdes}; 198238106Sdes 199238106Sdes/** 200238106Sdes * Reply to a client 201238106Sdes */ 202238106Sdesstruct mesh_reply { 203238106Sdes /** next in reply list */ 204238106Sdes struct mesh_reply* next; 205238106Sdes /** the query reply destination, packet buffer and where to send. */ 206238106Sdes struct comm_reply query_reply; 207238106Sdes /** edns data from query */ 208238106Sdes struct edns_data edns; 209238106Sdes /** the time when request was entered */ 210238106Sdes struct timeval start_time; 211238106Sdes /** id of query, in network byteorder. */ 212238106Sdes uint16_t qid; 213238106Sdes /** flags of query, for reply flags */ 214238106Sdes uint16_t qflags; 215238106Sdes /** qname from this query. len same as mesh qinfo. */ 216238106Sdes uint8_t* qname; 217238106Sdes}; 218238106Sdes 219238106Sdes/** 220238106Sdes * Mesh result callback func. 221238106Sdes * called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus); 222238106Sdes */ 223269257Sdestypedef void (*mesh_cb_func_t)(void*, int, struct sldns_buffer*, enum sec_status, 224238106Sdes char*); 225238106Sdes 226238106Sdes/** 227238106Sdes * Callback to result routine 228238106Sdes */ 229238106Sdesstruct mesh_cb { 230238106Sdes /** next in list */ 231238106Sdes struct mesh_cb* next; 232238106Sdes /** edns data from query */ 233238106Sdes struct edns_data edns; 234238106Sdes /** id of query, in network byteorder. */ 235238106Sdes uint16_t qid; 236238106Sdes /** flags of query, for reply flags */ 237238106Sdes uint16_t qflags; 238238106Sdes /** buffer for reply */ 239269257Sdes struct sldns_buffer* buf; 240238106Sdes 241238106Sdes /** callback routine for results. if rcode != 0 buf has message. 242238106Sdes * called as cb(cb_arg, rcode, buf, sec_state); 243238106Sdes */ 244238106Sdes mesh_cb_func_t cb; 245238106Sdes /** user arg for callback */ 246238106Sdes void* cb_arg; 247238106Sdes}; 248238106Sdes 249238106Sdes/* ------------------- Functions for worker -------------------- */ 250238106Sdes 251238106Sdes/** 252238106Sdes * Allocate mesh, to empty. 253238106Sdes * @param stack: module stack to activate, copied (as readonly reference). 254238106Sdes * @param env: environment for new queries. 255238106Sdes * @return mesh: the new mesh or NULL on error. 256238106Sdes */ 257238106Sdesstruct mesh_area* mesh_create(struct module_stack* stack, 258238106Sdes struct module_env* env); 259238106Sdes 260238106Sdes/** 261238106Sdes * Delete mesh, and all query states and replies in it. 262238106Sdes * @param mesh: the mesh to delete. 263238106Sdes */ 264238106Sdesvoid mesh_delete(struct mesh_area* mesh); 265238106Sdes 266238106Sdes/** 267238106Sdes * New query incoming from clients. Create new query state if needed, and 268238106Sdes * add mesh_reply to it. Returns error to client on malloc failures. 269238106Sdes * Will run the mesh area queries to process if a new query state is created. 270238106Sdes * 271238106Sdes * @param mesh: the mesh. 272238106Sdes * @param qinfo: query from client. 273238106Sdes * @param qflags: flags from client query. 274238106Sdes * @param edns: edns data from client query. 275238106Sdes * @param rep: where to reply to. 276238106Sdes * @param qid: query id to reply with. 277238106Sdes */ 278238106Sdesvoid mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, 279238106Sdes uint16_t qflags, struct edns_data* edns, struct comm_reply* rep, 280238106Sdes uint16_t qid); 281238106Sdes 282238106Sdes/** 283238106Sdes * New query with callback. Create new query state if needed, and 284238106Sdes * add mesh_cb to it. 285238106Sdes * Will run the mesh area queries to process if a new query state is created. 286238106Sdes * 287238106Sdes * @param mesh: the mesh. 288238106Sdes * @param qinfo: query from client. 289238106Sdes * @param qflags: flags from client query. 290238106Sdes * @param edns: edns data from client query. 291238106Sdes * @param buf: buffer for reply contents. 292238106Sdes * @param qid: query id to reply with. 293238106Sdes * @param cb: callback function. 294238106Sdes * @param cb_arg: callback user arg. 295238106Sdes * @return 0 on error. 296238106Sdes */ 297238106Sdesint mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, 298269257Sdes uint16_t qflags, struct edns_data* edns, struct sldns_buffer* buf, 299238106Sdes uint16_t qid, mesh_cb_func_t cb, void* cb_arg); 300238106Sdes 301238106Sdes/** 302238106Sdes * New prefetch message. Create new query state if needed. 303238106Sdes * Will run the mesh area queries to process if a new query state is created. 304238106Sdes * 305238106Sdes * @param mesh: the mesh. 306238106Sdes * @param qinfo: query from client. 307238106Sdes * @param qflags: flags from client query. 308238106Sdes * @param leeway: TTL leeway what to expire earlier for this update. 309238106Sdes */ 310238106Sdesvoid mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo, 311269257Sdes uint16_t qflags, time_t leeway); 312238106Sdes 313238106Sdes/** 314238106Sdes * Handle new event from the wire. A serviced query has returned. 315238106Sdes * The query state will be made runnable, and the mesh_area will process 316238106Sdes * query states until processing is complete. 317238106Sdes * 318238106Sdes * @param mesh: the query mesh. 319238106Sdes * @param e: outbound entry, with query state to run and reply pointer. 320238106Sdes * @param reply: the comm point reply info. 321238106Sdes * @param what: NETEVENT_* error code (if not 0, what is wrong, TIMEOUT). 322238106Sdes */ 323238106Sdesvoid mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e, 324238106Sdes struct comm_reply* reply, int what); 325238106Sdes 326238106Sdes/* ------------------- Functions for module environment --------------- */ 327238106Sdes 328238106Sdes/** 329238106Sdes * Detach-subqueries. 330238106Sdes * Remove all sub-query references from this query state. 331238106Sdes * Keeps super-references of those sub-queries correct. 332238106Sdes * Updates stat items in mesh_area structure. 333238106Sdes * @param qstate: used to find mesh state. 334238106Sdes */ 335238106Sdesvoid mesh_detach_subs(struct module_qstate* qstate); 336238106Sdes 337238106Sdes/** 338238106Sdes * Attach subquery. 339238106Sdes * Creates it if it does not exist already. 340238106Sdes * Keeps sub and super references correct. 341238106Sdes * Performs a cycle detection - for double check - and fails if there is one. 342238106Sdes * Also fails if the sub-sub-references become too large. 343238106Sdes * Updates stat items in mesh_area structure. 344238106Sdes * Pass if it is priming query or not. 345238106Sdes * return: 346238106Sdes * o if error (malloc) happened. 347238106Sdes * o need to initialise the new state (module init; it is a new state). 348238106Sdes * so that the next run of the query with this module is successful. 349238106Sdes * o no init needed, attachment successful. 350238106Sdes * 351238106Sdes * @param qstate: the state to find mesh state, and that wants to receive 352238106Sdes * the results from the new subquery. 353238106Sdes * @param qinfo: what to query for (copied). 354238106Sdes * @param qflags: what flags to use (RD / CD flag or not). 355238106Sdes * @param prime: if it is a (stub) priming query. 356285206Sdes * @param valrec: if it is a validation recursion query (lookup of key, DS). 357238106Sdes * @param newq: If the new subquery needs initialisation, it is returned, 358238106Sdes * otherwise NULL is returned. 359238106Sdes * @return: false on error, true if success (and init may be needed). 360238106Sdes */ 361238106Sdesint mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, 362285206Sdes uint16_t qflags, int prime, int valrec, struct module_qstate** newq); 363238106Sdes 364238106Sdes/** 365238106Sdes * Query state is done, send messages to reply entries. 366238106Sdes * Encode messages using reply entry values and the querystate (with original 367238106Sdes * qinfo), using given reply_info. 368238106Sdes * Pass errcode != 0 if an error reply is needed. 369238106Sdes * If no reply entries, nothing is done. 370238106Sdes * Must be called before a module can module_finished or return module_error. 371238106Sdes * The module must handle the super query states itself as well. 372238106Sdes * 373238106Sdes * @param mstate: mesh state that is done. return_rcode and return_msg 374238106Sdes * are used for replies. 375238106Sdes * return_rcode: if not 0 (NOERROR) an error is sent back (and 376238106Sdes * return_msg is ignored). 377238106Sdes * return_msg: reply to encode and send back to clients. 378238106Sdes */ 379238106Sdesvoid mesh_query_done(struct mesh_state* mstate); 380238106Sdes 381238106Sdes/** 382238106Sdes * Call inform_super for the super query states that are interested in the 383238106Sdes * results from this query state. These can then be changed for error 384238106Sdes * or results. 385238106Sdes * Called when a module is module_finished or returns module_error. 386238106Sdes * The super query states become runnable with event module_event_pass, 387238106Sdes * it calls the current module for the super with the inform_super event. 388238106Sdes * 389238106Sdes * @param mesh: mesh area to add newly runnable modules to. 390238106Sdes * @param mstate: the state that has results, used to find mesh state. 391238106Sdes */ 392238106Sdesvoid mesh_walk_supers(struct mesh_area* mesh, struct mesh_state* mstate); 393238106Sdes 394238106Sdes/** 395238106Sdes * Delete mesh state, cleanup and also rbtrees and so on. 396238106Sdes * Will detach from all super/subnodes. 397238106Sdes * @param qstate: to remove. 398238106Sdes */ 399238106Sdesvoid mesh_state_delete(struct module_qstate* qstate); 400238106Sdes 401238106Sdes/* ------------------- Functions for mesh -------------------- */ 402238106Sdes 403238106Sdes/** 404238106Sdes * Create and initialize a new mesh state and its query state 405238106Sdes * Does not put the mesh state into rbtrees and so on. 406238106Sdes * @param env: module environment to set. 407238106Sdes * @param qinfo: query info that the mesh is for. 408238106Sdes * @param qflags: flags for query (RD / CD flag). 409238106Sdes * @param prime: if true, it is a priming query, set is_priming on mesh state. 410285206Sdes * @param valrec: if true, it is a validation recursion query, and sets 411285206Sdes * is_valrec on the mesh state. 412238106Sdes * @return: new mesh state or NULL on allocation error. 413238106Sdes */ 414238106Sdesstruct mesh_state* mesh_state_create(struct module_env* env, 415285206Sdes struct query_info* qinfo, uint16_t qflags, int prime, int valrec); 416238106Sdes 417238106Sdes/** 418238106Sdes * Cleanup a mesh state and its query state. Does not do rbtree or 419238106Sdes * reference cleanup. 420238106Sdes * @param mstate: mesh state to cleanup. Its pointer may no longer be used 421238106Sdes * afterwards. Cleanup rbtrees before calling this function. 422238106Sdes */ 423238106Sdesvoid mesh_state_cleanup(struct mesh_state* mstate); 424238106Sdes 425238106Sdes/** 426238106Sdes * Delete all mesh states from the mesh. 427238106Sdes * @param mesh: the mesh area to clear 428238106Sdes */ 429238106Sdesvoid mesh_delete_all(struct mesh_area* mesh); 430238106Sdes 431238106Sdes/** 432238106Sdes * Find a mesh state in the mesh area. Pass relevant flags. 433238106Sdes * 434238106Sdes * @param mesh: the mesh area to look in. 435238106Sdes * @param qinfo: what query 436238106Sdes * @param qflags: if RD / CD bit is set or not. 437238106Sdes * @param prime: if it is a priming query. 438285206Sdes * @param valrec: if it is a validation-recursion query. 439238106Sdes * @return: mesh state or NULL if not found. 440238106Sdes */ 441238106Sdesstruct mesh_state* mesh_area_find(struct mesh_area* mesh, 442285206Sdes struct query_info* qinfo, uint16_t qflags, int prime, int valrec); 443238106Sdes 444238106Sdes/** 445238106Sdes * Setup attachment super/sub relation between super and sub mesh state. 446238106Sdes * The relation must not be present when calling the function. 447238106Sdes * Does not update stat items in mesh_area. 448238106Sdes * @param super: super state. 449238106Sdes * @param sub: sub state. 450238106Sdes * @return: 0 on alloc error. 451238106Sdes */ 452238106Sdesint mesh_state_attachment(struct mesh_state* super, struct mesh_state* sub); 453238106Sdes 454238106Sdes/** 455238106Sdes * Create new reply structure and attach it to a mesh state. 456238106Sdes * Does not update stat items in mesh area. 457238106Sdes * @param s: the mesh state. 458238106Sdes * @param edns: edns data for reply (bufsize). 459238106Sdes * @param rep: comm point reply info. 460238106Sdes * @param qid: ID of reply. 461238106Sdes * @param qflags: original query flags. 462238106Sdes * @param qname: original query name. 463238106Sdes * @return: 0 on alloc error. 464238106Sdes */ 465238106Sdesint mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns, 466238106Sdes struct comm_reply* rep, uint16_t qid, uint16_t qflags, uint8_t* qname); 467238106Sdes 468238106Sdes/** 469238106Sdes * Create new callback structure and attach it to a mesh state. 470238106Sdes * Does not update stat items in mesh area. 471238106Sdes * @param s: the mesh state. 472238106Sdes * @param edns: edns data for reply (bufsize). 473238106Sdes * @param buf: buffer for reply 474238106Sdes * @param cb: callback to call with results. 475238106Sdes * @param cb_arg: callback user arg. 476238106Sdes * @param qid: ID of reply. 477238106Sdes * @param qflags: original query flags. 478238106Sdes * @return: 0 on alloc error. 479238106Sdes */ 480238106Sdesint mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns, 481269257Sdes struct sldns_buffer* buf, mesh_cb_func_t cb, void* cb_arg, uint16_t qid, 482238106Sdes uint16_t qflags); 483238106Sdes 484238106Sdes/** 485238106Sdes * Run the mesh. Run all runnable mesh states. Which can create new 486238106Sdes * runnable mesh states. Until completion. Automatically called by 487238106Sdes * mesh_report_reply and mesh_new_client as needed. 488238106Sdes * @param mesh: mesh area. 489238106Sdes * @param mstate: first mesh state to run. 490238106Sdes * @param ev: event the mstate. Others get event_pass. 491238106Sdes * @param e: if a reply, its outbound entry. 492238106Sdes */ 493238106Sdesvoid mesh_run(struct mesh_area* mesh, struct mesh_state* mstate, 494238106Sdes enum module_ev ev, struct outbound_entry* e); 495238106Sdes 496238106Sdes/** 497238106Sdes * Print some stats about the mesh to the log. 498238106Sdes * @param mesh: the mesh to print it for. 499238106Sdes * @param str: descriptive string to go with it. 500238106Sdes */ 501238106Sdesvoid mesh_stats(struct mesh_area* mesh, const char* str); 502238106Sdes 503238106Sdes/** 504238106Sdes * Clear the stats that the mesh keeps (number of queries serviced) 505238106Sdes * @param mesh: the mesh 506238106Sdes */ 507238106Sdesvoid mesh_stats_clear(struct mesh_area* mesh); 508238106Sdes 509238106Sdes/** 510238106Sdes * Print all the states in the mesh to the log. 511238106Sdes * @param mesh: the mesh to print all states of. 512238106Sdes */ 513238106Sdesvoid mesh_log_list(struct mesh_area* mesh); 514238106Sdes 515238106Sdes/** 516238106Sdes * Calculate memory size in use by mesh and all queries inside it. 517238106Sdes * @param mesh: the mesh to examine. 518238106Sdes * @return size in bytes. 519238106Sdes */ 520238106Sdessize_t mesh_get_mem(struct mesh_area* mesh); 521238106Sdes 522238106Sdes/** 523238106Sdes * Find cycle; see if the given mesh is in the targets sub, or sub-sub, ... 524238106Sdes * trees. 525238106Sdes * If the sub-sub structure is too large, it returns 'a cycle'=2. 526238106Sdes * @param qstate: given mesh querystate. 527238106Sdes * @param qinfo: query info for dependency. 528238106Sdes * @param flags: query flags of dependency. 529238106Sdes * @param prime: if dependency is a priming query or not. 530285206Sdes * @param valrec: if it is a validation recursion query (lookup of key, DS). 531238106Sdes * @return true if the name,type,class exists and the given qstate mesh exists 532238106Sdes * as a dependency of that name. Thus if qstate becomes dependent on 533238106Sdes * name,type,class then a cycle is created, this is return value 1. 534238106Sdes * Too large to search is value 2 (also true). 535238106Sdes */ 536238106Sdesint mesh_detect_cycle(struct module_qstate* qstate, struct query_info* qinfo, 537285206Sdes uint16_t flags, int prime, int valrec); 538238106Sdes 539238106Sdes/** compare two mesh_states */ 540238106Sdesint mesh_state_compare(const void* ap, const void* bp); 541238106Sdes 542238106Sdes/** compare two mesh references */ 543238106Sdesint mesh_state_ref_compare(const void* ap, const void* bp); 544238106Sdes 545238106Sdes/** 546238106Sdes * Make space for another recursion state for a reply in the mesh 547238106Sdes * @param mesh: mesh area 548238106Sdes * @param qbuf: query buffer to save if recursion is invoked to make space. 549238106Sdes * This buffer is necessary, because the following sequence in calls 550238106Sdes * can result in an overwrite of the incoming query: 551238106Sdes * delete_other_mesh_query - iter_clean - serviced_delete - waiting 552238106Sdes * udp query is sent - on error callback - callback sends SERVFAIL reply 553238106Sdes * over the same network channel, and shared UDP buffer is overwritten. 554238106Sdes * You can pass NULL if there is no buffer that must be backed up. 555238106Sdes * @return false if no space is available. 556238106Sdes */ 557269257Sdesint mesh_make_new_space(struct mesh_area* mesh, struct sldns_buffer* qbuf); 558238106Sdes 559238106Sdes/** 560238106Sdes * Insert mesh state into a double linked list. Inserted at end. 561238106Sdes * @param m: mesh state. 562238106Sdes * @param fp: pointer to the first-elem-pointer of the list. 563238106Sdes * @param lp: pointer to the last-elem-pointer of the list. 564238106Sdes */ 565238106Sdesvoid mesh_list_insert(struct mesh_state* m, struct mesh_state** fp, 566238106Sdes struct mesh_state** lp); 567238106Sdes 568238106Sdes/** 569238106Sdes * Remove mesh state from a double linked list. Remove from any position. 570238106Sdes * @param m: mesh state. 571238106Sdes * @param fp: pointer to the first-elem-pointer of the list. 572238106Sdes * @param lp: pointer to the last-elem-pointer of the list. 573238106Sdes */ 574238106Sdesvoid mesh_list_remove(struct mesh_state* m, struct mesh_state** fp, 575238106Sdes struct mesh_state** lp); 576238106Sdes 577238106Sdes#endif /* SERVICES_MESH_H */ 578