1238106Sdes/*
2238106Sdes * services/localzone.h - local zones authority service.
3238106Sdes *
4238106Sdes * Copyright (c) 2007, NLnet Labs. All rights reserved.
5238106Sdes *
6238106Sdes * This software is open source.
7238106Sdes *
8238106Sdes * Redistribution and use in source and binary forms, with or without
9238106Sdes * modification, are permitted provided that the following conditions
10238106Sdes * are met:
11238106Sdes *
12238106Sdes * Redistributions of source code must retain the above copyright notice,
13238106Sdes * this list of conditions and the following disclaimer.
14238106Sdes *
15238106Sdes * Redistributions in binary form must reproduce the above copyright notice,
16238106Sdes * this list of conditions and the following disclaimer in the documentation
17238106Sdes * and/or other materials provided with the distribution.
18238106Sdes *
19238106Sdes * Neither the name of the NLNET LABS nor the names of its contributors may
20238106Sdes * be used to endorse or promote products derived from this software without
21238106Sdes * specific prior written permission.
22238106Sdes *
23238106Sdes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24269257Sdes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25269257Sdes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26269257Sdes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27269257Sdes * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28269257Sdes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29269257Sdes * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30269257Sdes * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31269257Sdes * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32269257Sdes * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33269257Sdes * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34238106Sdes */
35238106Sdes
36238106Sdes/**
37238106Sdes * \file
38238106Sdes *
39238106Sdes * This file contains functions to enable local zone authority service.
40238106Sdes */
41238106Sdes
42238106Sdes#ifndef SERVICES_LOCALZONE_H
43238106Sdes#define SERVICES_LOCALZONE_H
44238106Sdes#include "util/rbtree.h"
45238106Sdes#include "util/locks.h"
46238106Sdesstruct ub_packed_rrset_key;
47238106Sdesstruct regional;
48238106Sdesstruct config_file;
49238106Sdesstruct edns_data;
50238106Sdesstruct query_info;
51269257Sdesstruct sldns_buffer;
52238106Sdes
53238106Sdes/**
54238106Sdes * Local zone type
55238106Sdes * This type determines processing for queries that did not match
56238106Sdes * local-data directly.
57238106Sdes */
58238106Sdesenum localzone_type {
59238106Sdes	/** drop query */
60238106Sdes	local_zone_deny = 0,
61238106Sdes	/** answer with error */
62238106Sdes	local_zone_refuse,
63238106Sdes	/** answer nxdomain or nodata */
64238106Sdes	local_zone_static,
65238106Sdes	/** resolve normally */
66238106Sdes	local_zone_transparent,
67238106Sdes	/** do not block types at localdata names */
68238106Sdes	local_zone_typetransparent,
69238106Sdes	/** answer with data at zone apex */
70238106Sdes	local_zone_redirect,
71238106Sdes	/** remove default AS112 blocking contents for zone
72238106Sdes	 * nodefault is used in config not during service. */
73238106Sdes	local_zone_nodefault
74238106Sdes};
75238106Sdes
76238106Sdes/**
77238106Sdes * Authoritative local zones storage, shared.
78238106Sdes */
79238106Sdesstruct local_zones {
80238106Sdes	/** lock on the localzone tree */
81269257Sdes	lock_rw_t lock;
82238106Sdes	/** rbtree of struct local_zone */
83238106Sdes	rbtree_t ztree;
84238106Sdes};
85238106Sdes
86238106Sdes/**
87238106Sdes * Local zone. A locally served authoritative zone.
88238106Sdes */
89238106Sdesstruct local_zone {
90238106Sdes	/** rbtree node, key is name and class */
91238106Sdes	rbnode_t node;
92238106Sdes	/** parent zone, if any. */
93238106Sdes	struct local_zone* parent;
94238106Sdes
95238106Sdes	/** zone name, in uncompressed wireformat */
96238106Sdes	uint8_t* name;
97238106Sdes	/** length of zone name */
98238106Sdes	size_t namelen;
99238106Sdes	/** number of labels in zone name */
100238106Sdes	int namelabs;
101238106Sdes	/** the class of this zone.
102238106Sdes	 * uses 'dclass' to not conflict with c++ keyword class. */
103238106Sdes	uint16_t dclass;
104238106Sdes
105238106Sdes	/** lock on the data in the structure
106238106Sdes	 * For the node, parent, name, namelen, namelabs, dclass, you
107238106Sdes	 * need to also hold the zones_tree lock to change them (or to
108238106Sdes	 * delete this zone) */
109238106Sdes	lock_rw_t lock;
110238106Sdes
111238106Sdes	/** how to process zone */
112238106Sdes	enum localzone_type type;
113238106Sdes
114238106Sdes	/** in this region the zone's data is allocated.
115238106Sdes	 * the struct local_zone itself is malloced. */
116238106Sdes	struct regional* region;
117238106Sdes	/** local data for this zone
118238106Sdes	 * rbtree of struct local_data */
119238106Sdes	rbtree_t data;
120238106Sdes	/** if data contains zone apex SOA data, this is a ptr to it. */
121238106Sdes	struct ub_packed_rrset_key* soa;
122238106Sdes};
123238106Sdes
124238106Sdes/**
125238106Sdes * Local data. One domain name, and the RRs to go with it.
126238106Sdes */
127238106Sdesstruct local_data {
128238106Sdes	/** rbtree node, key is name only */
129238106Sdes	rbnode_t node;
130238106Sdes	/** domain name */
131238106Sdes	uint8_t* name;
132238106Sdes	/** length of name */
133238106Sdes	size_t namelen;
134238106Sdes	/** number of labels in name */
135238106Sdes	int namelabs;
136238106Sdes	/** the data rrsets, with different types, linked list.
137238106Sdes	 * If this list is NULL, the node is an empty non-terminal. */
138238106Sdes	struct local_rrset* rrsets;
139238106Sdes};
140238106Sdes
141238106Sdes/**
142238106Sdes * A local data RRset
143238106Sdes */
144238106Sdesstruct local_rrset {
145238106Sdes	/** next in list */
146238106Sdes	struct local_rrset* next;
147238106Sdes	/** RRset data item */
148238106Sdes	struct ub_packed_rrset_key* rrset;
149238106Sdes};
150238106Sdes
151238106Sdes/**
152238106Sdes * Create local zones storage
153238106Sdes * @return new struct or NULL on error.
154238106Sdes */
155238106Sdesstruct local_zones* local_zones_create(void);
156238106Sdes
157238106Sdes/**
158238106Sdes * Delete local zones storage
159238106Sdes * @param zones: to delete.
160238106Sdes */
161238106Sdesvoid local_zones_delete(struct local_zones* zones);
162238106Sdes
163238106Sdes/**
164238106Sdes * Apply config settings; setup the local authoritative data.
165238106Sdes * Takes care of locking.
166238106Sdes * @param zones: is set up.
167238106Sdes * @param cfg: config data.
168238106Sdes * @return false on error.
169238106Sdes */
170238106Sdesint local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg);
171238106Sdes
172238106Sdes/**
173238106Sdes * Compare two local_zone entries in rbtree. Sort hierarchical but not
174238106Sdes * canonical
175238106Sdes * @param z1: zone 1
176238106Sdes * @param z2: zone 2
177238106Sdes * @return: -1, 0, +1 comparison value.
178238106Sdes */
179238106Sdesint local_zone_cmp(const void* z1, const void* z2);
180238106Sdes
181238106Sdes/**
182238106Sdes * Compare two local_data entries in rbtree. Sort canonical.
183238106Sdes * @param d1: data 1
184238106Sdes * @param d2: data 2
185238106Sdes * @return: -1, 0, +1 comparison value.
186238106Sdes */
187238106Sdesint local_data_cmp(const void* d1, const void* d2);
188238106Sdes
189238106Sdes/**
190238106Sdes * Delete one zone
191238106Sdes * @param z: to delete.
192238106Sdes */
193238106Sdesvoid local_zone_delete(struct local_zone* z);
194238106Sdes
195238106Sdes/**
196238106Sdes * Lookup zone that contains the given name, class.
197238106Sdes * User must lock the tree or result zone.
198238106Sdes * @param zones: the zones tree
199238106Sdes * @param name: dname to lookup
200238106Sdes * @param len: length of name.
201238106Sdes * @param labs: labelcount of name.
202238106Sdes * @param dclass: class to lookup.
203238106Sdes * @return closest local_zone or NULL if no covering zone is found.
204238106Sdes */
205238106Sdesstruct local_zone* local_zones_lookup(struct local_zones* zones,
206238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass);
207238106Sdes
208238106Sdes/**
209238106Sdes * Debug helper. Print all zones
210238106Sdes * Takes care of locking.
211238106Sdes * @param zones: the zones tree
212238106Sdes */
213238106Sdesvoid local_zones_print(struct local_zones* zones);
214238106Sdes
215238106Sdes/**
216238106Sdes * Answer authoritatively for local zones.
217238106Sdes * Takes care of locking.
218238106Sdes * @param zones: the stored zones (shared, read only).
219238106Sdes * @param qinfo: query info (parsed).
220238106Sdes * @param edns: edns info (parsed).
221238106Sdes * @param buf: buffer with query ID and flags, also for reply.
222238106Sdes * @param temp: temporary storage region.
223238106Sdes * @return true if answer is in buffer. false if query is not answered
224238106Sdes * by authority data. If the reply should be dropped altogether, the return
225238106Sdes * value is true, but the buffer is cleared (empty).
226238106Sdes */
227238106Sdesint local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
228269257Sdes	struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp);
229238106Sdes
230238106Sdes/**
231238106Sdes * Parse the string into localzone type.
232238106Sdes *
233238106Sdes * @param str: string to parse
234238106Sdes * @param t: local zone type returned here.
235238106Sdes * @return 0 on parse error.
236238106Sdes */
237238106Sdesint local_zone_str2type(const char* str, enum localzone_type* t);
238238106Sdes
239238106Sdes/**
240238106Sdes * Print localzone type to a string.  Pointer to a constant string.
241238106Sdes *
242238106Sdes * @param t: local zone type.
243238106Sdes * @return constant string that describes type.
244238106Sdes */
245238106Sdesconst char* local_zone_type2str(enum localzone_type t);
246238106Sdes
247238106Sdes/**
248238106Sdes * Find zone that with exactly given name, class.
249238106Sdes * User must lock the tree or result zone.
250238106Sdes * @param zones: the zones tree
251238106Sdes * @param name: dname to lookup
252238106Sdes * @param len: length of name.
253238106Sdes * @param labs: labelcount of name.
254238106Sdes * @param dclass: class to lookup.
255238106Sdes * @return the exact local_zone or NULL.
256238106Sdes */
257238106Sdesstruct local_zone* local_zones_find(struct local_zones* zones,
258238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass);
259238106Sdes
260238106Sdes/**
261238106Sdes * Add a new zone. Caller must hold the zones lock.
262238106Sdes * Adjusts the other zones as well (parent pointers) after insertion.
263238106Sdes * The zone must NOT exist (returns NULL and logs error).
264238106Sdes * @param zones: the zones tree
265238106Sdes * @param name: dname to add
266238106Sdes * @param len: length of name.
267238106Sdes * @param labs: labelcount of name.
268238106Sdes * @param dclass: class to add.
269238106Sdes * @param tp: type.
270238106Sdes * @return local_zone or NULL on error, caller must printout memory error.
271238106Sdes */
272238106Sdesstruct local_zone* local_zones_add_zone(struct local_zones* zones,
273238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass,
274238106Sdes	enum localzone_type tp);
275238106Sdes
276238106Sdes/**
277238106Sdes * Delete a zone. Caller must hold the zones lock.
278238106Sdes * Adjusts the other zones as well (parent pointers) after insertion.
279238106Sdes * @param zones: the zones tree
280238106Sdes * @param zone: the zone to delete from tree. Also deletes zone from memory.
281238106Sdes */
282238106Sdesvoid local_zones_del_zone(struct local_zones* zones, struct local_zone* zone);
283238106Sdes
284238106Sdes/**
285238106Sdes * Add RR data into the localzone data.
286238106Sdes * Looks up the zone, if no covering zone, a transparent zone with the
287238106Sdes * name of the RR is created.
288238106Sdes * @param zones: the zones tree. Not locked by caller.
289238106Sdes * @param rr: string with on RR.
290238106Sdes * @return false on failure.
291238106Sdes */
292269257Sdesint local_zones_add_RR(struct local_zones* zones, const char* rr);
293238106Sdes
294238106Sdes/**
295238106Sdes * Remove data from domain name in the tree.
296238106Sdes * All types are removed. No effect if zone or name does not exist.
297238106Sdes * @param zones: zones tree.
298238106Sdes * @param name: dname to remove
299238106Sdes * @param len: length of name.
300238106Sdes * @param labs: labelcount of name.
301238106Sdes * @param dclass: class to remove.
302238106Sdes */
303238106Sdesvoid local_zones_del_data(struct local_zones* zones,
304238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass);
305238106Sdes
306238106Sdes
307238106Sdes/**
308238106Sdes * Form wireformat from text format domain name.
309238106Sdes * @param str: the domain name in text "www.example.com"
310238106Sdes * @param res: resulting wireformat is stored here with malloc.
311238106Sdes * @param len: length of resulting wireformat.
312238106Sdes * @param labs: number of labels in resulting wireformat.
313238106Sdes * @return false on error, syntax or memory. Also logged.
314238106Sdes */
315238106Sdesint parse_dname(const char* str, uint8_t** res, size_t* len, int* labs);
316238106Sdes
317238106Sdes#endif /* SERVICES_LOCALZONE_H */
318