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;
52285206Sdesstruct comm_reply;
53238106Sdes
54238106Sdes/**
55238106Sdes * Local zone type
56238106Sdes * This type determines processing for queries that did not match
57238106Sdes * local-data directly.
58238106Sdes */
59238106Sdesenum localzone_type {
60238106Sdes	/** drop query */
61238106Sdes	local_zone_deny = 0,
62238106Sdes	/** answer with error */
63238106Sdes	local_zone_refuse,
64238106Sdes	/** answer nxdomain or nodata */
65238106Sdes	local_zone_static,
66238106Sdes	/** resolve normally */
67238106Sdes	local_zone_transparent,
68238106Sdes	/** do not block types at localdata names */
69238106Sdes	local_zone_typetransparent,
70238106Sdes	/** answer with data at zone apex */
71238106Sdes	local_zone_redirect,
72238106Sdes	/** remove default AS112 blocking contents for zone
73238106Sdes	 * nodefault is used in config not during service. */
74285206Sdes	local_zone_nodefault,
75285206Sdes	/** log client address, but no block (transparent) */
76291767Sdes	local_zone_inform,
77291767Sdes	/** log client address, and block (drop) */
78291767Sdes	local_zone_inform_deny
79238106Sdes};
80238106Sdes
81238106Sdes/**
82238106Sdes * Authoritative local zones storage, shared.
83238106Sdes */
84238106Sdesstruct local_zones {
85238106Sdes	/** lock on the localzone tree */
86269257Sdes	lock_rw_t lock;
87238106Sdes	/** rbtree of struct local_zone */
88238106Sdes	rbtree_t ztree;
89238106Sdes};
90238106Sdes
91238106Sdes/**
92238106Sdes * Local zone. A locally served authoritative zone.
93238106Sdes */
94238106Sdesstruct local_zone {
95238106Sdes	/** rbtree node, key is name and class */
96238106Sdes	rbnode_t node;
97238106Sdes	/** parent zone, if any. */
98238106Sdes	struct local_zone* parent;
99238106Sdes
100238106Sdes	/** zone name, in uncompressed wireformat */
101238106Sdes	uint8_t* name;
102238106Sdes	/** length of zone name */
103238106Sdes	size_t namelen;
104238106Sdes	/** number of labels in zone name */
105238106Sdes	int namelabs;
106238106Sdes	/** the class of this zone.
107238106Sdes	 * uses 'dclass' to not conflict with c++ keyword class. */
108238106Sdes	uint16_t dclass;
109238106Sdes
110238106Sdes	/** lock on the data in the structure
111238106Sdes	 * For the node, parent, name, namelen, namelabs, dclass, you
112238106Sdes	 * need to also hold the zones_tree lock to change them (or to
113238106Sdes	 * delete this zone) */
114238106Sdes	lock_rw_t lock;
115238106Sdes
116238106Sdes	/** how to process zone */
117238106Sdes	enum localzone_type type;
118238106Sdes
119238106Sdes	/** in this region the zone's data is allocated.
120238106Sdes	 * the struct local_zone itself is malloced. */
121238106Sdes	struct regional* region;
122238106Sdes	/** local data for this zone
123238106Sdes	 * rbtree of struct local_data */
124238106Sdes	rbtree_t data;
125238106Sdes	/** if data contains zone apex SOA data, this is a ptr to it. */
126238106Sdes	struct ub_packed_rrset_key* soa;
127238106Sdes};
128238106Sdes
129238106Sdes/**
130238106Sdes * Local data. One domain name, and the RRs to go with it.
131238106Sdes */
132238106Sdesstruct local_data {
133238106Sdes	/** rbtree node, key is name only */
134238106Sdes	rbnode_t node;
135238106Sdes	/** domain name */
136238106Sdes	uint8_t* name;
137238106Sdes	/** length of name */
138238106Sdes	size_t namelen;
139238106Sdes	/** number of labels in name */
140238106Sdes	int namelabs;
141238106Sdes	/** the data rrsets, with different types, linked list.
142238106Sdes	 * If this list is NULL, the node is an empty non-terminal. */
143238106Sdes	struct local_rrset* rrsets;
144238106Sdes};
145238106Sdes
146238106Sdes/**
147238106Sdes * A local data RRset
148238106Sdes */
149238106Sdesstruct local_rrset {
150238106Sdes	/** next in list */
151238106Sdes	struct local_rrset* next;
152238106Sdes	/** RRset data item */
153238106Sdes	struct ub_packed_rrset_key* rrset;
154238106Sdes};
155238106Sdes
156238106Sdes/**
157238106Sdes * Create local zones storage
158238106Sdes * @return new struct or NULL on error.
159238106Sdes */
160238106Sdesstruct local_zones* local_zones_create(void);
161238106Sdes
162238106Sdes/**
163238106Sdes * Delete local zones storage
164238106Sdes * @param zones: to delete.
165238106Sdes */
166238106Sdesvoid local_zones_delete(struct local_zones* zones);
167238106Sdes
168238106Sdes/**
169238106Sdes * Apply config settings; setup the local authoritative data.
170238106Sdes * Takes care of locking.
171238106Sdes * @param zones: is set up.
172238106Sdes * @param cfg: config data.
173238106Sdes * @return false on error.
174238106Sdes */
175238106Sdesint local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg);
176238106Sdes
177238106Sdes/**
178238106Sdes * Compare two local_zone entries in rbtree. Sort hierarchical but not
179238106Sdes * canonical
180238106Sdes * @param z1: zone 1
181238106Sdes * @param z2: zone 2
182238106Sdes * @return: -1, 0, +1 comparison value.
183238106Sdes */
184238106Sdesint local_zone_cmp(const void* z1, const void* z2);
185238106Sdes
186238106Sdes/**
187238106Sdes * Compare two local_data entries in rbtree. Sort canonical.
188238106Sdes * @param d1: data 1
189238106Sdes * @param d2: data 2
190238106Sdes * @return: -1, 0, +1 comparison value.
191238106Sdes */
192238106Sdesint local_data_cmp(const void* d1, const void* d2);
193238106Sdes
194238106Sdes/**
195238106Sdes * Delete one zone
196238106Sdes * @param z: to delete.
197238106Sdes */
198238106Sdesvoid local_zone_delete(struct local_zone* z);
199238106Sdes
200238106Sdes/**
201238106Sdes * Lookup zone that contains the given name, class.
202238106Sdes * User must lock the tree or result zone.
203238106Sdes * @param zones: the zones tree
204238106Sdes * @param name: dname to lookup
205238106Sdes * @param len: length of name.
206238106Sdes * @param labs: labelcount of name.
207238106Sdes * @param dclass: class to lookup.
208238106Sdes * @return closest local_zone or NULL if no covering zone is found.
209238106Sdes */
210238106Sdesstruct local_zone* local_zones_lookup(struct local_zones* zones,
211238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass);
212238106Sdes
213238106Sdes/**
214238106Sdes * Debug helper. Print all zones
215238106Sdes * Takes care of locking.
216238106Sdes * @param zones: the zones tree
217238106Sdes */
218238106Sdesvoid local_zones_print(struct local_zones* zones);
219238106Sdes
220238106Sdes/**
221238106Sdes * Answer authoritatively for local zones.
222238106Sdes * Takes care of locking.
223238106Sdes * @param zones: the stored zones (shared, read only).
224238106Sdes * @param qinfo: query info (parsed).
225238106Sdes * @param edns: edns info (parsed).
226238106Sdes * @param buf: buffer with query ID and flags, also for reply.
227238106Sdes * @param temp: temporary storage region.
228285206Sdes * @param repinfo: source address for checks. may be NULL.
229238106Sdes * @return true if answer is in buffer. false if query is not answered
230238106Sdes * by authority data. If the reply should be dropped altogether, the return
231238106Sdes * value is true, but the buffer is cleared (empty).
232238106Sdes */
233238106Sdesint local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
234285206Sdes	struct edns_data* edns, struct sldns_buffer* buf, struct regional* temp,
235285206Sdes	struct comm_reply* repinfo);
236238106Sdes
237238106Sdes/**
238238106Sdes * Parse the string into localzone type.
239238106Sdes *
240238106Sdes * @param str: string to parse
241238106Sdes * @param t: local zone type returned here.
242238106Sdes * @return 0 on parse error.
243238106Sdes */
244238106Sdesint local_zone_str2type(const char* str, enum localzone_type* t);
245238106Sdes
246238106Sdes/**
247238106Sdes * Print localzone type to a string.  Pointer to a constant string.
248238106Sdes *
249238106Sdes * @param t: local zone type.
250238106Sdes * @return constant string that describes type.
251238106Sdes */
252238106Sdesconst char* local_zone_type2str(enum localzone_type t);
253238106Sdes
254238106Sdes/**
255238106Sdes * Find zone that with exactly given name, class.
256238106Sdes * User must lock the tree or result zone.
257238106Sdes * @param zones: the zones tree
258238106Sdes * @param name: dname to lookup
259238106Sdes * @param len: length of name.
260238106Sdes * @param labs: labelcount of name.
261238106Sdes * @param dclass: class to lookup.
262238106Sdes * @return the exact local_zone or NULL.
263238106Sdes */
264238106Sdesstruct local_zone* local_zones_find(struct local_zones* zones,
265238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass);
266238106Sdes
267238106Sdes/**
268238106Sdes * Add a new zone. Caller must hold the zones lock.
269238106Sdes * Adjusts the other zones as well (parent pointers) after insertion.
270238106Sdes * The zone must NOT exist (returns NULL and logs error).
271238106Sdes * @param zones: the zones tree
272238106Sdes * @param name: dname to add
273238106Sdes * @param len: length of name.
274238106Sdes * @param labs: labelcount of name.
275238106Sdes * @param dclass: class to add.
276238106Sdes * @param tp: type.
277238106Sdes * @return local_zone or NULL on error, caller must printout memory error.
278238106Sdes */
279238106Sdesstruct local_zone* local_zones_add_zone(struct local_zones* zones,
280238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass,
281238106Sdes	enum localzone_type tp);
282238106Sdes
283238106Sdes/**
284238106Sdes * Delete a zone. Caller must hold the zones lock.
285238106Sdes * Adjusts the other zones as well (parent pointers) after insertion.
286238106Sdes * @param zones: the zones tree
287238106Sdes * @param zone: the zone to delete from tree. Also deletes zone from memory.
288238106Sdes */
289238106Sdesvoid local_zones_del_zone(struct local_zones* zones, struct local_zone* zone);
290238106Sdes
291238106Sdes/**
292238106Sdes * Add RR data into the localzone data.
293238106Sdes * Looks up the zone, if no covering zone, a transparent zone with the
294238106Sdes * name of the RR is created.
295238106Sdes * @param zones: the zones tree. Not locked by caller.
296238106Sdes * @param rr: string with on RR.
297238106Sdes * @return false on failure.
298238106Sdes */
299269257Sdesint local_zones_add_RR(struct local_zones* zones, const char* rr);
300238106Sdes
301238106Sdes/**
302238106Sdes * Remove data from domain name in the tree.
303238106Sdes * All types are removed. No effect if zone or name does not exist.
304238106Sdes * @param zones: zones tree.
305238106Sdes * @param name: dname to remove
306238106Sdes * @param len: length of name.
307238106Sdes * @param labs: labelcount of name.
308238106Sdes * @param dclass: class to remove.
309238106Sdes */
310238106Sdesvoid local_zones_del_data(struct local_zones* zones,
311238106Sdes	uint8_t* name, size_t len, int labs, uint16_t dclass);
312238106Sdes
313238106Sdes
314238106Sdes/**
315238106Sdes * Form wireformat from text format domain name.
316238106Sdes * @param str: the domain name in text "www.example.com"
317238106Sdes * @param res: resulting wireformat is stored here with malloc.
318238106Sdes * @param len: length of resulting wireformat.
319238106Sdes * @param labs: number of labels in resulting wireformat.
320238106Sdes * @return false on error, syntax or memory. Also logged.
321238106Sdes */
322238106Sdesint parse_dname(const char* str, uint8_t** res, size_t* len, int* labs);
323238106Sdes
324238106Sdes#endif /* SERVICES_LOCALZONE_H */
325