outside_network.h File Reference
#include "util/alloc.h"
#include "util/rbtree.h"
#include "util/regional.h"
#include "util/netevent.h"
#include "dnstap/dnstap_config.h"

Data Structures

struct  outside_network
 Send queries to outside servers and wait for answers from servers. More...
 
struct  port_if
 Outgoing interface. More...
 
struct  port_comm
 Outgoing commpoint for UDP port. More...
 
struct  reuse_tcp
 Reuse TCP connection, still open can be used again. More...
 
struct  pending
 A query that has an answer pending for it. More...
 
struct  pending_tcp
 Pending TCP query to server. More...
 
struct  waiting_tcp
 Query waiting for TCP buffer. More...
 
struct  service_callback
 Callback to party interested in serviced query results. More...
 
struct  serviced_query
 Query service record. More...
 

Macros

#define EDNS_FRAG_SIZE_IP4   1472
 fallback size for fragmentation for EDNS in IPv4
 
#define EDNS_FRAG_SIZE_IP6   1232
 fallback size for EDNS in IPv6, fits one fragment with ip6-tunnel-ids
 

Functions

struct outside_networkoutside_network_create (struct comm_base *base, size_t bufsize, size_t num_ports, char **ifs, int num_ifs, int do_ip4, int do_ip6, size_t num_tcp, int dscp, struct infra_cache *infra, struct ub_randstate *rnd, int use_caps_for_id, int *availports, int numavailports, size_t unwanted_threshold, int tcp_mss, void(*unwanted_action)(void *), void *unwanted_param, int do_udp, void *sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv, int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout, int tcp_auth_query_timeout)
 Create outside_network structure with N udp ports. More...
 
void outside_network_delete (struct outside_network *outnet)
 Delete outside_network structure. More...
 
void outside_network_quit_prepare (struct outside_network *outnet)
 Prepare for quit. More...
 
struct pendingpending_udp_query (struct serviced_query *sq, struct sldns_buffer *packet, int timeout, comm_point_callback_type *callback, void *callback_arg)
 Send UDP query, create pending answer. More...
 
struct waiting_tcppending_tcp_query (struct serviced_query *sq, struct sldns_buffer *packet, int timeout, comm_point_callback_type *callback, void *callback_arg)
 Send TCP query. More...
 
void pending_delete (struct outside_network *outnet, struct pending *p)
 Delete pending answer. More...
 
struct serviced_queryoutnet_serviced_query (struct outside_network *outnet, struct query_info *qinfo, uint16_t flags, int dnssec, int want_dnssec, int nocaps, int check_ratelimit, int tcp_upstream, int ssl_upstream, char *tls_auth_name, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *zone, size_t zonelen, struct module_qstate *qstate, comm_point_callback_type *callback, void *callback_arg, struct sldns_buffer *buff, struct module_env *env, int *was_ratelimited)
 Perform a serviced query to the authoritative servers. More...
 
void outnet_serviced_query_stop (struct serviced_query *sq, void *cb_arg)
 Remove service query callback. More...
 
size_t outnet_get_mem (struct outside_network *outnet)
 Get memory size in use by outside network. More...
 
size_t serviced_get_mem (struct serviced_query *sq)
 Get memory size in use by serviced query while it is servicing callbacks. More...
 
uint16_t reuse_tcp_select_id (struct reuse_tcp *reuse, struct outside_network *outnet)
 Pick random ID value for a tcp stream, avoids existing IDs. More...
 
struct waiting_tcpreuse_tcp_by_id_find (struct reuse_tcp *reuse, uint16_t id)
 find element in tree by id
 
void reuse_tree_by_id_insert (struct reuse_tcp *reuse, struct waiting_tcp *w)
 insert element in tree by id
 
int reuse_tcp_insert (struct outside_network *outnet, struct pending_tcp *pend_tcp)
 insert element in tcp_reuse tree and LRU list More...
 
void reuse_tcp_lru_touch (struct outside_network *outnet, struct reuse_tcp *reuse)
 touch the LRU of the element More...
 
void reuse_tcp_remove_tree_list (struct outside_network *outnet, struct reuse_tcp *reuse)
 remove element from tree and LRU list More...
 
struct reuse_tcpreuse_tcp_lru_snip (struct outside_network *outnet)
 snip the last reuse_tcp element off of the LRU list if any More...
 
void reuse_del_readwait (rbtree_type *tree_by_id)
 delete readwait waiting_tcp elements, deletes the elements in the list
 
int outnet_get_tcp_fd (struct sockaddr_storage *addr, socklen_t addrlen, int tcp_mss, int dscp)
 get TCP file descriptor for address, returns -1 on failure, tcp_mss is 0 or maxseg size to set for TCP packets.
 
struct comm_pointoutnet_comm_point_for_udp (struct outside_network *outnet, comm_point_callback_type *cb, void *cb_arg, struct sockaddr_storage *to_addr, socklen_t to_addrlen)
 Create udp commpoint suitable for sending packets to the destination. More...
 
struct comm_pointoutnet_comm_point_for_tcp (struct outside_network *outnet, comm_point_callback_type *cb, void *cb_arg, struct sockaddr_storage *to_addr, socklen_t to_addrlen, struct sldns_buffer *query, int timeout, int ssl, char *host)
 Create tcp commpoint suitable for communication to the destination. More...
 
struct comm_pointoutnet_comm_point_for_http (struct outside_network *outnet, comm_point_callback_type *cb, void *cb_arg, struct sockaddr_storage *to_addr, socklen_t to_addrlen, int timeout, int ssl, char *host, char *path, struct config_file *cfg)
 Create http commpoint suitable for communication to the destination. More...
 
int outnet_tcp_connect (int s, struct sockaddr_storage *addr, socklen_t addrlen)
 connect tcp connection to addr, 0 on failure
 
int outnet_udp_cb (struct comm_point *c, void *arg, int error, struct comm_reply *reply_info)
 callback for incoming udp answers from the network
 
int outnet_tcp_cb (struct comm_point *c, void *arg, int error, struct comm_reply *reply_info)
 callback for pending tcp connections
 
void pending_udp_timer_cb (void *arg)
 callback for udp timeout
 
void pending_udp_timer_delay_cb (void *arg)
 callback for udp delay for timeout
 
void outnet_tcptimer (void *arg)
 callback for outgoing TCP timer event
 
void serviced_timer_cb (void *arg)
 callback to send serviced queries
 
int serviced_udp_callback (struct comm_point *c, void *arg, int error, struct comm_reply *rep)
 callback for serviced query UDP answers
 
int serviced_tcp_callback (struct comm_point *c, void *arg, int error, struct comm_reply *rep)
 TCP reply or error callback for serviced queries.
 
int pending_cmp (const void *key1, const void *key2)
 compare function of pending rbtree
 
int serviced_cmp (const void *key1, const void *key2)
 compare function of serviced query rbtree
 
int reuse_cmp (const void *key1, const void *key2)
 compare function of reuse_tcp rbtree in outside_network struct
 
int reuse_id_cmp (const void *key1, const void *key2)
 compare function of reuse_tcp tree_by_id rbtree
 

Detailed Description

This file has functions to send queries to authoritative servers, and wait for the pending answer, with timeouts.

Function Documentation

◆ outside_network_create()

struct outside_network* outside_network_create ( struct comm_base base,
size_t  bufsize,
size_t  num_ports,
char **  ifs,
int  num_ifs,
int  do_ip4,
int  do_ip6,
size_t  num_tcp,
int  dscp,
struct infra_cache infra,
struct ub_randstate *  rnd,
int  use_caps_for_id,
int *  availports,
int  numavailports,
size_t  unwanted_threshold,
int  tcp_mss,
void(*)(void *)  unwanted_action,
void *  unwanted_param,
int  do_udp,
void *  sslctx,
int  delayclose,
int  tls_use_sni,
struct dt_env *  dtenv,
int  udp_connect,
int  max_reuse_tcp_queries,
int  tcp_reuse_timeout,
int  tcp_auth_query_timeout 
)

Create outside_network structure with N udp ports.

Parameters
basethe communication base to use for event handling.
bufsizesize for network buffers.
num_portsnumber of udp ports to open per interface.
ifsinterface names (or NULL for default interface). These interfaces must be able to access all authoritative servers.
num_ifsnumber of names in array ifs.
do_ip4service IP4.
do_ip6service IP6.
num_tcpnumber of outgoing tcp buffers to preallocate.
dscpDSCP to use.
infrapointer to infra cached used for serviced queries.
rndstored to create random numbers for serviced queries.
use_caps_for_idenable to use 0x20 bits to encode id randomness.
availportsarray of available ports.
numavailportsnumber of available ports in array.
unwanted_thresholdwhen to take defensive action.
unwanted_actionthe action to take.
unwanted_paramuser parameter to action.
tcp_mssmaximum segment size of tcp socket.
do_udpif udp is done.
sslctxcontext to create outgoing connections with (if enabled).
delaycloseif not 0, udp sockets are delayed before timeout closure. msec to wait on timeouted udp sockets.
tls_use_sniif SNI is used for TLS connections.
dtenvenvironment to send dnstap events with (if enabled).
udp_connectif the udp_connect option is enabled.
max_reuse_tcp_queriesmax number of queries on a reuse connection.
tcp_reuse_timeouttimeout for REUSE entries in milliseconds.
tcp_auth_query_timeouttimeout in milliseconds for TCP queries to auth servers.
Returns
: the new structure (with no pending answers) or NULL on error.

References outside_network::base, calc_num46(), comm_base_timept(), port_comm::cp, create_pending_tcp(), outside_network::delay_tv, outside_network::delayclose, outside_network::do_udp, outside_network::infra, outside_network::ip4_ifs, outside_network::ip6_ifs, outside_network::ip_dscp, log_err(), outside_network::max_reuse_tcp_queries, outside_network::now_secs, outside_network::now_tv, outside_network::num_ip4, outside_network::num_ip6, outside_network::num_tcp, outside_network::num_tcp_outgoing, outside_network::num_udp_outgoing, outside_network_delete(), outside_network::pending, pending_cmp(), rbtree_create(), rbtree_init(), reuse_cmp(), outside_network::rnd, outside_network::serviced, serviced_cmp(), sldns_buffer_new(), outside_network::sslctx, outside_network::svcd_overhead, outside_network::tcp_auth_query_timeout, outside_network::tcp_mss, outside_network::tcp_reuse, outside_network::tcp_reuse_max, outside_network::tcp_reuse_timeout, outside_network::tls_use_sni, outside_network::udp_buff, outside_network::udp_connect, outside_network::unwanted_action, outside_network::unwanted_param, outside_network::unwanted_threshold, outside_network::use_caps_for_id, and outside_network::want_to_quit.

◆ outside_network_delete()

◆ outside_network_quit_prepare()

void outside_network_quit_prepare ( struct outside_network outnet)

Prepare for quit.

Sends no more queries, even if queued up.

Parameters
outnetobject to prepare for removal

References serviced_query::outnet, and outside_network::want_to_quit.

Referenced by libworker_delete_env(), and worker_delete().

◆ pending_udp_query()

struct pending* pending_udp_query ( struct serviced_query sq,
struct sldns_buffer packet,
int  timeout,
comm_point_callback_type callback,
void *  callback_arg 
)

Send UDP query, create pending answer.

Changes the ID for the query to be random and unique for that destination.

Parameters
sqserviced query.
packetwireformat query to send to destination.
timeoutin milliseconds from now.
callbackfunction to call on error, timeout or reply.
callback_arguser argument for callback function.
Returns
: NULL on error for malloc or socket. Else the pending query object.

References pending::addr, serviced_query::addr, pending::addrlen, serviced_query::addrlen, outside_network::base, serviced_query::busy, pending::cb, pending::cb_arg, comm_timer_create(), comm_timer_delete(), rbnode_type::key, log_assert, memdup(), pending::next_waiting, pending::node, pending::outnet, serviced_query::outnet, pending_delete(), pending_udp_timer_cb(), pending::pkt, pending::pkt_len, randomize_and_send_udp(), sldns_buffer_begin(), sldns_buffer_capacity(), sldns_buffer_flip(), sldns_buffer_limit(), sldns_buffer_new(), sldns_buffer_write(), pending::sq, pending::timeout, pending::timer, outside_network::udp_wait_first, outside_network::udp_wait_last, outside_network::unused_fds, VERB_ALGO, and verbose().

Referenced by serviced_udp_send().

◆ pending_tcp_query()

struct waiting_tcp* pending_tcp_query ( struct serviced_query sq,
struct sldns_buffer packet,
int  timeout,
comm_point_callback_type callback,
void *  callback_arg 
)

Send TCP query.

May wait for TCP buffer. Selects ID to be random, and checks id.

Parameters
sqserviced query.
packetwireformat query to send to destination. copied from.
timeoutin milliseconds from now. Timer starts running now. Timer may expire if all buffers are used, without any query been sent to the server yet.
callbackfunction to call on error, timeout or reply.
callback_arguser argument for callback function.
Returns
: false on error for malloc or socket. Else the pending TCP object.

References serviced_query::addr, serviced_query::addrlen, outside_network::base, comm_timer_create(), waiting_tcp::id, log_assert, log_reuse_tcp(), serviced_query::outnet, outnet_tcptimer(), reuse_tcp::pending, waiting_tcp::pkt, waiting_tcp::pkt_len, reuse_tcp_close_oldest(), reuse_tcp_find(), reuse_tcp_lru_touch(), sldns_buffer_begin(), sldns_buffer_capacity(), sldns_buffer_flip(), sldns_buffer_limit(), sldns_buffer_new(), sldns_buffer_write(), outside_network::tcp_free, tcp_select_id(), waiting_tcp::timer, VERB_ALGO, VERB_CLIENT, and verbose().

Referenced by serviced_tcp_initiate(), and serviced_tcp_send().

◆ pending_delete()

void pending_delete ( struct outside_network outnet,
struct pending p 
)

◆ outnet_serviced_query()

struct serviced_query* outnet_serviced_query ( struct outside_network outnet,
struct query_info qinfo,
uint16_t  flags,
int  dnssec,
int  want_dnssec,
int  nocaps,
int  check_ratelimit,
int  tcp_upstream,
int  ssl_upstream,
char *  tls_auth_name,
struct sockaddr_storage *  addr,
socklen_t  addrlen,
uint8_t *  zone,
size_t  zonelen,
struct module_qstate qstate,
comm_point_callback_type callback,
void *  callback_arg,
struct sldns_buffer buff,
struct module_env env,
int *  was_ratelimited 
)

Perform a serviced query to the authoritative servers.

Duplicate efforts are detected, and EDNS, TCP and UDP retry is performed.

Parameters
outnetoutside network, with rbtree of serviced queries.
qinfoquery info.
flagsflags u16 (host format), includes opcode, CD bit.
dnssecif set, DO bit is set in EDNS queries. If the value includes BIT_CD, CD bit is set when in EDNS queries. If the value includes BIT_DO, DO bit is set when in EDNS queries.
want_dnssecsignatures are needed, without EDNS the answer is likely to be useless.
nocapsignore use_caps_for_id and use unperturbed qname.
check_ratelimitif set, will check ratelimit before sending out.
tcp_upstreamuse TCP for upstream queries.
ssl_upstreamuse SSL for upstream queries.
tls_auth_namewhen ssl_upstream is true, use this name to check the server's peer certificate.
addrto which server to send the query.
addrlenlength of addr.
zonename of the zone of the delegation point. wireformat dname. This is the delegation point name for which the server is deemed authoritative.
zonelenlength of zone.
qstatemodule qstate. Mainly for inspecting the available edns_opts_lists.
callbackcallback function.
callback_arguser argument to callback function.
buffscratch buffer to create query contents in. Empty on exit.
envthe module environment.
was_ratelimitedit will signal back if the query failed to pass the ratelimit check.
Returns
0 on error, or pointer to serviced query that is used to answer this serviced query may be shared with other callbacks as well.

References module_env::alloc, alloc_reg_obtain(), alloc_reg_release(), service_callback::cb, service_callback::cb_arg, serviced_query::cblist, module_env::cfg, edns_strings::client_string_opcode, edns_strings::client_strings, edns_opt_copy_region(), edns_opt_list_append(), module_qstate::edns_opts_back_out, edns_string_addr_lookup(), module_env::edns_strings, module_env::infra_cache, infra_ratelimit_dec(), infra_ratelimit_inc(), inplace_cb_query_call(), LDNS_RR_CLASS_IN, LDNS_RR_TYPE_NS, log_nametypeclass(), lookup_serviced(), service_callback::next, serviced_query::node, module_env::now, config_file::pad_queries, config_file::pad_queries_block_size, query_info::qclass, module_qstate::qinfo, query_info::qname, query_info::qname_len, query_info::qtype, config_file::ratelimit_backoff, config_file::ratelimit_factor, rbtree_delete(), serviced_query::region, regional_alloc(), module_qstate::reply, module_env::rnd, outside_network::serviced, serviced_create(), serviced_gen_query(), serviced_node_del(), edns_string_addr::string, edns_string_addr::string_len, ub_random_max(), and VERB_ALGO.

Referenced by libworker_send_query(), and worker_send_query().

◆ outnet_serviced_query_stop()

void outnet_serviced_query_stop ( struct serviced_query sq,
void *  cb_arg 
)

Remove service query callback.

If that leads to zero callbacks, the query is completely cancelled.

Parameters
sqserviced query to adjust.
cb_argcallback argument of callback that needs removal. same as the callback_arg to outnet_serviced_query().

References fake_pending::buffer, serviced_query::busy, callback_list_remove(), fake_pending::cb_arg, service_callback::cb_arg, serviced_query::cblist, log_assert, log_info(), fake_pending::next, serviced_query::outnet, replay_runtime::pending_list, fake_pending::pkt, rbtree_delete(), fake_pending::runtime, outside_network::serviced, serviced_delete(), sldns_buffer_free(), serviced_query::to_be_deleted, and fake_pending::zone.

Referenced by outbound_list_clear(), and outbound_list_remove().

◆ outnet_get_mem()

size_t outnet_get_mem ( struct outside_network outnet)

Get memory size in use by outside network.

Counts buffers and outstanding query (serviced queries) malloced data.

Parameters
outnetoutside network structure.
Returns
size in bytes.

References outside_network::base, port_comm::next, sldns_buffer_capacity(), outside_network::udp_buff, and outside_network::unused_fds.

◆ serviced_get_mem()

size_t serviced_get_mem ( struct serviced_query sq)

Get memory size in use by serviced query while it is servicing callbacks.

This takes into account the pre-deleted status of it; it will be deleted when the callbacks are done.

Parameters
sqserviced query.
Returns
size in bytes.

References serviced_query::cblist, comm_timer_get_mem(), service_callback::next, serviced_query::qbuflen, and serviced_query::status.

◆ reuse_tcp_select_id()

uint16_t reuse_tcp_select_id ( struct reuse_tcp reuse,
struct outside_network outnet 
)

Pick random ID value for a tcp stream, avoids existing IDs.

Pick random ID value for a tcp stream, avoids existing IDs.

That is random and also does not collide with an existing query ID that is in use or waiting

References rbtree_type::count, GET_RANDOM_ID, log_assert, reuse_tcp::node, reuse_tcp::outnet, rbtree_first(), rbtree_last(), rbtree_next(), RBTREE_NULL, reuse_tcp_by_id_find(), outside_network::rnd, reuse_tcp::tree_by_id, tree_by_id_get_id(), and ub_random_max().

Referenced by tcp_select_id(), and tcpid_addmore().

◆ reuse_tcp_insert()

int reuse_tcp_insert ( struct outside_network outnet,
struct pending_tcp pend_tcp 
)

◆ reuse_tcp_lru_touch()

void reuse_tcp_lru_touch ( struct outside_network outnet,
struct reuse_tcp reuse 
)

touch the LRU of the element

touch the LRU of the element

This moves it to the front of the list, where it is not likely to be closed. Items at the back of the list are closed to make space.

References reuse_tcp::item_on_lru_list, log_assert, log_err(), reuse_tcp::lru_next, and outside_network::tcp_reuse_first.

Referenced by pending_tcp_query().

◆ reuse_tcp_remove_tree_list()

◆ reuse_tcp_lru_snip()

struct reuse_tcp* reuse_tcp_lru_snip ( struct outside_network outnet)

snip the last reuse_tcp element off of the LRU list if any

snip the last reuse_tcp element off of the LRU list if any

References reuse_tcp::item_on_lru_list, log_assert, reuse_tcp::lru_next, reuse_tcp::outnet, and outside_network::tcp_reuse_first.

Referenced by check_snip(), and reuse_tcp_close_oldest().

◆ outnet_comm_point_for_udp()

struct comm_point* outnet_comm_point_for_udp ( struct outside_network outnet,
comm_point_callback_type cb,
void *  cb_arg,
struct sockaddr_storage *  to_addr,
socklen_t  to_addrlen 
)

Create udp commpoint suitable for sending packets to the destination.

Parameters
outnetoutside_network with the comm_base it is attached to, with the outgoing interfaces chosen from, and rnd gen for random.
cbcallback function for the commpoint.
cb_argcallback argument for cb.
to_addrintended destination.
to_addrlenlength of to_addr.
Returns
commpoint that you can comm_point_send_udp_msg with, or NULL.

References comm_point::fd, and fd_for_dest().

Referenced by xfr_probe_send_probe().

◆ outnet_comm_point_for_tcp()

struct comm_point* outnet_comm_point_for_tcp ( struct outside_network outnet,
comm_point_callback_type cb,
void *  cb_arg,
struct sockaddr_storage *  to_addr,
socklen_t  to_addrlen,
struct sldns_buffer query,
int  timeout,
int  ssl,
char *  host 
)

Create tcp commpoint suitable for communication to the destination.

It also performs connect() to the to_addr.

Parameters
outnetoutside_network with the comm_base it is attached to, and the tcp_mss.
cbcallback function for the commpoint.
cb_argcallback argument for cb.
to_addrintended destination.
to_addrlenlength of to_addr.
queryinitial packet to send writing, in buffer. It is copied to the commpoint buffer that is created.
timeouttimeout for the TCP connection. timeout in milliseconds, or -1 for no (change to the) timeout. So seconds*1000.
sslset to true for TLS.
hosthostname for host name verification of TLS (or NULL if no TLS).
Returns
tcp_out commpoint, or NULL.

References comm_point::fd, fd_set_nonblock(), outside_network::ip_dscp, outnet_get_tcp_fd(), outnet_tcp_connect(), and outside_network::tcp_mss.

◆ outnet_comm_point_for_http()

struct comm_point* outnet_comm_point_for_http ( struct outside_network outnet,
comm_point_callback_type cb,
void *  cb_arg,
struct sockaddr_storage *  to_addr,
socklen_t  to_addrlen,
int  timeout,
int  ssl,
char *  host,
char *  path,
struct config_file cfg 
)

Create http commpoint suitable for communication to the destination.

Creates the http request buffer. It also performs connect() to the to_addr.

Parameters
outnetoutside_network with the comm_base it is attached to, and the tcp_mss.
cbcallback function for the commpoint.
cb_argcallback argument for cb.
to_addrintended destination.
to_addrlenlength of to_addr.
timeouttimeout for the TCP connection. timeout in milliseconds, or -1 for no (change to the) timeout. So seconds*1000.
sslset to true for https.
hosthostname to use for the destination. part of http request.
pathpathname to lookup, eg. name of the file on the destination.
cfgrunning configuration for User-Agent setup.
Returns
http_out commpoint, or NULL.

References comm_reply::addr, comm_reply::addrlen, outside_network::base, fake_commpoint::cb, fake_commpoint::cb_arg, replay_runtime::cb_arg, comm_point::cb_arg, comm_point_create_http_out(), comm_point_delete(), FAKE_COMMPOINT_TYPECODE, comm_point::fd, fd_set_nonblock(), outside_network::ip_dscp, log_err(), outnet_get_tcp_fd(), outnet_tcp_connect(), comm_point::repinfo, fake_commpoint::runtime, setup_comm_ssl(), comm_point::ssl, outside_network::tcp_mss, fake_commpoint::type_http_out, fake_commpoint::typecode, and outside_network::udp_buff.