Functions
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 "ldns/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_t dname_query_hash (uint8_t *dname, hashvalue_t h)
 Hash dname, label by label, lowercasing, into hashvalue. More...
 
hashvalue_t dname_pkt_hash (sldns_buffer *pkt, uint8_t *dname, hashvalue_t 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_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

size_t query_dname_len ( struct sldns_buffer query)

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

Parameters
query,:the 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 chaos_replystr(), dname_test_qdl(), and query_info_parse().

size_t dname_valid ( uint8_t *  dname,
size_t  len 
)

Determine if dname in memory is correct.

no compression ptrs allowed.

Parameters
dname,:where dname starts in memory.
len,:dname 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 canonical_compare(), canonicalize_rdata(), delegpt_rrset_add_ns(), dname_test_valid(), dnskey_verify_rrset_sig(), get_cname_target(), nsec_get_next(), nsec_has_type(), rrset_has_signer(), rrsig_get_signer(), sanitize_nsec_is_overreach(), and wipeout().

void pkt_dname_tolower ( struct sldns_buffer pkt,
uint8_t *  dname 
)

lowercase pkt dname (follows compression pointers)

Parameters
pkt,:the packet, used to follow compression pointers. Position is unchanged.
dname,:start 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(), and serviced_callbacks().

size_t pkt_dname_len ( struct sldns_buffer pkt)

Determine correct, compressed, dname present in packet.

Checks for parse errors.

Parameters
pkt,:packet 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(), dname_test_pkt_dname_len(), get_additional_name(), nsec_at_apex(), parse_edns_from_pkt(), parse_query_section(), parse_section(), and rdata_copy().

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
pkt,:packet, used to resolve compression pointers.
d1,:dname to compare
d2,:dname 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, PTR_OFFSET, and sldns_buffer_at().

Referenced by rrset_parse_equals(), scrub_message(), scrub_normalize(), scrub_sanitize(), and smart_compare().

hashvalue_t dname_query_hash ( uint8_t *  dname,
hashvalue_t  h 
)

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

Dname in query format (not compressed).

Parameters
dname,:dname to hash.
h,:initial hash value.
Returns
: result hash value.

References LDNS_MAX_LABELLEN, and log_assert.

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

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

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

Dname in pkt format (compressed).

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

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

Referenced by pkt_hash_rrset(), and pkt_hash_rrset_first().

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

Copy over a valid dname and decompress it.

Parameters
pkt,:packet to resolve compression pointers.
to,:buffer of size from pkt_len function to hold result.
dname,:pointer into packet where dname starts.

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

Referenced by parse_copy_decompress_rrset(), parse_create_qinfo(), pkt_strict_sub(), pkt_sub(), priv_lookup_name(), rdata_copy(), remove_rr(), remove_rrset(), sub_of_pkt(), synth_cname(), and synth_cname_rrset().

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

Debug helper.

Print wireformat dname to output.

Parameters
out,:like stdout or a file.
pkt,:if not NULL, the packet for resolving compression ptrs.
dname,:pointer to (start of) dname.

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

Referenced by analyze_dname(), parse_section(), and print_neg_cache().

int dname_count_labels ( uint8_t *  dname)
int dname_count_size_labels ( uint8_t *  dname,
size_t *  size 
)
static int memlowercmp ( uint8_t *  p1,
uint8_t *  p2,
uint8_t  len 
)
static

Compare labels in memory, lowercase while comparing.

Parameters
p1,:label 1
p2,:label 2
len,:number of bytes to compare.
Returns
: 0, -1, +1 comparison result.

Referenced by memcanoncmp().

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
d1,:first dname. pointer to uncompressed wireformat.
labs1,:number of labels in first dname.
d2,:second dname. pointer to uncompressed wireformat.
labs2,:number of labels in second dname.
mlabs,:number 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(), 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(), init_parents(), local_zone_cmp(), local_zones_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().

int dname_buffer_write ( struct sldns_buffer pkt,
uint8_t *  dname 
)

Copy over a valid dname to a packet.

Parameters
pkt,:packet to copy to.
dname,:dname 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().

void dname_str ( uint8_t *  dname,
char *  str 
)

Debug helper.

Print dname to given string buffer (string buffer must be at least 255 chars + 1 for the 0, in printable form. This may lose information (? for nonprintable characters, or & if the name is too long, # for a bad label length).

Parameters
dname,:uncompressed wireformat.
str,:buffer of 255+1 length.

References LDNS_MAX_DOMAINLEN, and LDNS_MAX_LABELLEN.

Referenced by anchors_assemble_rrsets(), autr_debug_print_tp(), delegpt_log(), do_dump_requestlist(), do_list_local_zones(), dump_infra_host(), errinf_dname(), errinf_rrset(), errinf_to_str(), fill_canon(), forwards_insert_data(), get_mesh_status(), hints_insert(), log_name_addr(), log_nametypeclass(), print_neg_cache(), serviced_perturb_qname(), and ssl_print_name_dp().

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
d1,:domain name, uncompressed wireformat
labs1,:number of labels in d1, including root label.
d2,:domain name, uncompressed wireformat
labs2,:number 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 dname_strict_subdomain_c(), dname_test_strict_subdomain(), hints_lookup_stub(), is_terminal(), iter_msg_from_zone(), and set_kiddo_parents().

int dname_strict_subdomain_c ( uint8_t *  d1,
uint8_t *  d2 
)

Like dname_strict_subdomain but counts labels.

Parameters
d1,:domain name, uncompressed wireformat
d2,:domain 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 handle_cname_response(), nsec_proves_nodata(), pkt_strict_sub(), processInit(), processQueryResponse(), response_type_from_server(), val_nsec_check_dlv(), val_nsec_proves_insecuredelegation(), and val_nsec_proves_name_error().

int dname_subdomain_c ( uint8_t *  d1,
uint8_t *  d2 
)
int dname_is_root ( uint8_t *  dname)
void dname_remove_label ( uint8_t **  dname,
size_t *  len 
)
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
dname,:from what to strip off. uncompressed wireformat.
len,:length, adjusted to become less.
n,:number of labels to strip off (from the left). if 0, nothing happens.
Returns
stripped off, or "." if input was ".".

References dname_remove_label().

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

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
dname,:valid uncompressed wireformat.
Returns
number of labels like in RRSIG; '*' and '.' are not counted.

Referenced by dname_test_sigcount(), dnskey_verify_rrset_sig(), and insert_can_owner().

int dname_is_wild ( uint8_t *  dname)

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

Parameters
dname,:valid uncompressed wireformat.
Returns
true if wildcard, or false.

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

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
p1,:label 1
len1,:length of label 1.
p2,:label 2
len2,:length of label 2.
Returns
: 0, -1, +1 comparison result.

References memlowercmp().

Referenced by 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
d1,:first dname. pointer to uncompressed wireformat.
labs1,:number of labels in first dname.
d2,:second dname. pointer to uncompressed wireformat.
labs2,:number of labels in second dname.
mlabs,:number 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 dname_canonical_compare(), local_data_cmp(), val_neg_data_compare(), val_neg_zone_compare(), and wipeout().

int dname_canonical_compare ( uint8_t *  d1,
uint8_t *  d2 
)

Canonical dname compare.

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

Parameters
d1,:first dname. pointer to uncompressed wireformat.
d2,:second 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(), val_nsec_check_dlv(), and val_nsec_proves_name_error().

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

Get the shared topdomain between two names.

Root "." or longer.

Parameters
d1,:first dname. pointer to uncompressed wireformat.
d2,:second 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 dlv_topdomain(), dname_test_topdomain(), and nsec_closest_encloser().