worker.c File Reference

This file implements the worker that handles callbacks on events, for pending requests. More...

#include "config.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/random.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
#include "daemon/remote.h"
#include "daemon/acl_list.h"
#include "util/netevent.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/regional.h"
#include "util/storage/slabhash.h"
#include "services/listen_dnsport.h"
#include "services/outside_network.h"
#include "services/outbound_list.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
#include "services/cache/dns.h"
#include "services/authzone.h"
#include "services/mesh.h"
#include "services/localzone.h"
#include "services/rpz.h"
#include "util/data/msgparse.h"
#include "util/data/msgencode.h"
#include "util/data/dname.h"
#include "util/fptr_wlist.h"
#include "util/proxy_protocol.h"
#include "util/tube.h"
#include "util/edns.h"
#include "util/timeval_func.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "iterator/iter_utils.h"
#include "validator/autotrust.h"
#include "validator/val_anchor.h"
#include "respip/respip.h"
#include "libunbound/context.h"
#include "libunbound/libworker.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "util/shm_side/shm_main.h"
#include "dnscrypt/dnscrypt.h"
#include "dnstap/dtstream.h"
#include <signal.h>

Data Structures

struct  check_request_result
 Structure holding the result of the worker_check_request function. More...
 

Macros

#define NORMAL_UDP_SIZE   512 /* bytes */
 Size of an UDP datagram.
 
#define ERROR_RATELIMIT   100 /* qps */
 ratelimit for error responses
 
#define PREFETCH_EXPIRY_ADD   60
 seconds to add to prefetch leeway. More...
 
#define TA_RESPONSE_MAX_TXT   16 /* max number of TXT records */
 
#define TA_RESPONSE_MAX_TAGS   32 /* max number of tags printed per zone */
 

Functions

static void worker_mem_report (struct worker *ATTR_UNUSED(worker), struct serviced_query *ATTR_UNUSED(cur_serv))
 Report on memory usage by this thread and global.
 
void worker_send_cmd (struct worker *worker, enum worker_commands cmd)
 Send a command to a worker. More...
 
int worker_handle_service_reply (struct comm_point *c, void *arg, int error, struct comm_reply *reply_info)
 process incoming serviced query replies from the network
 
static int worker_err_ratelimit (struct worker *worker, int err)
 ratelimit error replies More...
 
static void worker_check_request (sldns_buffer *pkt, struct worker *worker, struct check_request_result *out)
 check request sanity. More...
 
void worker_handle_control_cmd (struct tube *ATTR_UNUSED(tube), uint8_t *msg, size_t len, int error, void *arg)
 
static enum sec_status check_delegation_secure (struct reply_info *rep)
 check if a delegation is secure
 
static void deleg_remove_nonsecure_additional (struct reply_info *rep)
 remove nonsecure from a delegation referral additional section
 
static int answer_norec_from_cache (struct worker *worker, struct query_info *qinfo, uint16_t id, uint16_t flags, struct comm_reply *repinfo, struct edns_data *edns)
 answer nonrecursive query from the cache
 
static int apply_respip_action (struct worker *worker, const struct query_info *qinfo, struct respip_client_info *cinfo, struct reply_info *rep, struct sockaddr_storage *addr, socklen_t addrlen, struct ub_packed_rrset_key **alias_rrset, struct reply_info **encode_repp, struct auth_zones *az)
 Apply, if applicable, a response IP action to a cached answer. More...
 
static int answer_from_cache (struct worker *worker, struct query_info *qinfo, struct respip_client_info *cinfo, int *need_drop, int *is_expired_answer, int *is_secure_answer, struct ub_packed_rrset_key **alias_rrset, struct reply_info **partial_repp, struct reply_info *rep, uint16_t id, uint16_t flags, struct comm_reply *repinfo, struct edns_data *edns)
 answer query from the cache. More...
 
static void reply_and_prefetch (struct worker *worker, struct query_info *qinfo, uint16_t flags, struct comm_reply *repinfo, time_t leeway, int noreply, int rpz_passthru, struct edns_option *opt_list)
 Reply to client and perform prefetch to keep cache up to date.
 
static void chaos_replystr (sldns_buffer *pkt, char **str, int num, struct edns_data *edns, struct worker *worker, struct comm_reply *repinfo)
 Fill CH class answer into buffer. More...
 
static void chaos_replyonestr (sldns_buffer *pkt, const char *str, struct edns_data *edns, struct worker *worker, struct comm_reply *repinfo)
 Reply with one string.
 
static void chaos_trustanchor (sldns_buffer *pkt, struct edns_data *edns, struct worker *w, struct comm_reply *repinfo)
 Create CH class trustanchor answer. More...
 
static int answer_chaos (struct worker *w, struct query_info *qinfo, struct edns_data *edns, struct comm_reply *repinfo, sldns_buffer *pkt)
 Answer CH class queries. More...
 
static void answer_notify (struct worker *w, struct query_info *qinfo, struct edns_data *edns, sldns_buffer *pkt, struct sockaddr_storage *addr, socklen_t addrlen)
 Answer notify queries. More...
 
static int deny_refuse (struct comm_point *c, enum acl_access acl, enum acl_access deny, enum acl_access refuse, struct worker *worker, struct comm_reply *repinfo, struct acl_addr *acladdr, int ede, struct check_request_result *check_result)
 
static int deny_refuse_all (struct comm_point *c, enum acl_access *acl, struct worker *worker, struct comm_reply *repinfo, struct acl_addr **acladdr, int ede, int check_proxy, struct check_request_result *check_result)
 
static int deny_refuse_non_local (struct comm_point *c, enum acl_access acl, struct worker *worker, struct comm_reply *repinfo, struct acl_addr *acladdr, int ede, struct check_request_result *check_result)
 
static int check_ip_ratelimit (struct worker *worker, struct sockaddr_storage *addr, socklen_t addrlen, int has_cookie, sldns_buffer *pkt)
 
int worker_handle_request (struct comm_point *c, void *arg, int error, struct comm_reply *repinfo)
 handles callbacks from listening event interface
 
void worker_sighandler (int sig, void *arg)
 Worker signal handler function. More...
 
static void worker_restart_timer (struct worker *worker)
 restart statistics timer for worker, if enabled
 
void worker_stat_timer_cb (void *arg)
 statistics timer callback handler
 
void worker_probe_timer_cb (void *arg)
 probe timer callback handler
 
struct workerworker_create (struct daemon *daemon, int id, int *ports, int n)
 Create the worker structure. More...
 
int worker_init (struct worker *worker, struct config_file *cfg, struct listen_port *ports, int do_sigs)
 Initialize worker. More...
 
void worker_work (struct worker *worker)
 Make worker work.
 
void worker_delete (struct worker *worker)
 Delete worker.
 
struct outbound_entryworker_send_query (struct query_info *qinfo, uint16_t flags, int dnssec, int want_dnssec, int nocaps, int check_ratelimit, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char *tls_auth_name, struct module_qstate *q, int *was_ratelimited)
 Worker service routine to send serviced queries to authoritative servers. More...
 
void worker_alloc_cleanup (void *arg)
 cleanup the cache to remove all rrset IDs from it, arg is worker
 
void worker_stats_clear (struct worker *worker)
 Init worker stats - includes server_stats_init, outside network and mesh. More...
 
void worker_start_accept (void *arg)
 start accept callback handler
 
void worker_stop_accept (void *arg)
 stop accept callback handler
 
struct outbound_entrylibworker_send_query (struct query_info *ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit), struct sockaddr_storage *ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), uint8_t *ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), char *ATTR_UNUSED(tls_auth_name), struct module_qstate *ATTR_UNUSED(q), int *ATTR_UNUSED(was_ratelimited))
 
int libworker_handle_service_reply (struct comm_point *ATTR_UNUSED(c), void *ATTR_UNUSED(arg), int ATTR_UNUSED(error), struct comm_reply *ATTR_UNUSED(reply_info))
 
void libworker_handle_control_cmd (struct tube *ATTR_UNUSED(tube), uint8_t *ATTR_UNUSED(buffer), size_t ATTR_UNUSED(len), int ATTR_UNUSED(error), void *ATTR_UNUSED(arg))
 
void libworker_fg_done_cb (void *ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), sldns_buffer *ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), char *ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
 
void libworker_bg_done_cb (void *ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), sldns_buffer *ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), char *ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
 
void libworker_event_done_cb (void *ATTR_UNUSED(arg), int ATTR_UNUSED(rcode), sldns_buffer *ATTR_UNUSED(buf), enum sec_status ATTR_UNUSED(s), char *ATTR_UNUSED(why_bogus), int ATTR_UNUSED(was_ratelimited))
 
int context_query_cmp (const void *ATTR_UNUSED(a), const void *ATTR_UNUSED(b))
 
int order_lock_cmp (const void *ATTR_UNUSED(e1), const void *ATTR_UNUSED(e2))
 
int codeline_cmp (const void *ATTR_UNUSED(a), const void *ATTR_UNUSED(b))
 

Detailed Description

This file implements the worker that handles callbacks on events, for pending requests.

Macro Definition Documentation

◆ PREFETCH_EXPIRY_ADD

#define PREFETCH_EXPIRY_ADD   60

seconds to add to prefetch leeway.

This is a TTL that expires old rrsets earlier than they should in order to put the new update into the cache. This additional value is to make sure that if not all TTLs are equal in the message to be updated(and replaced), that rrsets with up to this much extra TTL are also replaced. This means that the resulting new message will have (most likely) this TTL at least, avoiding very small 'split second' TTLs due to operators choosing relative primes for TTLs (or so). Also has to be at least one to break ties (and overwrite cached entry).

Function Documentation

◆ worker_send_cmd()

void worker_send_cmd ( struct worker worker,
enum worker_commands  cmd 
)

Send a command to a worker.

Uses blocking writes.

Parameters
workerworker to send command to.
cmdcommand to send.

References worker::cmd, log_err(), and tube_write_msg().

Referenced by daemon_stop_others(), distribute_cmd(), and server_stats_obtain().

◆ worker_err_ratelimit()

static int worker_err_ratelimit ( struct worker worker,
int  err 
)
static

ratelimit error replies

Parameters
workerthe worker struct with ratelimit counter
errerror code that would be wanted.
Returns
value of err if okay, or -1 if it should be discarded instead.

References worker::env, worker::err_limit_count, worker::err_limit_time, ERROR_RATELIMIT, and module_env::now.

◆ worker_check_request()

static void worker_check_request ( sldns_buffer pkt,
struct worker worker,
struct check_request_result out 
)
static

check request sanity.

Parameters
pktthe wire packet to examine for sanity.
workerparameters for checking.
outstruct to update with the result.

References sldns_buffer_limit().

◆ apply_respip_action()

static int apply_respip_action ( struct worker worker,
const struct query_info qinfo,
struct respip_client_info cinfo,
struct reply_info rep,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
struct ub_packed_rrset_key **  alias_rrset,
struct reply_info **  encode_repp,
struct auth_zones az 
)
static

Apply, if applicable, a response IP action to a cached answer.

If the answer is rewritten as a result of an action, '*encode_repp' will point to the reply info containing the modified answer. '*encode_repp' will be intact otherwise. It returns 1 on success, 0 otherwise.

References ub_server_stats::extended, LDNS_RR_TYPE_A, LDNS_RR_TYPE_AAAA, LDNS_RR_TYPE_ANY, query_info::local_alias, query_info::qclass, query_info::qname, query_info::qtype, respip_always_deny, respip_deny, respip_inform_deny, respip_inform_print(), respip_none, respip_rewrite_reply(), ub_server_stats::rpz_action, worker::scratchpad, and worker::stats.

Referenced by mesh_serve_expired_callback().

◆ answer_from_cache()

static int answer_from_cache ( struct worker worker,
struct query_info qinfo,
struct respip_client_info cinfo,
int *  need_drop,
int *  is_expired_answer,
int *  is_secure_answer,
struct ub_packed_rrset_key **  alias_rrset,
struct reply_info **  partial_repp,
struct reply_info rep,
uint16_t  id,
uint16_t  flags,
struct comm_reply repinfo,
struct edns_data edns 
)
static

answer query from the cache.

Normally, the answer message will be built in repinfo->c->buffer; if the answer is supposed to be suppressed or the answer is supposed to be an incomplete CNAME chain, the buffer is explicitly cleared to signal the caller as such. In the latter case *partial_rep will point to the incomplete reply, and this function is (possibly) supposed to be called again with that *partial_rep value to complete the chain. In addition, if the query should be completely dropped, '*need_drop' will be set to 1.

References reply_info::an_numrrsets, BIT_CD, edns_data::bits, module_env::cfg, config_file::disable_edns_do, EDNS_ADVERTISED_SIZE, EDNS_ADVERTISED_VERSION, EDNS_DO, edns_data::edns_present, edns_data::edns_version, worker::env, edns_data::ext_rcode, reply_info::flags, config_file::ignore_cd, inplace_cb_reply_servfail_call(), LDNS_RR_TYPE_CNAME, LDNS_RR_TYPE_DNAME, module_env::need_to_validate, module_env::now, reply_info::ref, reply_check_cname_chain(), reply_info_can_answer_expired(), ub_packed_rrset_key::rk, rrset_array_lock(), reply_info::rrset_count, reply_info::rrsets, sec_status_bogus, sec_status_secure_sentinel_fail, reply_info::security, config_file::serve_expired, config_file::serve_expired_client_timeout, reply_info::serve_expired_norec_ttl, reply_info::ttl, packed_rrset_key::type, edns_data::udp_size, VERB_ALGO, and verbose().

◆ chaos_replystr()

static void chaos_replystr ( sldns_buffer pkt,
char **  str,
int  num,
struct edns_data edns,
struct worker worker,
struct comm_reply repinfo 
)
static

Fill CH class answer into buffer.

Keeps query.

Parameters
pktbuffer
strstring to put into text record (<255). array of strings, every string becomes a text record.
numnumber of strings in array.
ednsedns reply information.
workerworker with scratch region.
repinforeply information for a communication point.

◆ chaos_trustanchor()

static void chaos_trustanchor ( sldns_buffer pkt,
struct edns_data edns,
struct worker w,
struct comm_reply repinfo 
)
static

Create CH class trustanchor answer.

Parameters
pktbuffer
ednsedns reply information.
wworker with scratch region.
repinforeply information for a communication point.

Referenced by answer_chaos().

◆ answer_chaos()

static int answer_chaos ( struct worker w,
struct query_info qinfo,
struct edns_data edns,
struct comm_reply repinfo,
sldns_buffer pkt 
)
static

Answer CH class queries.

Parameters
wworker
qinfoquery info. Pointer into packet buffer.
ednsedns info from query.
repinforeply information for a communication point.
pktpacket buffer.
Returns
: true if a reply is to be sent.

References module_env::cfg, chaos_replyonestr(), chaos_trustanchor(), worker::env, config_file::hide_identity, config_file::hide_trustanchor, config_file::hide_version, config_file::identity, LDNS_RR_TYPE_ANY, LDNS_RR_TYPE_TXT, log_err(), query_info::qname, query_info::qtype, query_dname_compare(), and config_file::version.

◆ answer_notify()

static void answer_notify ( struct worker w,
struct query_info qinfo,
struct edns_data edns,
sldns_buffer pkt,
struct sockaddr_storage *  addr,
socklen_t  addrlen 
)
static

Answer notify queries.

These are notifies for authoritative zones, the reply is an ack that the notify has been received. We need to check access permission here.

Parameters
wworker
qinfoquery info. Pointer into packet buffer.
ednsedns info from query.
addrclient address.
addrlenclient address length.
pktpacket buffer.

◆ worker_sighandler()

void worker_sighandler ( int  sig,
void *  arg 
)

Worker signal handler function.

User argument is the worker itself.

Parameters
sigsignal number.
argthe worker (main worker) that handles signals.

References worker::base, comm_base_exit(), and worker::need_to_exit.

Referenced by fptr_whitelist_comm_signal(), and signal_handling_playback().

◆ worker_create()

struct worker* worker_create ( struct daemon daemon,
int  id,
int *  ports,
int  n 
)

Create the worker structure.

Bare bones version, zeroed struct, with backpointers only. Use worker_init on it later.

Parameters
daemonthe daemon that this worker thread is part of.
idthe thread number from 0.. numthreads-1.
portsthe ports it is allowed to use, array.
nthe number of ports.
Returns
: the new worker or NULL on alloc failure.

References worker::cmd, worker::daemon, log_err(), memdup(), worker::numports, worker::ports, daemon::rand, worker::rndstate, worker::thread_num, tube_create(), tube_delete(), and ub_initstate().

◆ worker_init()

int worker_init ( struct worker worker,
struct config_file cfg,
struct listen_port ports,
int  do_sigs 
)

Initialize worker.

Allocates event base, listens to ports

Parameters
workerworker to initialize, created with worker_create.
cfgconfiguration settings.
portslist of shared query ports.
do_sigsif true, worker installs signal handlers.
Returns
: false on error.

References worker::base, and worker::need_to_exit.

Referenced by thread_start().

◆ worker_send_query()

struct outbound_entry* worker_send_query ( struct query_info qinfo,
uint16_t  flags,
int  dnssec,
int  want_dnssec,
int  nocaps,
int  check_ratelimit,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  zone,
size_t  zonelen,
int  tcp_upstream,
int  ssl_upstream,
char *  tls_auth_name,
struct module_qstate q,
int *  was_ratelimited 
)

Worker service routine to send serviced queries to authoritative servers.

Parameters
qinfoquery info.
flagshost order flags word, with opcode and CD bit.
dnssecif set, EDNS record will have DO bit set.
want_dnssecsignatures needed.
nocapsignore capsforid(if in config), do not perturb qname.
check_ratelimitif set, will check ratelimit before sending out.
addrwhere to.
addrlenlength of addr.
zonewireformat dname of the zone.
zonelenlength of zone name.
tcp_upstreamuse TCP for upstream queries.
ssl_upstreamuse SSL for upstream queries.
tls_auth_nameif ssl_upstream, use this name with TLS authentication.
qwhich query state to reactivate upon return.
was_ratelimitedit will signal back if the query failed to pass the ratelimit check.
Returns
: false on failure (memory or socket related). no query was sent.

References worker::back, module_qstate::env, outnet_serviced_query(), outbound_entry::qsent, outbound_entry::qstate, module_qstate::region, regional_alloc(), outside_network::udp_buff, module_env::worker, and worker_handle_service_reply().

Referenced by fptr_whitelist_modenv_send_query().

◆ worker_stats_clear()

void worker_stats_clear ( struct worker worker)

Init worker stats - includes server_stats_init, outside network and mesh.

Parameters
workerthe worker to init

References worker::back, module_env::cfg, worker::env, module_env::mesh, mesh_stats_clear(), outside_network::num_tcp_outgoing, outside_network::num_udp_outgoing, server_stats_init(), worker::stats, and outside_network::unwanted_replies.

Referenced by do_flush_stats().