dname.c File Reference

This file contains domain name handling functions. More...

#include "config.h"
#include <ctype.h>
#include "util/data/dname.h"
#include "util/data/msgparse.h"
#include "util/log.h"
#include "util/storage/lookup3.h"
#include "sldns/sbuffer.h"

Functions

size_t query_dname_len (sldns_buffer *query)
 Determine length of dname in buffer, no compression ptrs allowed,. More...
 
size_t dname_valid (uint8_t *dname, size_t maxlen)
 Determine if dname in memory is correct. More...
 
int query_dname_compare (register uint8_t *d1, register uint8_t *d2)
 compare uncompressed, noncanonical, registers are hints for speed
 
void query_dname_tolower (uint8_t *dname)
 lowercase query dname
 
void pkt_dname_tolower (sldns_buffer *pkt, uint8_t *dname)
 lowercase pkt dname (follows compression pointers) More...
 
size_t pkt_dname_len (sldns_buffer *pkt)
 Determine correct, compressed, dname present in packet. More...
 
int dname_pkt_compare (sldns_buffer *pkt, uint8_t *d1, uint8_t *d2)
 Compare dnames in packet (compressed). More...
 
hashvalue_type dname_query_hash (uint8_t *dname, hashvalue_type h)
 Hash dname, label by label, lowercasing, into hashvalue. More...
 
hashvalue_type dname_pkt_hash (sldns_buffer *pkt, uint8_t *dname, hashvalue_type h)
 Hash dname, label by label, lowercasing, into hashvalue. More...
 
void dname_pkt_copy (sldns_buffer *pkt, uint8_t *to, uint8_t *dname)
 Copy over a valid dname and decompress it. More...
 
void dname_print (FILE *out, struct sldns_buffer *pkt, uint8_t *dname)
 Debug helper. More...
 
int dname_count_labels (uint8_t *dname)
 Count the number of labels in an uncompressed dname in memory. More...
 
int dname_count_size_labels (uint8_t *dname, size_t *size)
 Count labels and dname length both, for uncompressed dname in memory. More...
 
static int memlowercmp (uint8_t *p1, uint8_t *p2, uint8_t len)
 Compare labels in memory, lowercase while comparing. More...
 
int dname_lab_cmp (uint8_t *d1, int labs1, uint8_t *d2, int labs2, int *mlabs)
 Compare dnames, sorted not canonical, but by label. More...
 
int dname_lab_startswith (uint8_t *label, char *prefix, char **endptr)
 Check if labels starts with given prefix. More...
 
int dname_has_label (uint8_t *dname, size_t dnamelen, uint8_t *label)
 Check if dname contains label. More...
 
int dname_buffer_write (sldns_buffer *pkt, uint8_t *dname)
 Copy over a valid dname to a packet. More...
 
void dname_str (uint8_t *dname, char *str)
 Debug helper. More...
 
int dname_strict_subdomain (uint8_t *d1, int labs1, uint8_t *d2, int labs2)
 See if domain name d1 is a strict subdomain of d2. More...
 
int dname_strict_subdomain_c (uint8_t *d1, uint8_t *d2)
 Like dname_strict_subdomain but counts labels. More...
 
int dname_subdomain_c (uint8_t *d1, uint8_t *d2)
 Counts labels. More...
 
int dname_is_root (uint8_t *dname)
 Returns true if the uncompressed wireformat dname is the root ".". More...
 
void dname_remove_label (uint8_t **dname, size_t *len)
 Snip off first label from a dname, returning the parent zone. More...
 
void dname_remove_labels (uint8_t **dname, size_t *len, int n)
 Snip off first N labels from a dname, returning the parent zone. More...
 
int dname_signame_label_count (uint8_t *dname)
 Count labels for the RRSIG signature label field. More...
 
int dname_is_wild (uint8_t *dname)
 Return true if the label is a wildcard, *.example.com. More...
 
static int memcanoncmp (uint8_t *p1, uint8_t len1, uint8_t *p2, uint8_t len2)
 Compare labels in memory, lowercase while comparing. More...
 
int dname_canon_lab_cmp (uint8_t *d1, int labs1, uint8_t *d2, int labs2, int *mlabs)
 Compare dnames, Canonical in rfc4034 sense, but by label. More...
 
int dname_canonical_compare (uint8_t *d1, uint8_t *d2)
 Canonical dname compare. More...
 
uint8_t * dname_get_shared_topdomain (uint8_t *d1, uint8_t *d2)
 Get the shared topdomain between two names. More...
 

Detailed Description

This file contains domain name handling functions.

Function Documentation

◆ query_dname_len()

size_t query_dname_len ( struct sldns_buffer query)

Determine length of dname in buffer, no compression ptrs allowed,.

Parameters
querythe ldns buffer, current position at start of dname. at end, position is at end of the dname.
Returns
: 0 on parse failure, or length including ending 0 of dname.

References LDNS_MAX_DOMAINLEN, sldns_buffer_read_u8(), sldns_buffer_remaining(), and sldns_buffer_skip().

Referenced by dname_test_qdl().

◆ dname_valid()

size_t dname_valid ( uint8_t *  dname,
size_t  len 
)

Determine if dname in memory is correct.

no compression ptrs allowed.

Parameters
dnamewhere dname starts in memory.
lendname is not allowed to exceed this length (i.e. of allocation).
Returns
length of dname if dname is ok, 0 on a parse error.

References LDNS_MAX_DOMAINLEN.

Referenced by az_add_additionals_from(), az_insert_rr_decompress(), az_remove_rr_decompress(), canonical_compare(), canonicalize_rdata(), delegpt_rrset_add_ns(), dname_test_valid(), follow_cname_chain(), nsec_get_next(), nsec_has_type(), parse_get_cname_target(), rrset_has_signer(), and rrsig_get_signer().

◆ pkt_dname_tolower()

void pkt_dname_tolower ( struct sldns_buffer pkt,
uint8_t *  dname 
)

lowercase pkt dname (follows compression pointers)

Parameters
pktthe packet, used to follow compression pointers. Position is unchanged.
dnamestart of dname in packet.

References LABEL_IS_PTR, MAX_COMPRESS_PTRS, PTR_OFFSET, sldns_buffer_at(), sldns_buffer_end(), and sldns_buffer_limit().

Referenced by dname_test_pdtl().

◆ pkt_dname_len()

size_t pkt_dname_len ( struct sldns_buffer pkt)

Determine correct, compressed, dname present in packet.

Checks for parse errors.

Parameters
pktpacket to read from (from current start position).
Returns
: 0 on parse error. At exit the position is right after the (compressed) dname. Compression pointers are followed and checked for loops. The uncompressed wireformat length is returned.

References LABEL_IS_PTR, LDNS_MAX_DOMAINLEN, MAX_COMPRESS_PTRS, PTR_OFFSET, sldns_buffer_limit(), sldns_buffer_position(), sldns_buffer_read_u8(), sldns_buffer_remaining(), sldns_buffer_set_position(), and sldns_buffer_skip().

Referenced by analyze_dname(), calc_size(), decompress_rr_into_buffer(), dname_test_pkt_dname_len(), nsec_at_apex(), parse_get_cname_target(), and skip_pkt_rr().

◆ dname_pkt_compare()

int dname_pkt_compare ( struct sldns_buffer pkt,
uint8_t *  d1,
uint8_t *  d2 
)

Compare dnames in packet (compressed).

Dnames must be valid. routine performs lowercasing, so the packet casing is preserved.

Parameters
pktpacket, used to resolve compression pointers.
d1dname to compare
d2dname to compare
Returns
: -1, 0, or +1 depending on comparison results. Sort order is first difference found. not the canonical ordering.

References LABEL_IS_PTR, LDNS_MAX_LABELLEN, log_assert, MAX_COMPRESS_PTRS, PTR_OFFSET, sldns_buffer_at(), and sldns_buffer_limit().

Referenced by rrset_parse_equals(), and smart_compare().

◆ dname_query_hash()

hashvalue_type dname_query_hash ( uint8_t *  dname,
hashvalue_type  h 
)

Hash dname, label by label, lowercasing, into hashvalue.

Dname in query format (not compressed).

Parameters
dnamedname to hash.
hinitial hash value.
Returns
: result hash value.

References hashlittle(), LDNS_MAX_LABELLEN, and log_assert.

Referenced by hash_infra(), infra_create_ratedata(), infra_find_ratedata(), key_entry_hash(), query_info_hash(), and rrset_key_hash().

◆ dname_pkt_hash()

hashvalue_type dname_pkt_hash ( struct sldns_buffer pkt,
uint8_t *  dname,
hashvalue_type  h 
)

Hash dname, label by label, lowercasing, into hashvalue.

Dname in pkt format (compressed).

Parameters
pktpacket, for resolving compression pointers.
dnamedname to hash, pointer to the pkt buffer. Must be valid format. No loops, etc.
hinitial hash value.
Returns
: result hash value. Result is the same as dname_query_hash, even if compression is used.

References hashlittle(), LABEL_IS_PTR, LDNS_MAX_LABELLEN, log_assert, MAX_COMPRESS_PTRS, PTR_OFFSET, sldns_buffer_at(), and sldns_buffer_limit().

Referenced by pkt_hash_rrset(), and pkt_hash_rrset_first().

◆ dname_pkt_copy()

void dname_pkt_copy ( struct sldns_buffer pkt,
uint8_t *  to,
uint8_t *  dname 
)

Copy over a valid dname and decompress it.

Parameters
pktpacket to resolve compression pointers.
tobuffer of size from pkt_len function to hold result.
dnamepointer into packet where dname starts.

References LABEL_IS_PTR, LDNS_MAX_DOMAINLEN, LDNS_MAX_LABELLEN, log_assert, log_err(), MAX_COMPRESS_PTRS, PTR_OFFSET, sldns_buffer_at(), and sldns_buffer_limit().

Referenced by decompress_rr_into_buffer(), parse_copy_decompress_rrset(), parse_create_qinfo(), pkt_strict_sub(), pkt_sub(), priv_lookup_name(), shorten_rrset(), sub_of_pkt(), synth_cname(), and synth_cname_rrset().

◆ dname_print()

void dname_print ( FILE *  out,
struct sldns_buffer pkt,
uint8_t *  dname 
)

Debug helper.

Print wireformat dname to output.

Parameters
outlike stdout or a file.
pktif not NULL, the packet for resolving compression ptrs.
dnamepointer to (start of) dname.

References LABEL_IS_PTR, LDNS_MAX_LABELLEN, MAX_COMPRESS_PTRS, PTR_OFFSET, sldns_buffer_at(), and sldns_buffer_limit().

Referenced by analyze_dname(), and print_neg_cache().

◆ dname_count_labels()

◆ dname_count_size_labels()

int dname_count_size_labels ( uint8_t *  dname,
size_t *  size 
)

◆ memlowercmp()

static int memlowercmp ( uint8_t *  p1,
uint8_t *  p2,
uint8_t  len 
)
static

Compare labels in memory, lowercase while comparing.

Parameters
p1label 1
p2label 2
lennumber of bytes to compare.
Returns
: 0, -1, +1 comparison result.

Referenced by dname_has_label(), and memcanoncmp().

◆ dname_lab_cmp()

int dname_lab_cmp ( uint8_t *  d1,
int  labs1,
uint8_t *  d2,
int  labs2,
int *  mlabs 
)

Compare dnames, sorted not canonical, but by label.

Such that zone contents follows zone apex.

Parameters
d1first dname. pointer to uncompressed wireformat.
labs1number of labels in first dname.
d2second dname. pointer to uncompressed wireformat.
labs2number of labels in second dname.
mlabsnumber of labels that matched exactly (the shared topdomain).
Returns
: 0 for equal, -1 smaller, or +1 d1 larger than d2.

References log_assert.

Referenced by anchor_cmp(), anchors_init_parents_locked(), anchors_lookup(), auth_xfer_cmp(), auth_zone_cmp(), compress_tree_search(), dname_get_shared_topdomain(), dname_strict_subdomain(), dname_subdomain_c(), dname_test_dname_lab_cmp(), forwards_lookup(), fwd_cmp(), fwd_init_parents(), local_zone_cmp(), local_zones_tags_lookup(), lz_setup_implicit(), name_tree_compare(), name_tree_init_parents(), name_tree_lookup(), neg_closest_data_parent(), neg_closest_zone_parent(), and val_find_best_signer().

◆ dname_lab_startswith()

int dname_lab_startswith ( uint8_t *  label,
char *  prefix,
char **  endptr 
)

Check if labels starts with given prefix.

Parameters
labeldname label
prefixthe string to match label with, null terminated.
endptrpointer to location in label after prefix, only if return value is 1. NULL if nothing in the label after the prefix, i.e. prefix and label are the same.
Returns
: 1 if label starts with prefix, else 0

◆ dname_has_label()

int dname_has_label ( uint8_t *  dname,
size_t  dnamelen,
uint8_t *  label 
)

Check if dname contains label.

Parameters
dnamedname
dnamelenlength of dname
labellabel to be checked for presence in dname
Returns
: 1 if dname has this label, 0 otherwise

References memlowercmp().

Referenced by dname_test_has_label().

◆ dname_buffer_write()

int dname_buffer_write ( struct sldns_buffer pkt,
uint8_t *  dname 
)

Copy over a valid dname to a packet.

Parameters
pktpacket to copy to.
dnamedname to copy.
Returns
: 0 if not enough space in buffer.

References sldns_buffer_remaining(), sldns_buffer_write(), and sldns_buffer_write_u8().

Referenced by compress_any_dname().

◆ dname_str()

◆ dname_strict_subdomain()

int dname_strict_subdomain ( uint8_t *  d1,
int  labs1,
uint8_t *  d2,
int  labs2 
)

See if domain name d1 is a strict subdomain of d2.

That is a subdomain, but not equal.

Parameters
d1domain name, uncompressed wireformat
labs1number of labels in d1, including root label.
d2domain name, uncompressed wireformat
labs2number of labels in d2, including root label.
Returns
true if d1 is a subdomain of d2, but not equal to d2.

References dname_lab_cmp().

Referenced by az_nsec3_get_nextcloser(), dname_strict_subdomain_c(), dname_test_strict_subdomain(), hints_lookup_stub(), is_terminal(), iter_msg_from_zone(), iter_stub_fwd_no_cache(), and set_kiddo_parents().

◆ dname_strict_subdomain_c()

int dname_strict_subdomain_c ( uint8_t *  d1,
uint8_t *  d2 
)

Like dname_strict_subdomain but counts labels.

Parameters
d1domain name, uncompressed wireformat
d2domain name, uncompressed wireformat
Returns
true if d1 is a subdomain of d2, but not equal to d2.

References dname_count_labels(), and dname_strict_subdomain().

Referenced by az_empty_nonterminal(), cname_under_previous_dname(), handle_cname_response(), nsec_proves_nodata(), pkt_strict_sub(), processQueryResponse(), val_find_signer(), val_nsec_proves_insecuredelegation(), and val_nsec_proves_name_error().

◆ dname_subdomain_c()

◆ dname_is_root()

int dname_is_root ( uint8_t *  dname)

Returns true if the uncompressed wireformat dname is the root ".".

Parameters
dnamethe dname to check
Returns
true if ".", false if not.

References LABEL_IS_PTR, and log_assert.

Referenced by auth_zones_find_zone(), az_domain_go_up(), az_find_candidate_ce(), az_find_wildcard(), calc_zone_need(), check_data(), check_zone_invariants(), del_empty_term(), dname_test_isroot(), forward_request(), key_cache_obtain(), local_zones_tags_lookup(), name_tree_next_root(), and nsec_proves_nodata().

◆ dname_remove_label()

void dname_remove_label ( uint8_t **  dname,
size_t *  len 
)

◆ dname_remove_labels()

void dname_remove_labels ( uint8_t **  dname,
size_t *  len,
int  n 
)

Snip off first N labels from a dname, returning the parent zone.

Parameters
dnamefrom what to strip off. uncompressed wireformat.
lenlength, adjusted to become less.
nnumber of labels to strip off (from the left). if 0, nothing happens. return stripped off, or "." if input was ".".

References dname_remove_label().

Referenced by az_nsec3_get_nextcloser(), dname_get_shared_topdomain(), lz_setup_implicit(), next_closer(), val_nsec_proves_no_wc(), and val_rrset_wildcard().

◆ dname_signame_label_count()

int dname_signame_label_count ( uint8_t *  dname)

Count labels for the RRSIG signature label field.

Like a normal labelcount, but "*" wildcard and "." root are not counted.

Parameters
dnamevalid uncompressed wireformat.
Returns
number of labels like in RRSIG; '*' and '.' are not counted.

Referenced by dname_test_sigcount(), and insert_can_owner().

◆ dname_is_wild()

int dname_is_wild ( uint8_t *  dname)

Return true if the label is a wildcard, *.example.com.

Parameters
dnamevalid uncompressed wireformat.
Returns
true if wildcard, or false.

Referenced by dname_test_iswild(), nsec_proves_nodata(), and val_rrset_wildcard().

◆ memcanoncmp()

static int memcanoncmp ( uint8_t *  p1,
uint8_t  len1,
uint8_t *  p2,
uint8_t  len2 
)
static

Compare labels in memory, lowercase while comparing.

Returns canonical order for labels. If all is equal, the shortest is first.

Parameters
p1label 1
len1length of label 1.
p2label 2
len2length of label 2.
Returns
: 0, -1, +1 comparison result.

References memlowercmp().

Referenced by dname_canon_lab_cmp().

◆ dname_canon_lab_cmp()

int dname_canon_lab_cmp ( uint8_t *  d1,
int  labs1,
uint8_t *  d2,
int  labs2,
int *  mlabs 
)

Compare dnames, Canonical in rfc4034 sense, but by label.

Such that zone contents follows zone apex.

Parameters
d1first dname. pointer to uncompressed wireformat.
labs1number of labels in first dname.
d2second dname. pointer to uncompressed wireformat.
labs2number of labels in second dname.
mlabsnumber of labels that matched exactly (the shared topdomain).
Returns
: 0 for equal, -1 smaller, or +1 d1 larger than d2.

References log_assert, and memcanoncmp().

Referenced by auth_data_cmp(), dname_canonical_compare(), local_data_cmp(), val_neg_data_compare(), and val_neg_zone_compare().

◆ dname_canonical_compare()

int dname_canonical_compare ( uint8_t *  d1,
uint8_t *  d2 
)

Canonical dname compare.

Takes care of counting labels. Per rfc 4034 canonical order.

Parameters
d1first dname. pointer to uncompressed wireformat.
d2second dname. pointer to uncompressed wireformat.
Returns
: 0 for equal, -1 smaller, or +1 d1 larger than d2.

References dname_canon_lab_cmp(), and dname_count_labels().

Referenced by dname_test_canoncmp(), nsec_proves_nodata(), rrset_canonical_sort_cmp(), and val_nsec_proves_name_error().

◆ dname_get_shared_topdomain()

uint8_t* dname_get_shared_topdomain ( uint8_t *  d1,
uint8_t *  d2 
)

Get the shared topdomain between two names.

Root "." or longer.

Parameters
d1first dname. pointer to uncompressed wireformat.
d2second dname. pointer to uncompressed wireformat.
Returns
pointer to shared topdomain. Ptr to a part of d1.

References dname_count_labels(), dname_lab_cmp(), dname_remove_labels(), and LDNS_MAX_DOMAINLEN.

Referenced by auth_zones_find_zone(), az_find_candidate_ce(), dname_test_topdomain(), nsec_closest_encloser(), and rpz_find_zone().