1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
/* Copyright (C) 2022 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include "knot/journal/knot_lmdb.h"
#include "libknot/libknot.h"
#define CATALOG_VERSION "1.0"
#define CATALOG_ZONE_VERSION "2" // must be just one char long
#define CATALOG_ZONES_LABEL "\x05""zones"
#define CATALOG_GROUP_LABEL "\x05""group"
#define CATALOG_GROUP_MAXLEN 255
typedef struct catalog {
knot_lmdb_db_t db;
knot_lmdb_txn_t *ro_txn; // persistent RO transaction
knot_lmdb_txn_t *rw_txn; // temporary RW transaction
// private
knot_lmdb_txn_t *old_ro_txn;
} catalog_t;
/*!
* \brief Append a prefix dname to a dname in a storage.
*
* \return New dname length.
*/
size_t catalog_dname_append(knot_dname_storage_t storage, const knot_dname_t *name);
/*!
* \brief Return the number of bytes that subname has more than name.
*
* \return -1 if subname is not subname of name
*/
int catalog_bailiwick_shift(const knot_dname_t *subname, const knot_dname_t *name);
/*!
* \brief Initialize catalog structure.
*
* \param cat Catalog structure.
* \param path Path to LMDB for catalog.
* \param mapsize Mapsize of the LMDB.
*/
void catalog_init(catalog_t *cat, const char *path, size_t mapsize);
/*!
* \brief Open the catalog LMDB, create it if not exists.
*
* \param cat Catlog to be opened.
*
* \return KNOT_E*
*/
int catalog_open(catalog_t *cat);
/*!
* \brief Start a temporary RW transaction in the catalog.
*
* \param cat Catalog in question.
*
* \return KNOT_E*
*/
int catalog_begin(catalog_t *cat);
/*!
* \brief End using the temporary RW txn, refresh the persistent RO txn.
*
* \param cat Catalog in question.
*
* \return KNOT_E*
*/
int catalog_commit(catalog_t *cat);
/*!
* \brief Abort temporary RW txn.
*/
void catalog_abort(catalog_t *cat);
/*!
* \brief Free up old txns.
*
* \note This must be called after catalog_commit() with a delay of synchronize_rcu().
*
* \param cat Catalog.
*/
void catalog_commit_cleanup(catalog_t *cat);
/*!
* \brief Close the catalog and de-init the structure.
*
* \param cat Catalog to be closed.
*/
void catalog_deinit(catalog_t *cat);
/*!
* \brief Add a member zone to the catalog database.
*
* \param cat Catalog to be augmented.
* \param member Member zone name.
* \param owner Owner of the PTR record in catalog zone, respective to the member zone.
* \param catzone Name of the catalog zone whose it's the member.
* \param group Configuration group of the member.
*
* \return KNOT_E*
*/
int catalog_add(catalog_t *cat, const knot_dname_t *member,
const knot_dname_t *owner, const knot_dname_t *catzone,
const char *group);
/*!
* \brief Delete a member zone from the catalog database.
*
* \param cat Catalog to be removed from.
* \param member Member zone to be removed.
*
* \return KNOT_E*
*/
int catalog_del(catalog_t *cat, const knot_dname_t *member);
/*!
* \brief Find catz name of the catalog owning this member.
*
* \note This function may be called in multithreaded operation.
*
* \param cat Catalog database.
* \param member Member to search for.
* \param catz Out: name of catalog zone it resides in.
* \param group Out: configuration group the member resides in.
* \param tofree Out: a pointer that has to be freed later.
*
* \return KNOT_E*
*/
int catalog_get_catz(catalog_t *cat, const knot_dname_t *member,
const knot_dname_t **catz, const char **group, void **tofree);
/*!
* \brief Check if this member exists in any catalog zone.
*/
bool catalog_has_member(catalog_t *cat, const knot_dname_t *member);
/*!
* \brief Check if exactly this record (member, owner, catz) is in catalog DB.
*/
bool catalog_contains_exact(catalog_t *cat, const knot_dname_t *member,
const knot_dname_t *owner, const knot_dname_t *catz);
typedef int (*catalog_apply_cb_t)(const knot_dname_t *member, const knot_dname_t *owner,
const knot_dname_t *catz, const char *group, void *ctx);
/*!
* \brief Iterate through catalog database, applying callback.
*
* \param cat Catalog to be iterated.
* \param for_member (Optional) Iterate only on records for this member name.
* \param cb Callback to be called.
* \param ctx Context for this callback.
* \param rw Use read-write transaction.
*
* \return KNOT_E*
*/
int catalog_apply(catalog_t *cat, const knot_dname_t *for_member,
catalog_apply_cb_t cb, void *ctx, bool rw);
/*!
* \brief Copy records from one catalog database to other.
*
* \param from Catalog DB to copy from.
* \param to Catalog DB to copy to.
* \param cat_only Optional: copy only records for this catalog zone.
* \param read_rw_txn Use RW txn for read operations.
*
* \return KNOT_E*
*/
int catalog_copy(knot_lmdb_db_t *from, knot_lmdb_db_t *to,
const knot_dname_t *cat_only, bool read_rw_txn);
|