#include <arpa/inet.h>
#include <assert.h>
#include <ctype.h>
+#include <pthread.h>
+#include <contrib/ucw/mempool.h>
#include <libknot/descriptor.h>
+#include <libknot/dname.h>
#include <libknot/internal/base64.h>
+#include <libknot/rdataset.h>
+#include <libknot/rrset.h>
#include <libknot/rrtype/rdname.h>
#include "lib/defines.h"
#undef RDATA_MAXSIZE
#undef SEPARATORS
}
+
+#define MAX_ANCHORS 16
+struct trust_anchors_nolock {
+ mm_ctx_t pool;
+ knot_rrset_t *anchors[MAX_ANCHORS];
+ int used;
+};
+
+struct trust_anchors {
+ struct trust_anchors_nolock locked;
+ pthread_rwlock_t rwlock;
+};
+
+struct trust_anchors global_trust_anchors = {
+ .locked.pool = {0, },
+ .locked.anchors = {0, },
+ .locked.used = 0,
+};
+
+static int ta_init(struct trust_anchors_nolock *tan)
+{
+ assert(tan);
+
+ memset(tan, 0, sizeof(*tan));
+ tan->pool.ctx = mp_new(4 * CPU_PAGE_SIZE);
+ tan->pool.alloc = (mm_alloc_t) mp_alloc;
+ tan->used = 0;
+
+ return kr_ok();
+}
+
+static void ta_deinit(struct trust_anchors_nolock *tan)
+{
+ assert(tan);
+
+ if (tan->pool.ctx) {
+ mp_delete(tan->pool.ctx);
+ tan->pool.ctx = NULL;
+ }
+}
+
+int kr_ta_init(struct trust_anchors *tas)
+{
+ if (!tas) {
+ return kr_error(EINVAL);
+ }
+
+ int ret = ta_init(&tas->locked);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = pthread_rwlock_init(&tas->rwlock, NULL);
+ if (ret != 0) {
+ ta_deinit(&tas->locked);
+ return kr_error(ret);
+ }
+ return kr_ok();
+}
+
+void kr_ta_deinit(struct trust_anchors *tas)
+{
+ if (!tas) {
+ return;
+ }
+
+ while (pthread_rwlock_destroy(&tas->rwlock) == EBUSY);
+
+ ta_deinit(&tas->locked);
+}
+
+static int ta_reset(struct trust_anchors_nolock *tan, const char *ta_str)
+{
+ assert(tan);
+
+ ta_deinit(tan);
+ int ret = ta_init(tan);
+ if (ret != 0) {
+ return ret;
+ }
+
+ if (!ta_str || (ta_str[0] == '\0')) {
+ return kr_ok();
+ }
+
+ knot_rrset_t *ta = NULL;
+ ret = kr_ta_parse(&ta, ta_str, &tan->pool);
+ if (ret != 0) {
+ return ret;
+ }
+
+ assert(ta);
+
+ tan->anchors[tan->used++] = ta;
+
+ return kr_ok();
+}
+
+int kr_ta_reset(struct trust_anchors *tas, const char *ta_str)
+{
+ if (!tas) {
+ return kr_error(ENOENT);
+ }
+
+ int ret = pthread_rwlock_wrlock(&tas->rwlock);
+ if (ret != 0) {
+ return kr_error(ret);
+ }
+
+ ret = ta_reset(&tas->locked, ta_str);
+
+ pthread_rwlock_unlock(&tas->rwlock);
+ return ret;
+}
+
+static knot_rrset_t *ta_find(struct trust_anchors_nolock *tan, const knot_dname_t *name)
+{
+ assert(tan && name);
+
+ knot_rrset_t *found = NULL;
+
+ int i;
+ for (i = 0; i < tan->used; ++i) {
+ if (knot_dname_is_equal(tan->anchors[i]->owner, name)) {
+ found = tan->anchors[i];
+ break;
+ }
+ }
+
+ return found;
+}
+
+static int ta_add(struct trust_anchors_nolock *tan, const char *ta_str)
+{
+ assert(tan && ta_str);
+
+ if (tan->used >= MAX_ANCHORS) {
+ return kr_error(ENOMEM);
+ }
+
+ knot_rrset_t *ta = NULL;
+ int ret = kr_ta_parse(&ta, ta_str, &tan->pool);
+ if (ret != 0) {
+ return ret;
+ }
+ assert(ta);
+
+ knot_rrset_t *found = ta_find(tan, ta->owner);
+ if (!found) {
+ tan->anchors[tan->used++] = ta;
+ return kr_ok();
+ }
+
+ if (found->type != ta->type) {
+ knot_rrset_free(&ta, &tan->pool);
+ return kr_error(EINVAL);
+ }
+
+ ret = knot_rdataset_merge(&found->rrs, &ta->rrs, &tan->pool);
+ knot_rrset_free(&ta, &tan->pool);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return kr_ok();
+}
+
+int kr_ta_add(struct trust_anchors *tas, const char *ta_str)
+{
+ if (!tas || !ta_str) {
+ return kr_error(EINVAL);
+ }
+
+ int ret = pthread_rwlock_wrlock(&tas->rwlock);
+ if (ret != 0) {
+ return kr_error(ret);
+ }
+
+ ret = ta_add(&tas->locked, ta_str);
+
+ pthread_rwlock_unlock(&tas->rwlock);
+ return ret;
+}
+
+static int ta_get(knot_rrset_t **ta, struct trust_anchors_nolock *tan, const knot_dname_t *name, mm_ctx_t *pool)
+{
+ assert(ta && tan && name);
+
+ knot_rrset_t *copy = ta_find(tan, name);
+ if (!copy) {
+ kr_error(ENOENT);
+ }
+
+ copy = knot_rrset_copy(copy, pool);
+ if (!copy) {
+ kr_error(ENOMEM);
+ }
+
+ *ta = copy;
+
+ return kr_ok();
+}
+
+int kr_ta_get(knot_rrset_t **ta, struct trust_anchors *tas, const knot_dname_t *name, mm_ctx_t *pool)
+{
+ if (!ta || !tas || !name) {
+ return kr_error(EINVAL);
+ }
+
+ int ret = pthread_rwlock_rdlock(&tas->rwlock);
+ if (ret != 0) {
+ return kr_error(ret);
+ }
+
+ ret = ta_get(ta, &tas->locked, name, pool);
+
+ pthread_rwlock_unlock(&tas->rwlock);
+ return ret;
+}
#include <libknot/rrset.h>
//#define ROOT_TA ". IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
+#define ROOT_NAME ""
#define ROOT_TA ". IN DS 19036 RSASHA256 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
//#define ROOT_TA ". IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0="
* @return 0 or an error code
*/
int kr_ta_parse(knot_rrset_t **rr, const char *ds_str, mm_ctx_t *pool);
+
+/** Trust anchor container structure. */
+struct trust_anchors;
+
+/** Global trust anchor container. */
+extern struct trust_anchors global_trust_anchors;
+
+int kr_ta_init(struct trust_anchors *tas);
+
+void kr_ta_deinit(struct trust_anchors *tas);
+
+int kr_ta_reset(struct trust_anchors *tas, const char *ta_str);
+
+int kr_ta_add(struct trust_anchors *tas, const char *ta_str);
+
+int kr_ta_get(knot_rrset_t **ta, struct trust_anchors *tas, const knot_dname_t *name, mm_ctx_t *pool);
/* List of embedded modules */
const knot_layer_api_t *iterate_layer(struct kr_module *module);
+int validate_init(struct kr_module *module);
+int validate_deinit(struct kr_module *module);
+int validate_config(struct kr_module *module, const char *conf);
const knot_layer_api_t *validate_layer(struct kr_module *module);
+extern struct kr_prop validate_prop_list[];
const knot_layer_api_t *rrcache_layer(struct kr_module *module);
const knot_layer_api_t *pktcache_layer(struct kr_module *module);
static const struct kr_module embedded_modules[] = {
{ "iterate", NULL, NULL, NULL, iterate_layer, NULL, NULL, NULL },
- { "validate", NULL, NULL, NULL, validate_layer, NULL, NULL, NULL },
+ { "validate", validate_init, validate_deinit, validate_config, validate_layer, validate_prop_list, NULL, NULL },
{ "rrcache", NULL, NULL, NULL, rrcache_layer, NULL, NULL, NULL },
{ "pktcache", NULL, NULL, NULL, pktcache_layer, NULL, NULL, NULL },
};