Functions
localzone.c File Reference

This file contains functions to enable local zone authority service. More...

#include "config.h"
#include "services/localzone.h"
#include "ldns/str2wire.h"
#include "ldns/sbuffer.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/data/dname.h"
#include "util/data/packed_rrset.h"
#include "util/data/msgencode.h"
#include "util/net_help.h"
#include "util/data/msgreply.h"
#include "util/data/msgparse.h"

Functions

struct local_zoneslocal_zones_create (void)
 Create local zones storage. More...
 
static void lzdel (rbnode_t *n, void *ATTR_UNUSED(arg))
 helper traverse to delete zones
 
void local_zones_delete (struct local_zones *zones)
 Delete local zones storage. More...
 
void local_zone_delete (struct local_zone *z)
 Delete one zone. More...
 
int local_zone_cmp (const void *z1, const void *z2)
 Compare two local_zone entries in rbtree. More...
 
int local_data_cmp (const void *d1, const void *d2)
 Compare two local_data entries in rbtree. More...
 
int parse_dname (const char *str, uint8_t **res, size_t *len, int *labs)
 Form wireformat from text format domain name. More...
 
static struct local_zonelocal_zone_create (uint8_t *nm, size_t len, int labs, enum localzone_type t, uint16_t dclass)
 create a new localzone
 
static struct local_zonelz_enter_zone_dname (struct local_zones *zones, uint8_t *nm, size_t len, int labs, enum localzone_type t, uint16_t c)
 enter a new zone with allocated dname returns with WRlock
 
static struct local_zonelz_enter_zone (struct local_zones *zones, const char *name, const char *type, uint16_t dclass)
 enter a new zone
 
static int get_rr_content (const char *str, uint8_t **nm, uint16_t *type, uint16_t *dclass, time_t *ttl, uint8_t *rr, size_t len, uint8_t **rdata, size_t *rdata_len)
 return name and class and rdata of rr; parses string
 
static int get_rr_nameclass (const char *str, uint8_t **nm, uint16_t *dclass)
 return name and class of rr; parses string
 
static struct local_rrsetlocal_data_find_type (struct local_data *data, uint16_t type)
 Find an rrset in local data structure. More...
 
static int rr_is_duplicate (struct packed_rrset_data *pd, uint8_t *rdata, size_t rdata_len)
 check for RR duplicates
 
static struct local_rrsetnew_local_rrset (struct regional *region, struct local_data *node, uint16_t rrtype, uint16_t rrclass)
 new local_rrset
 
static int insert_rr (struct regional *region, struct packed_rrset_data *pd, uint8_t *rdata, size_t rdata_len, time_t ttl)
 insert RR into RRset data structure; Wastes a couple of bytes
 
static struct local_datalz_find_node (struct local_zone *z, uint8_t *nm, size_t nmlen, int nmlabs)
 find a data node by exact name
 
static int lz_find_create_node (struct local_zone *z, uint8_t *nm, size_t nmlen, int nmlabs, struct local_data **res)
 find a node, create it if not and all its empty nonterminal parents
 
static int lz_enter_rr_into_zone (struct local_zone *z, const char *rrstr)
 enter data RR into auth zone
 
static int lz_enter_rr_str (struct local_zones *zones, const char *rr)
 enter a data RR into auth data; a zone for it must exist
 
static int lz_enter_zones (struct local_zones *zones, struct config_file *cfg)
 parse local-zone: statements
 
static int lz_exists (struct local_zones *zones, const char *name)
 lookup a zone in rbtree; exact match only; SLOW due to parse
 
static int lz_nodefault (struct config_file *cfg, const char *name)
 lookup a zone in cfg->nodefault list
 
static int add_as112_default (struct local_zones *zones, struct config_file *cfg, const char *name)
 enter AS112 default zone
 
static int lz_enter_defaults (struct local_zones *zones, struct config_file *cfg)
 enter default zones
 
static void init_parents (struct local_zones *zones)
 setup parent pointers, so that a lookup can be done for closest match
 
static int lz_setup_implicit (struct local_zones *zones, struct config_file *cfg)
 enter implicit transparent zone for local-data: without local-zone:
 
static int lz_enter_data (struct local_zones *zones, struct config_file *cfg)
 enter auth data
 
static void lz_freeup_cfg (struct config_file *cfg)
 free memory from config
 
int local_zones_apply_cfg (struct local_zones *zones, struct config_file *cfg)
 Apply config settings; setup the local authoritative data. More...
 
struct local_zonelocal_zones_lookup (struct local_zones *zones, uint8_t *name, size_t len, int labs, uint16_t dclass)
 Lookup zone that contains the given name, class. More...
 
struct local_zonelocal_zones_find (struct local_zones *zones, uint8_t *name, size_t len, int labs, uint16_t dclass)
 Find zone that with exactly given name, class. More...
 
static void local_zone_out (struct local_zone *z)
 print all RRsets in local zone
 
void local_zones_print (struct local_zones *zones)
 Debug helper. More...
 
static int local_encode (struct query_info *qinfo, struct edns_data *edns, sldns_buffer *buf, struct regional *temp, struct ub_packed_rrset_key *rrset, int ansec, int rcode)
 encode answer consisting of 1 rrset
 
static int local_data_answer (struct local_zone *z, struct query_info *qinfo, struct edns_data *edns, sldns_buffer *buf, struct regional *temp, int labs, struct local_data **ldp)
 answer local data match
 
static int lz_zone_answer (struct local_zone *z, struct query_info *qinfo, struct edns_data *edns, sldns_buffer *buf, struct regional *temp, struct local_data *ld)
 answer in case where no exact match is found More...
 
int local_zones_answer (struct local_zones *zones, struct query_info *qinfo, struct edns_data *edns, sldns_buffer *buf, struct regional *temp)
 Answer authoritatively for local zones. More...
 
const char * local_zone_type2str (enum localzone_type t)
 Print localzone type to a string. More...
 
int local_zone_str2type (const char *type, enum localzone_type *t)
 Parse the string into localzone type. More...
 
static void set_kiddo_parents (struct local_zone *z, struct local_zone *match, struct local_zone *newp)
 iterate over the kiddies of the given name and set their parent ptr
 
struct local_zonelocal_zones_add_zone (struct local_zones *zones, uint8_t *name, size_t len, int labs, uint16_t dclass, enum localzone_type tp)
 Add a new zone. More...
 
void local_zones_del_zone (struct local_zones *zones, struct local_zone *z)
 Delete a zone. More...
 
int local_zones_add_RR (struct local_zones *zones, const char *rr)
 Add RR data into the localzone data. More...
 
static int is_terminal (struct local_data *d)
 returns true if the node is terminal so no deeper domain names exist
 
static void del_empty_term (struct local_zone *z, struct local_data *d, uint8_t *name, size_t len, int labs)
 delete empty terminals from tree when final data is deleted
 
void local_zones_del_data (struct local_zones *zones, uint8_t *name, size_t len, int labs, uint16_t dclass)
 Remove data from domain name in the tree. More...
 

Detailed Description

This file contains functions to enable local zone authority service.

Function Documentation

struct local_zones* local_zones_create ( void  )

Create local zones storage.

Returns
new struct or NULL on error.

References local_zone_cmp(), local_zones::lock, rbtree_init(), and local_zones::ztree.

Referenced by context_finalize(), daemon_fork(), and localzonechecks().

void local_zones_delete ( struct local_zones zones)

Delete local zones storage.

Parameters
zonesto delete.

References local_zones::lock, lzdel(), traverse_postorder(), and local_zones::ztree.

Referenced by daemon_cleanup(), localzonechecks(), and ub_ctx_delete().

void local_zone_delete ( struct local_zone z)
int local_zone_cmp ( const void *  z1,
const void *  z2 
)

Compare two local_zone entries in rbtree.

Sort hierarchical but not canonical

Parameters
z1zone 1
z2zone 2
Returns
: -1, 0, +1 comparison value.

References local_zone::dclass, dname_lab_cmp(), local_zone::name, and local_zone::namelabs.

Referenced by fptr_whitelist_rbtree_cmp(), and local_zones_create().

int local_data_cmp ( const void *  d1,
const void *  d2 
)

Compare two local_data entries in rbtree.

Sort canonical.

Parameters
d1data 1
d2data 2
Returns
: -1, 0, +1 comparison value.

References dname_canon_lab_cmp(), local_data::name, and local_data::namelabs.

Referenced by fptr_whitelist_rbtree_cmp(), and local_zone_create().

int parse_dname ( const char *  str,
uint8_t **  res,
size_t *  len,
int *  labs 
)

Form wireformat from text format domain name.

Parameters
strthe domain name in text "www.example.com"
resresulting wireformat is stored here with malloc.
lenlength of resulting wireformat.
labsnumber of labels in resulting wireformat.
Returns
false on error, syntax or memory. Also logged.

References dname_count_size_labels(), log_err(), and sldns_str2wire_dname().

Referenced by lz_enter_zone(), lz_exists(), ub_ctx_data_remove(), ub_ctx_zone_add(), and ub_ctx_zone_remove().

static struct local_rrset* local_data_find_type ( struct local_data data,
uint16_t  type 
)
static

Find an rrset in local data structure.

Parameters
datalocal data domain name structure.
typetype to look for (host order).
Returns
rrset pointer or NULL if not found.

References local_rrset::next, ub_packed_rrset_key::rk, local_rrset::rrset, local_data::rrsets, and packed_rrset_key::type.

Referenced by local_data_answer(), and lz_enter_rr_into_zone().

int local_zones_apply_cfg ( struct local_zones zones,
struct config_file cfg 
)

Apply config settings; setup the local authoritative data.

Takes care of locking.

Parameters
zonesis set up.
cfgconfig data.
Returns
false on error.

References init_parents(), lz_enter_data(), lz_enter_defaults(), lz_enter_zones(), lz_freeup_cfg(), and lz_setup_implicit().

Referenced by context_finalize(), daemon_fork(), and localzonechecks().

struct local_zone* local_zones_lookup ( struct local_zones zones,
uint8_t *  name,
size_t  len,
int  labs,
uint16_t  dclass 
)

Lookup zone that contains the given name, class.

User must lock the tree or result zone.

Parameters
zonesthe zones tree
namedname to lookup
lenlength of name.
labslabelcount of name.
dclassclass to lookup.
Returns
closest local_zone or NULL if no covering zone is found.

References local_zone::dclass, dname_lab_cmp(), rbnode_t::key, local_zone::name, local_zone::namelabs, local_zone::namelen, local_zone::node, local_zone::parent, rbtree_find_less_equal(), and local_zones::ztree.

Referenced by local_zones_add_RR(), local_zones_answer(), local_zones_del_data(), lz_enter_rr_str(), and lz_setup_implicit().

struct local_zone* local_zones_find ( struct local_zones zones,
uint8_t *  name,
size_t  len,
int  labs,
uint16_t  dclass 
)

Find zone that with exactly given name, class.

User must lock the tree or result zone.

Parameters
zonesthe zones tree
namedname to lookup
lenlength of name.
labslabelcount of name.
dclassclass to lookup.
Returns
the exact local_zone or NULL.

References local_zone::dclass, rbnode_t::key, local_zone::name, local_zone::namelabs, local_zone::namelen, local_zone::node, rbtree_search(), and local_zones::ztree.

Referenced by do_zone_add(), do_zone_remove(), local_zones_add_zone(), ub_ctx_zone_add(), and ub_ctx_zone_remove().

void local_zones_print ( struct local_zones zones)
static int lz_zone_answer ( struct local_zone z,
struct query_info qinfo,
struct edns_data edns,
sldns_buffer buf,
struct regional temp,
struct local_data ld 
)
static

answer in case where no exact match is found

Parameters
zzone for query
qinfoquery
ednsedns from query
bufbuffer for answer.
temptemp region for encoding
ldlocal data, if NULL, no such name exists in localdata.
Returns
1 if a reply is to be sent, 0 if not.

no reply at all, signal caller by clearing buffer.

References BIT_AA, error_encode(), local_encode(), local_zone_deny, local_zone_redirect, local_zone_refuse, local_zone_static, local_zone_typetransparent, local_data::rrsets, sldns_buffer_begin(), sldns_buffer_clear(), sldns_buffer_flip(), sldns_buffer_read_u16_at(), local_zone::soa, and local_zone::type.

Referenced by local_zones_answer().

int local_zones_answer ( struct local_zones zones,
struct query_info qinfo,
struct edns_data edns,
struct sldns_buffer buf,
struct regional temp 
)

Answer authoritatively for local zones.

Takes care of locking.

Parameters
zonesthe stored zones (shared, read only).
qinfoquery info (parsed).
ednsedns info (parsed).
bufbuffer with query ID and flags, also for reply.
temptemporary storage region.
Returns
true if answer is in buffer. false if query is not answered by authority data. If the reply should be dropped altogether, the return value is true, but the buffer is cleared (empty).

References dname_count_labels(), local_data_answer(), local_zones_lookup(), local_zones::lock, local_zone::lock, lz_zone_answer(), query_info::qclass, query_info::qname, and query_info::qname_len.

Referenced by handle_newq(), libworker_attach_mesh(), libworker_fg(), and worker_handle_request().

const char* local_zone_type2str ( enum localzone_type  t)

Print localzone type to a string.

Pointer to a constant string.

Parameters
tlocal zone type.
Returns
constant string that describes type.

References local_zone_deny, local_zone_nodefault, local_zone_redirect, local_zone_refuse, local_zone_static, local_zone_transparent, and local_zone_typetransparent.

Referenced by do_list_local_zones().

int local_zone_str2type ( const char *  str,
enum localzone_type t 
)

Parse the string into localzone type.

Parameters
strstring to parse
tlocal zone type returned here.
Returns
0 on parse error.

References local_zone_deny, local_zone_redirect, local_zone_refuse, local_zone_static, local_zone_transparent, and local_zone_typetransparent.

Referenced by do_zone_add(), lz_enter_zone(), and ub_ctx_zone_add().

struct local_zone* local_zones_add_zone ( struct local_zones zones,
uint8_t *  name,
size_t  len,
int  labs,
uint16_t  dclass,
enum localzone_type  tp 
)

Add a new zone.

Caller must hold the zones lock. Adjusts the other zones as well (parent pointers) after insertion. The zone must NOT exist (returns NULL and logs error).

Parameters
zonesthe zones tree
namedname to add
lenlength of name.
labslabelcount of name.
dclassclass to add.
tptype.
Returns
local_zone or NULL on error, caller must printout memory error.

References local_zone_create(), local_zone_delete(), local_zones_find(), local_zone::lock, log_err(), local_zone::node, local_zone::parent, rbtree_insert(), set_kiddo_parents(), and local_zones::ztree.

Referenced by do_zone_add(), local_zones_add_RR(), and ub_ctx_zone_add().

void local_zones_del_zone ( struct local_zones zones,
struct local_zone zone 
)

Delete a zone.

Caller must hold the zones lock. Adjusts the other zones as well (parent pointers) after insertion.

Parameters
zonesthe zones tree
zonethe zone to delete from tree. Also deletes zone from memory.

References local_zone_delete(), local_zone::lock, local_zone::parent, rbtree_delete(), set_kiddo_parents(), and local_zones::ztree.

Referenced by do_zone_remove(), and ub_ctx_zone_remove().

int local_zones_add_RR ( struct local_zones zones,
const char *  rr 
)

Add RR data into the localzone data.

Looks up the zone, if no covering zone, a transparent zone with the name of the RR is created.

Parameters
zonesthe zones tree. Not locked by caller.
rrstring with on RR.
Returns
false on failure.

References dname_count_size_labels(), get_rr_nameclass(), local_zone_transparent, local_zones_add_zone(), local_zones_lookup(), local_zones::lock, local_zone::lock, and lz_enter_rr_into_zone().

Referenced by do_data_add(), and ub_ctx_data_add().

void local_zones_del_data ( struct local_zones zones,
uint8_t *  name,
size_t  len,
int  labs,
uint16_t  dclass 
)

Remove data from domain name in the tree.

All types are removed. No effect if zone or name does not exist.

Parameters
zoneszones tree.
namedname to remove
lenlength of name.
labslabelcount of name.
dclassclass to remove.

References del_empty_term(), local_zones_lookup(), local_zones::lock, local_zone::lock, lz_find_node(), local_zone::name, local_data::name, query_dname_compare(), local_data::rrsets, and local_zone::soa.

Referenced by do_data_remove(), and ub_ctx_data_remove().