This file contains a module that performs DNS64 query processing. More...
#include "config.h"
#include "dns64/dns64.h"
#include "services/cache/dns.h"
#include "services/cache/rrset.h"
#include "util/config_file.h"
#include "util/data/msgreply.h"
#include "util/fptr_wlist.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/storage/dnstree.h"
#include "util/data/dname.h"
#include "sldns/str2wire.h"
Data Structures | |
struct | dns64_qstate |
Per-query module-specific state. More... | |
struct | dns64_env |
This structure contains module configuration information. More... | |
Macros | |
#define | MAX_PTR_QNAME_IPV4 30 |
Maximum length of a domain name in a PTR query in the .in-addr.arpa tree. | |
#define | swap(t, a, b) do {t x = a; a = b; b = x;} while(0) |
Generic macro for swapping two variables. More... | |
Enumerations | |
enum | dns64_state { DNS64_INTERNAL_QUERY , DNS64_NEW_QUERY , DNS64_SUBQUERY_FINISHED } |
State of DNS64 processing for a query. More... | |
Functions | |
static void | reverse (char *begin, char *end) |
Reverses a string. More... | |
static int | uitoa (unsigned n, char *s) |
Convert an unsigned integer to a string. More... | |
static uint32_t | extract_ipv4 (const uint8_t ipv6[], size_t ipv6_len, const int offset) |
Extract an IPv4 address embedded in the IPv6 address ipv6 at offset offset (in bits). More... | |
static size_t | ipv4_to_ptr (uint32_t ipv4, char ptr[], size_t nm_len) |
Builds the PTR query name corresponding to an IPv4 address. More... | |
static int | ptr_to_ipv6 (const char *ptr, uint8_t ipv6[], size_t ipv6_len) |
Converts an IPv6-related domain name string from a PTR query into an IPv6 address represented as a 128-bit array. More... | |
static void | synthesize_aaaa (const uint8_t prefix_addr[], size_t prefix_addr_len, int prefix_net, const uint8_t a[], size_t a_len, uint8_t aaaa[], size_t aaaa_len) |
Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix. More... | |
static int | dns64_insert_ignore_aaaa (struct dns64_env *dns64_env, char *str) |
insert ignore_aaaa element into the tree More... | |
static int | dns64_apply_cfg (struct dns64_env *dns64_env, struct config_file *cfg) |
This function applies the configuration found in the parsed configuration file cfg to this instance of the dns64 module. More... | |
int | dns64_init (struct module_env *env, int id) |
Initializes this instance of the dns64 module. More... | |
static void | free_ignore_aaaa_node (rbnode_type *node, void *ATTR_UNUSED(arg)) |
free ignore AAAA elements | |
void | dns64_deinit (struct module_env *env, int id) |
Deinitializes this instance of the dns64 module. More... | |
static enum module_ext_state | handle_ipv6_ptr (struct module_qstate *qstate, int id) |
Handle PTR queries for IPv6 addresses. More... | |
static enum module_ext_state | generate_type_A_query (struct module_qstate *qstate, int id) |
static int | dns64_always_synth_for_qname (struct module_qstate *qstate, int id) |
See if query name is in the always synth config. More... | |
static enum module_ext_state | handle_event_pass (struct module_qstate *qstate, int id) |
Handles the "pass" event for a query. More... | |
static enum module_ext_state | handle_event_moddone (struct module_qstate *qstate, int id) |
Handles the "done" event for a query. More... | |
void | dns64_operate (struct module_qstate *qstate, enum module_ev event, int id, struct outbound_entry *outbound) |
This is the module's main() function. More... | |
static void | dns64_synth_aaaa_data (const struct ub_packed_rrset_key *fk, const struct packed_rrset_data *fd, struct ub_packed_rrset_key *dk, struct packed_rrset_data **dd_out, struct regional *region, struct dns64_env *dns64_env) |
static void | dns64_adjust_a (int id, struct module_qstate *super, struct module_qstate *qstate) |
Synthesize an AAAA RR set from an A sub-query's answer and add it to the original empty response. More... | |
static void | dns64_adjust_ptr (struct module_qstate *qstate, struct module_qstate *super) |
Generate a response for the original IPv6 PTR query based on an IPv4 PTR sub-query's response. More... | |
void | dns64_inform_super (struct module_qstate *qstate, int id, struct module_qstate *super) |
This function is called when a sub-query finishes to inform the parent query. More... | |
void | dns64_clear (struct module_qstate *qstate, int id) |
Clear module-specific data from query state. More... | |
size_t | dns64_get_mem (struct module_env *env, int id) |
Returns the amount of global memory that this module uses, not including per-query data. More... | |
struct module_func_block * | dns64_get_funcblock (void) |
Function for returning the above function block. More... | |
Variables | |
static const char | DEFAULT_DNS64_PREFIX [] = "64:ff9b::/96" |
This is the default DNS64 prefix that is used when the dns64 module is listed in module-config but when the dns64-prefix variable is not present. | |
static struct module_func_block | dns64_block |
The dns64 function block. More... | |
This file contains a module that performs DNS64 query processing.
#define swap | ( | t, | |
a, | |||
b | |||
) | do {t x = a; a = b; b = x;} while(0) |
Generic macro for swapping two variables.
t | Type of the variables. (e.g. int) |
a | First variable. |
b | Second variable. |
enum dns64_state |
|
static |
Reverses a string.
begin | Points to the first character of the string. |
end | Points one past the last character of the string. |
References swap.
Referenced by lookup(), massage_qname(), massage_type(), and uitoa().
|
static |
Convert an unsigned integer to a string.
The point of this function is that of being faster than sprintf().
n | The number to be converted. |
s | The result will be written here. Must be large enough, be careful! |
References reverse().
Referenced by ipv4_to_ptr().
|
static |
Extract an IPv4 address embedded in the IPv6 address ipv6 at offset offset (in bits).
Note that bits are not necessarily aligned on bytes so we need to be careful.
ipv6 | IPv6 address represented as a 128-bit array in big-endian order. |
ipv6_len | length of the ipv6 byte array. |
offset | Index of the MSB of the IPv4 address embedded in the IPv6 address. |
References log_assert.
|
static |
Builds the PTR query name corresponding to an IPv4 address.
For example, given the number 3,464,175,361, this will build the string "\03206\03123\0231\011\07in-addr\04arpa".
ipv4 | IPv4 address represented as an unsigned 32-bit number. |
ptr | The result will be written here. Must be large enough, be careful! |
nm_len | length of the ptr buffer. |
References log_assert, MAX_PTR_QNAME_IPV4, and uitoa().
|
static |
Converts an IPv6-related domain name string from a PTR query into an IPv6 address represented as a 128-bit array.
ptr | The domain name. (e.g. "\011[...]\010\012\016\012\03ip6\04arpa") |
ipv6 | The result will be written here, in network byte order. |
ipv6_len | length of the ipv6 byte array. |
References log_assert.
|
static |
Synthesize an IPv6 address based on an IPv4 address and the DNS64 prefix.
prefix_addr | DNS64 prefix address. |
prefix_addr_len | length of the prefix_addr buffer. |
prefix_net | CIDR length of the DNS64 prefix. Must be between 0 and 96. |
a | IPv4 address. |
a_len | length of the a buffer. |
aaaa | IPv6 address. The result will be written here. |
aaaa_len | length of the aaaa buffer. |
References log_assert.
|
static |
insert ignore_aaaa element into the tree
dns64_env | module env. |
str | string with domain name. |
Referenced by dns64_apply_cfg().
|
static |
This function applies the configuration found in the parsed configuration file cfg to this instance of the dns64 module.
Currently only the DNS64 prefix (a.k.a. Pref64) is configurable.
dns64_env | Module-specific global parameters. |
cfg | Parsed configuration file. |
References addr_is_ip6(), DEFAULT_DNS64_PREFIX, config_file::dns64_ignore_aaaa, dns64_insert_ignore_aaaa(), dns64_env::ignore_aaaa, log_err(), name_tree_init_parents(), netblockstrtoaddr(), config_strlist::next, dns64_env::prefix_addr, dns64_env::prefix_addrlen, dns64_env::prefix_net, config_strlist::str, VERB_ALGO, and verbose().
Referenced by dns64_init().
int dns64_init | ( | struct module_env * | env, |
int | id | ||
) |
Initializes this instance of the dns64 module.
dns64 init
env | Global state of all module instances. |
id | This instance's ID number. |
References module_env::cfg, dns64_apply_cfg(), dns64_env::ignore_aaaa, log_err(), module_env::modinfo, and name_tree_init().
Referenced by fptr_whitelist_mod_init().
void dns64_deinit | ( | struct module_env * | env, |
int | id | ||
) |
Deinitializes this instance of the dns64 module.
dns64 deinit
env | Global state of all module instances. |
id | This instance's ID number. |
References free_ignore_aaaa_node(), dns64_env::ignore_aaaa, module_env::modinfo, and traverse_postorder().
Referenced by fptr_whitelist_mod_deinit().
|
static |
Handle PTR queries for IPv6 addresses.
If the address belongs to the DNS64 prefix, we must do a PTR query for the corresponding IPv4 address instead.
qstate | Query state structure. |
id | This module instance's ID number. |
|
static |
See if query name is in the always synth config.
The ignore-aaaa list has names for which the AAAA for the domain is ignored and the A is always used to create the answer.
qstate | query state. |
id | module id. |
References dname_count_labels(), module_qstate::env, dns64_env::ignore_aaaa, name_tree_node::labs, module_env::modinfo, name_tree_lookup(), name_tree_node::node, query_info::qclass, module_qstate::qinfo, query_info::qname, and query_info::qname_len.
|
static |
Handles the "pass" event for a query.
This event is received when a new query is received by this module. The query may have been generated internally by another module, in which case we don't want to do any special processing (this is an interesting discussion topic), or it may be brand new, e.g. received over a socket, in which case we do want to apply DNS64 processing.
qstate | A structure representing the state of the query that has just received the "pass" event. |
id | This module's instance ID. |
Referenced by dns64_operate().
|
static |
Handles the "done" event for a query.
We need to analyze the response and maybe issue a new sub-query for the A record.
qstate | A structure representing the state of the query that has just received the "pass" event. |
id | This module's instance ID. |
Referenced by dns64_operate().
void dns64_operate | ( | struct module_qstate * | qstate, |
enum module_ev | event, | ||
int | id, | ||
struct outbound_entry * | outbound | ||
) |
This is the module's main() function.
dns64 operate on a query
It gets called each time a query receives an event which we may need to handle. We respond by updating the state of the query.
qstate | Structure containing the state of the query. |
event | Event that has just been received. |
id | This module's instance ID. |
outbound | State of a DNS query on an authoritative server. We never do our own queries ourselves (other modules do it for us), so this is unused. |
References DNS64_INTERNAL_QUERY, DNS64_NEW_QUERY, module_qstate::ext_state, handle_event_moddone(), handle_event_pass(), log_err(), log_query_info(), module_qstate::minfo, module_error, module_event_moddone, module_event_new, module_event_pass, module_finished, module_qstate::no_cache_store, module_qstate::qinfo, module_qstate::region, regional_alloc(), dns64_qstate::started_no_cache_store, dns64_qstate::state, strextstate(), strmodulevent(), VERB_QUERY, and verbose().
Referenced by fptr_whitelist_mod_operate().
|
static |
Synthesize an AAAA RR set from an A sub-query's answer and add it to the original empty response.
id | This module's instance ID. |
super | Original AAAA query. |
qstate | A query. |
References reply_info::an_numrrsets, reply_info::ar_numrrsets, construct_reply_info_base(), module_qstate::env, reply_info::flags, log_assert, module_env::modinfo, reply_info::ns_numrrsets, reply_info::prefetch_ttl, reply_info::qdcount, dns_msg::qinfo, module_qstate::qinfo, module_qstate::region, regional_alloc(), dns_msg::rep, module_qstate::return_msg, reply_info::rrset_count, reply_info::security, reply_info::serve_expired_norec_ttl, reply_info::serve_expired_ttl, reply_info::ttl, VERB_ALGO, and verbose().
|
static |
Generate a response for the original IPv6 PTR query based on an IPv4 PTR sub-query's response.
qstate | IPv4 PTR sub-query. |
super | Original IPv6 PTR query. |
References packed_rrset_key::dname, packed_rrset_key::dname_len, dns_msg::qinfo, module_qstate::qinfo, query_info::qname, query_info::qname_len, module_qstate::region, regional_alloc(), dns_msg::rep, reply_find_answer_rrset(), reply_info_copy(), module_qstate::return_msg, ub_packed_rrset_key::rk, VERB_ALGO, and verbose().
void dns64_inform_super | ( | struct module_qstate * | qstate, |
int | id, | ||
struct module_qstate * | super | ||
) |
This function is called when a sub-query finishes to inform the parent query.
We issue two kinds of sub-queries: PTR and A.
qstate | State of the sub-query. |
id | This module's instance ID. |
super | State of the super-query. |
References log_err(), log_query_info(), module_qstate::minfo, module_qstate::qinfo, module_qstate::region, regional_alloc(), module_qstate::return_rcode, and VERB_ALGO.
Referenced by fptr_whitelist_mod_inform_super().
void dns64_clear | ( | struct module_qstate * | qstate, |
int | id | ||
) |
Clear module-specific data from query state.
dns64 cleanup query state
Since we do not allocate memory, it's just a matter of setting a pointer to NULL.
qstate | Query state. |
id | This module's instance ID. |
References module_qstate::minfo.
Referenced by fptr_whitelist_mod_clear().
size_t dns64_get_mem | ( | struct module_env * | env, |
int | id | ||
) |
Returns the amount of global memory that this module uses, not including per-query data.
dns64 alloc size routine
env | Module environment. |
id | This module's instance ID. |
Referenced by fptr_whitelist_mod_get_mem().
struct module_func_block* dns64_get_funcblock | ( | void | ) |
Function for returning the above function block.
Get the dns64 function block.
Referenced by module_funcs_avail().
|
static |
The dns64 function block.