xref: /freebsd/contrib/unbound/services/authzone.h (revision be771a7b7f4580a30d99e41a5bb1b93a385a119d)
1c7f4d7adSDag-Erling Smørgrav /*
2c7f4d7adSDag-Erling Smørgrav  * services/authzone.h - authoritative zone that is locally hosted.
3c7f4d7adSDag-Erling Smørgrav  *
4c7f4d7adSDag-Erling Smørgrav  * Copyright (c) 2017, NLnet Labs. All rights reserved.
5c7f4d7adSDag-Erling Smørgrav  *
6c7f4d7adSDag-Erling Smørgrav  * This software is open source.
7c7f4d7adSDag-Erling Smørgrav  *
8c7f4d7adSDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
9c7f4d7adSDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
10c7f4d7adSDag-Erling Smørgrav  * are met:
11c7f4d7adSDag-Erling Smørgrav  *
12c7f4d7adSDag-Erling Smørgrav  * Redistributions of source code must retain the above copyright notice,
13c7f4d7adSDag-Erling Smørgrav  * this list of conditions and the following disclaimer.
14c7f4d7adSDag-Erling Smørgrav  *
15c7f4d7adSDag-Erling Smørgrav  * Redistributions in binary form must reproduce the above copyright notice,
16c7f4d7adSDag-Erling Smørgrav  * this list of conditions and the following disclaimer in the documentation
17c7f4d7adSDag-Erling Smørgrav  * and/or other materials provided with the distribution.
18c7f4d7adSDag-Erling Smørgrav  *
19c7f4d7adSDag-Erling Smørgrav  * Neither the name of the NLNET LABS nor the names of its contributors may
20c7f4d7adSDag-Erling Smørgrav  * be used to endorse or promote products derived from this software without
21c7f4d7adSDag-Erling Smørgrav  * specific prior written permission.
22c7f4d7adSDag-Erling Smørgrav  *
23c7f4d7adSDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24c7f4d7adSDag-Erling Smørgrav  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25c7f4d7adSDag-Erling Smørgrav  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26c7f4d7adSDag-Erling Smørgrav  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27c7f4d7adSDag-Erling Smørgrav  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28c7f4d7adSDag-Erling Smørgrav  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29c7f4d7adSDag-Erling Smørgrav  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30c7f4d7adSDag-Erling Smørgrav  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31c7f4d7adSDag-Erling Smørgrav  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32c7f4d7adSDag-Erling Smørgrav  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33c7f4d7adSDag-Erling Smørgrav  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34c7f4d7adSDag-Erling Smørgrav  */
35c7f4d7adSDag-Erling Smørgrav 
36c7f4d7adSDag-Erling Smørgrav /**
37c7f4d7adSDag-Erling Smørgrav  * \file
38c7f4d7adSDag-Erling Smørgrav  *
39c7f4d7adSDag-Erling Smørgrav  * This file contains the functions for an authority zone.  This zone
40c7f4d7adSDag-Erling Smørgrav  * is queried by the iterator, just like a stub or forward zone, but then
41c7f4d7adSDag-Erling Smørgrav  * the data is locally held.
42c7f4d7adSDag-Erling Smørgrav  */
43c7f4d7adSDag-Erling Smørgrav 
44c7f4d7adSDag-Erling Smørgrav #ifndef SERVICES_AUTHZONE_H
45c7f4d7adSDag-Erling Smørgrav #define SERVICES_AUTHZONE_H
46c7f4d7adSDag-Erling Smørgrav #include "util/rbtree.h"
47c7f4d7adSDag-Erling Smørgrav #include "util/locks.h"
4857bddd21SDag-Erling Smørgrav #include "services/mesh.h"
49091e9e46SCy Schubert #include "services/rpz.h"
50c7f4d7adSDag-Erling Smørgrav struct ub_packed_rrset_key;
51c7f4d7adSDag-Erling Smørgrav struct regional;
52c7f4d7adSDag-Erling Smørgrav struct config_file;
5357bddd21SDag-Erling Smørgrav struct config_auth;
54c7f4d7adSDag-Erling Smørgrav struct query_info;
55c7f4d7adSDag-Erling Smørgrav struct dns_msg;
5657bddd21SDag-Erling Smørgrav struct edns_data;
5757bddd21SDag-Erling Smørgrav struct module_env;
5857bddd21SDag-Erling Smørgrav struct worker;
5957bddd21SDag-Erling Smørgrav struct comm_point;
6057bddd21SDag-Erling Smørgrav struct comm_timer;
6157bddd21SDag-Erling Smørgrav struct comm_reply;
6257bddd21SDag-Erling Smørgrav struct auth_rrset;
6357bddd21SDag-Erling Smørgrav struct auth_nextprobe;
6457bddd21SDag-Erling Smørgrav struct auth_probe;
6557bddd21SDag-Erling Smørgrav struct auth_transfer;
6657bddd21SDag-Erling Smørgrav struct auth_master;
6757bddd21SDag-Erling Smørgrav struct auth_chunk;
68c7f4d7adSDag-Erling Smørgrav 
69c7f4d7adSDag-Erling Smørgrav /**
70c7f4d7adSDag-Erling Smørgrav  * Authoritative zones, shared.
71c7f4d7adSDag-Erling Smørgrav  */
72c7f4d7adSDag-Erling Smørgrav struct auth_zones {
73*be771a7bSCy Schubert 	/** lock on the authzone trees. It is locked after views, respip,
74*be771a7bSCy Schubert 	 * local_zones and before fwds and stubs. */
75c7f4d7adSDag-Erling Smørgrav 	lock_rw_type lock;
76c7f4d7adSDag-Erling Smørgrav 	/** rbtree of struct auth_zone */
77c7f4d7adSDag-Erling Smørgrav 	rbtree_type ztree;
7857bddd21SDag-Erling Smørgrav 	/** rbtree of struct auth_xfer */
7957bddd21SDag-Erling Smørgrav 	rbtree_type xtree;
8057bddd21SDag-Erling Smørgrav 	/** do we have downstream enabled */
8157bddd21SDag-Erling Smørgrav 	int have_downstream;
8225039b37SCy Schubert 	/** first auth zone containing rpz item in linked list */
8325039b37SCy Schubert 	struct auth_zone* rpz_first;
84091e9e46SCy Schubert 	/** rw lock for rpz linked list, needed when iterating or editing linked
85091e9e46SCy Schubert 	 * list. */
86091e9e46SCy Schubert 	lock_rw_type rpz_lock;
87c7f4d7adSDag-Erling Smørgrav };
88c7f4d7adSDag-Erling Smørgrav 
89c7f4d7adSDag-Erling Smørgrav /**
90c7f4d7adSDag-Erling Smørgrav  * Auth zone.  Authoritative data, that is fetched from instead of sending
91c7f4d7adSDag-Erling Smørgrav  * packets to the internet.
92c7f4d7adSDag-Erling Smørgrav  */
93c7f4d7adSDag-Erling Smørgrav struct auth_zone {
94c7f4d7adSDag-Erling Smørgrav 	/** rbtree node, key is name and class */
95c7f4d7adSDag-Erling Smørgrav 	rbnode_type node;
96c7f4d7adSDag-Erling Smørgrav 
97c7f4d7adSDag-Erling Smørgrav 	/** zone name, in uncompressed wireformat */
98c7f4d7adSDag-Erling Smørgrav 	uint8_t* name;
99c7f4d7adSDag-Erling Smørgrav 	/** length of zone name */
100c7f4d7adSDag-Erling Smørgrav 	size_t namelen;
101c7f4d7adSDag-Erling Smørgrav 	/** number of labels in zone name */
102c7f4d7adSDag-Erling Smørgrav 	int namelabs;
103c7f4d7adSDag-Erling Smørgrav 	/** the class of this zone, in host byteorder.
104c7f4d7adSDag-Erling Smørgrav 	 * uses 'dclass' to not conflict with c++ keyword class. */
105c7f4d7adSDag-Erling Smørgrav 	uint16_t dclass;
106c7f4d7adSDag-Erling Smørgrav 
107c7f4d7adSDag-Erling Smørgrav 	/** lock on the data in the structure
108c7f4d7adSDag-Erling Smørgrav 	 * For the node, parent, name, namelen, namelabs, dclass, you
109c7f4d7adSDag-Erling Smørgrav 	 * need to also hold the zones_tree lock to change them (or to
110c7f4d7adSDag-Erling Smørgrav 	 * delete this zone) */
111c7f4d7adSDag-Erling Smørgrav 	lock_rw_type lock;
112c7f4d7adSDag-Erling Smørgrav 
113c7f4d7adSDag-Erling Smørgrav 	/** auth data for this zone
114c7f4d7adSDag-Erling Smørgrav 	 * rbtree of struct auth_data */
115c7f4d7adSDag-Erling Smørgrav 	rbtree_type data;
116c7f4d7adSDag-Erling Smørgrav 
11757bddd21SDag-Erling Smørgrav 	/** zonefile name (or NULL for no zonefile) */
118c7f4d7adSDag-Erling Smørgrav 	char* zonefile;
11957bddd21SDag-Erling Smørgrav 	/** fallback to the internet on failure or ttl-expiry of auth zone */
120c7f4d7adSDag-Erling Smørgrav 	int fallback_enabled;
12157bddd21SDag-Erling Smørgrav 	/** the zone has expired (enabled by the xfer worker), fallback
12257bddd21SDag-Erling Smørgrav 	 * happens if that option is enabled. */
12357bddd21SDag-Erling Smørgrav 	int zone_expired;
12457bddd21SDag-Erling Smørgrav 	/** zone is a slave zone (it has masters) */
12557bddd21SDag-Erling Smørgrav 	int zone_is_slave;
12657bddd21SDag-Erling Smørgrav 	/** for downstream: this zone answers queries towards the downstream
12757bddd21SDag-Erling Smørgrav 	 * clients */
12857bddd21SDag-Erling Smørgrav 	int for_downstream;
12957bddd21SDag-Erling Smørgrav 	/** for upstream: this zone answers queries that unbound intends to
13057bddd21SDag-Erling Smørgrav 	 * send upstream. */
13157bddd21SDag-Erling Smørgrav 	int for_upstream;
1325469a995SCy Schubert 	/** check ZONEMD records */
1335469a995SCy Schubert 	int zonemd_check;
1345469a995SCy Schubert 	/** reject absence of ZONEMD records */
1355469a995SCy Schubert 	int zonemd_reject_absence;
136091e9e46SCy Schubert 	/** RPZ zones */
137091e9e46SCy Schubert 	struct rpz* rpz;
1385469a995SCy Schubert 	/** store the env (worker thread specific) for the zonemd callbacks
1395469a995SCy Schubert 	 * from the mesh with the results of the lookup, if nonNULL, some
1405469a995SCy Schubert 	 * worker has already picked up the zonemd verification task and
1415469a995SCy Schubert 	 * this worker does not have to do it as well. */
1425469a995SCy Schubert 	struct module_env* zonemd_callback_env;
14324e36522SCy Schubert 	/** for the zonemd callback, the type of data looked up */
14424e36522SCy Schubert 	uint16_t zonemd_callback_qtype;
1450fb34990SDag-Erling Smørgrav 	/** zone has been deleted */
1460fb34990SDag-Erling Smørgrav 	int zone_deleted;
1470fb34990SDag-Erling Smørgrav 	/** deletelist pointer, unused normally except during delete */
1480fb34990SDag-Erling Smørgrav 	struct auth_zone* delete_next;
14925039b37SCy Schubert 	/* not protected by auth_zone lock, must be last items in struct */
15025039b37SCy Schubert 	/** next auth zone containing RPZ data, or NULL */
15125039b37SCy Schubert 	struct auth_zone* rpz_az_next;
15225039b37SCy Schubert 	/** previous auth zone containing RPZ data, or NULL */
15325039b37SCy Schubert 	struct auth_zone* rpz_az_prev;
154c7f4d7adSDag-Erling Smørgrav };
155c7f4d7adSDag-Erling Smørgrav 
156c7f4d7adSDag-Erling Smørgrav /**
157c7f4d7adSDag-Erling Smørgrav  * Auth data. One domain name, and the RRs to go with it.
158c7f4d7adSDag-Erling Smørgrav  */
159c7f4d7adSDag-Erling Smørgrav struct auth_data {
160c7f4d7adSDag-Erling Smørgrav 	/** rbtree node, key is name only */
161c7f4d7adSDag-Erling Smørgrav 	rbnode_type node;
162c7f4d7adSDag-Erling Smørgrav 	/** domain name */
163c7f4d7adSDag-Erling Smørgrav 	uint8_t* name;
164c7f4d7adSDag-Erling Smørgrav 	/** length of name */
165c7f4d7adSDag-Erling Smørgrav 	size_t namelen;
166c7f4d7adSDag-Erling Smørgrav 	/** number of labels in name */
167c7f4d7adSDag-Erling Smørgrav 	int namelabs;
168c7f4d7adSDag-Erling Smørgrav 	/** the data rrsets, with different types, linked list.
169c7f4d7adSDag-Erling Smørgrav 	 * if the list if NULL the node would be an empty non-terminal,
170c7f4d7adSDag-Erling Smørgrav 	 * but in this data structure such nodes that represent an empty
171c7f4d7adSDag-Erling Smørgrav 	 * non-terminal are not needed; they just don't exist.
172c7f4d7adSDag-Erling Smørgrav 	 */
173c7f4d7adSDag-Erling Smørgrav 	struct auth_rrset* rrsets;
174c7f4d7adSDag-Erling Smørgrav };
175c7f4d7adSDag-Erling Smørgrav 
176c7f4d7adSDag-Erling Smørgrav /**
177c7f4d7adSDag-Erling Smørgrav  * A auth data RRset
178c7f4d7adSDag-Erling Smørgrav  */
179c7f4d7adSDag-Erling Smørgrav struct auth_rrset {
180c7f4d7adSDag-Erling Smørgrav 	/** next in list */
181c7f4d7adSDag-Erling Smørgrav 	struct auth_rrset* next;
182c7f4d7adSDag-Erling Smørgrav 	/** RR type in host byteorder */
183c7f4d7adSDag-Erling Smørgrav 	uint16_t type;
184c7f4d7adSDag-Erling Smørgrav 	/** RRset data item */
185c7f4d7adSDag-Erling Smørgrav 	struct packed_rrset_data* data;
186c7f4d7adSDag-Erling Smørgrav };
187c7f4d7adSDag-Erling Smørgrav 
188c7f4d7adSDag-Erling Smørgrav /**
18957bddd21SDag-Erling Smørgrav  * Authoritative zone transfer structure.
19057bddd21SDag-Erling Smørgrav  * Create and destroy needs the auth_zones* biglock.
19157bddd21SDag-Erling Smørgrav  * The structure consists of different tasks.  Each can be unowned (-1) or
19257bddd21SDag-Erling Smørgrav  * owner by a worker (worker-num).  A worker can pick up a task and then do
19357bddd21SDag-Erling Smørgrav  * it.  This means the events (timeouts, sockets) are for that worker.
19457bddd21SDag-Erling Smørgrav  *
19557bddd21SDag-Erling Smørgrav  * (move this to tasks).
19657bddd21SDag-Erling Smørgrav  * They don't have locks themselves, the worker (that owns it) uses it,
19757bddd21SDag-Erling Smørgrav  * also as part of callbacks, hence it has separate zonename pointers for
19857bddd21SDag-Erling Smørgrav  * lookup in the main zonetree.  If the zone has no transfers, this
19957bddd21SDag-Erling Smørgrav  * structure is not created.
20057bddd21SDag-Erling Smørgrav  */
20157bddd21SDag-Erling Smørgrav struct auth_xfer {
20257bddd21SDag-Erling Smørgrav 	/** rbtree node, key is name and class */
20357bddd21SDag-Erling Smørgrav 	rbnode_type node;
20457bddd21SDag-Erling Smørgrav 
20557bddd21SDag-Erling Smørgrav 	/** lock on this structure, and on the workernum elements of the
20657bddd21SDag-Erling Smørgrav 	 * tasks.  First hold the tree-lock in auth_zones, find the auth_xfer,
20757bddd21SDag-Erling Smørgrav 	 * lock this lock.  Then a worker can reassign itself to fill up
20857bddd21SDag-Erling Smørgrav 	 * one of the tasks.
20957bddd21SDag-Erling Smørgrav 	 * Once it has the task assigned to it, the worker can access the
21057bddd21SDag-Erling Smørgrav 	 * other elements of the task structure without a lock, because that
211*be771a7bSCy Schubert 	 * is necessary for the eventloop and callbacks from that.
212*be771a7bSCy Schubert 	 * The auth_zone->lock is locked before this lock.
213*be771a7bSCy Schubert 	 */
21457bddd21SDag-Erling Smørgrav 	lock_basic_type lock;
21557bddd21SDag-Erling Smørgrav 
21657bddd21SDag-Erling Smørgrav 	/** zone name, in uncompressed wireformat */
21757bddd21SDag-Erling Smørgrav 	uint8_t* name;
21857bddd21SDag-Erling Smørgrav 	/** length of zone name */
21957bddd21SDag-Erling Smørgrav 	size_t namelen;
22057bddd21SDag-Erling Smørgrav 	/** number of labels in zone name */
22157bddd21SDag-Erling Smørgrav 	int namelabs;
22257bddd21SDag-Erling Smørgrav 	/** the class of this zone, in host byteorder.
22357bddd21SDag-Erling Smørgrav 	 * uses 'dclass' to not conflict with c++ keyword class. */
22457bddd21SDag-Erling Smørgrav 	uint16_t dclass;
22557bddd21SDag-Erling Smørgrav 
22657bddd21SDag-Erling Smørgrav 	/** task to wait for next-probe-timeout,
22757bddd21SDag-Erling Smørgrav 	 * once timeouted, see if a SOA probe is needed, or already
22857bddd21SDag-Erling Smørgrav 	 * in progress */
22957bddd21SDag-Erling Smørgrav 	struct auth_nextprobe* task_nextprobe;
23057bddd21SDag-Erling Smørgrav 
23157bddd21SDag-Erling Smørgrav 	/** task for SOA probe.  Check if the zone can be updated */
23257bddd21SDag-Erling Smørgrav 	struct auth_probe* task_probe;
23357bddd21SDag-Erling Smørgrav 
23457bddd21SDag-Erling Smørgrav 	/** Task for transfer.  Transferring and updating the zone.  This
23557bddd21SDag-Erling Smørgrav 	 * includes trying (potentially) several upstream masters.  Downloading
23657bddd21SDag-Erling Smørgrav 	 * and storing the zone */
23757bddd21SDag-Erling Smørgrav 	struct auth_transfer* task_transfer;
23857bddd21SDag-Erling Smørgrav 
23957bddd21SDag-Erling Smørgrav 	/** a notify was received, but a zone transfer or probe was already
24057bddd21SDag-Erling Smørgrav 	 * acted on.
24157bddd21SDag-Erling Smørgrav 	 * However, the zone transfer could signal a newer serial number.
24257bddd21SDag-Erling Smørgrav 	 * The serial number of that notify is saved below.  The transfer and
24357bddd21SDag-Erling Smørgrav 	 * probe tasks should check this once done to see if they need to
24457bddd21SDag-Erling Smørgrav 	 * restart the transfer task for the newer notify serial.
24557bddd21SDag-Erling Smørgrav 	 * Hold the lock to access this member (and the serial).
24657bddd21SDag-Erling Smørgrav 	 */
24757bddd21SDag-Erling Smørgrav 	int notify_received;
2480fb34990SDag-Erling Smørgrav 	/** true if the notify_received has a serial number */
2490fb34990SDag-Erling Smørgrav 	int notify_has_serial;
25057bddd21SDag-Erling Smørgrav 	/** serial number of the notify */
25157bddd21SDag-Erling Smørgrav 	uint32_t notify_serial;
2520fb34990SDag-Erling Smørgrav 	/** the list of masters for checking notifies.  This list is
2530fb34990SDag-Erling Smørgrav 	 * empty on start, and a copy of the list from the probe_task when
2540fb34990SDag-Erling Smørgrav 	 * it is done looking them up. */
2550fb34990SDag-Erling Smørgrav 	struct auth_master* allow_notify_list;
25657bddd21SDag-Erling Smørgrav 
25757bddd21SDag-Erling Smørgrav 	/* protected by the lock on the structure, information about
25857bddd21SDag-Erling Smørgrav 	 * the loaded authority zone. */
25957bddd21SDag-Erling Smørgrav 	/** is the zone currently considered expired? after expiry also older
26057bddd21SDag-Erling Smørgrav          * serial numbers are allowed (not just newer) */
26157bddd21SDag-Erling Smørgrav 	int zone_expired;
26257bddd21SDag-Erling Smørgrav 	/** do we have a zone (if 0, no zone data at all) */
26357bddd21SDag-Erling Smørgrav 	int have_zone;
26457bddd21SDag-Erling Smørgrav 
26557bddd21SDag-Erling Smørgrav 	/** current serial (from SOA), if we have no zone, 0 */
26657bddd21SDag-Erling Smørgrav 	uint32_t serial;
26757bddd21SDag-Erling Smørgrav 	/** retry time (from SOA), time to wait with next_probe
26857bddd21SDag-Erling Smørgrav 	 * if no master responds */
26957bddd21SDag-Erling Smørgrav 	time_t retry;
27057bddd21SDag-Erling Smørgrav 	/** refresh time (from SOA), time to wait with next_probe
27157bddd21SDag-Erling Smørgrav 	 * if everything is fine */
27257bddd21SDag-Erling Smørgrav 	time_t refresh;
27357bddd21SDag-Erling Smørgrav 	/** expiry time (from SOA), time until zone data is not considered
27457bddd21SDag-Erling Smørgrav 	 * valid any more, if no master responds within this time, either
27557bddd21SDag-Erling Smørgrav 	 * with the current zone or a new zone. */
27657bddd21SDag-Erling Smørgrav 	time_t expiry;
27757bddd21SDag-Erling Smørgrav 
27857bddd21SDag-Erling Smørgrav 	/** zone lease start time (start+expiry is expiration time).
27957bddd21SDag-Erling Smørgrav 	 * this is renewed every SOA probe and transfer.  On zone load
28057bddd21SDag-Erling Smørgrav 	 * from zonefile it is also set (with probe set soon to check) */
28157bddd21SDag-Erling Smørgrav 	time_t lease_time;
28257bddd21SDag-Erling Smørgrav };
28357bddd21SDag-Erling Smørgrav 
28457bddd21SDag-Erling Smørgrav /**
28557bddd21SDag-Erling Smørgrav  * The next probe task.
28657bddd21SDag-Erling Smørgrav  * This task consists of waiting for the probetimeout.  It is a task because
28757bddd21SDag-Erling Smørgrav  * it needs an event in the eventtable.  Once the timeout has passed, that
28857bddd21SDag-Erling Smørgrav  * worker can (potentially) become the auth_probe worker, or if another worker
28957bddd21SDag-Erling Smørgrav  * is already doing that, do nothing.  Tasks becomes unowned.
29057bddd21SDag-Erling Smørgrav  * The probe worker, if it detects nothing has to be done picks up this task,
29157bddd21SDag-Erling Smørgrav  * if unowned.
29257bddd21SDag-Erling Smørgrav  */
29357bddd21SDag-Erling Smørgrav struct auth_nextprobe {
29457bddd21SDag-Erling Smørgrav 	/* Worker pointer. NULL means unowned. */
29557bddd21SDag-Erling Smørgrav 	struct worker* worker;
29657bddd21SDag-Erling Smørgrav 	/* module env for this task */
29757bddd21SDag-Erling Smørgrav 	struct module_env* env;
29857bddd21SDag-Erling Smørgrav 
29957bddd21SDag-Erling Smørgrav 	/** increasing backoff for failures */
30057bddd21SDag-Erling Smørgrav 	time_t backoff;
30157bddd21SDag-Erling Smørgrav 	/** Timeout for next probe (for SOA) */
30257bddd21SDag-Erling Smørgrav 	time_t next_probe;
30357bddd21SDag-Erling Smørgrav 	/** timeout callback for next_probe or expiry(if that is sooner).
30457bddd21SDag-Erling Smørgrav 	 * it is on the worker's event_base */
30557bddd21SDag-Erling Smørgrav 	struct comm_timer* timer;
30657bddd21SDag-Erling Smørgrav };
30757bddd21SDag-Erling Smørgrav 
30857bddd21SDag-Erling Smørgrav /**
30957bddd21SDag-Erling Smørgrav  * The probe task.
31057bddd21SDag-Erling Smørgrav  * Send a SOA UDP query to see if the zone needs to be updated (or similar,
31157bddd21SDag-Erling Smørgrav  * potential, HTTP probe query) and check serial number.
31257bddd21SDag-Erling Smørgrav  * If yes, start the auth_transfer task.  If no, make sure auth_nextprobe
31357bddd21SDag-Erling Smørgrav  * timeout wait task is running.
31457bddd21SDag-Erling Smørgrav  * Needs to be a task, because the UDP query needs an event entry.
31557bddd21SDag-Erling Smørgrav  * This task could also be started by eg. a NOTIFY being received, even though
31657bddd21SDag-Erling Smørgrav  * another worker is performing the nextprobe task (and that worker keeps
31757bddd21SDag-Erling Smørgrav  * waiting uninterrupted).
31857bddd21SDag-Erling Smørgrav  */
31957bddd21SDag-Erling Smørgrav struct auth_probe {
32057bddd21SDag-Erling Smørgrav 	/* Worker pointer. NULL means unowned. */
32157bddd21SDag-Erling Smørgrav 	struct worker* worker;
32257bddd21SDag-Erling Smørgrav 	/* module env for this task */
32357bddd21SDag-Erling Smørgrav 	struct module_env* env;
32457bddd21SDag-Erling Smørgrav 
32557bddd21SDag-Erling Smørgrav 	/** list of upstream masters for this zone, from config */
32657bddd21SDag-Erling Smørgrav 	struct auth_master* masters;
32757bddd21SDag-Erling Smørgrav 
32857bddd21SDag-Erling Smørgrav 	/** for the hostname lookups, which master is current */
32957bddd21SDag-Erling Smørgrav 	struct auth_master* lookup_target;
33057bddd21SDag-Erling Smørgrav 	/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
33157bddd21SDag-Erling Smørgrav 	int lookup_aaaa;
3320fb34990SDag-Erling Smørgrav 	/** we only want to do lookups for making config work (for notify),
3330fb34990SDag-Erling Smørgrav 	 * don't proceed with UDP SOA probe queries */
3340fb34990SDag-Erling Smørgrav 	int only_lookup;
3354c75e3aaSDag-Erling Smørgrav 	/** we have seen a new lease this scan, because one of the masters
3364c75e3aaSDag-Erling Smørgrav 	 * replied with the current SOA serial version */
3374c75e3aaSDag-Erling Smørgrav 	int have_new_lease;
33857bddd21SDag-Erling Smørgrav 
33957bddd21SDag-Erling Smørgrav 	/** once notified, or the timeout has been reached. a scan starts. */
34057bddd21SDag-Erling Smørgrav 	/** the scan specific target (notify source), or NULL if none */
34157bddd21SDag-Erling Smørgrav 	struct auth_master* scan_specific;
34257bddd21SDag-Erling Smørgrav 	/** scan tries all the upstream masters. the scan current target.
34357bddd21SDag-Erling Smørgrav 	 * or NULL if not working on sequential scan */
34457bddd21SDag-Erling Smørgrav 	struct auth_master* scan_target;
34557bddd21SDag-Erling Smørgrav 	/** if not NULL, the specific addr for the current master */
34657bddd21SDag-Erling Smørgrav 	struct auth_addr* scan_addr;
34757bddd21SDag-Erling Smørgrav 
34857bddd21SDag-Erling Smørgrav 	/** dns id of packet in flight */
34957bddd21SDag-Erling Smørgrav 	uint16_t id;
35057bddd21SDag-Erling Smørgrav 	/** the SOA probe udp event.
35157bddd21SDag-Erling Smørgrav 	 * on the workers event base. */
35257bddd21SDag-Erling Smørgrav 	struct comm_point* cp;
353e86b9096SDag-Erling Smørgrav 	/** is the cp for ip6 or ip4 */
354e86b9096SDag-Erling Smørgrav 	int cp_is_ip6;
35557bddd21SDag-Erling Smørgrav 	/** timeout for packets.
35657bddd21SDag-Erling Smørgrav 	 * on the workers event base. */
35757bddd21SDag-Erling Smørgrav 	struct comm_timer* timer;
35857bddd21SDag-Erling Smørgrav 	/** timeout in msec */
35957bddd21SDag-Erling Smørgrav 	int timeout;
36057bddd21SDag-Erling Smørgrav };
36157bddd21SDag-Erling Smørgrav 
36257bddd21SDag-Erling Smørgrav /**
36357bddd21SDag-Erling Smørgrav  * The transfer task.
36457bddd21SDag-Erling Smørgrav  * Once done, make sure the nextprobe waiting task is running, whether done
36557bddd21SDag-Erling Smørgrav  * with failure or success.  If failure, use shorter timeout for wait time.
36657bddd21SDag-Erling Smørgrav  */
36757bddd21SDag-Erling Smørgrav struct auth_transfer {
36857bddd21SDag-Erling Smørgrav 	/* Worker pointer. NULL means unowned. */
36957bddd21SDag-Erling Smørgrav 	struct worker* worker;
37057bddd21SDag-Erling Smørgrav 	/* module env for this task */
37157bddd21SDag-Erling Smørgrav 	struct module_env* env;
37257bddd21SDag-Erling Smørgrav 
37357bddd21SDag-Erling Smørgrav 	/** xfer data that has been transferred, the data is applied
37457bddd21SDag-Erling Smørgrav 	 * once the transfer has completed correctly */
37557bddd21SDag-Erling Smørgrav 	struct auth_chunk* chunks_first;
37657bddd21SDag-Erling Smørgrav 	/** last element in chunks list (to append new data at the end) */
37757bddd21SDag-Erling Smørgrav 	struct auth_chunk* chunks_last;
37857bddd21SDag-Erling Smørgrav 
37957bddd21SDag-Erling Smørgrav 	/** list of upstream masters for this zone, from config */
38057bddd21SDag-Erling Smørgrav 	struct auth_master* masters;
38157bddd21SDag-Erling Smørgrav 
38257bddd21SDag-Erling Smørgrav 	/** for the hostname lookups, which master is current */
38357bddd21SDag-Erling Smørgrav 	struct auth_master* lookup_target;
38457bddd21SDag-Erling Smørgrav 	/** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */
38557bddd21SDag-Erling Smørgrav 	int lookup_aaaa;
38657bddd21SDag-Erling Smørgrav 
38757bddd21SDag-Erling Smørgrav 	/** once notified, or the timeout has been reached. a scan starts. */
38857bddd21SDag-Erling Smørgrav 	/** the scan specific target (notify source), or NULL if none */
38957bddd21SDag-Erling Smørgrav 	struct auth_master* scan_specific;
39057bddd21SDag-Erling Smørgrav 	/** scan tries all the upstream masters. the scan current target.
39157bddd21SDag-Erling Smørgrav 	 * or NULL if not working on sequential scan */
39257bddd21SDag-Erling Smørgrav 	struct auth_master* scan_target;
39357bddd21SDag-Erling Smørgrav 	/** what address we are scanning for the master, or NULL if the
39457bddd21SDag-Erling Smørgrav 	 * master is in IP format itself */
39557bddd21SDag-Erling Smørgrav 	struct auth_addr* scan_addr;
39657bddd21SDag-Erling Smørgrav 	/** the zone transfer in progress (or NULL if in scan).  It is
39757bddd21SDag-Erling Smørgrav 	 * from this master */
39857bddd21SDag-Erling Smørgrav 	struct auth_master* master;
39957bddd21SDag-Erling Smørgrav 
40057bddd21SDag-Erling Smørgrav 	/** failed ixfr transfer, retry with axfr (to the current master),
40157bddd21SDag-Erling Smørgrav 	 * the IXFR was 'REFUSED', 'SERVFAIL', 'NOTIMPL' or the contents of
40257bddd21SDag-Erling Smørgrav 	 * the IXFR did not apply cleanly (out of sync, delete of nonexistent
40357bddd21SDag-Erling Smørgrav 	 * data or add of duplicate data).  Flag is cleared once the retry
40457bddd21SDag-Erling Smørgrav 	 * with axfr is done. */
40557bddd21SDag-Erling Smørgrav 	int ixfr_fail;
406e86b9096SDag-Erling Smørgrav 	/** we saw an ixfr-indicating timeout, count of them */
407e86b9096SDag-Erling Smørgrav 	int ixfr_possible_timeout_count;
40857bddd21SDag-Erling Smørgrav 	/** we are doing IXFR right now */
40957bddd21SDag-Erling Smørgrav 	int on_ixfr;
41057bddd21SDag-Erling Smørgrav 	/** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
41157bddd21SDag-Erling Smørgrav 	 * 1 we saw the first, 2 we saw the second, 3 must be last SOA in xfr*/
41257bddd21SDag-Erling Smørgrav 	int got_xfr_serial;
41357bddd21SDag-Erling Smørgrav 	/** number of RRs scanned for AXFR/IXFR detection */
41457bddd21SDag-Erling Smørgrav 	size_t rr_scan_num;
41557bddd21SDag-Erling Smørgrav 	/** we are doing an IXFR but we detected an AXFR contents */
41657bddd21SDag-Erling Smørgrav 	int on_ixfr_is_axfr;
41757bddd21SDag-Erling Smørgrav 	/** the serial number for the current AXFR/IXFR incoming reply,
41857bddd21SDag-Erling Smørgrav 	 * for IXFR, the outermost SOA records serial */
41957bddd21SDag-Erling Smørgrav 	uint32_t incoming_xfr_serial;
42057bddd21SDag-Erling Smørgrav 
42157bddd21SDag-Erling Smørgrav 	/** dns id of AXFR query */
42257bddd21SDag-Erling Smørgrav 	uint16_t id;
42357bddd21SDag-Erling Smørgrav 	/** the transfer (TCP) to the master.
42457bddd21SDag-Erling Smørgrav 	 * on the workers event base. */
42557bddd21SDag-Erling Smørgrav 	struct comm_point* cp;
426e86b9096SDag-Erling Smørgrav 	/** timeout for the transfer.
427e86b9096SDag-Erling Smørgrav 	 * on the workers event base. */
428e86b9096SDag-Erling Smørgrav 	struct comm_timer* timer;
42957bddd21SDag-Erling Smørgrav };
43057bddd21SDag-Erling Smørgrav 
43157bddd21SDag-Erling Smørgrav /** list of addresses */
43257bddd21SDag-Erling Smørgrav struct auth_addr {
43357bddd21SDag-Erling Smørgrav 	/** next in list */
43457bddd21SDag-Erling Smørgrav 	struct auth_addr* next;
43557bddd21SDag-Erling Smørgrav 	/** IP address */
43657bddd21SDag-Erling Smørgrav 	struct sockaddr_storage addr;
43757bddd21SDag-Erling Smørgrav 	/** addr length */
43857bddd21SDag-Erling Smørgrav 	socklen_t addrlen;
43957bddd21SDag-Erling Smørgrav };
44057bddd21SDag-Erling Smørgrav 
44157bddd21SDag-Erling Smørgrav /** auth zone master upstream, and the config settings for it */
44257bddd21SDag-Erling Smørgrav struct auth_master {
44357bddd21SDag-Erling Smørgrav 	/** next master in list */
44457bddd21SDag-Erling Smørgrav 	struct auth_master* next;
44557bddd21SDag-Erling Smørgrav 	/** master IP address (and port), or hostname, string */
44657bddd21SDag-Erling Smørgrav 	char* host;
44757bddd21SDag-Erling Smørgrav 	/** for http, filename */
44857bddd21SDag-Erling Smørgrav 	char* file;
44957bddd21SDag-Erling Smørgrav 	/** use HTTP for this master */
45057bddd21SDag-Erling Smørgrav 	int http;
45157bddd21SDag-Erling Smørgrav 	/** use IXFR for this master */
45257bddd21SDag-Erling Smørgrav 	int ixfr;
4530fb34990SDag-Erling Smørgrav 	/** this is an allow notify member, the master can send notifies
4540fb34990SDag-Erling Smørgrav 	 * to us, but we don't send SOA probes, or zone transfer from it */
4550fb34990SDag-Erling Smørgrav 	int allow_notify;
45657bddd21SDag-Erling Smørgrav 	/** use ssl for channel */
45757bddd21SDag-Erling Smørgrav 	int ssl;
45857bddd21SDag-Erling Smørgrav 	/** the port number (for urls) */
45957bddd21SDag-Erling Smørgrav 	int port;
46057bddd21SDag-Erling Smørgrav 	/** if the host is a hostname, the list of resolved addrs, if any*/
46157bddd21SDag-Erling Smørgrav 	struct auth_addr* list;
46257bddd21SDag-Erling Smørgrav };
46357bddd21SDag-Erling Smørgrav 
46457bddd21SDag-Erling Smørgrav /** auth zone master zone transfer data chunk */
46557bddd21SDag-Erling Smørgrav struct auth_chunk {
46657bddd21SDag-Erling Smørgrav 	/** next chunk in list */
46757bddd21SDag-Erling Smørgrav 	struct auth_chunk* next;
46857bddd21SDag-Erling Smørgrav 	/** the data from this chunk, this is what was received.
46957bddd21SDag-Erling Smørgrav 	 * for an IXFR that means results from comm_net tcp actions,
47057bddd21SDag-Erling Smørgrav 	 * packets. also for an AXFR. For HTTP a zonefile chunk. */
47157bddd21SDag-Erling Smørgrav 	uint8_t* data;
47257bddd21SDag-Erling Smørgrav 	/** length of allocated data */
47357bddd21SDag-Erling Smørgrav 	size_t len;
47457bddd21SDag-Erling Smørgrav };
47557bddd21SDag-Erling Smørgrav 
47657bddd21SDag-Erling Smørgrav /**
477c7f4d7adSDag-Erling Smørgrav  * Create auth zones structure
478c7f4d7adSDag-Erling Smørgrav  */
479c7f4d7adSDag-Erling Smørgrav struct auth_zones* auth_zones_create(void);
480c7f4d7adSDag-Erling Smørgrav 
481c7f4d7adSDag-Erling Smørgrav /**
482c7f4d7adSDag-Erling Smørgrav  * Apply configuration to auth zones.  Reads zonefiles.
48357bddd21SDag-Erling Smørgrav  * @param az: auth zones structure
48457bddd21SDag-Erling Smørgrav  * @param cfg: config to apply.
48557bddd21SDag-Erling Smørgrav  * @param setup: if true, also sets up values in the auth zones structure
486091e9e46SCy Schubert  * @param is_rpz: set to 1 if at least one RPZ zone is configured.
4875469a995SCy Schubert  * @param env: environment for offline verification.
4885469a995SCy Schubert  * @param mods: modules in environment.
48957bddd21SDag-Erling Smørgrav  * @return false on failure.
490c7f4d7adSDag-Erling Smørgrav  */
49157bddd21SDag-Erling Smørgrav int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
4925469a995SCy Schubert 	int setup, int* is_rpz, struct module_env* env,
4935469a995SCy Schubert 	struct module_stack* mods);
49457bddd21SDag-Erling Smørgrav 
49557bddd21SDag-Erling Smørgrav /** initial pick up of worker timeouts, ties events to worker event loop
49657bddd21SDag-Erling Smørgrav  * @param az: auth zones structure
49757bddd21SDag-Erling Smørgrav  * @param env: worker env, of first worker that receives the events (if any)
49857bddd21SDag-Erling Smørgrav  * 	in its eventloop.
49957bddd21SDag-Erling Smørgrav  */
50057bddd21SDag-Erling Smørgrav void auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env);
50157bddd21SDag-Erling Smørgrav 
50257bddd21SDag-Erling Smørgrav /**
50357bddd21SDag-Erling Smørgrav  * Cleanup auth zones.  This removes all events from event bases.
50457bddd21SDag-Erling Smørgrav  * Stops the xfr tasks.  But leaves zone data.
50557bddd21SDag-Erling Smørgrav  * @param az: auth zones structure.
50657bddd21SDag-Erling Smørgrav  */
50757bddd21SDag-Erling Smørgrav void auth_zones_cleanup(struct auth_zones* az);
508c7f4d7adSDag-Erling Smørgrav 
509c7f4d7adSDag-Erling Smørgrav /**
510c7f4d7adSDag-Erling Smørgrav  * Delete auth zones structure
511c7f4d7adSDag-Erling Smørgrav  */
512c7f4d7adSDag-Erling Smørgrav void auth_zones_delete(struct auth_zones* az);
513c7f4d7adSDag-Erling Smørgrav 
514c7f4d7adSDag-Erling Smørgrav /**
515c7f4d7adSDag-Erling Smørgrav  * Write auth zone data to file, in zonefile format.
516c7f4d7adSDag-Erling Smørgrav  */
517c7f4d7adSDag-Erling Smørgrav int auth_zone_write_file(struct auth_zone* z, const char* fname);
518c7f4d7adSDag-Erling Smørgrav 
519c7f4d7adSDag-Erling Smørgrav /**
520c7f4d7adSDag-Erling Smørgrav  * Use auth zones to lookup the answer to a query.
521c7f4d7adSDag-Erling Smørgrav  * The query is from the iterator.  And the auth zones attempts to provide
522c7f4d7adSDag-Erling Smørgrav  * the answer instead of going to the internet.
523c7f4d7adSDag-Erling Smørgrav  *
524c7f4d7adSDag-Erling Smørgrav  * @param az: auth zones structure.
525c7f4d7adSDag-Erling Smørgrav  * @param qinfo: query info to lookup.
526c7f4d7adSDag-Erling Smørgrav  * @param region: region to use to allocate the reply in.
527c7f4d7adSDag-Erling Smørgrav  * @param msg: reply is stored here (if one).
528c7f4d7adSDag-Erling Smørgrav  * @param fallback: if true, fallback to making a query to the internet.
529c7f4d7adSDag-Erling Smørgrav  * @param dp_nm: name of delegation point to look for.  This zone is used
530c7f4d7adSDag-Erling Smørgrav  *	to answer the query.
531c7f4d7adSDag-Erling Smørgrav  *	If the dp_nm is not found, fallback is set to true and false returned.
532c7f4d7adSDag-Erling Smørgrav  * @param dp_nmlen: length of dp_nm.
533c7f4d7adSDag-Erling Smørgrav  * @return 0: failure (an error of some sort, like servfail).
534c7f4d7adSDag-Erling Smørgrav  *         if 0 and fallback is true, fallback to the internet.
535c7f4d7adSDag-Erling Smørgrav  *         if 0 and fallback is false, like getting servfail.
536c7f4d7adSDag-Erling Smørgrav  *         If true, an answer is available.
537c7f4d7adSDag-Erling Smørgrav  */
538c7f4d7adSDag-Erling Smørgrav int auth_zones_lookup(struct auth_zones* az, struct query_info* qinfo,
539c7f4d7adSDag-Erling Smørgrav 	struct regional* region, struct dns_msg** msg, int* fallback,
540c7f4d7adSDag-Erling Smørgrav 	uint8_t* dp_nm, size_t dp_nmlen);
541c7f4d7adSDag-Erling Smørgrav 
542c7f4d7adSDag-Erling Smørgrav /**
54357bddd21SDag-Erling Smørgrav  * Answer query from auth zone.  Create authoritative answer.
54457bddd21SDag-Erling Smørgrav  * @param az: auth zones structure.
54557bddd21SDag-Erling Smørgrav  * @param env: the module environment.
54657bddd21SDag-Erling Smørgrav  * @param qinfo: query info (parsed).
54757bddd21SDag-Erling Smørgrav  * @param edns: edns info (parsed).
54857bddd21SDag-Erling Smørgrav  * @param buf: buffer with query ID and flags, also for reply.
5494c75e3aaSDag-Erling Smørgrav  * @param repinfo: reply information for a communication point.
55057bddd21SDag-Erling Smørgrav  * @param temp: temporary storage region.
55157bddd21SDag-Erling Smørgrav  * @return false if not answered
55257bddd21SDag-Erling Smørgrav  */
55357bddd21SDag-Erling Smørgrav int auth_zones_answer(struct auth_zones* az, struct module_env* env,
5544c75e3aaSDag-Erling Smørgrav 	struct query_info* qinfo, struct edns_data* edns,
5554c75e3aaSDag-Erling Smørgrav 	struct comm_reply* repinfo, struct sldns_buffer* buf, struct regional* temp);
55657bddd21SDag-Erling Smørgrav 
55757bddd21SDag-Erling Smørgrav /**
558c7f4d7adSDag-Erling Smørgrav  * Find the auth zone that is above the given qname.
559c7f4d7adSDag-Erling Smørgrav  * Return NULL when there is no auth_zone above the give name, otherwise
560c7f4d7adSDag-Erling Smørgrav  * returns the closest auth_zone above the qname that pertains to it.
561c7f4d7adSDag-Erling Smørgrav  * @param az: auth zones structure.
56257bddd21SDag-Erling Smørgrav  * @param name: query to look up for.
56357bddd21SDag-Erling Smørgrav  * @param name_len: length of name.
56457bddd21SDag-Erling Smørgrav  * @param dclass: class of zone to find.
565c7f4d7adSDag-Erling Smørgrav  * @return NULL or auth_zone that pertains to the query.
566c7f4d7adSDag-Erling Smørgrav  */
567c7f4d7adSDag-Erling Smørgrav struct auth_zone* auth_zones_find_zone(struct auth_zones* az,
56857bddd21SDag-Erling Smørgrav 	uint8_t* name, size_t name_len, uint16_t dclass);
569c7f4d7adSDag-Erling Smørgrav 
570c7f4d7adSDag-Erling Smørgrav /** find an auth zone by name (exact match by name or NULL returned) */
571c7f4d7adSDag-Erling Smørgrav struct auth_zone* auth_zone_find(struct auth_zones* az, uint8_t* nm,
572c7f4d7adSDag-Erling Smørgrav 	size_t nmlen, uint16_t dclass);
573c7f4d7adSDag-Erling Smørgrav 
57457bddd21SDag-Erling Smørgrav /** find an xfer zone by name (exact match by name or NULL returned) */
57557bddd21SDag-Erling Smørgrav struct auth_xfer* auth_xfer_find(struct auth_zones* az, uint8_t* nm,
57657bddd21SDag-Erling Smørgrav 	size_t nmlen, uint16_t dclass);
57757bddd21SDag-Erling Smørgrav 
578c7f4d7adSDag-Erling Smørgrav /** create an auth zone. returns wrlocked zone. caller must have wrlock
579c7f4d7adSDag-Erling Smørgrav  * on az. returns NULL on malloc failure */
580c7f4d7adSDag-Erling Smørgrav struct auth_zone* auth_zone_create(struct auth_zones* az, uint8_t* nm,
581c7f4d7adSDag-Erling Smørgrav 	size_t nmlen, uint16_t dclass);
582c7f4d7adSDag-Erling Smørgrav 
583c7f4d7adSDag-Erling Smørgrav /** set auth zone zonefile string. caller must have lock on zone */
584c7f4d7adSDag-Erling Smørgrav int auth_zone_set_zonefile(struct auth_zone* z, char* zonefile);
585c7f4d7adSDag-Erling Smørgrav 
586c7f4d7adSDag-Erling Smørgrav /** set auth zone fallback. caller must have lock on zone.
587c7f4d7adSDag-Erling Smørgrav  * fallbackstr is "yes" or "no". false on parse failure. */
588c7f4d7adSDag-Erling Smørgrav int auth_zone_set_fallback(struct auth_zone* z, char* fallbackstr);
589c7f4d7adSDag-Erling Smørgrav 
59057bddd21SDag-Erling Smørgrav /** see if the auth zone for the name can fallback
59157bddd21SDag-Erling Smørgrav  * @param az: auth zones
59257bddd21SDag-Erling Smørgrav  * @param nm: name of delegation point.
59357bddd21SDag-Erling Smørgrav  * @param nmlen: length of nm.
59457bddd21SDag-Erling Smørgrav  * @param dclass: class of zone to look for.
59557bddd21SDag-Erling Smørgrav  * @return true if fallback_enabled is true. false if not.
59657bddd21SDag-Erling Smørgrav  * if the zone does not exist, fallback is true (more lenient)
59757bddd21SDag-Erling Smørgrav  * also true if zone does not do upstream requests.
59857bddd21SDag-Erling Smørgrav  */
59957bddd21SDag-Erling Smørgrav int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
60057bddd21SDag-Erling Smørgrav 	uint16_t dclass);
60157bddd21SDag-Erling Smørgrav 
6020fb34990SDag-Erling Smørgrav /** process notify for auth zones.
6030fb34990SDag-Erling Smørgrav  * first checks the access list.  Then processes the notify. This starts
6040fb34990SDag-Erling Smørgrav  * the probe sequence or it notes the serial number (if any)
6050fb34990SDag-Erling Smørgrav  * @param az: auth zones structure.
6060fb34990SDag-Erling Smørgrav  * @param env: module env of the worker that is handling the notify. it will
6070fb34990SDag-Erling Smørgrav  * 	pick up the task probe (or transfer), unless already in progress by
6080fb34990SDag-Erling Smørgrav  * 	another worker.
6090fb34990SDag-Erling Smørgrav  * @param nm: name of the zone.  Uncompressed. from query.
6100fb34990SDag-Erling Smørgrav  * @param nmlen: length of name.
6110fb34990SDag-Erling Smørgrav  * @param dclass: class of zone.
6120fb34990SDag-Erling Smørgrav  * @param addr: source address of notify
6130fb34990SDag-Erling Smørgrav  * @param addrlen: length of addr.
6140fb34990SDag-Erling Smørgrav  * @param has_serial: if true, the notify has a serial attached.
6150fb34990SDag-Erling Smørgrav  * @param serial: the serial number, if has_serial is true.
6160fb34990SDag-Erling Smørgrav  * @param refused: is set to true on failure to note refused access.
6170fb34990SDag-Erling Smørgrav  * @return fail on failures (refused is false) and when access is
6180fb34990SDag-Erling Smørgrav  * 	denied (refused is true).  True when processed.
6190fb34990SDag-Erling Smørgrav  */
6200fb34990SDag-Erling Smørgrav int auth_zones_notify(struct auth_zones* az, struct module_env* env,
6210fb34990SDag-Erling Smørgrav 	uint8_t* nm, size_t nmlen, uint16_t dclass,
6220fb34990SDag-Erling Smørgrav 	struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
6230fb34990SDag-Erling Smørgrav 	uint32_t serial, int* refused);
6240fb34990SDag-Erling Smørgrav 
6250fb34990SDag-Erling Smørgrav /** process notify packet and read serial number from SOA.
6260fb34990SDag-Erling Smørgrav  * returns 0 if no soa record in the notify */
6270fb34990SDag-Erling Smørgrav int auth_zone_parse_notify_serial(struct sldns_buffer* pkt, uint32_t *serial);
6280fb34990SDag-Erling Smørgrav 
6294c75e3aaSDag-Erling Smørgrav /** for the zone and if not already going, starts the probe sequence.
6304c75e3aaSDag-Erling Smørgrav  * false if zone cannot be found.  This is like a notify arrived and was
6314c75e3aaSDag-Erling Smørgrav  * accepted for that zone. */
6324c75e3aaSDag-Erling Smørgrav int auth_zones_startprobesequence(struct auth_zones* az,
6334c75e3aaSDag-Erling Smørgrav 	struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t dclass);
6344c75e3aaSDag-Erling Smørgrav 
635c7f4d7adSDag-Erling Smørgrav /** read auth zone from zonefile. caller must lock zone. false on failure */
636e86b9096SDag-Erling Smørgrav int auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg);
637c7f4d7adSDag-Erling Smørgrav 
63824e36522SCy Schubert /** find the apex SOA RRset, if it exists. NULL if no SOA RRset. */
63924e36522SCy Schubert struct auth_rrset* auth_zone_get_soa_rrset(struct auth_zone* z);
64024e36522SCy Schubert 
6410fb34990SDag-Erling Smørgrav /** find serial number of zone or false if none (no SOA record) */
6420fb34990SDag-Erling Smørgrav int auth_zone_get_serial(struct auth_zone* z, uint32_t* serial);
6430fb34990SDag-Erling Smørgrav 
6445469a995SCy Schubert /** Find auth_zone SOA and populate the values in xfr(soa values). */
6455469a995SCy Schubert int xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr);
6465469a995SCy Schubert 
647c7f4d7adSDag-Erling Smørgrav /** compare auth_zones for sorted rbtree */
648c7f4d7adSDag-Erling Smørgrav int auth_zone_cmp(const void* z1, const void* z2);
649c7f4d7adSDag-Erling Smørgrav 
650c7f4d7adSDag-Erling Smørgrav /** compare auth_data for sorted rbtree */
651c7f4d7adSDag-Erling Smørgrav int auth_data_cmp(const void* z1, const void* z2);
652c7f4d7adSDag-Erling Smørgrav 
65357bddd21SDag-Erling Smørgrav /** compare auth_xfer for sorted rbtree */
65457bddd21SDag-Erling Smørgrav int auth_xfer_cmp(const void* z1, const void* z2);
65557bddd21SDag-Erling Smørgrav 
65657bddd21SDag-Erling Smørgrav /** Create auth_xfer structure.
65757bddd21SDag-Erling Smørgrav  * Caller must have wrlock on az. Returns locked xfer zone.
65857bddd21SDag-Erling Smørgrav  * @param az: zones structure.
65957bddd21SDag-Erling Smørgrav  * @param z: zone with name and class
66057bddd21SDag-Erling Smørgrav  * @return xfer zone or NULL
66157bddd21SDag-Erling Smørgrav  */
66257bddd21SDag-Erling Smørgrav struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
66357bddd21SDag-Erling Smørgrav 
66457bddd21SDag-Erling Smørgrav /**
66557bddd21SDag-Erling Smørgrav  * Set masters in auth xfer structure from config.
66657bddd21SDag-Erling Smørgrav  * @param list: pointer to start of list.  The malloced list is returned here.
66757bddd21SDag-Erling Smørgrav  * @param c: the config items to copy over.
66857bddd21SDag-Erling Smørgrav  * @param with_http: if true, http urls are also included, before the masters.
66957bddd21SDag-Erling Smørgrav  * @return false on failure.
67057bddd21SDag-Erling Smørgrav  */
67157bddd21SDag-Erling Smørgrav int xfer_set_masters(struct auth_master** list, struct config_auth* c,
67257bddd21SDag-Erling Smørgrav 	int with_http);
67357bddd21SDag-Erling Smørgrav 
67457bddd21SDag-Erling Smørgrav /** xfer nextprobe timeout callback, this is part of task_nextprobe */
67557bddd21SDag-Erling Smørgrav void auth_xfer_timer(void* arg);
67657bddd21SDag-Erling Smørgrav 
67757bddd21SDag-Erling Smørgrav /** callback for commpoint udp replies to task_probe */
67857bddd21SDag-Erling Smørgrav int auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
67957bddd21SDag-Erling Smørgrav         struct comm_reply* repinfo);
68057bddd21SDag-Erling Smørgrav /** callback for task_transfer tcp connections */
68157bddd21SDag-Erling Smørgrav int auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
68257bddd21SDag-Erling Smørgrav         struct comm_reply* repinfo);
68357bddd21SDag-Erling Smørgrav /** callback for task_transfer http connections */
68457bddd21SDag-Erling Smørgrav int auth_xfer_transfer_http_callback(struct comm_point* c, void* arg, int err,
68557bddd21SDag-Erling Smørgrav         struct comm_reply* repinfo);
68657bddd21SDag-Erling Smørgrav /** xfer probe timeout callback, part of task_probe */
68757bddd21SDag-Erling Smørgrav void auth_xfer_probe_timer_callback(void* arg);
688e86b9096SDag-Erling Smørgrav /** xfer transfer timeout callback, part of task_transfer */
689e86b9096SDag-Erling Smørgrav void auth_xfer_transfer_timer_callback(void* arg);
69057bddd21SDag-Erling Smørgrav /** mesh callback for task_probe on lookup of host names */
69157bddd21SDag-Erling Smørgrav void auth_xfer_probe_lookup_callback(void* arg, int rcode,
6924c75e3aaSDag-Erling Smørgrav 	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
6934c75e3aaSDag-Erling Smørgrav 	int was_ratelimited);
69457bddd21SDag-Erling Smørgrav /** mesh callback for task_transfer on lookup of host names */
69557bddd21SDag-Erling Smørgrav void auth_xfer_transfer_lookup_callback(void* arg, int rcode,
6964c75e3aaSDag-Erling Smørgrav 	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
6974c75e3aaSDag-Erling Smørgrav 	int was_ratelimited);
69857bddd21SDag-Erling Smørgrav 
69957bddd21SDag-Erling Smørgrav /*
70057bddd21SDag-Erling Smørgrav  * Compares two 32-bit serial numbers as defined in RFC1982.  Returns
70157bddd21SDag-Erling Smørgrav  * <0 if a < b, 0 if a == b, and >0 if a > b.  The result is undefined
70257bddd21SDag-Erling Smørgrav  * if a != b but neither is greater or smaller (see RFC1982 section
70357bddd21SDag-Erling Smørgrav  * 3.2.).
70457bddd21SDag-Erling Smørgrav  */
70557bddd21SDag-Erling Smørgrav int compare_serial(uint32_t a, uint32_t b);
70657bddd21SDag-Erling Smørgrav 
7075469a995SCy Schubert /**
7085469a995SCy Schubert  * Generate ZONEMD digest for the auth zone.
7095469a995SCy Schubert  * @param z: the auth zone to digest.
7105469a995SCy Schubert  * 	omits zonemd at apex and its RRSIG from the digest.
7115469a995SCy Schubert  * @param scheme: the collation scheme to use.  Numbers as defined for ZONEMD.
7125469a995SCy Schubert  * @param hashalgo: the hash algo, from the registry defined for ZONEMD type.
7135469a995SCy Schubert  * @param hash: the result buffer.
7145469a995SCy Schubert  * @param buflen: size of the result buffer, must be large enough. or the
7155469a995SCy Schubert  * 	routine fails.
7165469a995SCy Schubert  * @param resultlen: size of the hash in the result buffer of the result.
7175469a995SCy Schubert  * @param region: temp region for allocs during canonicalisation.
7185469a995SCy Schubert  * @param buf: temp buffer during canonicalisation.
7195469a995SCy Schubert  * @param reason: failure reason, returns a string, NULL on success.
7205469a995SCy Schubert  * @return false on failure.
7215469a995SCy Schubert  */
7225469a995SCy Schubert int auth_zone_generate_zonemd_hash(struct auth_zone* z, int scheme,
7235469a995SCy Schubert 	int hashalgo, uint8_t* hash, size_t buflen, size_t* resultlen,
7245469a995SCy Schubert 	struct regional* region, struct sldns_buffer* buf, char** reason);
7255469a995SCy Schubert 
7265469a995SCy Schubert /** ZONEMD scheme definitions */
7275469a995SCy Schubert #define ZONEMD_SCHEME_SIMPLE 1
7285469a995SCy Schubert 
7295469a995SCy Schubert /** ZONEMD hash algorithm definition for SHA384 */
7305469a995SCy Schubert #define ZONEMD_ALGO_SHA384 1
7315469a995SCy Schubert /** ZONEMD hash algorithm definition for SHA512 */
7325469a995SCy Schubert #define ZONEMD_ALGO_SHA512 2
7335469a995SCy Schubert 
7345469a995SCy Schubert /** returns true if a zonemd hash algo is supported */
7355469a995SCy Schubert int zonemd_hashalgo_supported(int hashalgo);
7365469a995SCy Schubert /** returns true if a zonemd scheme is supported */
7375469a995SCy Schubert int zonemd_scheme_supported(int scheme);
7385469a995SCy Schubert 
7395469a995SCy Schubert /**
7405469a995SCy Schubert  * Check ZONEMD digest for the auth zone.
7415469a995SCy Schubert  * @param z: auth zone to digest.
7425469a995SCy Schubert  * @param scheme: zonemd scheme.
7435469a995SCy Schubert  * @param hashalgo: zonemd hash algorithm.
7445469a995SCy Schubert  * @param hash: the hash to check.
7455469a995SCy Schubert  * @param hashlen: length of hash buffer.
7465469a995SCy Schubert  * @param region: temp region for allocs during canonicalisation.
7475469a995SCy Schubert  * @param buf: temp buffer during canonicalisation.
7485469a995SCy Schubert  * @param reason: string returned with failure reason.
749a39a5a69SCy Schubert  * 	If the hash cannot be checked, but it is allowed, for unknown
750a39a5a69SCy Schubert  * 	algorithms, the routine returns success, and the reason is nonNULL,
751a39a5a69SCy Schubert  * 	with the allowance reason.
7525469a995SCy Schubert  * @return false on failure.
7535469a995SCy Schubert  */
7545469a995SCy Schubert int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,
7555469a995SCy Schubert 	int hashalgo, uint8_t* hash, size_t hashlen, struct regional* region,
7565469a995SCy Schubert 	struct sldns_buffer* buf, char** reason);
7575469a995SCy Schubert 
7585469a995SCy Schubert /**
7595469a995SCy Schubert  * Perform ZONEMD checks and verification for the auth zone.
7605469a995SCy Schubert  * This includes DNSSEC verification if applicable.
7615469a995SCy Schubert  * @param z: auth zone to check.  Caller holds lock. wrlock.
7625469a995SCy Schubert  * @param env: with temp region, buffer and config.
7635469a995SCy Schubert  * @param mods: module stack for validator env.
7645469a995SCy Schubert  * @param result: if not NULL, result string strdupped in here.
7655469a995SCy Schubert  * @param offline: if true, there is no spawned lookup when online is needed.
7665469a995SCy Schubert  * 	Those zones are skipped for ZONEMD checking.
7675469a995SCy Schubert  * @param only_online: if true, only for ZONEMD that need online lookup
7685469a995SCy Schubert  * 	of DNSKEY chain of trust are processed.
7695469a995SCy Schubert  */
7705469a995SCy Schubert void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
7715469a995SCy Schubert 	struct module_stack* mods, char** result, int offline,
7725469a995SCy Schubert 	int only_online);
7735469a995SCy Schubert 
7745469a995SCy Schubert /** mesh callback for zonemd on lookup of dnskey */
7755469a995SCy Schubert void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode,
7765469a995SCy Schubert 	struct sldns_buffer* buf, enum sec_status sec, char* why_bogus,
7775469a995SCy Schubert 	int was_ratelimited);
7785469a995SCy Schubert 
7795469a995SCy Schubert /**
7805469a995SCy Schubert  * Check the ZONEMD records that need online DNSSEC chain lookups,
7815469a995SCy Schubert  * for them spawn the lookup process to get it checked out.
7825469a995SCy Schubert  * Attaches the lookup process to the worker event base and mesh state.
7835469a995SCy Schubert  * @param az: auth zones, every zones is checked.
7845469a995SCy Schubert  * @param env: env of the worker where the task is attached.
7855469a995SCy Schubert  */
7865469a995SCy Schubert void auth_zones_pickup_zonemd_verify(struct auth_zones* az,
7875469a995SCy Schubert 	struct module_env* env);
7885469a995SCy Schubert 
789*be771a7bSCy Schubert /** Get memory usage for auth zones. The routine locks and unlocks
790*be771a7bSCy Schubert  * for reading. */
791*be771a7bSCy Schubert size_t auth_zones_get_mem(struct auth_zones* zones);
792*be771a7bSCy Schubert 
793*be771a7bSCy Schubert /**
794*be771a7bSCy Schubert  * Initial pick up of the auth zone nextprobe timeout and that turns
795*be771a7bSCy Schubert  * into further zone transfer work, if any. Also sets the lease time.
796*be771a7bSCy Schubert  * @param x: xfer structure, locked by caller.
797*be771a7bSCy Schubert  * @param env: environment of the worker that picks up the task.
798*be771a7bSCy Schubert  */
799*be771a7bSCy Schubert void auth_xfer_pickup_initial_zone(struct auth_xfer* x,
800*be771a7bSCy Schubert 	struct module_env* env);
801*be771a7bSCy Schubert 
802*be771a7bSCy Schubert /**
803*be771a7bSCy Schubert  * Delete auth xfer structure
804*be771a7bSCy Schubert  * @param xfr: delete this xfer and its tasks.
805*be771a7bSCy Schubert  */
806*be771a7bSCy Schubert void auth_xfer_delete(struct auth_xfer* xfr);
807*be771a7bSCy Schubert 
808*be771a7bSCy Schubert /**
809*be771a7bSCy Schubert  * Disown tasks from the xfr that belong to this worker.
810*be771a7bSCy Schubert  * Only tasks for the worker in question, the comm point and timer
811*be771a7bSCy Schubert  * delete functions need to run in the thread of that worker to be
812*be771a7bSCy Schubert  * able to delete the callback from the event base.
813*be771a7bSCy Schubert  * @param xfr: xfr structure
814*be771a7bSCy Schubert  * @param worker: the worker for which to stop tasks.
815*be771a7bSCy Schubert  */
816*be771a7bSCy Schubert void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker);
817*be771a7bSCy Schubert 
818c7f4d7adSDag-Erling Smørgrav #endif /* SERVICES_AUTHZONE_H */
819