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 worker * | worker_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_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. 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_entry * | libworker_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)) |
This file implements the worker that handles callbacks on events, for pending requests.
#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).
void worker_send_cmd | ( | struct worker * | worker, |
enum worker_commands | cmd | ||
) |
Send a command to a worker.
Uses blocking writes.
worker | worker to send command to. |
cmd | command to send. |
References worker::cmd, log_err(), and tube_write_msg().
Referenced by daemon_stop_others(), distribute_cmd(), and server_stats_obtain().
|
static |
ratelimit error replies
worker | the worker struct with ratelimit counter |
err | error code that would be wanted. |
References worker::env, worker::err_limit_count, worker::err_limit_time, ERROR_RATELIMIT, and module_env::now.
|
static |
check request sanity.
pkt | the wire packet to examine for sanity. |
worker | parameters for checking. |
out | struct to update with the result. |
References sldns_buffer_limit().
|
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().
|
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().
|
static |
Fill CH class answer into buffer.
Keeps query.
pkt | buffer |
str | string to put into text record (<255). array of strings, every string becomes a text record. |
num | number of strings in array. |
edns | edns reply information. |
worker | worker with scratch region. |
repinfo | reply information for a communication point. |
|
static |
Create CH class trustanchor answer.
pkt | buffer |
edns | edns reply information. |
w | worker with scratch region. |
repinfo | reply information for a communication point. |
Referenced by answer_chaos().
|
static |
Answer CH class queries.
w | worker |
qinfo | query info. Pointer into packet buffer. |
edns | edns info from query. |
repinfo | reply information for a communication point. |
pkt | packet buffer. |
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.
|
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.
w | worker |
qinfo | query info. Pointer into packet buffer. |
edns | edns info from query. |
addr | client address. |
addrlen | client address length. |
pkt | packet buffer. |
void worker_sighandler | ( | int | sig, |
void * | arg | ||
) |
Worker signal handler function.
User argument is the worker itself.
sig | signal number. |
arg | the 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().
Create the worker structure.
Bare bones version, zeroed struct, with backpointers only. Use worker_init on it later.
daemon | the daemon that this worker thread is part of. |
id | the thread number from 0.. numthreads-1. |
ports | the ports it is allowed to use, array. |
n | the number of ports. |
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().
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
worker | worker to initialize, created with worker_create. |
cfg | configuration settings. |
ports | list of shared query ports. |
do_sigs | if true, worker installs signal handlers. |
References worker::base, and worker::need_to_exit.
Referenced by thread_start().
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.
qinfo | query info. |
flags | host order flags word, with opcode and CD bit. |
dnssec | if set, EDNS record will have DO bit set. |
want_dnssec | signatures needed. |
nocaps | ignore capsforid(if in config), do not perturb qname. |
check_ratelimit | if set, will check ratelimit before sending out. |
addr | where to. |
addrlen | length of addr. |
zone | wireformat dname of the zone. |
zonelen | length of zone name. |
tcp_upstream | use TCP for upstream queries. |
ssl_upstream | use SSL for upstream queries. |
tls_auth_name | if ssl_upstream, use this name with TLS authentication. |
q | which query state to reactivate upon return. |
was_ratelimited | it will signal back if the query failed to pass the ratelimit check. |
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().
void worker_stats_clear | ( | struct worker * | worker | ) |
Init worker stats - includes server_stats_init, outside network and mesh.
worker | the 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().