210 lines
6.8 KiB
C
210 lines
6.8 KiB
C
/*
|
|
* services/authzone.h - authoritative zone that is locally hosted.
|
|
*
|
|
* Copyright (c) 2017, NLnet Labs. All rights reserved.
|
|
*
|
|
* This software is open source.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* Redistributions in binary form must reproduce the above copyright notice,
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
* and/or other materials provided with the distribution.
|
|
*
|
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
|
* be used to endorse or promote products derived from this software without
|
|
* specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* This file contains the functions for an authority zone. This zone
|
|
* is queried by the iterator, just like a stub or forward zone, but then
|
|
* the data is locally held.
|
|
*/
|
|
|
|
#ifndef SERVICES_AUTHZONE_H
|
|
#define SERVICES_AUTHZONE_H
|
|
#include "util/rbtree.h"
|
|
#include "util/locks.h"
|
|
struct ub_packed_rrset_key;
|
|
struct regional;
|
|
struct config_file;
|
|
struct query_info;
|
|
struct dns_msg;
|
|
|
|
/**
|
|
* Authoritative zones, shared.
|
|
*/
|
|
struct auth_zones {
|
|
/** lock on the authzone tree */
|
|
lock_rw_type lock;
|
|
/** rbtree of struct auth_zone */
|
|
rbtree_type ztree;
|
|
};
|
|
|
|
/**
|
|
* Auth zone. Authoritative data, that is fetched from instead of sending
|
|
* packets to the internet.
|
|
*/
|
|
struct auth_zone {
|
|
/** rbtree node, key is name and class */
|
|
rbnode_type node;
|
|
|
|
/** zone name, in uncompressed wireformat */
|
|
uint8_t* name;
|
|
/** length of zone name */
|
|
size_t namelen;
|
|
/** number of labels in zone name */
|
|
int namelabs;
|
|
/** the class of this zone, in host byteorder.
|
|
* uses 'dclass' to not conflict with c++ keyword class. */
|
|
uint16_t dclass;
|
|
|
|
/** lock on the data in the structure
|
|
* For the node, parent, name, namelen, namelabs, dclass, you
|
|
* need to also hold the zones_tree lock to change them (or to
|
|
* delete this zone) */
|
|
lock_rw_type lock;
|
|
|
|
/** auth data for this zone
|
|
* rbtree of struct auth_data */
|
|
rbtree_type data;
|
|
|
|
/* zonefile name (or NULL for no zonefile) */
|
|
char* zonefile;
|
|
/* fallback to the internet on failure or ttl-expiry of auth zone */
|
|
int fallback_enabled;
|
|
};
|
|
|
|
/**
|
|
* Auth data. One domain name, and the RRs to go with it.
|
|
*/
|
|
struct auth_data {
|
|
/** rbtree node, key is name only */
|
|
rbnode_type node;
|
|
/** domain name */
|
|
uint8_t* name;
|
|
/** length of name */
|
|
size_t namelen;
|
|
/** number of labels in name */
|
|
int namelabs;
|
|
/** the data rrsets, with different types, linked list.
|
|
* if the list if NULL the node would be an empty non-terminal,
|
|
* but in this data structure such nodes that represent an empty
|
|
* non-terminal are not needed; they just don't exist.
|
|
*/
|
|
struct auth_rrset* rrsets;
|
|
};
|
|
|
|
/**
|
|
* A auth data RRset
|
|
*/
|
|
struct auth_rrset {
|
|
/** next in list */
|
|
struct auth_rrset* next;
|
|
/** RR type in host byteorder */
|
|
uint16_t type;
|
|
/** RRset data item */
|
|
struct packed_rrset_data* data;
|
|
};
|
|
|
|
/**
|
|
* Create auth zones structure
|
|
*/
|
|
struct auth_zones* auth_zones_create(void);
|
|
|
|
/**
|
|
* Apply configuration to auth zones. Reads zonefiles.
|
|
*/
|
|
int auth_zones_apply_config(struct auth_zones* az, struct config_file* cfg);
|
|
|
|
/**
|
|
* Delete auth zones structure
|
|
*/
|
|
void auth_zones_delete(struct auth_zones* az);
|
|
|
|
/**
|
|
* Write auth zone data to file, in zonefile format.
|
|
*/
|
|
int auth_zone_write_file(struct auth_zone* z, const char* fname);
|
|
|
|
/**
|
|
* Use auth zones to lookup the answer to a query.
|
|
* The query is from the iterator. And the auth zones attempts to provide
|
|
* the answer instead of going to the internet.
|
|
*
|
|
* @param az: auth zones structure.
|
|
* @param qinfo: query info to lookup.
|
|
* @param region: region to use to allocate the reply in.
|
|
* @param msg: reply is stored here (if one).
|
|
* @param fallback: if true, fallback to making a query to the internet.
|
|
* @param dp_nm: name of delegation point to look for. This zone is used
|
|
* to answer the query.
|
|
* If the dp_nm is not found, fallback is set to true and false returned.
|
|
* @param dp_nmlen: length of dp_nm.
|
|
* @return 0: failure (an error of some sort, like servfail).
|
|
* if 0 and fallback is true, fallback to the internet.
|
|
* if 0 and fallback is false, like getting servfail.
|
|
* If true, an answer is available.
|
|
*/
|
|
int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
|
|
struct regional* region, struct dns_msg** msg, int* fallback,
|
|
uint8_t* dp_nm, size_t dp_nmlen);
|
|
|
|
/**
|
|
* Find the auth zone that is above the given qname.
|
|
* Return NULL when there is no auth_zone above the give name, otherwise
|
|
* returns the closest auth_zone above the qname that pertains to it.
|
|
* @param az: auth zones structure.
|
|
* @param qinfo: query info to lookup.
|
|
* @return NULL or auth_zone that pertains to the query.
|
|
*/
|
|
struct auth_zone* auth_zones_find_zone(struct auth_zones* az,
|
|
struct query_info* qinfo);
|
|
|
|
/** find an auth zone by name (exact match by name or NULL returned) */
|
|
struct auth_zone* auth_zone_find(struct auth_zones* az, uint8_t* nm,
|
|
size_t nmlen, uint16_t dclass);
|
|
|
|
/** create an auth zone. returns wrlocked zone. caller must have wrlock
|
|
* on az. returns NULL on malloc failure */
|
|
struct auth_zone* auth_zone_create(struct auth_zones* az, uint8_t* nm,
|
|
size_t nmlen, uint16_t dclass);
|
|
|
|
/** set auth zone zonefile string. caller must have lock on zone */
|
|
int auth_zone_set_zonefile(struct auth_zone* z, char* zonefile);
|
|
|
|
/** set auth zone fallback. caller must have lock on zone.
|
|
* fallbackstr is "yes" or "no". false on parse failure. */
|
|
int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
|
|
|
|
/** read auth zone from zonefile. caller must lock zone. false on failure */
|
|
int auth_zone_read_zonefile(struct auth_zone* z);
|
|
|
|
/** compare auth_zones for sorted rbtree */
|
|
int auth_zone_cmp(const void* z1, const void* z2);
|
|
|
|
/** compare auth_data for sorted rbtree */
|
|
int auth_data_cmp(const void* z1, const void* z2);
|
|
|
|
#endif /* SERVICES_AUTHZONE_H */
|