Commit 1a848d22 authored by Marek Vavruša's avatar Marek Vavruša

Merge branch 'master' into resolver_compat

Conflicts:
	Knot.files
	src/Makefile.am
	src/knot/conf/conf.h
	src/knot/nameserver/process_answer.c
	src/knot/zone/events/handlers.c
parents e8599597 a053cc38
......@@ -24,6 +24,8 @@ man/Makefile.am
patches/Makefile.am
samples/Makefile.am
src/Makefile.am
src/Makefile.am
src/Makefile.am
src/common-knot/crc.h
src/common-knot/evsched.c
src/common-knot/evsched.h
......@@ -63,6 +65,11 @@ src/common/mem.c
src/common/mem.h
src/common/mempool.c
src/common/mempool.h
src/common/namedb/namedb.h
src/common/namedb/namedb_lmdb.c
src/common/namedb/namedb_lmdb.h
src/common/namedb/namedb_trie.c
src/common/namedb/namedb_trie.h
src/common/print.c
src/common/print.h
src/common/sockaddr.c
......@@ -88,6 +95,8 @@ src/knot/conf/cf-lex.l
src/knot/conf/cf-parse.y
src/knot/conf/conf.c
src/knot/conf/conf.h
src/knot/conf/conf.h
src/knot/conf/conf.h
src/knot/conf/extra.c
src/knot/conf/extra.h
src/knot/conf/includes.c
......@@ -132,6 +141,8 @@ src/knot/nameserver/notify.h
src/knot/nameserver/nsec_proofs.c
src/knot/nameserver/nsec_proofs.h
src/knot/nameserver/process_answer.c
src/knot/nameserver/process_answer.c
src/knot/nameserver/process_answer.c
src/knot/nameserver/process_answer.h
src/knot/nameserver/process_query.c
src/knot/nameserver/process_query.h
......@@ -140,8 +151,6 @@ src/knot/nameserver/query_module.h
src/knot/nameserver/tsig_ctx.c
src/knot/nameserver/tsig_ctx.h
src/knot/nameserver/update.c
src/knot/nameserver/update.c
src/knot/nameserver/update.c
src/knot/nameserver/update.h
src/knot/other/debug.h
src/knot/server/dthreads.c
......@@ -174,12 +183,20 @@ src/knot/worker/queue.c
src/knot/worker/queue.h
src/knot/zone/contents.c
src/knot/zone/contents.h
src/knot/zone/events.c
src/knot/zone/events.h
src/knot/zone/events/events.c
src/knot/zone/events/events.h
src/knot/zone/events/handlers.c
src/knot/zone/events/handlers.c
src/knot/zone/events/handlers.c
src/knot/zone/events/handlers.h
src/knot/zone/events/replan.c
src/knot/zone/events/replan.h
src/knot/zone/node.c
src/knot/zone/node.h
src/knot/zone/semantic-check.c
src/knot/zone/semantic-check.h
src/knot/zone/timers.c
src/knot/zone/timers.h
src/knot/zone/zone-diff.c
src/knot/zone/zone-diff.h
src/knot/zone/zone-dump.c
......@@ -240,8 +257,6 @@ src/libknot/processing/overlay.c
src/libknot/processing/overlay.h
src/libknot/processing/requestor.c
src/libknot/processing/requestor.h
src/libknot/processing/requestor.h
src/libknot/processing/requestor.h
src/libknot/rdata.c
src/libknot/rdata.h
src/libknot/rdataset.c
......@@ -329,6 +344,7 @@ tests/fdset.c
tests/hattrie.c
tests/hhash.c
tests/journal.c
tests/namedb.c
tests/node.c
tests/overlay.c
tests/pkt.c
......@@ -348,7 +364,7 @@ tests/wire.c
tests/worker_pool.c
tests/worker_queue.c
tests/zone_events.c
tests/zone_timers.c
tests/zone_update.c
tests/zonedb.c
tests/zone-update.c
tests/ztree.c
Knot DNS 1.5.3 (2014-09-15)
==========================
Bugfixes:
---------
- Some specific incoming IXFRs were causing server to crash
- Rare sychronization error during reload caused read-after-free
- Response synthetization module did not work properly with DNSSEC-enabled zones
- When Knot sent AXFR when IXFR was requested, message ID and opcode were wrong
- Knot failed to send large messages to remote control (present since 1.5.1)
Knot DNS 1.5.2 (2014-09-08)
==========================
Bugfixes:
---------
- Some RR parsing corner cases were not handled properly
- AXFR-style IXFR was refused and had to be retransfered
- Hash character (#) was not properly escaped when storing text zone file
Knot DNS 1.5.1 (2014-08-19)
===========================
......
# -*- Autoconf -*-
AC_PREREQ([2.60])
AC_INIT([knot], [1.5.1], [knot-dns@labs.nic.cz])
AC_INIT([knot], [1.5.3], [knot-dns@labs.nic.cz])
AM_INIT_AUTOMAKE([gnits subdir-objects dist-xz -Wall -Werror])
AM_SILENT_RULES([yes])
AC_CONFIG_SRCDIR([src/knot/main.c])
......@@ -312,6 +312,10 @@ dt_DNSTAP([
])
AM_CONDITIONAL([HAVE_DNSTAP], test "$opt_dnstap" != "no")
dnl Check for LMDB
KNOT_CHECK_HEADER([lmdb], [LMDB], [auto], [lmdb.h], [], [-llmdb])
AS_IF([test "$enable_lmdb" = yes], [AC_DEFINE([HAVE_LMDB], [1], [Define to 1 to enable LMDB support])])
AC_SEARCH_LIBS([pow], [m])
AC_SEARCH_LIBS([pthread_create], [pthread], [], [AC_MSG_ERROR([pthreads not found])])
AC_SEARCH_LIBS([dlopen], [dl])
......@@ -407,6 +411,7 @@ AC_MSG_RESULT([
Systemd integration: ${enable_systemd}
Dnstap support: ${opt_dnstap}
Code coverage: ${enable_code_coverage}
LMDB support: ${enable_lmdb}
Continue with 'make' command
])
......@@ -45,14 +45,13 @@ If you want to control the daemon directly, use ``SIGINT`` to quit the process o
-f, --force Force operation - override some checks.
-v, --verbose Verbose mode - additional runtime information.
-V, --version Print knot server version.
-i, --interactive Interactive mode (do not daemonize).
-h, --help Print help and usage.
Actions:
stop Stop server.
reload Reload configuration and changed zones.
refresh <zone> Refresh slave zone (all if not specified).
flush Flush journal and update zone files.
flush <zone> Flush journal and update zone files. (all if not specified)
status Check if server is running.
zonestatus Show status of configured zones.
checkconf Check current server configuration.
......
......@@ -31,7 +31,7 @@ AC_DEFUN([AX_CODE_COVERAGE], [
AC_CHECK_PROG([LCOV], [lcov], [lcov])
AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
lcov_version_list="1.6 1.7 1.8 1.9 1.10"
lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11"
AS_IF([test "$LCOV"], [
AC_CACHE_CHECK([for lcov version], ac_cv_lvoc_version, [
......
# KNOT_CHECK_HEADER([prefix], [name], [default], [header], [cflags], [libs])
# -----------------------------------------------------------------------------
# Check presence of a library by checking for a header file.
#
# - adds --enable-prefix configure flag
#
# - if $enable_prefix is yes or auto, checks for the header file
#
# - emits an error if $enable_prefix is yes and the header is not present
#
# - check can be overridden by setting prefix_CFLAGS and prefix_LIBS
# environment variables
#
# Output variables: $enable_foo (yes or no), $foo_CFLAGS, and $foo_LIBS
#
AC_DEFUN([KNOT_CHECK_HEADER],
[
AC_ARG_ENABLE([$1], AC_HELP_STRING([--enable-$1], [Support for $2 [default $3]]),
[enable_][$1][=$enableval], [enable_][$1][=][$3])
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $2, overriding defaults])
AC_ARG_VAR([$1][_LIBS], [linker flags for $2, overriding defaults])
AS_CASE([$enable_][$1],
[no], [
[$1][_CFLAGS]=
[$1][_LIBS]=
],
[auto|yes], [
AS_IF([test -n "$][$1][_LIBS"], [
dnl: skip header check if environment variable is set
[enable_][$1][=yes]
],[
dnl: check for header
AC_CHECK_HEADER([$4], [
[enable_][$1]=yes
[$1][_CFLAGS]=[$5]
[$1][_LIBS]=[$6]
], [
AS_IF([test "$enable_][$1][" = auto],
[[enable_][$1]=no],
[AC_MSG_ERROR([Header file "$4" for $2 not found])]
)
])
])
],
[AC_MSG_ERROR([Invalid value of --enable-$1])]
)
])
......@@ -32,9 +32,6 @@ Verbose mode \- additional runtime information.
\fB\-V\fR, \fB\-\-version\fR
Print version of the server.
.TP
\fB\-i\fR, \fB\-\-interactive\fR
Interactive mode (do not daemonize).
.TP
\fB\-h\fR, \fB\-\-help\fR
Print help and usage.
.SS "Actions:"
......@@ -42,11 +39,11 @@ Print help and usage.
\fBstop\fR
Stop server (no\-op if not running).
.TP
\fBreload\fR
Reload configuration and changed zones.
\fBreload\fR [\fIzone\fR]...
Reload configuration and changed zones (all if not specified).
.TP
\fBflush\fR
Flush journal and update zone files.
\fBflush\fR [\fIzone\fR]...
Flush journal and update zone files (all if not specified).
.TP
\fBstatus\fR
Check if server is running.
......
......@@ -112,6 +112,11 @@ libknotcs_la_SOURCES = \
common/trie/hat-trie.h \
common/trie/murmurhash3.c \
common/trie/murmurhash3.h \
common/namedb/namedb.h \
common/namedb/namedb_lmdb.h \
common/namedb/namedb_lmdb.c \
common/namedb/namedb_trie.h \
common/namedb/namedb_trie.c \
common/log.c \
common/log.h
......@@ -299,12 +304,18 @@ libknotd_la_SOURCES = \
knot/worker/queue.h \
knot/zone/contents.c \
knot/zone/contents.h \
knot/zone/events.c \
knot/zone/events.h \
knot/zone/events/events.c \
knot/zone/events/events.h \
knot/zone/events/handlers.c \
knot/zone/events/handlers.h \
knot/zone/events/replan.c \
knot/zone/events/replan.h \
knot/zone/node.c \
knot/zone/node.h \
knot/zone/semantic-check.c \
knot/zone/semantic-check.h \
knot/zone/timers.c \
knot/zone/timers.h \
knot/zone/zone-diff.c \
knot/zone/zone-diff.h \
knot/zone/zone-dump.c \
......@@ -325,17 +336,20 @@ libknotd_la_SOURCES = \
# libraries
libknot_la_LIBADD = libknotcs.la zscanner/libzscanner.la
libknotd_la_LIBADD = libknots.la libknotcs.la libknot.la
libknotus_la_LIBADD = libknots.la libknotcs.la libknot.la
libknotd_la_CPPFLAGS = $(AM_CPPFLAGS) $(lmdb_CFLAGS)
libknotd_la_LDFLAGS = $(AM_LDFLAGS) $(lmdb_LIBS)
libknotus_la_CPPFLAGS = $(AM_CPPFLAGS) $(libidn_CFLAGS)
libknotus_la_LDFLAGS = $(AM_LDFLAGS) $(libidn_LIBS)
libknotcs_la_CPPFLAGS = $(AM_CPPFLAGS) $(systemd_CFLAGS)
libknotcs_la_LDFLAGS = $(AM_LDFLAGS) $(systemd_LIBS)
libknotcs_la_CPPFLAGS = $(AM_CPPFLAGS) $(systemd_CFLAGS) $(lmdb_CFLAGS)
libknotcs_la_LDFLAGS = $(AM_LDFLAGS) $(systemd_LIBS) $(lmdb_LIBS)
# sbin programs
knotd_LDADD = libknot.la libknotd.la $(systemd_LIBS)
knotd_LDADD = libknot.la libknotd.la $(systemd_LIBS) $(lmdb_LIBS)
knotc_LDADD = libknot.la libknotd.la
# bin programs
BIN_LIBS = libknotus.la libknotcs.la libknots.la libknot.la
BIN_LIBS = libknotus.la libknots.la
kdig_LDADD = $(BIN_LIBS) $(libidn_LIBS)
khost_LDADD = $(BIN_LIBS) $(libidn_LIBS)
knsupdate_LDADD = $(BIN_LIBS) zscanner/libzscanner.la
......
......@@ -403,7 +403,7 @@ int log_msg_zone(int priority, const knot_dname_t *zone, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
char *zone_str = knot_dname_to_str(zone);
char *zone_str = knot_dname_to_str_alloc(zone);
int result = log_msg_text(priority,
zone_str ? zone_str : LOG_NULL_ZONE_STRING,
fmt, args);
......
/* Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "libknot/dname.h"
enum {
KNOT_NAMEDB_RDONLY = 1 << 0,
KNOT_NAMEDB_SORTED = 1 << 1
};
typedef void knot_namedb_t;
typedef void knot_iter_t;
typedef struct knot_val {
void *data;
size_t len;
} knot_val_t;
typedef struct knot_txn {
knot_namedb_t *db;
void *txn;
} knot_txn_t;
struct namedb_api {
const char *name;
/* Context operations */
knot_namedb_t *(*init)(const char *handle, mm_ctx_t *mm);
void (*deinit)(knot_namedb_t *db);
/* Transactions */
int (*txn_begin)(knot_namedb_t *db, knot_txn_t *txn, unsigned flags);
int (*txn_commit)(knot_txn_t *txn);
void (*txn_abort)(knot_txn_t *txn);
/* Data access */
int (*count)(knot_txn_t *txn);
int (*find)(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned flags);
int (*insert)(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned flags);
int (*del)(knot_txn_t *txn,knot_val_t *key);
/* Iteration */
knot_iter_t *(*iter_begin)(knot_txn_t *txn, unsigned flags);
knot_iter_t *(*iter_next)(knot_iter_t *iter);
int (*iter_key)(knot_iter_t *iter, knot_val_t *key);
int (*iter_val)(knot_iter_t *iter, knot_val_t *val);
void (*iter_finish)(knot_iter_t *iter);
};
/* Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_LMDB
#include <lmdb.h>
#include "common/namedb/namedb_lmdb.h"
#include "libknot/errcode.h"
struct lmdb_env
{
MDB_dbi dbi;
MDB_env *env;
mm_ctx_t *pool;
};
static int dbase_open(struct lmdb_env *env, const char *handle)
{
int ret = mdb_env_create(&env->env);
if (ret != 0) {
return ret;
}
ret = mdb_env_open(env->env, handle, 0, 0644);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
}
MDB_txn *txn = NULL;
ret = mdb_txn_begin(env->env, NULL, 0, &txn);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
}
ret = mdb_open(txn, NULL, 0, &env->dbi);
if (ret != 0) {
mdb_txn_abort(txn);
mdb_env_close(env->env);
return ret;
}
ret = mdb_txn_commit(txn);
if (ret != 0) {
mdb_env_close(env->env);
return ret;
}
return 0;
}
static void dbase_close(struct lmdb_env *env)
{
mdb_close(env->env, env->dbi);
mdb_env_close(env->env);
}
static knot_namedb_t *init(const char *handle, mm_ctx_t *mm)
{
struct lmdb_env *env = mm_alloc(mm, sizeof(struct lmdb_env));
if (env == NULL) {
return NULL;
}
memset(env, 0, sizeof(struct lmdb_env));
int ret = dbase_open(env, handle);
if (ret != 0) {
mm_free(mm, env);
return NULL;
}
env->pool = mm;
return env;
}
static void deinit(knot_namedb_t *db)
{
if (db) {
struct lmdb_env *env = db;
dbase_close(env);
mm_free(env->pool, env);
}
}
static int txn_begin(knot_namedb_t *db, knot_txn_t *txn, unsigned flags)
{
txn->db = db;
txn->txn = NULL;
unsigned txn_flags = 0;
if (flags & KNOT_NAMEDB_RDONLY) {
txn_flags |= MDB_RDONLY;
}
struct lmdb_env *env = db;
int ret = mdb_txn_begin(env->env, NULL, txn_flags, (MDB_txn **)&txn->txn);
if (ret != 0) {
return KNOT_ERROR;
}
return KNOT_EOK;
}
static int txn_commit(knot_txn_t *txn)
{
int ret = mdb_txn_commit((MDB_txn *)txn->txn);
if (ret != 0) {
return KNOT_ERROR;
}
return KNOT_EOK;
}
static void txn_abort(knot_txn_t *txn)
{
mdb_txn_abort((MDB_txn *)txn->txn);
}
static int count(knot_txn_t *txn)
{
struct lmdb_env *env = txn->db;
MDB_stat stat;
int ret = mdb_stat(txn->txn, env->dbi, &stat);
if (ret != 0) {
return KNOT_ERROR;
}
return stat.ms_entries;
}
static int find(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned flags)
{
struct lmdb_env *env = txn->db;
MDB_val db_key = { key->len, key->data };
MDB_val data = { 0, NULL };
int ret = mdb_get(txn->txn, env->dbi, &db_key, &data);
if (ret != 0) {
if (ret == MDB_NOTFOUND) {
return KNOT_ENOENT;
} else {
return KNOT_ERROR;
}
}
val->data = data.mv_data;
val->len = data.mv_size;
return KNOT_EOK;
}
static int insert(knot_txn_t *txn, knot_val_t *key, knot_val_t *val, unsigned flags)
{
struct lmdb_env *env = txn->db;
MDB_cursor *cursor = NULL;
int ret = mdb_cursor_open(txn->txn, env->dbi, &cursor);
if (ret != 0) {
return KNOT_ERROR;
}
MDB_val db_key = { key->len, key->data };
MDB_val data = { val->len, val->data };
ret = mdb_cursor_get(cursor, &db_key, NULL, MDB_SET);
if (ret != 0) {
mdb_cursor_close(cursor);
if (ret == MDB_NOTFOUND) {
// Insert new item
ret = mdb_put(txn->txn, env->dbi, &db_key, &data, 0);
if (ret != 0) {
return KNOT_ERROR;
}
return KNOT_EOK;
} else {
return ret;
}
}
ret = mdb_cursor_put(cursor, &db_key, &data, MDB_CURRENT);
mdb_cursor_close(cursor);
if (ret != 0) {
return KNOT_ERROR;
}
return KNOT_EOK;
}
static int del(knot_txn_t *txn, knot_val_t *key)
{
struct lmdb_env *env = txn->db;
MDB_val db_key = { key->len, key->data };
MDB_val data = { 0, NULL };
int ret = mdb_del(txn->txn, env->dbi, &db_key, &data);
if (ret != 0) {
return KNOT_ERROR;
}
return KNOT_EOK;
}
static knot_iter_t *iter_begin(knot_txn_t *txn, unsigned flags)
{
struct lmdb_env *env = txn->db;
MDB_cursor *cursor = NULL;
int ret = mdb_cursor_open(txn->txn, env->dbi, &cursor);
if (ret != 0) {
return NULL;
}
ret = mdb_cursor_get(cursor, NULL, NULL, MDB_FIRST);
if (ret != 0) {
mdb_cursor_close(cursor);
return NULL;
}
return cursor;
}
static knot_iter_t *iter_next(knot_iter_t *iter)
{
MDB_cursor *cursor = iter;
int ret = mdb_cursor_get(cursor, NULL, NULL, MDB_NEXT);
if (ret != 0) {
mdb_cursor_close(cursor);
return NULL;
}
return cursor;
}
static int iter_key(knot_iter_t *iter, knot_val_t *key)
{
MDB_cursor *cursor = iter;
MDB_val mdb_key, mdb_val;
int ret = mdb_cursor_get(cursor, &mdb_key, &mdb_val, MDB_GET_CURRENT);
if (ret != 0) {
return KNOT_ERROR;
}
key->data = mdb_key.mv_data;
key->len = mdb_key.mv_size;
return KNOT_EOK;
}
static int iter_val(knot_iter_t *iter, knot_val_t *val)
{
MDB_cursor *cursor = iter;
MDB_val mdb_key, mdb_val;
int ret = mdb_cursor_get(cursor, &mdb_key, &mdb_val, MDB_GET_CURRENT);
if (ret != 0) {
return KNOT_ERROR;
}
val->data = mdb_val.mv_data;
val->len = mdb_val.mv_size;
return KNOT_EOK;
}
static void iter_finish(knot_iter_t *iter)
{
if (iter == NULL) {
return;
}
MDB_cursor *cursor = iter;
mdb_cursor_close(cursor);
}
struct namedb_api *namedb_lmdb_api(void)
{
static struct namedb_api api = {
"lmdb",
init, deinit,
txn_begin, txn_commit, txn_abort,
count, find, insert, del,
iter_begin, iter_next, iter_key, iter_val, iter_finish
};
return &api;
}
#else
#include <stdlib.h>
struct namedb_api *namedb_lmdb_api(void)
{
return NULL;
}
#endif
/* Copyright (C) 2014 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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/namedb/namedb.h"
struct namedb_api *namedb_lmdb_api(void);