unbound: services/mesh.h File Reference

unbound 0.1

Data Structures | Macros | Typedefs | Functions
mesh.h File Reference

This file contains functions to assist in dealing with a mesh of query states. More...

`#include "util/rbtree.h"`
`#include "util/netevent.h"`
`#include "util/data/msgparse.h"`
`#include "util/module.h"`
`#include "services/modstack.h"`
`#include "services/rpz.h"`
`#include "libunbound/unbound.h"`

## Data Structures
struct | mesh_area
| Mesh of query states. More...
struct | mesh_state
| A mesh query state Unique per qname, qtype, qclass (from the qstate). More...
struct | mesh_state_ref
| Rbtree reference to a mesh_state. More...
struct | mesh_reply
| Reply to a client. More...
struct | mesh_cb
| Callback to result routine. More...

## Macros
#define | MESH_MAX_ACTIVATION 10000
| Maximum number of mesh state activations.
#define | MESH_MAX_SUBSUB 1024
| Max number of references-to-references-to-references.

## Typedefs
typedef void(* | mesh_cb_func_type) (void *cb_arg, int rcode, struct sldns_buffer *, enum sec_status, char *why_bogus, int was_ratelimited)
| Mesh result callback func.

## Functions
struct mesh_area * | mesh_create (struct module_stack *stack, struct module_env *env)
| Allocate mesh, to empty.
void | mesh_delete (struct mesh_area *mesh)
| Delete mesh, and all query states and replies in it.
void | mesh_new_client (struct mesh_area *mesh, struct query_info *qinfo, struct respip_client_info *cinfo, uint16_t qflags, struct edns_data *edns, struct comm_reply *rep, uint16_t qid, int rpz_passthru)
| New query incoming from clients.
int | mesh_new_callback (struct mesh_area *mesh, struct query_info *qinfo, uint16_t qflags, struct edns_data *edns, struct sldns_buffer *buf, uint16_t qid, mesh_cb_func_type cb, void *cb_arg, int rpz_passthru)
| New query with callback.
void | mesh_new_prefetch (struct mesh_area *mesh, struct query_info *qinfo, uint16_t qflags, time_t leeway, int rpz_passthru, struct comm_reply *rep, struct edns_option *opt_list)
| New prefetch message.
void | mesh_report_reply (struct mesh_area *mesh, struct outbound_entry *e, struct comm_reply *reply, int what)
| Handle new event from the wire.
void | mesh_detach_subs (struct module_qstate *qstate)
| Detach-subqueries.
int | mesh_attach_sub (struct module_qstate *qstate, struct query_info *qinfo, uint16_t qflags, int prime, int valrec, struct module_qstate **newq)
| Attach subquery.
int | mesh_add_sub (struct module_qstate *qstate, struct query_info *qinfo, uint16_t qflags, int prime, int valrec, struct module_qstate **newq, struct mesh_state **sub)
| Add detached query.
void | mesh_query_done (struct mesh_state *mstate)
| Query state is done, send messages to reply entries.
void | mesh_walk_supers (struct mesh_area *mesh, struct mesh_state *mstate)
| Call inform_super for the super query states that are interested in the results from this query state.
void | mesh_state_delete (struct module_qstate *qstate)
| Delete mesh state, cleanup and also rbtrees and so on.
struct mesh_state * | mesh_state_create (struct module_env *env, struct query_info *qinfo, struct respip_client_info *cinfo, uint16_t qflags, int prime, int valrec)
| Create and initialize a new mesh state and its query state Does not put the mesh state into rbtrees and so on.
int | mesh_state_is_unique (struct mesh_state *mstate)
| Check if the mesh state is unique.
void | mesh_state_make_unique (struct mesh_state *mstate)
| Make a mesh state unique.
void | mesh_state_cleanup (struct mesh_state *mstate)
| Cleanup a mesh state and its query state.
void | mesh_delete_all (struct mesh_area *mesh)
| Delete all mesh states from the mesh.
struct mesh_state * | mesh_area_find (struct mesh_area *mesh, struct respip_client_info *cinfo, struct query_info *qinfo, uint16_t qflags, int prime, int valrec)
| Find a mesh state in the mesh area.
int | mesh_state_attachment (struct mesh_state *super, struct mesh_state *sub)
| Setup attachment super/sub relation between super and sub mesh state.
int | mesh_state_add_reply (struct mesh_state *s, struct edns_data *edns, struct comm_reply *rep, uint16_t qid, uint16_t qflags, const struct query_info *qinfo)
| Create new reply structure and attach it to a mesh state.
int | mesh_state_add_cb (struct mesh_state *s, struct edns_data *edns, struct sldns_buffer *buf, mesh_cb_func_type cb, void *cb_arg, uint16_t qid, uint16_t qflags)
| Create new callback structure and attach it to a mesh state.
void | mesh_run (struct mesh_area *mesh, struct mesh_state *mstate, enum module_ev ev, struct outbound_entry *e)
| Run the mesh.
void | mesh_stats (struct mesh_area *mesh, const char *str)
| Print some stats about the mesh to the log.
void | mesh_stats_clear (struct mesh_area *mesh)
| Clear the stats that the mesh keeps (number of queries serviced)
void | mesh_log_list (struct mesh_area *mesh)
| Print all the states in the mesh to the log.
size_t | mesh_get_mem (struct mesh_area *mesh)
| Calculate memory size in use by mesh and all queries inside it.
int | mesh_detect_cycle (struct module_qstate *qstate, struct query_info *qinfo, uint16_t flags, int prime, int valrec)
| Find cycle; see if the given mesh is in the targets sub, or sub-sub, ... trees.
int | mesh_state_compare (const void *ap, const void *bp)
| compare two mesh_states
int | mesh_state_ref_compare (const void *ap, const void *bp)
| compare two mesh references
int | mesh_make_new_space (struct mesh_area *mesh, struct sldns_buffer *qbuf)
| Make space for another recursion state for a reply in the mesh.
void | mesh_list_insert (struct mesh_state *m, struct mesh_state **fp, struct mesh_state **lp)
| Insert mesh state into a double linked list.
void | mesh_list_remove (struct mesh_state *m, struct mesh_state **fp, struct mesh_state **lp)
| Remove mesh state from a double linked list.
void | mesh_state_remove_reply (struct mesh_area *mesh, struct mesh_state *m, struct comm_point *cp)
| Remove mesh reply entry from the reply entry list.
void | mesh_serve_expired_callback (void *arg)
| Callback for when the serve expired client timer has run out.
struct dns_msg * | mesh_serve_expired_lookup (struct module_qstate *qstate, struct query_info *lookup_qinfo)
| Try to get a (expired) cached answer.
int | mesh_jostle_exceeded (struct mesh_area *mesh)
| See if the mesh has space for more queries.

## Detailed Description

This file contains functions to assist in dealing with a mesh of query states.

This mesh is supposed to be thread-specific. It consists of query states (per qname, qtype, qclass) and connections between query states and the super and subquery states, and replies to send back to clients.

## Macro Definition Documentation

## ◆ MESH_MAX_ACTIVATION

#define MESH_MAX_ACTIVATION 10000

Maximum number of mesh state activations.

Any more is likely an infinite loop in the module. It is then terminated.

## ◆ MESH_MAX_SUBSUB

#define MESH_MAX_SUBSUB 1024

Max number of references-to-references-to-references.

. search size. Any more is treated like 'too large', and the creation of a new dependency is failed (so that no loops can be created).

## Typedef Documentation

## ◆ mesh_cb_func_type

typedef void(* mesh_cb_func_type) (void *cb_arg, int rcode, struct sldns_buffer *, enum sec_status, char *why_bogus, int was_ratelimited)

Mesh result callback func.

called as func(cb_arg, rcode, buffer_with_reply, security, why_bogus, was_ratelimited);

## Function Documentation

## ◆ mesh_create()

struct mesh_area * mesh_create | ( | struct module_stack * | stack,
|  | struct module_env * | env
| ) |  |

Allocate mesh, to empty.

Parameters

  stack | module stack to activate, copied (as readonly reference).
  env | environment for new queries.

Returns
  mesh: the new mesh or NULL on error.

References mesh_area::all, mesh_area::ans_expired, module_env::cfg, mesh_area::env, mesh_area::histogram, mesh_area::jostle_max, config_file::jostle_time, log_err(), mesh_area::max_forever_states, mesh_area::max_reply_states, mesh_state_compare(), mesh_area::mods, config_file::msg_buffer_size, mesh_area::num_detached_states, mesh_area::num_forever_states, config_file::num_queries_per_thread, mesh_area::num_reply_addrs, mesh_area::num_reply_states, mesh_area::qbuf_bak, rbtree_init(), mesh_area::run, sldns_buffer_new(), mesh_area::stats_dropped, mesh_area::stats_jostled, and timehist_setup().

Referenced by libworker_setup(), worker_init(), and zonemd_verify_test().

## ◆ mesh_delete()

void mesh_delete | ( | struct mesh_area * | mesh | ) |

Delete mesh, and all query states and replies in it.

Parameters

  mesh | the mesh to delete.

References mesh_area::all, rbtree_type::count, mesh_area::histogram, mesh_delete_helper(), mesh_area::qbuf_bak, rbtree_type::root, sldns_buffer_free(), and timehist_delete().

Referenced by libworker_delete_env(), worker_delete(), and zonemd_verify_test().

## ◆ mesh_new_client()

void mesh_new_client | ( | struct mesh_area * | mesh,
|  | struct query_info * | qinfo,
|  | struct respip_client_info * | cinfo,
|  | uint16_t | qflags,
|  | struct edns_data * | edns,
|  | struct comm_reply * | rep,
|  | uint16_t | qid,
|  | int | rpz_passthru
| ) |  |

New query incoming from clients.

Create new query state if needed, and add mesh_reply to it. Returns error to client on malloc failures. Will run the mesh area queries to process if a new query state is created.

Parameters

  mesh | the mesh.
  qinfo | query from client.
  cinfo | additional information associated with the query client. 'cinfo' itself is ephemeral but data pointed to by its members can be assumed to be valid and unchanged until the query processing is completed.
  qflags | flags from client query.
  edns | edns data from client query.
  rep | where to reply to.
  qid | query id to reply with.
  rpz_passthru | if true, the rpz passthru was previously found and further rpz processing is stopped.

References mesh_area::all, BIT_CD, BIT_RD, comm_point::buffer, comm_reply::c, mesh_state::cb_list, module_env::cfg, comm_point_drop_reply(), comm_point_send_reply(), rbtree_type::count, edns_opt_copy_region(), module_qstate::edns_opts_front_in, mesh_area::env, error_encode(), mesh_area::forever_first, mesh_area::forever_last, comm_point::h2_stream, inplace_cb_reply_servfail_call(), mesh_area::jostle_first, mesh_area::jostle_last, log_assert, log_err(), mesh_area::max_forever_states, mesh_area::max_reply_states, mesh_area_find(), mesh_list_insert(), mesh_make_new_space(), mesh_run(), mesh_serve_expired_init(), mesh_state_add_reply(), mesh_state_create(), mesh_state_delete(), mesh_state_make_unique(), module_event_new, mesh_state::node, module_env::now_tv, mesh_area::num_detached_states, mesh_area::num_forever_states, mesh_area::num_reply_addrs, mesh_area::num_reply_states, edns_data::opt_list_in, edns_data::opt_list_inplace_cb_out, rbtree_insert(), module_qstate::region, mesh_state::reply_list, module_qstate::rpz_passthru, mesh_state::s, module_env::scratch, config_file::serve_expired, config_file::serve_expired_client_timeout, tcp_req_info::spool_buffer, mesh_area::stats_dropped, mesh_state::super_set, comm_point::tcp_req_info, tcp_req_info_add_meshstate(), mesh_state::unique, unique_mesh_state(), comm_point::use_h2, VERB_ALGO, and verbose().

Referenced by worker_handle_request().

## ◆ mesh_new_callback()

int mesh_new_callback | ( | struct mesh_area * | mesh,
|  | struct query_info * | qinfo,
|  | uint16_t | qflags,
|  | struct edns_data * | edns,
|  | struct sldns_buffer * | buf,
|  | uint16_t | qid,
|  | mesh_cb_func_type | cb,
|  | void * | cb_arg,
|  | int | rpz_passthru
| ) |  |

New query with callback.

Create new query state if needed, and add mesh_cb to it. Will run the mesh area queries to process if a new query state is created.

Parameters

  mesh | the mesh.
  qinfo | query from client.
  qflags | flags from client query.
  edns | edns data from client query.
  buf | buffer for reply contents.
  qid | query id to reply with.
  cb | callback function.
  cb_arg | callback user arg.
  rpz_passthru | if true, the rpz passthru was previously found and further rpz processing is stopped.

Returns
  0 on error.

References mesh_area::all, BIT_CD, BIT_RD, mesh_state::cb_list, module_env::cfg, rbtree_type::count, edns_opt_copy_region(), module_qstate::edns_opts_front_in, mesh_area::env, log_assert, mesh_area_find(), mesh_run(), mesh_serve_expired_init(), mesh_state_add_cb(), mesh_state_create(), mesh_state_delete(), mesh_state_make_unique(), module_event_new, mesh_state::node, mesh_area::num_detached_states, mesh_area::num_reply_addrs, mesh_area::num_reply_states, edns_data::opt_list_in, rbtree_insert(), module_qstate::region, mesh_state::reply_list, module_qstate::rpz_passthru, mesh_state::s, config_file::serve_expired, config_file::serve_expired_client_timeout, mesh_state::super_set, mesh_state::unique, and unique_mesh_state().

Referenced by handle_newq(), libworker_attach_mesh(), libworker_fg(), probe_anchor(), xfr_probe_lookup_host(), xfr_transfer_lookup_host(), and zonemd_lookup_dnskey().

## ◆ mesh_new_prefetch()

void mesh_new_prefetch | ( | struct mesh_area * | mesh,
|  | struct query_info * | qinfo,
|  | uint16_t | qflags,
|  | time_t | leeway,
|  | int | rpz_passthru,
|  | struct comm_reply * | rep,
|  | struct edns_option * | opt_list
| ) |  |

New prefetch message.

Create new query state if needed. Will run the mesh area queries to process if a new query state is created.

Parameters

  mesh | the mesh.
  qinfo | query from client.
  qflags | flags from client query.
  leeway | TTL leeway what to expire earlier for this update.
  rpz_passthru | if true, the rpz passthru was previously found and further rpz processing is stopped.
  rep | comm_reply for the client; to be used when subnet is enabled.
  opt_list | edns opt_list from the client; to be used when subnet is enabled.

Referenced by reply_and_prefetch().

## ◆ mesh_report_reply()

void mesh_report_reply | ( | struct mesh_area * | mesh,
|  | struct outbound_entry * | e,
|  | struct comm_reply * | reply,
|  | int | what
| ) |  |

Handle new event from the wire.

A serviced query has returned. The query state will be made runnable, and the mesh_area will process query states until processing is complete.

Parameters

  mesh | the query mesh.
  e | outbound entry, with query state to run and reply pointer.
  reply | the comm point reply info.
  what | NETEVENT_* error code (if not 0, what is wrong, TIMEOUT).

References module_qstate::mesh_info, mesh_run(), module_event_capsfail, module_event_noreply, module_event_reply, NETEVENT_CAPSFAIL, NETEVENT_NOERROR, outbound_entry::qstate, and module_qstate::reply.

Referenced by libworker_handle_service_reply(), and worker_handle_service_reply().

## ◆ mesh_detach_subs()

void mesh_detach_subs | ( | struct module_qstate * | qstate | ) |

Detach-subqueries.

Remove all sub-query references from this query state. Keeps super-references of those sub-queries correct. Updates stat items in mesh_area structure.

Parameters

  qstate | used to find mesh state.

References mesh_area::all, mesh_state::cb_list, rbtree_type::count, module_qstate::env, log_assert, lookup(), module_env::mesh, module_qstate::mesh_info, mesh_state_ref_compare(), mesh_area::num_detached_states, mesh_area::num_reply_states, rbtree_delete(), RBTREE_FOR, rbtree_init(), mesh_state::reply_list, mesh_state_ref::s, mesh_state::sub_set, and mesh_state::super_set.

Referenced by fptr_whitelist_modenv_detach_subs(), libworker_setup(), mesh_state_delete(), and worker_init().

## ◆ mesh_attach_sub()

int mesh_attach_sub | ( | struct module_qstate * | qstate,
|  | struct query_info * | qinfo,
|  | uint16_t | qflags,
|  | int | prime,
|  | int | valrec,
|  | struct module_qstate ** | newq
| ) |  |

Attach subquery.

Creates it if it does not exist already. Keeps sub and super references correct. Performs a cycle detection - for double check - and fails if there is one. Also fails if the sub-sub-references become too large. Updates stat items in mesh_area structure. Pass if it is priming query or not. return: o if error (malloc) happened. o need to initialise the new state (module init; it is a new state). so that the next run of the query with this module is successful. o no init needed, attachment successful.

Parameters

  qstate | the state to find mesh state, and that wants to receive the results from the new subquery.
  qinfo | what to query for (copied).
  qflags | what flags to use (RD / CD flag or not).
  prime | if it is a (stub) priming query.
  valrec | if it is a validation recursion query (lookup of key, DS).
  newq | If the new subquery needs initialisation, it is returned, otherwise NULL is returned.

Returns
  : false on error, true if success (and init may be needed).

References mesh_state::cb_list, rbtree_type::count, module_qstate::env, log_assert, module_env::mesh, mesh_add_sub(), module_qstate::mesh_info, mesh_state_attachment(), mesh_area::num_detached_states, mesh_state::reply_list, and mesh_state::super_set.

Referenced by fptr_whitelist_modenv_attach_sub(), libworker_setup(), and worker_init().

## ◆ mesh_add_sub()

int mesh_add_sub | ( | struct module_qstate * | qstate,
|  | struct query_info * | qinfo,
|  | uint16_t | qflags,
|  | int | prime,
|  | int | valrec,
|  | struct module_qstate ** | newq,
|  | struct mesh_state ** | sub
| ) |  |

Add detached query.

Creates it if it does not exist already. Does not make super/sub references. Performs a cycle detection - for double check - and fails if there is one. Updates stat items in mesh_area structure. Pass if it is priming query or not. return: o if error (malloc) happened. o need to initialise the new state (module init; it is a new state). so that the next run of the query with this module is successful. o no init needed, attachment successful. o added subquery, created if it did not exist already.

Parameters

  qstate | the state to find mesh state, and that wants to receive the results from the new subquery.
  qinfo | what to query for (copied).
  qflags | what flags to use (RD / CD flag or not).
  prime | if it is a (stub) priming query.
  valrec | if it is a validation recursion query (lookup of key, DS).
  newq | If the new subquery needs initialisation, it is returned, otherwise NULL is returned.
  sub | The added mesh state, created if it did not exist already.

Returns
  : false on error, true if success (and init may be needed).

References mesh_area::all, module_qstate::env, log_assert, log_err(), module_env::mesh, mesh_area_find(), mesh_detect_cycle_found(), mesh_state_create(), mesh_area::num_detached_states, rbtree_insert(), mesh_area::run, VERB_ALGO, and verbose().

Referenced by fptr_whitelist_modenv_add_sub(), libworker_setup(), mesh_attach_sub(), and worker_init().

## ◆ mesh_query_done()

void mesh_query_done | ( | struct mesh_state * | mstate | ) |

Query state is done, send messages to reply entries.

Encode messages using reply entry values and the querystate (with original qinfo), using given reply_info. Pass errcode != 0 if an error reply is needed. If no reply entries, nothing is done. Must be called before a module can module_finished or return module_error. The module must handle the super query states itself as well.

Parameters

  mstate | mesh state that is done. return_rcode and return_msg are used for replies. return_rcode: if not 0 (NOERROR) an error is sent back (and return_msg is ignored). return_msg: reply to encode and send back to clients.

References comm_point::buffer, comm_reply::c, mesh_state::cb_list, module_env::cfg, comm_reply::client_addr, comm_reply::client_addrlen, comm_point_drop_reply(), comm_timer_delete(), rbtree_type::count, module_qstate::env, errinf_to_str_servfail(), reply_info::flags, FLAGS_GET_RCODE, module_qstate::is_drop, mesh_reply::local_alias, log_assert, log_err(), config_file::log_servfail, module_env::mesh, mesh_do_callback(), mesh_send_reply(), mesh_serve_expired_callback(), mesh_reply::next, mesh_cb::next, mesh_area::num_detached_states, mesh_area::num_reply_states, query_info::qclass, module_qstate::qinfo, mesh_reply::qname, query_info::qtype, mesh_reply::query_reply, dns_msg::rep, mesh_state::replies_sent, mesh_state::reply_list, module_qstate::respip_action_info, respip_inform_print(), module_qstate::return_msg, module_qstate::return_rcode, mesh_area::rpz_action, mesh_state::s, module_qstate::serve_expired_data, tcp_req_info::spool_buffer, mesh_reply::start_time, config_file::stat_extended, mesh_state::super_set, comm_point::tcp_req_info, tcp_req_info_remove_mesh_state(), and config_file::val_log_squelch.

Referenced by mesh_continue().

## ◆ mesh_walk_supers()

void mesh_walk_supers | ( | struct mesh_area * | mesh,
|  | struct mesh_state * | mstate
| ) |  |

Call inform_super for the super query states that are interested in the results from this query state.

These can then be changed for error or results. Called when a module is module_finished or returns module_error. The super query states become runnable with event module_event_pass, it calls the current module for the super with the inform_super event.

Parameters

  mesh | mesh area to add newly runnable modules to.
  mstate | the state that has results, used to find mesh state.

References module_qstate::curmod, fptr_ok, fptr_whitelist_mod_inform_super(), module_func_block::inform_super, module_stack::mod, mesh_area::mods, RBTREE_FOR, rbtree_insert(), mesh_area::run, mesh_state::run_node, mesh_state::s, mesh_state_ref::s, and mesh_state::super_set.

Referenced by mesh_continue(), and mesh_make_new_space().

## ◆ mesh_state_delete()

void mesh_state_delete | ( | struct module_qstate * | qstate | ) |

Delete mesh state, cleanup and also rbtrees and so on.

Will detach from all super/subnodes.

Parameters

  qstate | to remove.

References mesh_area::all, mesh_state::cb_list, rbtree_type::count, module_qstate::env, mesh_area::forever_first, mesh_area::forever_last, mesh_area::jostle_first, mesh_area::jostle_last, rbnode_type::key, log_assert, module_env::mesh, mesh_detach_subs(), module_qstate::mesh_info, mesh_list_remove(), mesh_state_cleanup(), mesh_state_ref::node, mesh_area::num_detached_states, mesh_area::num_forever_states, mesh_area::num_reply_states, rbtree_delete(), RBTREE_FOR, mesh_state::reply_list, mesh_area::run, mesh_state::s, mesh_state_ref::s, mesh_state::sub_set, and mesh_state::super_set.

Referenced by fptr_whitelist_modenv_kill_sub(), libworker_setup(), mesh_continue(), mesh_delete_helper(), mesh_make_new_space(), mesh_new_callback(), mesh_new_client(), and worker_init().

## ◆ mesh_state_create()

struct mesh_state * mesh_state_create | ( | struct module_env * | env,
|  | struct query_info * | qinfo,
|  | struct respip_client_info * | cinfo,
|  | uint16_t | qflags,
|  | int | prime,
|  | int | valrec
| ) |  |

Create and initialize a new mesh state and its query state Does not put the mesh state into rbtrees and so on.

Parameters

  env | module environment to set.
  qinfo | query info that the mesh is for.
  cinfo | control info for the query client (can be NULL).
  qflags | flags for query (RD / CD flag).
  prime | if true, it is a priming query, set is_priming on mesh state.
  valrec | if true, it is a validation recursion query, and sets is_valrec on the mesh state.

Returns
  : new mesh state or NULL on allocation error.

References module_env::alloc, alloc_reg_obtain(), alloc_reg_release(), BIT_CD, BIT_RD, module_qstate::client_info, module_qstate::curmod, module_qstate::edns_opts_back_in, module_qstate::edns_opts_back_out, module_qstate::edns_opts_front_in, module_qstate::edns_opts_front_out, module_qstate::env, module_qstate::ext_state, module_qstate::is_priming, module_qstate::is_valrec, rbnode_type::key, query_info::local_alias, module_env::mesh, module_qstate::mesh_info, mesh_state_ref_compare(), module_qstate::minfo, mesh_area::mods, module_state_initial, module_qstate::need_refetch, module_qstate::no_cache_lookup, module_qstate::no_cache_store, mesh_state::node, module_env::now, module_stack::num, mesh_state::num_activated, module_qstate::prefetch_leeway, query_info::qclass, module_qstate::qinfo, query_info::qname, query_info::qname_len, module_qstate::qstarttime, query_info::qtype, module_qstate::query_flags, rbtree_init(), RBTREE_NULL, module_qstate::region, regional_alloc(), regional_alloc_init(), mesh_state::replies_sent, module_qstate::reply, mesh_state::reply_list, module_qstate::return_msg, module_qstate::return_rcode, mesh_state::run_node, mesh_state::s, module_qstate::serve_expired_data, mesh_state::sub_set, mesh_state::super_set, mesh_state::unique, and module_qstate::was_ratelimited.

Referenced by mesh_add_sub(), mesh_new_callback(), and mesh_new_client().

## ◆ mesh_state_is_unique()

int mesh_state_is_unique | ( | struct mesh_state * | mstate | ) |

Check if the mesh state is unique.

A unique mesh state uses it's unique member to point to itself, else NULL.

Parameters

  mstate | mesh state to check.

Returns
  true if the mesh state is unique, false otherwise.

References mesh_state::unique.

## ◆ mesh_state_make_unique()

void mesh_state_make_unique | ( | struct mesh_state * | mstate | ) |

Make a mesh state unique.

A unique mesh state uses it's unique member to point to itself.

Parameters

  mstate | mesh state to check.

References mesh_state::unique.

Referenced by mesh_new_callback(), and mesh_new_client().

## ◆ mesh_state_cleanup()

void mesh_state_cleanup | ( | struct mesh_state * | mstate | ) |

Cleanup a mesh state and its query state.

Does not do rbtree or reference cleanup.

Parameters

  mstate | mesh state to cleanup. Its pointer may no longer be used afterwards. Cleanup rbtrees before calling this function.

References module_env::alloc, alloc_reg_release(), mesh_cb::cb, mesh_state::cb_list, module_func_block::clear, comm_point_drop_reply(), comm_timer_delete(), module_qstate::env, module_qstate::ext_state, fptr_ok, fptr_whitelist_mesh_cb(), fptr_whitelist_mod_clear(), log_assert, module_env::mesh, module_qstate::minfo, module_stack::mod, mesh_area::mods, module_finished, mesh_reply::next, module_stack::num, mesh_area::num_reply_addrs, mesh_reply::query_reply, module_qstate::region, mesh_state::replies_sent, mesh_state::reply_list, mesh_state::s, sec_status_unchecked, and module_qstate::serve_expired_data.

Referenced by mesh_state_delete().

## ◆ mesh_delete_all()

void mesh_delete_all | ( | struct mesh_area * | mesh | ) |

Delete all mesh states from the mesh.

Parameters

  mesh | the mesh area to clear

References mesh_area::all, rbtree_type::count, mesh_area::forever_first, mesh_area::forever_last, mesh_area::jostle_first, mesh_area::jostle_last, mesh_delete_helper(), mesh_state_compare(), mesh_area::num_detached_states, mesh_area::num_forever_states, mesh_area::num_reply_addrs, mesh_area::num_reply_states, rbtree_init(), rbtree_type::root, mesh_area::run, and mesh_area::stats_dropped.

Referenced by do_flush_requestlist(), and do_forward().

## ◆ mesh_area_find()

struct mesh_state * mesh_area_find | ( | struct mesh_area * | mesh,
|  | struct respip_client_info * | cinfo,
|  | struct query_info * | qinfo,
|  | uint16_t | qflags,
|  | int | prime,
|  | int | valrec
| ) |  |

Find a mesh state in the mesh area.

Pass relevant flags.

Parameters

  mesh | the mesh area to look in.
  cinfo | if non-NULL client specific info that may affect IP-based actions that apply to the query result.
  qinfo | what query
  qflags | if RD / CD bit is set or not.
  prime | if it is a priming query.
  valrec | if it is a validation-recursion query.

Returns
  : mesh state or NULL if not found.

References mesh_area::all, module_qstate::client_info, module_qstate::is_priming, module_qstate::is_valrec, rbnode_type::key, mesh_state::node, module_qstate::qinfo, module_qstate::query_flags, rbtree_search(), mesh_state::s, and mesh_state::unique.

Referenced by mesh_add_sub(), mesh_detect_cycle(), mesh_new_callback(), and mesh_new_client().

## ◆ mesh_state_attachment()

int mesh_state_attachment | ( | struct mesh_state * | super,
|  | struct mesh_state * | sub
| ) |  |

Setup attachment super/sub relation between super and sub mesh state.

The relation must not be present when calling the function. Does not update stat items in mesh_area.

Parameters

  super | super state.
  sub | sub state.

Returns
  : 0 on alloc error.

References rbnode_type::key, log_assert, log_err(), mesh_state_ref::node, rbtree_insert(), module_qstate::region, regional_alloc(), mesh_state::s, mesh_state_ref::s, mesh_state::sub_set, and mesh_state::super_set.

Referenced by mesh_attach_sub().

## ◆ mesh_state_add_reply()

int mesh_state_add_reply | ( | struct mesh_state * | s,
|  | struct edns_data * | edns,
|  | struct comm_reply * | rep,
|  | uint16_t | qid,
|  | uint16_t | qflags,
|  | const struct query_info * | qinfo
| ) |  |

Create new reply structure and attach it to a mesh state.

Does not update stat items in mesh area.

Parameters

  s | the mesh state.
  edns | edns data for reply (bufsize).
  rep | comm point reply info.
  qid | ID of reply.
  qflags | original query flags.
  qinfo | original query info.

Returns
  : 0 on alloc error.

References comm_reply::c, packed_rrset_data::count, lruhash_entry::data, packed_rrset_key::dname, packed_rrset_key::dname_len, mesh_reply::edns, edns_opt_copy_region(), ub_packed_rrset_key::entry, module_qstate::env, mesh_reply::h2_stream, comm_point::h2_stream, LDNS_RR_TYPE_CNAME, mesh_reply::local_alias, query_info::local_alias, log_assert, local_rrset::next, mesh_reply::next, module_env::now_tv, edns_data::opt_list_in, edns_data::opt_list_inplace_cb_out, edns_data::opt_list_out, mesh_reply::qflags, mesh_reply::qid, module_qstate::qinfo, mesh_reply::qname, query_info::qname, query_info::qname_len, mesh_reply::query_reply, module_qstate::region, regional_alloc(), regional_alloc_init(), regional_alloc_zero(), mesh_state::reply_list, ub_packed_rrset_key::rk, packed_rrset_data::rr_data, packed_rrset_data::rr_len, packed_rrset_data::rr_ttl, local_rrset::rrset, rrset_insert_rr(), mesh_state::s, mesh_reply::start_time, packed_rrset_key::type, and comm_point::use_h2.

Referenced by mesh_new_client().

## ◆ mesh_state_add_cb()

int mesh_state_add_cb | ( | struct mesh_state * | s,
|  | struct edns_data * | edns,
|  | struct sldns_buffer * | buf,
|  | mesh_cb_func_type | cb,
|  | void * | cb_arg,
|  | uint16_t | qid,
|  | uint16_t | qflags
| ) |  |

Create new callback structure and attach it to a mesh state.

Does not update stat items in mesh area.

Parameters

  s | the mesh state.
  edns | edns data for reply (bufsize).
  buf | buffer for reply
  cb | callback to call with results.
  cb_arg | callback user arg.
  qid | ID of reply.
  qflags | original query flags.

Returns
  : 0 on alloc error.

References mesh_cb::buf, mesh_cb::cb, mesh_cb::cb_arg, mesh_state::cb_list, mesh_cb::edns, edns_opt_copy_region(), fptr_whitelist_mesh_cb(), log_assert, mesh_cb::next, edns_data::opt_list_in, edns_data::opt_list_inplace_cb_out, edns_data::opt_list_out, mesh_cb::qflags, mesh_cb::qid, module_qstate::region, regional_alloc(), and mesh_state::s.

Referenced by mesh_new_callback().

## ◆ mesh_run()

void mesh_run | ( | struct mesh_area * | mesh,
|  | struct mesh_state * | mstate,
|  | enum module_ev | ev,
|  | struct outbound_entry * | e
| ) |  |

Run the mesh.

Run all runnable mesh states. Which can create new runnable mesh states. Until completion. Automatically called by mesh_report_reply and mesh_new_client as needed.

Parameters

  mesh | mesh area.
  mstate | first mesh state to run.
  ev | event the mstate. Others get event_pass.
  e | if a reply, its outbound entry.

References rbtree_type::count, module_qstate::curmod, module_qstate::env, module_qstate::ext_state, fptr_ok, fptr_whitelist_mod_operate(), rbnode_type::key, mesh_continue(), mesh_log_list(), mesh_stats(), module_stack::mod, mesh_area::mods, module_event_pass, module_func_block::name, module_func_block::operate, rbtree_delete(), regional_free_all(), module_qstate::reply, rbtree_type::root, mesh_area::run, mesh_state::s, module_env::scratch, strextstate(), VERB_ALGO, verbose(), and verbosity.

Referenced by mesh_new_callback(), mesh_new_client(), and mesh_report_reply().

## ◆ mesh_stats()

void mesh_stats | ( | struct mesh_area * | mesh,
|  | const char * | str
| ) |  |

Print some stats about the mesh to the log.

Parameters

  mesh | the mesh to print it for.
  str | descriptive string to go with it.

References mesh_area::all, rbtree_type::count, mesh_area::histogram, log_info(), mesh_area::num_detached_states, mesh_area::num_reply_addrs, mesh_area::num_reply_states, mesh_area::replies_sent, mesh_area::replies_sum_wait, mesh_area::stats_dropped, mesh_area::stats_jostled, timehist_log(), timeval_divide(), VERB_DETAIL, and verbose().

Referenced by mesh_run(), worker_delete(), and worker_stat_timer_cb().

## ◆ mesh_stats_clear()

void mesh_stats_clear | ( | struct mesh_area * | mesh | ) |

Clear the stats that the mesh keeps (number of queries serviced)

Parameters

  mesh | the mesh

References mesh_area::ans_bogus, mesh_area::ans_expired, mesh_area::ans_nodata, mesh_area::ans_rcode, mesh_area::ans_secure, mesh_area::histogram, mesh_area::replies_sent, mesh_area::replies_sum_wait, mesh_area::rpz_action, mesh_area::stats_dropped, mesh_area::stats_jostled, timehist_clear(), UB_STATS_RCODE_NUM, and UB_STATS_RPZ_ACTION_NUM.

Referenced by worker_stats_clear().

## ◆ mesh_log_list()

void mesh_log_list | ( | struct mesh_area * | mesh | ) |

Print all the states in the mesh to the log.

Parameters

  mesh | the mesh to print all states of.

References mesh_area::all, BIT_CD, BIT_RD, mesh_state::cb_list, rbtree_type::count, module_qstate::curmod, module_qstate::is_priming, module_qstate::is_valrec, log_query_info(), module_qstate::qinfo, module_qstate::query_flags, RBTREE_FOR, mesh_state::reply_list, mesh_state::s, mesh_state::sub_set, mesh_state::super_set, and VERB_ALGO.

Referenced by mesh_run().

## ◆ mesh_get_mem()

size_t mesh_get_mem | ( | struct mesh_area * | mesh | ) |

Calculate memory size in use by mesh and all queries inside it.

Parameters

  mesh | the mesh to examine.

Returns
  size in bytes.

References mesh_area::all, mesh_area::histogram, timehist::num, mesh_area::qbuf_bak, RBTREE_FOR, module_qstate::region, regional_get_mem(), mesh_state::s, and sldns_buffer_capacity().

Referenced by worker_mem_report().

## ◆ mesh_detect_cycle()

int mesh_detect_cycle | ( | struct module_qstate * | qstate,
|  | struct query_info * | qinfo,
|  | uint16_t | flags,
|  | int | prime,
|  | int | valrec
| ) |  |

Find cycle; see if the given mesh is in the targets sub, or sub-sub, ... trees.

If the sub-sub structure is too large, it returns 'a cycle'=2.

Parameters

  qstate | given mesh querystate.
  qinfo | query info for dependency.
  flags | query flags of dependency.
  prime | if dependency is a priming query or not.
  valrec | if it is a validation recursion query (lookup of key, DS).

Returns
  true if the name,type,class exists and the given qstate mesh exists as a dependency of that name. Thus if qstate becomes dependent on name,type,class then a cycle is created, this is return value 1. Too large to search is value 2 (also true).

References module_qstate::env, module_env::mesh, mesh_area_find(), and mesh_detect_cycle_found().

Referenced by fptr_whitelist_modenv_detect_cycle(), libworker_setup(), and worker_init().

## ◆ mesh_make_new_space()

int mesh_make_new_space | ( | struct mesh_area * | mesh,
|  | struct sldns_buffer * | qbuf
| ) |  |

Make space for another recursion state for a reply in the mesh.

Parameters

  mesh | mesh area
  qbuf | query buffer to save if recursion is invoked to make space. This buffer is necessary, because the following sequence in calls can result in an overwrite of the incoming query: delete_other_mesh_query - iter_clean - serviced_delete - waiting udp query is sent - on error callback - callback sends SERVFAIL reply over the same network channel, and shared UDP buffer is overwritten. You can pass NULL if there is no buffer that must be backed up.

Returns
  false if no space is available.

References rbtree_type::count, mesh_area::env, mesh_area::jostle_first, mesh_area::jostle_max, log_nametypeclass(), mesh_area::max_reply_states, mesh_state_delete(), mesh_walk_supers(), module_env::now_tv, mesh_area::num_reply_states, mesh_area::qbuf_bak, query_info::qclass, module_qstate::qinfo, query_info::qname, query_info::qtype, mesh_state::reply_list, module_qstate::return_msg, module_qstate::return_rcode, mesh_state::s, sldns_buffer_copy(), mesh_reply::start_time, mesh_area::stats_jostled, mesh_state::super_set, timeval_smaller(), timeval_subtract(), VERB_ALGO, and verbose().

Referenced by mesh_new_client().

## ◆ mesh_list_insert()

void mesh_list_insert | ( | struct mesh_state * | m,
|  | struct mesh_state ** | fp,
|  | struct mesh_state ** | lp
| ) |  |

Insert mesh state into a double linked list.

Inserted at end.

Parameters

  m | mesh state.
  fp | pointer to the first-elem-pointer of the list.
  lp | pointer to the last-elem-pointer of the list.

References mesh_state::next, and mesh_state::prev.

Referenced by mesh_new_client().

## ◆ mesh_list_remove()

void mesh_list_remove | ( | struct mesh_state * | m,
|  | struct mesh_state ** | fp,
|  | struct mesh_state ** | lp
| ) |  |

Remove mesh state from a double linked list.

Remove from any position.

Parameters

  m | mesh state.
  fp | pointer to the first-elem-pointer of the list.
  lp | pointer to the last-elem-pointer of the list.

References mesh_state::next, and mesh_state::prev.

Referenced by mesh_state_delete().

## ◆ mesh_state_remove_reply()

void mesh_state_remove_reply | ( | struct mesh_area * | mesh,
|  | struct mesh_state * | m,
|  | struct comm_point * | cp
| ) |  |

Remove mesh reply entry from the reply entry list.

Searches for the comm_point pointer.

Parameters

  mesh | to update the counters.
  m | the mesh state.
  cp | the comm_point to remove from the list.

References comm_reply::c, mesh_state::cb_list, rbtree_type::count, log_assert, mesh_reply::next, mesh_area::num_detached_states, mesh_area::num_reply_addrs, mesh_area::num_reply_states, mesh_reply::query_reply, mesh_state::reply_list, and mesh_state::super_set.

Referenced by tcp_req_info_clear().

## ◆ mesh_serve_expired_callback()

void mesh_serve_expired_callback | ( | void * | arg | ) |

Callback for when the serve expired client timer has run out.

Tries to find an expired answer in the cache and reply that to the client.

Parameters

  arg | the argument passed to the callback.

References mesh_area::ans_expired, apply_respip_action(), module_env::auth_zones, BIT_CD, comm_point::buffer, comm_reply::c, mesh_state::cb_list, module_env::cfg, comm_reply::client_addr, comm_reply::client_addrlen, module_qstate::client_info, comm_timer_delete(), rbtree_type::count, config_file::ede, config_file::ede_serve_expired, mesh_reply::edns, edns_opt_list_append_ede(), edns_data::edns_present, module_qstate::env, fptr_ok, fptr_whitelist_serve_expired_lookup(), get_cname_target(), config_file::ignore_cd, module_qstate::is_drop, mesh_reply::local_alias, log_assert, log_dns_msg(), log_err(), module_env::mesh, mesh_do_callback(), mesh_send_reply(), module_env::need_to_validate, mesh_reply::next, mesh_cb::next, module_qstate::no_cache_lookup, mesh_area::num_detached_states, mesh_area::num_reply_states, edns_data::opt_list_out, query_info::qclass, module_qstate::qinfo, mesh_reply::qname, query_info::qname, query_info::qname_len, query_info::qtype, module_qstate::query_flags, mesh_reply::query_reply, module_qstate::region, dns_msg::rep, mesh_state::reply_list, respip_inform_print(), respip_merge_cname(), respip_none, mesh_area::rpz_action, mesh_state::s, module_qstate::serve_expired_data, tcp_req_info::spool_buffer, mesh_reply::start_time, config_file::stat_extended, mesh_state::super_set, comm_point::tcp_req_info, tcp_req_info_remove_mesh_state(), mesh_area::use_response_ip, mesh_area::use_rpz, VERB_ALGO, verbose(), and verbosity.

Referenced by fptr_whitelist_comm_timer(), mesh_query_done(), and mesh_serve_expired_init().

## ◆ mesh_serve_expired_lookup()

struct dns_msg * mesh_serve_expired_lookup | ( | struct module_qstate * | qstate,
|  | struct query_info * | lookup_qinfo
| ) |  |

Try to get a (expired) cached answer.

This needs to behave like the worker's answer_from_cache() in order to have the same behavior as when replying from cache.

Parameters

  qstate | the module qstate.
  lookup_qinfo | the query info to look for in the cache.

Returns
  dns_msg if a cached answer was found, otherwise NULL.

References BIT_CD, module_env::cfg, lruhash_entry::data, module_qstate::env, config_file::ignore_cd, msgreply_entry::key, lruhash_entry::key, lruhash_entry::lock, module_env::msg_cache, module_env::need_to_validate, module_env::now, module_qstate::query_flags, query_info_hash(), module_qstate::region, dns_msg::rep, reply_all_rrsets_secure(), module_env::scratch, sec_status_bogus, sec_status_secure, sec_status_secure_sentinel_fail, sec_status_unchecked, reply_info::security, config_file::serve_expired, slabhash_lookup(), tomsg(), VERB_ALGO, and verbose().

Referenced by fptr_whitelist_serve_expired_lookup(), and mesh_serve_expired_init().

## ◆ mesh_jostle_exceeded()

int mesh_jostle_exceeded | ( | struct mesh_area * | mesh | ) |

See if the mesh has space for more queries.

You can allocate queries anyway, but this checks for the allocated space.

Parameters

  mesh | mesh area.

Returns
  true if the query list is full. It checks the number of all queries, not just number of reply states, that have a client address. So that spawned queries count too, that were created by the iterator, or other modules.

References mesh_area::all, rbtree_type::count, and mesh_area::max_reply_states.

Referenced by generate_dnskey_prefetch(), processLastResort(), processQueryTargets(), and query_for_targets().