1 /*  Copyright (C) 2014-2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2  *  SPDX-License-Identifier: GPL-3.0-or-later
3  */
4 
5 #pragma once
6 
7 #include "lib/cache/api.h"
8 #include "lib/defines.h"
9 #include "lib/generic/pack.h"
10 #include "lib/generic/trie.h"
11 
12 
13 struct kr_rplan;
14 struct kr_context;
15 
16 /**
17  * Current zone cut representation.
18 */
19 struct kr_zonecut {
20 	knot_dname_t *name; /**< Zone cut name. */
21 	knot_rrset_t* key;  /**< Zone cut DNSKEY. */
22 	knot_rrset_t* trust_anchor; /**< Current trust anchor. */
23 	struct kr_zonecut *parent; /**< Parent zone cut. */
24 	trie_t *nsset;        /**< Map of nameserver => address_set (pack_t). */
25 	knot_mm_t *pool;     /**< Memory pool. */
26 };
27 
28 /**
29  * Populate root zone cut with SBELT.
30  * @param cut zone cut
31  * @param name
32  * @param pool
33  * @return 0 or error code
34  */
35 KR_EXPORT
36 int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, knot_mm_t *pool);
37 
38 /**
39  * Clear the structure and free the address set.
40  * @param cut zone cut
41  */
42 KR_EXPORT
43 void kr_zonecut_deinit(struct kr_zonecut *cut);
44 
45 /**
46  * Move a zonecut, transferring ownership of any pointed-to memory.
47  * @param to the target - it gets deinit-ed
48  * @param from the source - not modified, but shouldn't be used afterward
49  */
50 KR_EXPORT
51 void kr_zonecut_move(struct kr_zonecut *to, const struct kr_zonecut *from);
52 
53 /**
54  * Reset zone cut to given name and clear address list.
55  * @note This clears the address list even if the name doesn't change. TA and DNSKEY don't change.
56  * @param cut  zone cut to be set
57  * @param name new zone cut name
58  */
59 KR_EXPORT
60 void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name);
61 
62 /**
63  * Copy zone cut, including all data. Does not copy keys and trust anchor.
64  * @param dst destination zone cut
65  * @param src source zone cut
66  * @return 0 or an error code; If it fails with kr_error(ENOMEM),
67  * it may be in a half-filled state, but it's safe to deinit...
68  * @note addresses for names in `src` get replaced and others are left as they were.
69  */
70 KR_EXPORT
71 int kr_zonecut_copy(struct kr_zonecut *dst, const struct kr_zonecut *src);
72 
73 /**
74  * Copy zone trust anchor and keys.
75  * @param dst destination zone cut
76  * @param src source zone cut
77  * @return 0 or an error code
78  */
79 KR_EXPORT
80 int kr_zonecut_copy_trust(struct kr_zonecut *dst, const struct kr_zonecut *src);
81 
82 /**
83  * Add address record to the zone cut.
84  *
85  * The record will be merged with existing data,
86  * it may be either A/AAAA type.
87  *
88  * @param cut    zone cut to be populated
89  * @param ns     nameserver name
90  * @param data   typically knot_rdata_t::data
91  * @param len    typically knot_rdata_t::len
92  * @return 0 or error code
93  */
94 KR_EXPORT
95 int kr_zonecut_add(struct kr_zonecut *cut, const knot_dname_t *ns, const void *data, int len);
96 
97 /**
98  * Delete nameserver/address pair from the zone cut.
99  * @param  cut
100  * @param  ns    name server name
101  * @param  data  typically knot_rdata_t::data
102  * @param  len   typically knot_rdata_t::len
103  * @return       0 or error code
104  */
105 KR_EXPORT
106 int kr_zonecut_del(struct kr_zonecut *cut, const knot_dname_t *ns, const void *data, int len);
107 
108 /**
109  * Delete all addresses associated with the given name.
110  * @param  cut
111  * @param  ns    name server name
112  * @return       0 or error code
113  */
114 KR_EXPORT
115 int kr_zonecut_del_all(struct kr_zonecut *cut, const knot_dname_t *ns);
116 
117 /**
118  * Find nameserver address list in the zone cut.
119  *
120  * @note This can be used for membership test, a non-null pack is returned
121  *       if the nameserver name exists.
122  *
123  * @param  cut
124  * @param  ns    name server name
125  * @return       pack of addresses or NULL
126  */
127 KR_EXPORT KR_PURE
128 pack_t *kr_zonecut_find(struct kr_zonecut *cut, const knot_dname_t *ns);
129 
130 /**
131  * Populate zone cut with a root zone using SBELT :rfc:`1034`
132  *
133  * @param ctx resolution context (to fetch root hints)
134  * @param cut zone cut to be populated
135  * @return 0 or error code
136  */
137 KR_EXPORT
138 int kr_zonecut_set_sbelt(struct kr_context *ctx, struct kr_zonecut *cut);
139 
140 /**
141  * Populate zone cut address set from cache.
142  *
143  * @param ctx       resolution context (to fetch data from LRU caches)
144  * @param cut       zone cut to be populated
145  * @param name      QNAME to start finding zone cut for
146  * @param qry       query for timestamp and stale-serving decisions
147  * @param secured   set to true if want secured zone cut, will return false if it is provably insecure
148  * @return 0 or error code (ENOENT if it doesn't find anything)
149  */
150 KR_EXPORT
151 int kr_zonecut_find_cached(struct kr_context *ctx, struct kr_zonecut *cut,
152 			   const knot_dname_t *name, const struct kr_query *qry,
153 			   bool * restrict secured);
154 /**
155  * Check if any address is present in the zone cut.
156  *
157  * @param cut zone cut to check
158  * @return true/false
159  */
160 KR_EXPORT
161 bool kr_zonecut_is_empty(struct kr_zonecut *cut);
162 
163