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