Commit 64050118 authored by Grigorii Demidov's avatar Grigorii Demidov Committed by Petr Špaček

daemon: root zone import

parent 26c3d7a6
......@@ -26,6 +26,7 @@
#include "daemon/bindings.h"
#include "daemon/worker.h"
#include "daemon/tls.h"
#include "daemon/zimport.h"
#define xstr(s) str(s)
#define str(s) #s
......@@ -1149,6 +1150,73 @@ static int cache_ns_tout(lua_State *L)
return 1;
}
/** Zone import completion callback.
* Deallocates zone import context. */
static void cache_zone_import_cb(int state, void *param)
{
assert (param);
(void)state;
struct worker_ctx *worker = (struct worker_ctx *)param;
assert (worker->z_import);
zi_free(worker->z_import);
worker->z_import = NULL;
}
/** Import zone from file. */
static int cache_zone_import(lua_State *L)
{
struct worker_ctx *worker = wrk_luaget(L);
if (!worker) {
return 0;
}
if (worker->z_import && zi_import_started(worker->z_import)) {
format_error(L, "import has already started");
lua_error(L);
}
struct engine *engine = engine_luaget(L);
if (!engine) {
return 0;
}
struct kr_cache *cache = &engine->resolver.cache;
if (!kr_cache_is_open(cache)) {
return 0;
}
/* Check parameters */
int n = lua_gettop(L);
if (n < 1 || !lua_isstring(L, 1)) {
format_error(L, "expected 'cache.zone_import(string key)'");
lua_error(L);
}
/* Parse zone file */
const char *zone_file = lua_tostring(L, 1);
const char *default_origin = NULL; /* TODO */
uint16_t default_rclass = 1;
uint32_t default_ttl = 0;
if (worker->z_import == NULL) {
worker->z_import = zi_allocate(worker, cache_zone_import_cb, worker);
if (worker->z_import == NULL) {
format_error(L, "can't allocate zone import context");
lua_error(L);
}
}
int ret = zi_zone_import(worker->z_import, zone_file, default_origin,
default_rclass, default_ttl);
if (ret != 0) {
format_error(L, "error parsing zone file");
lua_error(L);
}
lua_pushstring(L, "zone file successfully parsed, import started");
return 1;
}
int lib_cache(lua_State *L)
{
......@@ -1165,6 +1233,7 @@ int lib_cache(lua_State *L)
{ "max_ttl", cache_max_ttl },
{ "min_ttl", cache_min_ttl },
{ "ns_tout", cache_ns_tout },
{ "zone_import", cache_zone_import },
{ NULL, NULL }
};
......
......@@ -7,6 +7,7 @@ kresd_SOURCES := \
daemon/ffimodule.c \
daemon/tls.c \
daemon/tls_ephemeral_credentials.c \
daemon/zimport.c \
daemon/main.c
kresd_DIST := daemon/lua/kres.lua daemon/lua/kres-gen.lua \
......
......@@ -35,6 +35,7 @@
#include "daemon/engine.h"
#include "daemon/io.h"
#include "daemon/tls.h"
#include "daemon/zimport.h"
#define VERBOSE_MSG(qry, fmt...) QRVERBOSE(qry, "wrkr", fmt)
......@@ -2385,6 +2386,11 @@ struct kr_request *worker_task_request(struct qr_task *task)
return &task->ctx->req;
}
int worker_task_finalize(struct qr_task *task, int state)
{
return qr_task_finalize(task, state);
}
void worker_session_close(struct session *session)
{
session_close(session);
......@@ -2434,6 +2440,10 @@ void worker_reclaim(struct worker_ctx *worker)
worker->subreq_out = NULL;
map_clear(&worker->tcp_connected);
map_clear(&worker->tcp_waiting);
if (worker->z_import != NULL) {
zi_free(worker->z_import);
worker->z_import = NULL;
}
}
struct worker_ctx *worker_create(struct engine *engine, knot_mm_t *pool,
......
......@@ -29,6 +29,8 @@ struct qr_task;
struct worker_ctx;
/** Transport session (opaque). */
struct session;
/** Zone import context (opaque). */
struct zone_import_ctx;
/** Create and initialize the worker. */
struct worker_ctx *worker_create(struct engine *engine, knot_mm_t *pool,
......@@ -140,6 +142,7 @@ struct worker_ctx {
size_t timeout;
} stats;
struct zone_import_ctx* z_import;
bool too_many_open;
size_t rconcurrent_highwatermark;
/** List of active outbound TCP sessions */
......
This diff is collapsed.
/* Copyright (C) 2018 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 <stdbool.h>
struct worker_ctx;
/** Zone import context (opaque). */
struct zone_import_ctx;
/**
* Completion callback
*
* @param state -1 - fail
* 0 - success
* 1 - success, but there are non-critical errors
* @param pointer to user data
*/
typedef void (*zi_callback)(int state, void *param);
/**
* Allocate and initialize zone import context.
*
* @param worker pointer to worker state
* @return NULL or pointer to zone import context.
*/
struct zone_import_ctx *zi_allocate(struct worker_ctx *worker,
zi_callback cb, void *param);
/** Free zone import context. */
void zi_free(struct zone_import_ctx *z_import);
/**
* Import zone from file.
*
* @note only root zone import is supported; origin must be NULL or "."
* @param z_import pointer to zone import context
* @param zone_file zone file name
* @param origin default origin
* @param rclass default class
* @param ttl default ttl
* @return 0 or an error code
*/
int zi_zone_import(struct zone_import_ctx *z_import,
const char *zone_file, const char *origin,
uint16_t rclass, uint32_t ttl);
/**
* Check if import already in process.
*
* @param z_import pointer to zone import context.
* @return true if import already in process; false otherwise.
*/
bool zi_import_started(struct zone_import_ctx *z_import);
......@@ -124,14 +124,6 @@ static inline void array_std_free(void *baton, void *p)
#define array_reserve_mm(array, n, reserve, baton) \
(reserve)((baton), (char **) &(array).at, sizeof((array).at[0]), (n), &(array).cap)
/**
* Push value at the end of the array, resize it if necessary (plain malloc/free).
* @note May fail if the capacity is not reserved.
* @return element index on success, <0 on failure
*/
#define array_push(array, val) \
array_push_mm(array, val, array_std_reserve, NULL)
/**
* Push value at the end of the array, resize it if necessary.
* Mempool usage: pass kr_memreserve and a knot_mm_t* .
......@@ -143,6 +135,14 @@ static inline void array_std_free(void *baton, void *p)
: (array_reserve_mm(array, ((array).cap + 1), reserve, baton) < 0 ? -1 \
: ((array).at[(array).len] = val, (array).len++)))
/**
* Push value at the end of the array, resize it if necessary (plain malloc/free).
* @note May fail if the capacity is not reserved.
* @return element index on success, <0 on failure
*/
#define array_push(array, val) \
array_push_mm(array, val, array_std_reserve, NULL)
/**
* Pop value from the end of the array.
*/
......
......@@ -600,6 +600,37 @@ int kr_rrkey(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank)
return (char *)&key_buf[ret] - key;
}
int kr_rrkey2(char *key, uint16_t class, const knot_dname_t *owner,
uint16_t type, uint16_t additional)
{
if (!key || !owner) {
return kr_error(EINVAL);
}
uint8_t *key_buf = (uint8_t *)key;
int ret = u16tostr(key_buf, class);
if (ret <= 0) {
return ret;
}
key_buf += ret;
ret = knot_dname_to_wire(key_buf, owner, KNOT_DNAME_MAXLEN);
if (ret <= 0) {
return ret;
}
knot_dname_to_lower(key_buf);
key_buf += ret - 1;
ret = u16tostr(key_buf, type);
if (ret <= 0) {
return ret;
}
key_buf += ret;
ret = u16tostr(key_buf, additional);
if (ret <= 0) {
return ret;
}
key_buf[ret] = '\0';
return (char *)&key_buf[ret] - key;
}
/** Return whether two RRsets match, i.e. would form the same set; see ranked_rr_array_t */
static inline bool rrsets_match(const knot_rrset_t *rr1, const knot_rrset_t *rr2)
{
......
......@@ -298,6 +298,21 @@ static inline bool KEY_COVERING_RRSIG(const char *key)
KR_EXPORT
int kr_rrkey(char *key, const knot_dname_t *owner, uint16_t type, uint8_t rank);
/* Stash key = {[5] class, [1-255] owner, [5] type, [5] additional, [1] \x00 } */
#define KR_RRKEY2_LEN (16 + KNOT_DNAME_MAXLEN)
/** Create unique null-terminated string key for RR.
* @param key Destination buffer for key size, MUST be KR_RRKEY2_LEN or larger.
* @param class RR class.
* @param owner RR owner name.
* @param type RR type.
* @param additional flags (for instance can be used for storing covered type
* when RR type is RRSIG).
* @return key length if successful or an error
* */
KR_EXPORT
int kr_rrkey2(char *key, uint16_t class, const knot_dname_t *owner,
uint16_t type, uint16_t additional);
/** @internal Add RRSet copy to ranked RR array. */
KR_EXPORT
int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment