Macros | Functions
outside_network.c File Reference

This file has functions to send queries to authoritative servers and wait for the pending answer events. More...

#include "config.h"
#include <ctype.h>
#include <sys/time.h>
#include "services/outside_network.h"
#include "services/listen_dnsport.h"
#include "services/cache/infra.h"
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
#include "util/data/msgencode.h"
#include "util/data/dname.h"
#include "util/netevent.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
#include "sldns/sbuffer.h"
#include "dnstap/dnstap.h"
#include <fcntl.h>

Macros

#define MAX_ID_RETRY   1000
 number of times to retry making a random ID that is unique. More...
 
#define MAX_PORT_RETRY   10000
 number of times to retry finding interface, port that can be opened. More...
 
#define OUTBOUND_UDP_RETRY   1
 number of retries on outgoing UDP queries
 

Functions

static void serviced_tcp_initiate (struct serviced_query *sq, sldns_buffer *buff)
 initiate TCP transaction for serviced query
 
static int randomize_and_send_udp (struct pending *pend, sldns_buffer *packet, int timeout)
 with a fd available, randomize and send UDP
 
static void waiting_list_remove (struct outside_network *outnet, struct waiting_tcp *w)
 remove waiting tcp from the outnet waiting list
 
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
 
static void waiting_tcp_delete (struct waiting_tcp *w)
 delete waiting_tcp entry. More...
 
static int pick_outgoing_tcp (struct waiting_tcp *w, int s)
 Pick random outgoing-interface of that family, and bind it. More...
 
static int outnet_tcp_take_into_use (struct waiting_tcp *w, uint8_t *pkt, size_t pkt_len)
 use next free buffer to service a tcp query
 
static void use_free_buffer (struct outside_network *outnet)
 see if buffers can be used to service TCP queries
 
static void decommission_pending_tcp (struct outside_network *outnet, struct pending_tcp *pend)
 decommission a tcp buffer, closes commpoint and frees waiting_tcp entry
 
int outnet_tcp_cb (struct comm_point *c, void *arg, int error, struct comm_reply *reply_info)
 callback for pending tcp connections
 
static void portcomm_loweruse (struct outside_network *outnet, struct port_comm *pc)
 lower use count on pc, see if it can be closed
 
static void outnet_send_wait_udp (struct outside_network *outnet)
 try to send waiting UDP queries
 
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
 
static void calc_num46 (char **ifs, int num_ifs, int do_ip4, int do_ip6, int *num_ip4, int *num_ip6)
 calculate number of ip4 and ip6 interfaces
 
void pending_udp_timer_delay_cb (void *arg)
 callback for udp delay for timeout
 
void pending_udp_timer_cb (void *arg)
 callback for udp timeout
 
static int create_pending_tcp (struct outside_network *outnet, size_t bufsize)
 create pending_tcp buffers
 
static int setup_if (struct port_if *pif, const char *addrstr, int *avail, int numavail, size_t numfd)
 setup an outgoing interface, ready address
 
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, 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, struct dt_env *dtenv)
 Create outside_network structure with N udp ports. More...
 
static void pending_node_del (rbnode_type *node, void *arg)
 helper pending delete
 
static void serviced_node_del (rbnode_type *node, void *ATTR_UNUSED(arg))
 helper serviced delete
 
void outside_network_quit_prepare (struct outside_network *outnet)
 Prepare for quit. More...
 
void outside_network_delete (struct outside_network *outnet)
 Delete outside_network structure. More...
 
void pending_delete (struct outside_network *outnet, struct pending *p)
 Delete pending answer. More...
 
static void sai6_putrandom (struct sockaddr_in6 *sa, int pfxlen, struct ub_randstate *rnd)
 
static int udp_sockport (struct sockaddr_storage *addr, socklen_t addrlen, int pfxlen, int port, int *inuse, struct ub_randstate *rnd)
 Try to open a UDP socket for outgoing communication. More...
 
static int select_id (struct outside_network *outnet, struct pending *pend, sldns_buffer *packet)
 Select random ID.
 
static int select_ifport (struct outside_network *outnet, struct pending *pend, int num_if, struct port_if *ifs)
 Select random interface and port.
 
struct pendingpending_udp_query (struct serviced_query *sq, struct sldns_buffer *packet, int timeout, comm_point_callback_type *cb, void *cb_arg)
 Send UDP query, create pending answer. More...
 
void outnet_tcptimer (void *arg)
 callback for outgoing TCP timer event
 
struct waiting_tcppending_tcp_query (struct serviced_query *sq, sldns_buffer *packet, int timeout, comm_point_callback_type *callback, void *callback_arg)
 Send TCP query. More...
 
static void serviced_gen_query (sldns_buffer *buff, uint8_t *qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint16_t flags)
 create query for serviced queries
 
static struct serviced_querylookup_serviced (struct outside_network *outnet, sldns_buffer *buff, int dnssec, struct sockaddr_storage *addr, socklen_t addrlen, struct edns_option *opt_list)
 lookup serviced query in serviced query rbtree
 
static struct serviced_queryserviced_create (struct outside_network *outnet, sldns_buffer *buff, int dnssec, int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream, struct sockaddr_storage *addr, socklen_t addrlen, uint8_t *zone, size_t zonelen, int qtype, struct edns_option *opt_list)
 Create new serviced entry.
 
static void serviced_delete (struct serviced_query *sq)
 cleanup serviced query entry
 
static void serviced_perturb_qname (struct ub_randstate *rnd, uint8_t *qbuf, size_t len)
 perturb a dname capitalization randomly
 
static void serviced_encode (struct serviced_query *sq, sldns_buffer *buff, int with_edns)
 put serviced query into a buffer
 
static int serviced_udp_send (struct serviced_query *sq, sldns_buffer *buff)
 Perform serviced query UDP sending operation. More...
 
static int serviced_check_qname (sldns_buffer *pkt, uint8_t *qbuf, size_t qbuflen)
 check that perturbed qname is identical
 
static void serviced_callbacks (struct serviced_query *sq, int error, struct comm_point *c, struct comm_reply *rep)
 call the callbacks for a serviced query
 
int serviced_tcp_callback (struct comm_point *c, void *arg, int error, struct comm_reply *rep)
 TCP reply or error callback for serviced queries.
 
static int serviced_tcp_send (struct serviced_query *sq, sldns_buffer *buff)
 Send serviced query over TCP return false on initial failure.
 
static int packet_edns_malformed (struct sldns_buffer *buf, int qtype)
 
int serviced_udp_callback (struct comm_point *c, void *arg, int error, struct comm_reply *rep)
 callback for serviced query UDP answers
 
struct serviced_queryoutnet_serviced_query (struct outside_network *outnet, struct query_info *qinfo, uint16_t flags, int dnssec, int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream, 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, sldns_buffer *buff, struct module_env *env)
 Perform a serviced query to the authoritative servers. More...
 
static void callback_list_remove (struct serviced_query *sq, void *cb_arg)
 remove callback from list
 
void outnet_serviced_query_stop (struct serviced_query *sq, void *cb_arg)
 Remove service query callback. More...
 
static size_t waiting_tcp_get_mem (struct waiting_tcp *w)
 get memory used by waiting tcp entry (in use or not)
 
static size_t if_get_mem (struct port_if *pif)
 get memory used by port if
 
static size_t waiting_udp_get_mem (struct pending *w)
 get memory used by waiting udp
 
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...
 

Detailed Description

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

Macro Definition Documentation

◆ MAX_ID_RETRY

#define MAX_ID_RETRY   1000

number of times to retry making a random ID that is unique.

◆ MAX_PORT_RETRY

#define MAX_PORT_RETRY   10000

number of times to retry finding interface, port that can be opened.

Function Documentation

◆ waiting_tcp_delete()

static void waiting_tcp_delete ( struct waiting_tcp w)
static

delete waiting_tcp entry.

Does not unlink from waiting list.

Parameters
wto delete.

References comm_timer_delete(), and waiting_tcp::timer.

Referenced by decommission_pending_tcp(), outnet_tcptimer(), outside_network_delete(), serviced_delete(), and use_free_buffer().

◆ pick_outgoing_tcp()

static int pick_outgoing_tcp ( struct waiting_tcp w,
int  s 
)
static

Pick random outgoing-interface of that family, and bind it.

port set to 0 so OS picks a port number for us. if it is the ANY address, do not bind.

Parameters
wtcp structure with destination address.
ssocket fd.
Returns
false on error, socket closed.

References port_if::addr, waiting_tcp::addr, addr_is_any(), addr_is_ip6(), port_if::addrlen, waiting_tcp::addrlen, outside_network::ip4_ifs, outside_network::ip6_ifs, log_addr(), log_assert, log_err(), outside_network::num_ip4, outside_network::num_ip6, waiting_tcp::outnet, outside_network::rnd, ub_random_max(), VERB_ALGO, and VERB_OPS.

Referenced by outnet_tcp_take_into_use().

◆ 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,
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,
struct dt_env *  dtenv 
)

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.
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.
dtenvenvironment to send dnstap events with (if enabled).
Returns
: the new structure (with no pending answers) or NULL on error.

References outside_network::base, calc_num46(), comm_base_timept(), comm_point_create_udp(), 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, log_err(), port_comm::next, 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, outnet_udp_cb(), outside_network_delete(), outside_network::pending, pending_cmp(), rbtree_create(), outside_network::rnd, outside_network::serviced, serviced_cmp(), setup_if(), sldns_buffer_new(), outside_network::sslctx, str_is_ip6(), outside_network::svcd_overhead, outside_network::tcp_mss, outside_network::udp_buff, outside_network::unused_fds, 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_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 outside_network::want_to_quit.

Referenced by libworker_delete_env(), and worker_delete().

◆ outside_network_delete()

void outside_network_delete ( struct outside_network outnet)

Delete outside_network structure.

Parameters
outnetobject to delete.

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

◆ pending_delete()

void pending_delete ( struct outside_network outnet,
struct pending p 
)

◆ udp_sockport()

static int udp_sockport ( struct sockaddr_storage *  addr,
socklen_t  addrlen,
int  pfxlen,
int  port,
int *  inuse,
struct ub_randstate *  rnd 
)
static

Try to open a UDP socket for outgoing communication.

Sets sockets options as needed.

Parameters
addrsocket address.
addrlenlength of address.
pfxlenlength of network prefix (for address randomisation).
portport override for addr.
inuseif -1 is returned, this bool means the port was in use.
rndrandom state (for address randomisation).
Returns
fd or -1

References addr_is_ip6().

Referenced by select_ifport().

◆ 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.

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 seconds 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.

Referenced by serviced_tcp_initiate(), and serviced_tcp_send().

◆ serviced_udp_send()

static int serviced_udp_send ( struct serviced_query sq,
sldns_buffer buff 
)
static

◆ 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  tcp_upstream,
int  ssl_upstream,
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 
)

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.
tcp_upstreamuse TCP for upstream queries.
ssl_upstreamuse SSL for upstream queries.
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.
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 service_callback::cb, service_callback::cb_arg, serviced_query::cblist, outside_network::do_udp, module_qstate::edns_opts_back_out, inplace_cb_query_call(), lookup_serviced(), service_callback::next, serviced_query::qbuf, query_info::qclass, query_info::qname, query_info::qname_len, query_info::qtype, rbtree_delete(), module_qstate::region, outside_network::serviced, serviced_create(), serviced_gen_query(), serviced_tcp_send(), serviced_udp_send(), and serviced_query::zone.

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().

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.