summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy40
-rw-r--r--.gitattributes2
-rw-r--r--.github/workflows/macOS.yaml52
-rw-r--r--.gitignore83
-rw-r--r--.gitlab-ci.yml860
-rw-r--r--.gitmodules9
-rw-r--r--NEWS13
-rw-r--r--ci/images/README.md49
-rwxr-xr-xci/images/build.sh23
-rw-r--r--ci/images/debian-11-coverity/Dockerfile43
-rw-r--r--ci/images/debian-11/Dockerfile146
-rw-r--r--ci/images/debian-buster/Dockerfile146
-rwxr-xr-xci/images/push.sh8
-rwxr-xr-xci/images/update.sh22
-rwxr-xr-xci/images/vars.sh13
-rw-r--r--ci/pkgtest.yaml3
-rw-r--r--contrib/dynarray.h112
-rw-r--r--contrib/dynarray.spdx10
-rw-r--r--daemon/bindings/net.c12
-rw-r--r--daemon/engine.c7
-rw-r--r--daemon/io.c39
-rw-r--r--daemon/main.c6
-rw-r--r--daemon/meson.build1
-rw-r--r--daemon/proxyv2.c3
-rw-r--r--daemon/session.c2
-rw-r--r--daemon/tls.c6
-rw-r--r--daemon/tls.h2
-rw-r--r--daemon/tls_ephemeral_credentials.c20
-rw-r--r--daemon/tls_session_ticket-srv.c2
-rw-r--r--daemon/udp_queue.c6
-rw-r--r--daemon/worker.c2
-rw-r--r--daemon/zimport.c6
-rw-r--r--lib/cache/api.c2
-rw-r--r--lib/cache/peek.c3
-rw-r--r--lib/dnssec.c2
-rw-r--r--lib/dnssec/nsec.c20
-rw-r--r--lib/dnssec/nsec3.c12
-rw-r--r--lib/dnssec/signature.c2
-rw-r--r--lib/dnssec/ta.c13
-rw-r--r--lib/generic/array.h14
-rw-r--r--lib/generic/lru.h5
-rw-r--r--lib/generic/queue.c10
-rw-r--r--lib/generic/queue.h6
-rw-r--r--lib/generic/trie.c4
-rw-r--r--lib/layer/iterate.c7
-rw-r--r--lib/layer/validate.c2
-rw-r--r--lib/log.c2
-rw-r--r--lib/resolve.c22
-rw-r--r--lib/selection.c2
-rw-r--r--lib/utils.c7
-rw-r--r--lib/utils.h6
-rw-r--r--lib/zonecut.c2
-rw-r--r--meson.build16
-rw-r--r--meson_options.txt12
-rw-r--r--modules/bogus_log/meson.build2
-rw-r--r--modules/dnstap/dnstap.c1
-rw-r--r--modules/dnstap/meson.build3
-rw-r--r--modules/edns_keepalive/meson.build2
-rw-r--r--modules/extended_error/meson.build4
-rw-r--r--modules/hints/hints.c21
-rw-r--r--modules/hints/meson.build7
-rw-r--r--modules/http/meson.build4
-rw-r--r--modules/meson.build7
-rw-r--r--modules/nsid/meson.build5
-rw-r--r--modules/policy/lua-aho-corasick/.gitignore6
-rw-r--r--modules/refuse_nord/meson.build2
-rw-r--r--modules/stats/README.rst2
-rw-r--r--modules/stats/meson.build4
-rw-r--r--modules/stats/stats.c96
-rw-r--r--tests/config/meson.build4
-rw-r--r--tests/dnstap/src/dnstap-test/go.mod2
-rw-r--r--tests/dnstap/src/dnstap-test/go.sum44
-rwxr-xr-xtests/dnstap/src/dnstap-test/run.sh17
-rw-r--r--tests/integration/deckard/.gitignore20
-rw-r--r--tests/integration/deckard/.gitlab-ci.yml130
-rw-r--r--tests/integration/deckard/.gitmodules3
-rw-r--r--tests/pytests/conftest.py2
-rw-r--r--tests/pytests/test_tls.py47
-rw-r--r--tests/pytests/utils.py19
-rw-r--r--tests/unit/meson.build7
-rw-r--r--utils/cache_gc/categories.c2
-rw-r--r--utils/cache_gc/db.c6
-rw-r--r--utils/cache_gc/kr_cache_gc.c77
-rw-r--r--utils/cache_gc/main.c26
-rw-r--r--utils/cache_gc/meson.build3
-rw-r--r--utils/client/.clang-tidy2
-rw-r--r--utils/client/meson.build1
87 files changed, 1585 insertions, 912 deletions
diff --git a/.clang-tidy b/.clang-tidy
index b496044..ecc9a62 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -1,6 +1,42 @@
---
-Checks: 'bugprone-*,cert-*,-cert-dcl03-c,-clang-analyzer-unix.Malloc,-clang-analyzer-deadcode.DeadStores,-clang-analyzer-valist.Uninitialized,readability-*,-readability-braces-*,-readability-else-after-return,-readability-redundant-declaration,-readability-non-const-parameter,google-readability-casting,misc-*,-misc-static-assert,-misc-macro-parentheses,-misc-unused-parameters'
-WarningsAsErrors: 'cert-*,misc-*,readability-*,clang-analyzer-*,-readability-non-const-parameter'
+Checks:
+ - bugprone-*
+ - cert-*
+ - google-readability-casting
+ - misc-*
+ - readability-*
+
+ - -bugprone-assignment-in-if-condition # we explicitly put assignments into parentheses so they are very visible
+ - -bugprone-branch-clone
+ - -bugprone-easily-swappable-parameters
+ - -bugprone-inc-dec-in-conditions
+ - -bugprone-multi-level-implicit-pointer-conversion
+ - -bugprone-narrowing-conversions
+ - -bugprone-sizeof-expression # may be useful, but it's utterly broken
+ - -bugprone-suspicious-string-compare
+ - -cert-dcl03-c
+ - -clang-analyzer-deadcode.DeadStores
+ - -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
+ - -clang-analyzer-unix.Malloc
+ - -clang-analyzer-valist.Uninitialized
+ - -clang-analyzer-optin.core.EnumCastOutOfRange # libknot uses enums as flags
+ - -misc-include-cleaner
+ - -misc-macro-parentheses
+ - -misc-no-recursion
+ - -misc-static-assert
+ - -misc-unused-parameters
+ - -readability-avoid-nested-conditional-operator
+ - -readability-avoid-unconditional-preprocessor-if
+ - -readability-braces-*
+ - -readability-cognitive-complexity
+ - -readability-else-after-return
+ - -readability-function-cognitive-complexity
+ - -readability-identifier-length
+ - -readability-isolate-declaration
+ - -readability-magic-numbers
+ - -readability-non-const-parameter
+ - -readability-redundant-declaration
+WarningsAsErrors: 'cert-*,clang-analyzer-*,misc-*,readability-*,-readability-non-const-parameter'
HeaderFilterRegex: 'contrib/ucw/*.h'
CheckOptions:
- key: readability-identifier-naming
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..1da6af4
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,2 @@
+*.c diff=cpp
+*.cpp diff=cpp
diff --git a/.github/workflows/macOS.yaml b/.github/workflows/macOS.yaml
new file mode 100644
index 0000000..f7fe090
--- /dev/null
+++ b/.github/workflows/macOS.yaml
@@ -0,0 +1,52 @@
+name: macOS
+
+on: push
+
+jobs:
+ build-test:
+ name: Build & unit tests & sanity check
+ runs-on: macOS-latest
+ strategy:
+ matrix:
+ knot-version: ['3.2', '3.3']
+
+ steps:
+ - name: Checkout resolver code
+ uses: actions/checkout@v2
+ with:
+ submodules: true
+
+ - name: Install dependecies from brew
+ run:
+ brew install cmocka luajit libuv lmdb meson nghttp2 autoconf automake m4 libtool pkg-config
+
+ - name: Install libknot from sources
+ env:
+ KNOT_DNS_VERSION: ${{ matrix.knot-version }}
+ run: |
+ git clone -b ${KNOT_DNS_VERSION} https://gitlab.nic.cz/knot/knot-dns.git
+ cd knot-dns
+ autoreconf -fi
+ ./configure --prefix=${HOME}/.local/usr --disable-static --disable-fastparser --disable-documentation --disable-daemon --disable-utilities --with-lmdb=no
+ make -j2 install
+ cd ..
+
+ - name: Build resolver
+ run: |
+ export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${HOME}/.local/usr/lib/pkgconfig"
+ meson build_darwin --default-library=static --buildtype=debugoptimized --prefix=${HOME}/.local/usr -Dc_args='-fno-omit-frame-pointer'
+ ninja -C build_darwin -v install
+
+ - name: Run unit tests
+ env:
+ MALLOC_CHECK_: 3
+ MALLOC_PERTURB_: 223
+ run: meson test -C build_darwin --suite unit
+
+ - name: Run kresd
+ env:
+ MALLOC_CHECK_: 3
+ MALLOC_PERTURB_: 223
+ run: |
+ export DYLD_FALLBACK_LIBRARY_PATH="${DYLD_FALLBACK_LIBRARY_PATH}:${HOME}/.local/usr/lib/"
+ echo "quit()" | ${HOME}/.local/usr/sbin/kresd -a 127.0.0.1@53535 .
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..749bc07
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,83 @@
+*.6
+*.Plo
+*.a
+*.db
+*.dylib
+*.dylib.*
+*.gcda
+*.gcno
+*.gcov
+*.info
+*.la
+*.lo
+*.log
+*.mdb
+*.o
+*.out
+*.so
+*.so.*
+*.swp
+*~
+.deps
+.dirstamp
+.libs
+.pytest_cache
+/.build-depend
+/.cache
+/aclocal.m4
+/ar-lib
+/autom4te.cache/*
+/bench/bench_lru
+/build*
+/client/kresc
+/compile
+/compile_commands.json
+/config.guess
+/config.h
+/config.log
+/config.status
+/config.sub
+/configure
+/control
+/coverage
+/coverage.stats
+/daemon/kresd
+/daemon/lua/*.inc
+/daemon/lua/trust_anchors.lua
+/depcomp
+/distro/tests/*/.vagrant
+/doc/.doctrees
+/doc/doxyxml
+/doc/html
+/doc/kresd.8
+/doc/texinfo
+/ephemeral_key.pem
+/install-sh
+/libkres.pc
+/libtool
+/ltmain.sh
+/missing
+/modules/dnstap/dnstap.pb-c.d
+/pkg
+/self.crt
+/self.key
+/stamp-h1
+/tags
+/tests/dnstap/src/dnstap-test/go.sum
+/tests/pytests/*/tcproxy
+/tests/pytests/*/tlsproxy
+/tests/pytests/pytests.*.html
+/tests/pytests/*.junit.xml
+/tests/test_array
+/tests/test_lru
+/tests/test_map
+/tests/test_module
+/tests/test_pack
+/tests/test_set
+/tests/test_utils
+/tests/test_zonecut
+/ylwrap
+_obj
+kresd.amalg.c
+libkres.amalg.c
+luacov.*.out
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..61e0c92
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,860 @@
+# SPDX-License-Identifier: GPL-3.0-or-later
+# vim:foldmethod=marker
+variables:
+ DEBIAN_FRONTEND: noninteractive
+ LC_ALL: C.UTF-8
+ GIT_SUBMODULE_STRATEGY: recursive
+ GIT_STRATEGY: clone # sometimes unclean submodule dirs otherwise
+ RESPDIFF_PRIORITY: 5
+ DISTROTEST_PRIORITY: 6
+ RESPDIFF_COUNT: 1
+ RESPDIFF_FORCE: 0
+ RESPERF_FORCE: 0
+ KNOT_VERSION: '3.1'
+ LIBKRES_ABI: 9
+ LIBKRES_NAME: libkres
+ MESON_TEST: meson test -C build_ci* -t 4 --print-errorlogs
+ PREFIX: $CI_PROJECT_DIR/.local
+ EMAIL: 'ci@nic'
+
+ # IMAGE_TAG is a Git branch/tag name from https://gitlab.nic.cz/knot/knot-resolver-ci
+ # In general, keep it pointing to a tag - use a branch only for development.
+ # More info in the knot-resolver-ci repository.
+ IMAGE_TAG: 'v20240506'
+ IMAGE_PREFIX: '$CI_REGISTRY/knot/knot-resolver-ci'
+
+image: $IMAGE_PREFIX/debian12-knot_3_3:$IMAGE_TAG
+default:
+ interruptible: true
+ tags:
+ - docker
+ - linux
+ - amd64
+
+stages:
+ - build
+ - sanity
+ - test
+ - respdiff
+ - deploy
+ - pkgtest
+
+ # https://docs.gitlab.com/ce/ci/jobs/job_control.html#select-different-runner-tags-for-each-parallel-matrix-job
+.multi_platform: &multi_platform
+ parallel:
+ matrix:
+ - PLATFORM: [ amd64, arm64 ]
+ tags: # some will override this part
+ - ${PLATFORM}
+ - docker
+ - linux
+
+.common: &common
+ except:
+ refs:
+ - master@knot/knot-resolver
+ - master@knot/security/knot-resolver
+ - tags
+ variables:
+ - $SKIP_CI == "1"
+ tags:
+ - docker
+ - linux
+ - amd64
+ # Tests which decided to skip themselves get orange non-failure.
+ allow_failure:
+ exit_codes:
+ - 77
+
+.after_build: &after_build
+ <<: *common
+ needs:
+ - build-stable
+ before_script:
+ # meson detects changes and performs useless rebuild; hide the log
+ - ninja -C build_ci* &>/dev/null
+ - rm build_ci*/meson-logs/testlog*.txt # start with clean testlog
+ artifacts:
+ when: always
+ # The deckard-specific parts are a little messy, but they're hard to separate in YAML.
+ paths:
+ - build_ci*/meson-logs/testlog*.txt
+ - tmpdeckard*
+ - build_ci*/meson-logs/integration.deckard.junit.xml
+ reports:
+ junit: build_ci*/meson-logs/integration.deckard.junit.xml
+
+.nodep: &nodep
+ <<: *common
+ needs: []
+
+# build {{{
+.build: &build
+ <<: *common
+ stage: build
+ artifacts:
+ when: always
+ paths:
+ - .local
+ - build_ci*
+ - pkg
+ reports:
+ junit: build_ci*/meson-logs/testlog.junit.xml
+ before_script:
+ - "echo \"PATH: $PATH\""
+ - "echo \"Using Python at: $(which python)\""
+ after_script:
+ - ci/fix-meson-junit.sh build_ci*/meson-logs/testlog.junit.xml
+
+archive:
+ <<: *build
+ except: null
+ script:
+ - apkg make-archive
+
+build-stable:
+ <<: *build
+ script:
+ - meson build_ci_stable --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled
+ - ninja -C build_ci_stable
+ - ninja -C build_ci_stable install >/dev/null
+ - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake
+
+build-deb11-knot31:
+ <<: *build
+ image: $IMAGE_PREFIX/debian11-knot_3_1:$IMAGE_TAG
+ script:
+ - meson build_ci_deb11_knot31 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled
+ - ninja -C build_ci_deb11_knot31
+ - ninja -C build_ci_deb11_knot31 install >/dev/null
+ - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake
+
+build-deb11-knot32:
+ <<: *build
+ image: $IMAGE_PREFIX/debian11-knot_3_2:$IMAGE_TAG
+ script:
+ - meson build_ci_deb11_knot32 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled
+ - ninja -C build_ci_deb11_knot32
+ - ninja -C build_ci_deb11_knot32 install >/dev/null
+ - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake
+
+build-deb12-knot32:
+ <<: *build
+ image: $IMAGE_PREFIX/debian12-knot_3_2:$IMAGE_TAG
+ script:
+ - meson build_ci_deb12_knot32 --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled
+ - ninja -C build_ci_deb12_knot32
+ - ninja -C build_ci_deb12_knot32 install >/dev/null
+ - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake
+
+build-deb12-knot-master:
+ <<: *build
+ image: $IMAGE_PREFIX/debian12-knot_master:$IMAGE_TAG
+ script:
+ - meson build_ci_deb12_knot_master --prefix=$PREFIX -Dmalloc=disabled -Dwerror=true -Dextra_tests=enabled
+ - ninja -C build_ci_deb12_knot_master
+ - ninja -C build_ci_deb12_knot_master install >/dev/null
+ - ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite snowflake
+ allow_failure: true
+
+build-stable-asan-gcc:
+ <<: *build
+ script:
+ - CFLAGS=-fno-sanitize-recover=all meson build_ci_asan_gcc --prefix=$PREFIX -Dmalloc=jemalloc -Db_sanitize=address,undefined -Dextra_tests=enabled
+ - ninja -C build_ci_asan_gcc
+ - ninja -C build_ci_asan_gcc install >/dev/null
+ - MESON_TESTTHREADS=1 ${MESON_TEST} --suite unit --suite dnstap --no-suite skip_asan --no-suite snowflake
+ - MESON_TESTTHREADS=1 ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite config --no-suite skip_asan --no-suite snowflake
+
+
+# TODO: Clang sanitizer seems to be broken in the current version of Debian. Use
+# GCC above and maybe re-enable the Clang one once we update at some point.
+
+#build-stable-asan-clang:
+# <<: *build
+# script:
+# # issues with UBSan and ASan in CI:
+# # - `ahocorasick.so` causes C++ problems
+# # - `--default-library=shared` causes link problems
+# - CC=clang CXX=clang++ CFLAGS=-fno-sanitize-recover=all CXXFLAGS=-fno-sanitize=undefined meson build_ci_asan_clang --default-library=static --prefix=$PREFIX -Dmalloc=jemalloc -Db_sanitize=address,undefined -Dextra_tests=enabled
+# - ninja -C build_ci_asan_clang
+# - ninja -C build_ci_asan_clang install >/dev/null
+# # TODO _leaks: not sure what exactly is wrong in leak detection on config tests
+# # TODO skip_asan: all three of these disappear locally when using gcc 9.1 (except some leaks)
+# - MESON_TESTTHREADS=1 ASAN_OPTIONS=detect_leaks=0 ${MESON_TEST} --suite unit --suite config --suite dnstap --no-suite skip_asan --no-suite snowflake
+
+build:macOS:
+ <<: *nodep
+ image: python:3-alpine
+ only:
+ refs:
+ - branches@knot/knot-resolver
+ stage: build
+ when: delayed
+ start_in: 3 minutes # allow some time for mirroring, job creation
+ script:
+ - pip3 install -U requests
+ - python3 ./ci/gh_actions.py ${CI_COMMIT_REF_NAME} ${CI_COMMIT_SHA}
+
+docker:
+ <<: *nodep
+ stage: build
+ image: docker:latest
+ <<: *multi_platform
+ only:
+ refs:
+ - branches@knot/knot-resolver
+ tags:
+ - ${PLATFORM}
+ - dind
+ variables:
+ DOCKER_IMAGE_NAME: knot-resolver-test:${CI_COMMIT_SHA}
+ script:
+ - docker build --no-cache -t ${DOCKER_IMAGE_NAME} .
+ - echo "quit()" | docker run -i ${DOCKER_IMAGE_NAME}
+ after_script: # remove dangling images to avoid running out of disk space
+ - docker rmi ${DOCKER_IMAGE_NAME}
+ - docker rmi $(docker images -f "dangling=true" -q)
+# }}}
+
+# sanity {{{
+.sanity: &sanity
+ <<: *nodep
+ stage: sanity
+
+authors:
+ <<: *sanity
+ only:
+ refs:
+ - /^release.*$/
+ script:
+ - LC_ALL=en_US.UTF-8 scripts/update-authors.sh
+
+news:
+ <<: *sanity
+ only:
+ refs:
+ - /^release.*$/
+ script:
+ - head -n 1 NEWS | grep -q $(date +%Y-%m-%d)
+
+trivial_checks: # aggregated to save some processing
+ <<: *sanity
+ script:
+ - ci/no_assert_check.sh
+ - ci/deckard_commit_check.sh
+
+lint:other:
+ <<: *sanity
+ script:
+ - meson build_ci_lint &>/dev/null
+ - ninja -C build_ci* pylint
+ - ninja -C build_ci* flake8
+ - ninja -C build_ci* luacheck
+
+lint:pedantic:
+ <<: *after_build
+ stage: sanity
+ script:
+ - meson build_pedantic_gcc -Dwerror=true -Dc_args='-Wpedantic' -Dextra_tests=enabled
+ - ninja -C build_pedantic_gcc
+ - >
+ CC=clang CXX=clang++ meson build_pedantic_clang -Dwerror=true -Dextra_tests=enabled -Dc_args='
+ -Wpedantic -Wno-newline-eof -Wno-gnu-zero-variadic-macro-arguments -Wno-gnu-folding-constant'
+ - ninja -C build_pedantic_clang
+
+lint:tidy:
+ <<: *after_build
+ stage: sanity
+ script:
+ - ninja -C build_ci* tidy
+
+# Coverity reference: https://www.synopsys.com/blogs/software-security/integrating-coverity-scan-with-gitlab-ci/
+lint:coverity:
+ <<: *sanity
+ image: $IMAGE_PREFIX/coverity:$IMAGE_TAG
+ only:
+ refs:
+ - nightly@knot/knot-resolver
+ - coverity@knot/knot-resolver
+ script:
+ - meson build_ci_cov --prefix=$PREFIX
+ - /opt/cov-analysis/bin/cov-build --dir cov-int ninja -C build_ci_cov
+ - tar cfz cov-int.tar.gz cov-int
+ - curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME
+ --form token=$COVERITY_SCAN_TOKEN --form email="knot-resolver@labs.nic.cz"
+ --form file=@cov-int.tar.gz --form version="`git describe --tags`"
+ --form description="`git describe --tags` / $CI_COMMIT_TITLE / $CI_COMMIT_REF_NAME:$CI_PIPELINE_ID"
+ --fail-with-body
+
+.kres-gen: &kres-gen
+ <<: *sanity
+ script:
+ - meson build_ci_lib --prefix=$PREFIX -Dkres_gen_test=false
+ - ninja -C build_ci_lib daemon/kresd
+ - ninja -C build_ci_lib kres-gen
+ - git diff --quiet || (git diff; exit 1)
+kres-gen-31:
+ <<: *kres-gen
+ image: $IMAGE_PREFIX/debian11-knot_3_1:$IMAGE_TAG
+kres-gen-32:
+ <<: *kres-gen
+ image: $IMAGE_PREFIX/debian12-knot_3_2:$IMAGE_TAG
+
+root.hints:
+ <<: *sanity
+ only:
+ refs:
+ - /^release.*$/
+ script:
+ - scripts/update-root-hints.sh
+
+ci-image-is-tag:
+ <<: *sanity
+ image: alpine:3
+ variables:
+ GIT_STRATEGY: none
+ script:
+ - apk add git
+ - (
+ git ls-remote --tags --exit-code
+ https://gitlab.nic.cz/knot/knot-resolver-ci.git
+ refs/tags/$IMAGE_TAG
+ && echo "Everything is OK!"
+ )
+ || (echo "'$IMAGE_TAG' is not a tag (probably a branch). Make sure to set it to a tag in production!"; exit 2)
+# }}}
+
+# test {{{
+.test_flaky: &test_flaky
+ <<: *after_build
+ stage: test
+ retry:
+ max: 1
+ when:
+ - script_failure
+
+deckard:
+ <<: *test_flaky
+ # Deckard won't work with jemalloc due to a faketime bug:
+ # https://github.com/wolfcw/libfaketime/issues/130
+ only: # trigger job only in repos under our control (privileged runner required)
+ - branches@knot/knot-resolver
+ - branches@knot/security/knot-resolver
+ tags:
+ - privileged
+ - amd64
+ variables:
+ TMPDIR: $CI_PROJECT_DIR
+ script:
+ - ${MESON_TEST} --suite integration
+
+respdiff:basic:
+ <<: *after_build
+ stage: test
+ needs:
+ - build-stable-asan-gcc
+ script:
+ - ulimit -n "$(ulimit -Hn)" # applies only for kresd ATM
+ - ./ci/respdiff/start-resolvers.sh
+ - ./ci/respdiff/run-respdiff-tests.sh udp
+ - $PREFIX/sbin/kres-cache-gc -c . -u 0 # simple GC sanity check
+ - cat results/respdiff.txt
+ - echo 'test if mismatch rate < 1.0 %'
+ - grep -q '^target disagrees.*0\.[0-9][0-9] %' results/respdiff.txt
+ after_script:
+ - killall --wait kresd
+ artifacts:
+ when: always
+ paths:
+ - kresd.log*
+ - results/*.txt
+ - results/*.png
+ - results/respdiff.db/data.mdb*
+ - ./*.info
+
+test:valgrind:
+ <<: *test_flaky
+ script:
+ - ${MESON_TEST} --suite unit --suite config --no-suite snowflake --wrap="valgrind --leak-check=full --trace-children=yes --quiet --suppressions=/lj.supp"
+ - MESON_TESTTHREADS=1 ${MESON_TEST} --wrap="valgrind --leak-check=full --trace-children=yes --quiet --suppressions=/lj.supp" --suite snowflake
+
+pkgtest:
+ stage: test
+ trigger:
+ include: ci/pkgtest.yaml
+ strategy: depend
+ needs:
+ - build-stable
+ variables: # https://gitlab.nic.cz/help/ci/yaml/README.md#artifact-downloads-to-child-pipelines
+ PARENT_PIPELINE_ID: $CI_PIPELINE_ID
+ except:
+ refs:
+ - master@knot/knot-resolver
+ - master@knot/security/knot-resolver
+ - tags
+ variables:
+ - $SKIP_CI == "1"
+
+pytests:
+ <<: *test_flaky
+ needs:
+ - build-stable-asan-gcc
+ artifacts:
+ when: always
+ paths:
+ - build_ci*/meson-logs/testlog*.txt
+ - tests/pytests/*.html
+ - tests/pytests/*.junit.xml
+ reports: # Can't have multiple junit XMLs?
+ junit: tests/pytests/pytests.parallel.junit.xml
+ script:
+ - ${MESON_TEST} --suite pytests
+# }}}
+
+# respdiff {{{
+.condor: &condor
+ <<: *common
+ tags:
+ - condor
+ needs: []
+ only: # trigger job only in repos under our control
+ - branches@knot/knot-resolver
+ - branches@knot/security/knot-resolver
+ # The set of respdiff+resperf jobs takes over two hours to execute.
+ when: manual
+
+.respdiff: &respdiff
+ <<: *condor
+ stage: respdiff
+ script:
+ - git diff-index --name-only origin/master | grep -qEv '^(AUTHORS|ci/|config.mk|COPYING|distro/|doc/|etc/|NEWS|README.md|scripts/|tests/|\.gitignore|\.gitlab-ci\.yml|\.travis\.yml)' || test $RESPDIFF_FORCE -gt 0 || exit 77
+ - test ! -f /var/tmp/respdiff-jobs/buffer/buffer_$RESPDIFF_TEST_stats.json || test $RESPDIFF_FORCE -gt 0 || ( echo "Reference unstable, try again in ~3h or use RESPDIFF_FORCE=1."; exit 1 )
+ - export LABEL=gl$(date +%s)
+ - export COMMITDIR="/var/tmp/respdiff-jobs/$(git rev-parse --short HEAD)-$LABEL"
+ - export TESTDIR="$COMMITDIR/$RESPDIFF_TEST"
+ - ln -s $COMMITDIR respdiff_commitdir
+ - >
+ sudo -u respdiff /var/opt/respdiff/contrib/job_manager/submit.py -w
+ -p $RESPDIFF_PRIORITY
+ -c $RESPDIFF_COUNT
+ $(sudo -u respdiff /var/opt/respdiff/contrib/job_manager/create.py
+ "$(git rev-parse --short HEAD)" -l $LABEL -t $RESPDIFF_TEST --knot-branch=$KNOT_VERSION
+ --respdiff-stats /var/tmp/respdiff-jobs/ref_current/*_${RESPDIFF_TEST}_stats.json)
+ - for f in $TESTDIR/*.json; do test -s "$f" || (cat $TESTDIR/*stderr*; cat $TESTDIR/j*_docker.txt; exit 1); done
+ - sudo -u respdiff /var/opt/respdiff/contrib/job_manager/plot_ref.sh $TESTDIR/.. /var/tmp/respdiff-jobs/ref_current $RESPDIFF_TEST
+ after_script:
+ - 'cp -t . respdiff_commitdir/$RESPDIFF_TEST/j* ||:'
+ - 'cp -t . respdiff_commitdir/*$RESPDIFF_TEST*.png ||:'
+ - 'cat respdiff_commitdir/$RESPDIFF_TEST/*histogram.tar.gz | tar -xf - -i ||:'
+ artifacts:
+ when: always
+ expire_in: 1 week
+ paths:
+ - ./j*
+ - ./*.png
+ - ./*histogram/*
+
+fwd-tls6-kresd.udp6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.fwd-tls6-kresd.udp6
+
+fwd-udp6-kresd.udp6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.fwd-udp6-kresd.udp6
+
+iter.udp6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.iter.udp6
+
+iter.tls6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.iter.tls6
+
+fwd-udp6-unbound.udp6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.fwd-udp6-unbound.udp6
+
+fwd-udp6-unbound.tcp6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.fwd-udp6-unbound.tcp6
+
+fwd-udp6-unbound.tls6:
+ <<: *respdiff
+ variables:
+ RESPDIFF_TEST: shortlist.fwd-udp6-unbound.tls6
+
+.resperf: &resperf
+ <<: *condor
+ stage: respdiff
+ script:
+ - git diff-index --name-only origin/master | grep -qEv '^(AUTHORS|ci/|config.mk|COPYING|distro/|doc/|etc/|NEWS|README.md|scripts/|tests/|\.gitignore|\.gitlab-ci\.yml|\.travis\.yml)' || test $RESPERF_FORCE -gt 0 || exit 77
+ - export LABEL=gl$(date +%s)
+ - export COMMITDIR="/var/tmp/respdiff-jobs/$(git rev-parse --short HEAD)-$LABEL"
+ - export TESTDIR="$COMMITDIR/$RESPERF_TEST"
+ - ln -s $COMMITDIR resperf_commitdir
+ - >
+ sudo -u respdiff /var/opt/respdiff/contrib/job_manager/submit.py -w
+ $(sudo -u respdiff /var/opt/respdiff/contrib/job_manager/create.py
+ "$(git rev-parse --short HEAD)" -l $LABEL --asan -t $RESPERF_TEST --knot-branch=$KNOT_VERSION)
+ - export EXITCODE=$(cat $TESTDIR/j*_exitcode)
+ - if [[ "$EXITCODE" == "0" ]]; then cat $TESTDIR/j*_resperf.txt; else cat $TESTDIR/j*_docker.txt; fi
+ - exit $EXITCODE
+ after_script:
+ - 'cp -t . resperf_commitdir/$RESPERF_TEST/j* ||:'
+ artifacts:
+ when: always
+ expire_in: 1 week
+ paths:
+ - ./j*
+
+rp:fwd-tls6.udp-asan:
+ <<: *resperf
+ variables:
+ RESPERF_TEST: resperf.fwd-tls6.udp
+
+rp:fwd-udp6.udp-asan:
+ <<: *resperf
+ variables:
+ RESPERF_TEST: resperf.fwd-udp6.udp
+
+rp:iter.udp-asan:
+ <<: *resperf
+ variables:
+ RESPERF_TEST: resperf.iter.udp
+# }}}
+
+# deploy {{{
+# copy snapshot of current master to nightly branch for further processing
+# (this is workaround for missing complex conditions for job limits in Gitlab)
+nightly:copy:
+ stage: deploy
+ needs: []
+ only:
+ variables:
+ - $CREATE_NIGHTLY == "1"
+ refs:
+ - master@knot/knot-resolver
+ script:
+ - 'tmp_file=$(mktemp)'
+ # delete nightly branch
+ - 'STATUS=$(curl --request PUT --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" -s -o ${tmp_file} -w "%{http_code}" "https://gitlab.nic.cz/api/v4/projects/147/repository/branches/nightly/unprotect")'
+ - '[ "x${STATUS}" == "x200" ] || { cat ${tmp_file}; rm ${tmp_file}; exit 1; }'
+ # no output from DELETE command
+ - 'STATUS=$(curl --request DELETE --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" -s -o ${tmp_file} -w "%{http_code}" "https://gitlab.nic.cz/api/v4/projects/147/repository/branches/nightly")'
+ # recreate nightly branch from current master
+ - 'STATUS=$(curl --request POST --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" -s -o ${tmp_file} -w "%{http_code}" "https://gitlab.nic.cz/api/v4/projects/147/repository/branches?branch=nightly&ref=master")'
+ - '[ "x${STATUS}" == "x201" ] || { cat ${tmp_file}; rm ${tmp_file}; exit 1; }'
+ - 'STATUS=$(curl --request PUT --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" -s -o ${tmp_file} -w "%{http_code}" "https://gitlab.nic.cz/api/v4/projects/147/repository/branches/nightly/protect")'
+ - '[ "x${STATUS}" == "x200" ] || { cat ${tmp_file}; rm ${tmp_file}; exit 1; }'
+ - 'rm ${tmp_file}'
+
+obs:trigger: &obs_trigger
+ stage: deploy
+ only:
+ variables:
+ - $OBS_REPO
+ dependencies: # wait for previous stages to finish
+ - archive
+ environment:
+ name: OBS/$OBS_REPO
+ url: https://build.opensuse.org/package/show/home:CZ-NIC:$OBS_REPO/knot-resolver
+ tags:
+ - condor
+ allow_failure: false # required to make when: manual action blocking
+ script:
+ - python3 -m venv ./venv
+ - source ./venv/bin/activate
+ - pip install --upgrade pip
+ - pip install apkg
+ - scripts/make-obs.sh
+ - echo y | scripts/build-in-obs.sh $OBS_REPO
+
+obs:release:
+ <<: *obs_trigger
+ only:
+ - tags
+ variables:
+ OBS_REPO: knot-resolver-latest
+ when: manual
+
+obs:odvr:
+ <<: *obs_trigger
+ stage: pkgtest # last stage to ensure it doesn't block anything
+ only:
+ - tags
+ variables:
+ OBS_REPO: knot-resolver-odvr
+ when: manual
+# }}}
+
+# pkgtest {{{
+.deploytest: &deploytest
+ stage: pkgtest
+ only:
+ variables:
+ - $OBS_REPO =~ /^knot-resolver-devel|knot-dns-devel|knot-resolver-testing$/
+ - $CI_COMMIT_TAG
+ dependencies: [] # wait for previous stages to finish
+ variables:
+ OBS_REPO: knot-resolver-latest
+ when: delayed
+ start_in: 3 minutes # give OBS build some time
+ tags:
+ - condor
+
+obs:build:all:
+ <<: *deploytest
+ only:
+ variables:
+ - $OBS_REPO =~ /^knot-resolver-devel|knot-dns-devel|knot-resolver-testing|knot-resolver-odvr$/
+ - $CI_COMMIT_TAG
+ allow_failure: true
+ script:
+ - "osc results home:CZ-NIC:$OBS_REPO knot-resolver -w"
+ - version=$(sed 's/^v//' <(git describe --exact-match HEAD || git rev-parse --short HEAD) )
+ - > # check version only for one (reliable) repo to avoid false negatives
+ ! osc ls -b home:CZ-NIC:$OBS_REPO knot-resolver Debian_9.0 x86_64 | \
+ grep -E '(rpm|deb|tar\.xz)$' | grep -v $version || \
+ (echo "ERROR: version mismatch"; exit 1)
+ - >
+ ! osc results home:CZ-NIC:$OBS_REPO knot-resolver --csv | \
+ grep -Ev 'disabled|excluded|Rawhide|CentOS_8_EPEL' | grep -v 'succeeded' -q || \
+ (echo "ERROR: build(s) failed"; exit 1)
+
+.distrotest: &distrotest
+ <<: *deploytest
+ # Description of the distrotest script workflow:
+ # 1. wait for OBS package build to complete
+ # 2. check the OBS build suceeded
+ # 3. set up some variables, dir names etc.
+ # 4. create a symlink with predictable name to export artifacts afterwards
+ # 5. create an HTCondor job and submit it to a HTCondor cluster
+ # 6. check exit code from condor, optionally display one of the logs and end the job with same exit code
+ script:
+ - "osc results home:CZ-NIC:$OBS_REPO knot-resolver -a x86_64 -r $DISTROTEST_REPO -w"
+ - >
+ osc results home:CZ-NIC:$OBS_REPO knot-resolver -a x86_64 -r $DISTROTEST_REPO --csv | grep 'succeeded|$' -q || \
+ (echo "ERROR: build failed"; exit 1)
+ - export LABEL="gl$(date +%s)_$OBS_REPO"
+ - export COMMITDIR="/var/tmp/respdiff-jobs/$(git rev-parse --short HEAD)-$LABEL"
+ - export TESTDIR="$COMMITDIR/distrotest.$DISTROTEST_NAME"
+ - ln -s $COMMITDIR distrotest_commitdir
+ - sudo -u respdiff /var/opt/respdiff/contrib/job_manager/submit.py -w
+ -p $DISTROTEST_PRIORITY
+ $(sudo -u respdiff /var/opt/respdiff/contrib/job_manager/create.py
+ "$(git rev-parse --short HEAD)" -l $LABEL -t distrotest.$DISTROTEST_NAME
+ --obs-repo $OBS_REPO)
+ - export EXITCODE=$(cat $TESTDIR/j*_exitcode)
+ - if [[ "$EXITCODE" != "0" ]]; then cat $TESTDIR/j*_{vagrant.log.txt,stdout.txt}; fi
+ - exit $EXITCODE
+ after_script:
+ - 'cp -t . distrotest_commitdir/distrotest.$DISTROTEST_NAME/j* ||:'
+ artifacts:
+ when: always
+ expire_in: 1 week
+ paths:
+ - ./j*
+ retry:
+ max: 1
+ when:
+ - script_failure
+
+obs:rocky8:x86_64:
+ <<: *distrotest
+ allow_failure: true
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: rocky8
+ DISTROTEST_REPO: CentOS_8_EPEL
+
+obs:debian10:x86_64:
+ <<: *distrotest
+ only:
+ variables:
+ - $OBS_REPO =~ /^knot-resolver-devel|knot-dns-devel|knot-resolver-testing|knot-resolver-odvr$/
+ - $CI_COMMIT_TAG
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: debian10
+ DISTROTEST_REPO: Debian_10
+
+obs:debian11:x86_64:
+ <<: *distrotest
+ only:
+ variables:
+ - $OBS_REPO =~ /^knot-resolver-devel|knot-dns-devel|knot-resolver-testing|knot-resolver-odvr$/
+ - $CI_COMMIT_TAG
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: debian11
+ DISTROTEST_REPO: Debian_11
+
+obs:fedora35:x86_64:
+ <<: *distrotest
+ allow_failure: true
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: fedora35
+ DISTROTEST_REPO: Fedora_35
+
+obs:fedora36:x86_64:
+ <<: *distrotest
+ allow_failure: true
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: fedora36
+ DISTROTEST_REPO: Fedora_36
+
+obs:leap15:x86_64:
+ <<: *distrotest
+ allow_failure: true
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: leap15
+ DISTROTEST_REPO: openSUSE_Leap_15.4
+
+obs:ubuntu1804:x86_64:
+ <<: *distrotest
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: ubuntu1804
+ DISTROTEST_REPO: xUbuntu_18.04
+
+obs:ubuntu2004:x86_64:
+ <<: *distrotest
+ only:
+ variables:
+ - $OBS_REPO =~ /^knot-resolver-devel|knot-dns-devel|knot-resolver-testing|knot-resolver-odvr$/
+ - $CI_COMMIT_TAG
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: ubuntu2004
+ DISTROTEST_REPO: xUbuntu_20.04
+
+obs:ubuntu2204:x86_64:
+ <<: *distrotest
+ allow_failure: true
+ variables:
+ OBS_REPO: knot-resolver-latest
+ DISTROTEST_NAME: ubuntu2204
+ DISTROTEST_REPO: xUbuntu_22.04
+
+.packagingtest: &packagingtest
+ stage: pkgtest
+ only:
+ refs:
+ - nightly@knot/knot-resolver
+ needs: []
+ tags:
+ - dind
+ - amd64
+ variables:
+ DISTRO: debian_10
+ script:
+ - pytest -r fEsxX tests/packaging -k $DISTRO
+
+packaging:centos_8:
+ <<: *packagingtest
+ variables:
+ DISTRO: centos_8
+
+packaging:centos_7:
+ <<: *packagingtest
+ variables:
+ DISTRO: centos_7
+
+packaging:fedora_31:
+ <<: *packagingtest
+ variables:
+ DISTRO: fedora_31
+
+packaging:fedora_32:
+ <<: *packagingtest
+ variables:
+ DISTRO: fedora_32
+
+# }}}
+
+# docs: {{{
+
+docs:build:
+ stage: deploy
+ needs: []
+ script:
+ - git submodule update --init --recursive
+ - pip3 install -U -r doc/requirements.txt
+ - pip3 install -U sphinx_rtd_theme
+ - meson build_doc -Ddoc=enabled
+ - ninja -C build_doc doc
+ artifacts:
+ paths:
+ - doc/html
+
+# This job deploys the Knot Resolver documentation into a development
+# environment, which may be found at
+# <https://gitlab.nic.cz/knot/knot-resolver/-/environments/folders/docs-develop>.
+# The actual URL is found in the `environment.url` property, where
+# $CI_PROJECT_NAMESPACE will be "knot" on the upstream GitLab.
+docs:develop:
+ stage: deploy
+ needs:
+ - docs:build
+ except:
+ refs:
+ - tags
+ script:
+ - echo "Propagating artifacts into develop environment"
+ artifacts:
+ paths:
+ - doc/html
+ environment:
+ name: docs-develop/$CI_COMMIT_REF_NAME
+ url: https://$CI_PROJECT_NAMESPACE.pages.nic.cz/-/knot-resolver/-/jobs/$CI_JOB_ID/artifacts/doc/html/index.html
+
+# This job deploys the Knot Resolver documentation into a release environment,
+# which may be found at
+# <https://gitlab.nic.cz/knot/knot-resolver/-/environments/folders/docs-release>.
+# The actual URL is found in the `environment.url` property, where
+# $CI_PROJECT_NAMESPACE will be "knot" on the upstream GitLab.
+# The job requires the `DOCS_ENV_NAME` variable to be set by the user.
+docs:release:
+ stage: deploy
+ needs:
+ - docs:build
+ only:
+ refs:
+ - tags
+ script: echo "Propagating artifacts into release environment"
+ artifacts:
+ paths:
+ - doc/html
+ environment:
+ name: docs-release/$CI_COMMIT_TAG
+ url: https://$CI_PROJECT_NAMESPACE.pages.nic.cz/-/knot-resolver/-/jobs/$CI_JOB_ID/artifacts/doc/html/index.html
+
+# This job pushes the Knot Resolver documentation into a new branch of the
+# `websites/knot-resolver.cz` repository.
+docs:website:
+ stage: deploy
+ needs:
+ - docs:build
+ when: manual
+ variables:
+ script:
+ - "SRC_COMMIT_REF=\"$CI_COMMIT_TAG$CI_COMMIT_BRANCH$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME\""
+ - "git clone \"https://gitlab-ci-token:$WEBSITE_DOCS_CI_TOKEN@$CI_SERVER_HOST:$CI_SERVER_PORT/websites/knot-resolver.cz.git\" website"
+ - "cp --recursive --verbose \"doc/html\" \"website/content/documentation/$SRC_COMMIT_REF\""
+ - cd website
+ - "git checkout -b \"docs/$SRC_COMMIT_REF\""
+ - "git add \"content/documentation/$SRC_COMMIT_REF\""
+ - "git commit -m \"docs: $SRC_COMMIT_REF\""
+ - "git push --force --set-upstream origin \"docs/$SRC_COMMIT_REF\""
+
+# }}}
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..aebacbe
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "tests/integration/deckard"]
+ path = tests/integration/deckard
+ url = https://gitlab.nic.cz/knot/deckard.git
+[submodule "modules/policy/lua-aho-corasick"]
+ path = modules/policy/lua-aho-corasick
+ url = https://gitlab.nic.cz/knot/3rdparty/lua-aho-corasick.git
+[submodule "tests/config/tapered"]
+ path = tests/config/tapered
+ url = https://gitlab.nic.cz/knot/3rdparty/lua-tapered.git
diff --git a/NEWS b/NEWS
index f1e5d30..311d7f3 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,16 @@
+Knot Resolver 5.7.3 (2024-05-30)
+================================
+
+Improvements
+------------
+- stats: add separate metrics for IPv6 and IPv4 (!1544)
+
+Bugfixes
+--------
+- fix NSEC3 records missing in answer for positive wildcard expansion
+ with the NSEC3 having over-limit iteration count (#910, !1550)
+
+
Knot Resolver 5.7.2 (2024-03-27)
================================
diff --git a/ci/images/README.md b/ci/images/README.md
deleted file mode 100644
index 3d09f60..0000000
--- a/ci/images/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Container images for CI
-
-## Image purpose
-
-### debian-11
-
-The main image used by shared runners to execute most CI builds and tests.
-
-### debian-11-coverity
-
-A stripped down version of `debian-11`. It only contains build (not test)
-dependencies of `kresd`. It also contains the `cov-build` tool for generating
-inputs for [Coverity Scan](https://scan.coverity.com/).
-
-It is used by the `coverity` CI job to generate and send data to Coverity Scan
-for analysis.
-
-To build this image, you need to retrieve the Coverity Scan token from the
-dashboard and pass it to the `build.sh` script using the `COVERITY_SCAN_TOKEN`
-environment variable, e.g.:
-
-```
-$ COVERITY_SCAN_TOKEN=the_secret_token ./build.sh debian-11-coverity
-```
-
-### debian-buster (10)
-
-Used to serve the same purpose as `debian-11`. As of 2022-03-09, it is still
-used by some jobs (linters).
-
-## Maintenance
-
-The `ci/images/` directory contains utility scripts to build, push or update
-the container images.
-
-```
-$ ./build.sh debian-11 # builds a debian-11 image locally
-$ ./push.sh debian-11 # pushes the local image into target registry
-$ ./update.sh debian-11 # utility wrapper that both builds and pushes the image
-$ ./update.sh */ # use shell expansion of dirnames to update all images
-```
-
-By default, a branch of Knot DNS deemed to be stable is selected according to
-the `vars.sh` file. To build an image for a different Knot DNS branch, set the
-`KNOT_BRANCH` environment variable to the name of the branch, e.g.:
-
-```
-$ KNOT_BRANCH='3.2' ./update.sh debian-11
-```
diff --git a/ci/images/build.sh b/ci/images/build.sh
deleted file mode 100755
index 1e9eabb..0000000
--- a/ci/images/build.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# build specified docker image
-
-CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
-source "${CURRENT_DIR}"/vars.sh "$@"
-set -ex
-
-if [ -n "$COVERITY_SCAN_TOKEN" ]; then
- SECRETS="$SECRETS --secret id=coverity-token,env=COVERITY_SCAN_TOKEN"
-fi
-
-DOCKERFILE="$(realpath "${IMAGE}")/Dockerfile"
-
-cd "$CURRENT_DIR/../.."
-export DOCKER_BUILDKIT=1 # Enables using secrets in docker-build
-docker build \
- --pull \
- --no-cache \
- --tag "${FULL_NAME}" \
- --file "${DOCKERFILE}" \
- . \
- --build-arg KNOT_BRANCH=${KNOT_BRANCH} \
- $SECRETS
diff --git a/ci/images/debian-11-coverity/Dockerfile b/ci/images/debian-11-coverity/Dockerfile
deleted file mode 100644
index 1915614..0000000
--- a/ci/images/debian-11-coverity/Dockerfile
+++ /dev/null
@@ -1,43 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-FROM debian:bullseye
-MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
-# >= 3.0 needed because of --enable-xdp=yes
-ARG KNOT_BRANCH=3.1
-ARG COVERITY_SCAN_PROJECT_NAME=CZ-NIC/knot-resolver
-ENV DEBIAN_FRONTEND=noninteractive
-
-WORKDIR /root
-CMD ["/bin/bash"]
-
-# generic cleanup
-RUN apt-get update -qq
-
-# Knot and Knot Resolver dependencies
-RUN apt-get install -y -qqq git make cmake pkg-config meson \
- build-essential bsdmainutils libtool autoconf libcmocka-dev \
- liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
- libelf-dev libmnl-dev libidn11-dev libuv1-dev \
- libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev
-
-# LuaJIT binary for stand-alone scripting
-RUN apt-get install -y -qqq luajit
-
-# build and install latest version of Knot DNS
-RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot
-WORKDIR /tmp/knot
-RUN pwd
-RUN autoreconf -if
-RUN ./configure --prefix=/usr --enable-xdp=yes
-RUN CFLAGS="-g" make
-RUN make install
-RUN ldconfig
-
-# curl and tar (for downloading Coverity tools and uploading logs)
-RUN apt-get install -y curl tar
-
-RUN --mount=type=secret,id=coverity-token \
- curl -o /tmp/cov-analysis-linux64.tar.gz https://scan.coverity.com/download/cxx/linux64 \
- --form project=$COVERITY_SCAN_PROJECT_NAME --form token=$(cat /run/secrets/coverity-token)
-RUN tar xfz /tmp/cov-analysis-linux64.tar.gz
-RUN mv cov-analysis-linux64-* /opt/cov-analysis
diff --git a/ci/images/debian-11/Dockerfile b/ci/images/debian-11/Dockerfile
deleted file mode 100644
index 0241a6d..0000000
--- a/ci/images/debian-11/Dockerfile
+++ /dev/null
@@ -1,146 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-FROM debian:bullseye
-MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
-# >= 3.0 needed because of --enable-xdp=yes
-ARG KNOT_BRANCH=3.1
-ENV DEBIAN_FRONTEND=noninteractive
-
-WORKDIR /root
-CMD ["/bin/bash"]
-
-# generic cleanup
-RUN apt-get update -qq
-
-# Knot and Knot Resolver dependencies
-RUN apt-get install -y -qqq git make cmake pkg-config meson \
- build-essential bsdmainutils libtool autoconf libcmocka-dev \
- liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
- libelf-dev libmnl-dev libidn11-dev libuv1-dev libjemalloc-dev \
- libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev
-
-# Build and testing deps for Resolver's dnstap module (go stuff is just for testing)
-RUN apt-get install -y -qqq \
- protobuf-c-compiler libprotobuf-c-dev libfstrm-dev \
- golang-any
-COPY ./tests/dnstap /root/tests/dnstap
-WORKDIR /root/tests/dnstap/src/dnstap-test
-RUN go get .
-WORKDIR /root
-
-# documentation dependencies
-RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
-
-# Python packages required for Deckard CI
-# Python: grab latest versions from PyPi
-# (Augeas binding in Debian packages are slow and buggy)
-RUN apt-get install -y -qqq python3-pip wget augeas-tools
-RUN pip3 install --upgrade pip
-RUN pip3 install pylint
-RUN pip3 install pep8
-# FIXME replace with dnspython >= 2.2.0 once released
-RUN pip3 install git+https://github.com/bwelling/dnspython.git@72348d4698a8f8b209fbdf9e72738904ad31b930
-# tests/pytest dependencies: skip over broken versions
-RUN pip3 install jinja2 'pytest != 6.0.0' pytest-html pytest-xdist pytest-forked
-# apkg for packaging
-RUN pip3 install apkg
-
-# packet capture tools for Deckard
-RUN apt-get install --no-install-suggests --no-install-recommends -y -qqq tcpdump wireshark-common
-
-# Faketime for Deckard
-RUN apt-get install -y -qqq faketime
-
-# C dependencies for python-augeas
-RUN apt-get install -y -qqq libaugeas-dev libffi-dev
-# Python dependencies for Deckard
-RUN wget https://gitlab.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt
-RUN pip3 install -r /tmp/deckard-req.txt
-
-# build and install latest version of Knot DNS
-RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot
-WORKDIR /tmp/knot
-RUN pwd
-RUN autoreconf -if
-RUN ./configure --prefix=/usr --enable-xdp=yes
-RUN CFLAGS="-g" make
-RUN make install
-RUN ldconfig
-
-# Valgrind for kresd CI
-RUN apt-get install valgrind -y -qqq
-RUN wget https://github.com/LuaJIT/LuaJIT/raw/v2.1.0-beta3/src/lj.supp -O /lj.supp
-# TODO: rebuild LuaJIT with Valgrind support
-
-# Lua lint for kresd CI
-RUN apt-get install luarocks -y -qqq
-RUN luarocks --lua-version 5.1 install luacheck
-
-# respdiff for kresd CI
-RUN apt-get install lmdb-utils -y -qqq
-RUN git clone --depth=1 https://gitlab.nic.cz/knot/respdiff /var/opt/respdiff
-RUN pip3 install -r /var/opt/respdiff/requirements.txt
-
-# Python static analysis for respdiff
-RUN pip3 install mypy
-RUN pip3 install flake8
-
-# Python requests for CI scripts
-RUN pip3 install requests
-
-# docker-py for packaging tests
-RUN pip3 install docker
-
-# Unbound for respdiff
-RUN apt-get install unbound unbound-anchor -y -qqq
-RUN printf "server:\n interface: 127.0.0.1@53535\n use-syslog: yes\n do-ip6: no\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf
-
-# BIND for respdiff
-RUN apt-get install bind9 -y -qqq
-RUN printf '\nOPTIONS="-4 $OPTIONS"' >> /etc/default/bind9
-RUN printf 'options {\n directory "/var/cache/bind";\n listen-on port 53533 { 127.0.0.1; };\n listen-on-v6 port 53533 { ::1; };\n};\n' > /etc/bind/named.conf.options
-
-# PowerDNS Recursor for Deckard CI
-RUN apt-get install pdns-recursor -y -qqq
-
-# dnsdist for Deckard CI
-RUN apt-get install dnsdist -y -qqq
-
-# code coverage
-RUN apt-get install -y -qqq lcov
-RUN luarocks --lua-version 5.1 install luacov
-
-# LuaJIT binary for stand-alone scripting
-RUN apt-get install -y -qqq luajit
-
-# clang for kresd CI, version updated as debian updates it
-RUN apt-get install -y -qqq clang clang-tools clang-tidy
-
-# OpenBuildService CLI tool
-RUN apt-get install -y osc
-
-# curl (API)
-RUN apt-get install -y curl
-
-# configure knot-resolver-testing OBS repo for dependencies missing in Debian
-RUN echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-testing/Debian_11/ /' > /etc/apt/sources.list.d/knot-resolver-testing.list
-RUN wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Debian_11/Release.key -O Release.key
-RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add Release.key
-RUN rm Release.key
-RUN apt-get update -qq
-
-# packages from our knot-resolver-testing repo
-RUN apt-get update
-RUN apt-get install -y -qqq lua-psl
-
-# en_US.UTF-8 locale for scripts.update-authors.sh
-RUN apt-get install -y -qqq locales
-RUN sed -i "/en_US.UTF-8/ s/^#\(.*\)/\1/" /etc/locale.gen
-RUN locale-gen
-
-# SonarCloud scanner
-RUN wget -O /var/opt/wrapper.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip
-RUN wget -O /var/opt/scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip
-RUN unzip -d /var/opt /var/opt/wrapper.zip
-RUN unzip -d /var/opt /var/opt/scanner.zip
-ENV PATH "$PATH:/var/opt/build-wrapper-linux-x86:/var/opt/sonar-scanner-5.0.1.3006-linux/bin"
diff --git a/ci/images/debian-buster/Dockerfile b/ci/images/debian-buster/Dockerfile
deleted file mode 100644
index 39f4327..0000000
--- a/ci/images/debian-buster/Dockerfile
+++ /dev/null
@@ -1,146 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-FROM debian:buster
-MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
-# >= 3.0 needed because of --enable-xdp=yes
-ARG KNOT_BRANCH=3.0
-ENV DEBIAN_FRONTEND=noninteractive
-
-WORKDIR /root
-CMD ["/bin/bash"]
-
-# generic cleanup
-RUN apt-get update -qq
-# TODO: run upgrade once buster reaches a stable release
-# RUN apt-get upgrade -y -qqq
-
-# Knot and Knot Resolver dependencies
-RUN apt-get install -y -qqq git make cmake pkg-config meson \
- build-essential bsdmainutils libtool autoconf libcmocka-dev \
- liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev \
- libelf-dev libmnl-dev libidn11-dev libuv1-dev \
- libluajit-5.1-dev lua-http libssl-dev libnghttp2-dev
-
-# Build and testing deps for Resolver's dnstap module (go stuff is just for testing)
-RUN apt-get install -y -qqq \
- protobuf-c-compiler libprotobuf-c-dev libfstrm-dev \
- golang-any
-COPY ./tests/dnstap /root/tests/dnstap
-WORKDIR /root/tests/dnstap/src/dnstap-test
-RUN go get .
-WORKDIR /root
-
-# documentation dependencies
-RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
-
-# Python packages required for Deckard CI
-# Python: grab latest versions from PyPi
-# (Augeas binding in Debian packages are slow and buggy)
-RUN apt-get install -y -qqq python3-pip wget augeas-tools
-RUN pip3 install --upgrade pip
-RUN pip3 install pylint
-RUN pip3 install pep8
-RUN pip3 install pytest-xdist
-# tests/pytest dependencies: skip over broken versions
-RUN pip3 install 'dnspython != 2.0.0' 'jinja2 == 2.11.3' 'pytest != 6.0.0' pytest-html pytest-xdist
-
-# packet capture tools for Deckard
-RUN apt-get install --no-install-suggests --no-install-recommends -y -qqq tcpdump wireshark-common
-
-# Faketime for Deckard
-RUN apt-get install -y -qqq faketime
-
-# C dependencies for python-augeas
-RUN apt-get install -y -qqq libaugeas-dev libffi-dev
-# Python dependencies for Deckard
-RUN wget https://gitlab.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt
-RUN pip3 install -r /tmp/deckard-req.txt
-
-# build and install latest version of Knot DNS
-RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.nic.cz/knot/knot-dns.git /tmp/knot
-WORKDIR /tmp/knot
-RUN pwd
-RUN autoreconf -if
-RUN ./configure --prefix=/usr --enable-xdp=yes
-RUN CFLAGS="-g" make
-RUN make install
-RUN ldconfig
-
-# Valgrind for kresd CI
-RUN apt-get install valgrind -y -qqq
-RUN wget https://github.com/LuaJIT/LuaJIT/raw/v2.1.0-beta3/src/lj.supp -O /lj.supp
-# TODO: rebuild LuaJIT with Valgrind support
-
-# Lua lint for kresd CI
-RUN apt-get install luarocks -y -qqq
-RUN luarocks --lua-version 5.1 install luacheck
-
-# respdiff for kresd CI
-RUN apt-get install lmdb-utils -y -qqq
-RUN git clone --depth=1 https://gitlab.nic.cz/knot/respdiff /var/opt/respdiff
-RUN pip3 install -r /var/opt/respdiff/requirements.txt
-
-# Python static analysis for respdiff
-RUN pip3 install mypy
-RUN pip3 install flake8
-
-# Python requests for CI scripts
-RUN pip3 install requests
-
-# docker-py for packaging tests
-RUN pip3 install docker
-
-# Unbound for respdiff
-RUN apt-get install unbound unbound-anchor -y -qqq
-RUN printf "server:\n interface: 127.0.0.1@53535\n use-syslog: yes\n do-ip6: no\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf
-
-# BIND for respdiff
-RUN apt-get install bind9 -y -qqq
-RUN printf '\nOPTIONS="-4 $OPTIONS"' >> /etc/default/bind9
-RUN printf 'options {\n directory "/var/cache/bind";\n listen-on port 53533 { 127.0.0.1; };\n listen-on-v6 port 53533 { ::1; };\n};\n' > /etc/bind/named.conf.options
-
-# PowerDNS Recursor for Deckard CI
-RUN apt-get install pdns-recursor -y -qqq
-
-# code coverage
-RUN apt-get install -y -qqq lcov
-RUN luarocks --lua-version 5.1 install luacov
-
-# LuaJIT binary for stand-alone scripting
-RUN apt-get install -y -qqq luajit
-
-# clang for kresd CI, version updated as debian updates it
-RUN apt-get install -y -qqq clang clang-tools clang-tidy
-
-# OpenBuildService CLI tool
-RUN apt-get install -y osc
-
-# curl (API)
-RUN apt-get install -y curl
-
-# configure knot-resolver-testing OBS repo for dependencies missing in Debian
-RUN echo 'deb http://download.opensuse.org/repositories/home:/CZ-NIC:/knot-resolver-testing/Debian_10/ /' > /etc/apt/sources.list.d/knot-resolver-testing.list
-RUN wget -nv https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Debian_10/Release.key -O Release.key
-RUN APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add Release.key
-RUN rm Release.key
-RUN apt-get update -qq
-
-# packages from our knot-resolver-testing repo
-RUN apt-get install -y -qqq lua-http lua-psl
-
-# en_US.UTF-8 locale for scripts.update-authors.sh
-RUN apt-get install -y -qqq locales
-RUN sed -i "/en_US.UTF-8/ s/^#\(.*\)/\1/" /etc/locale.gen
-RUN locale-gen
-
-# SonarCloud scanner
-RUN wget -O /var/opt/wrapper.zip https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip
-RUN wget -O /var/opt/scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip
-RUN unzip -d /var/opt /var/opt/wrapper.zip
-RUN unzip -d /var/opt /var/opt/scanner.zip
-ENV PATH "$PATH:/var/opt/build-wrapper-linux-x86:/var/opt/sonar-scanner-4.4.0.2170-linux/bin"
-
-# let's get newer meson from backports
-RUN echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/backports.list
-RUN apt-get update -qq
-RUN apt-get -t buster-backports install -y -qqq meson
diff --git a/ci/images/push.sh b/ci/images/push.sh
deleted file mode 100755
index 75f5f87..0000000
--- a/ci/images/push.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-# upload docker image into registry
-
-CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
-source "${CURRENT_DIR}"/vars.sh "$@"
-set -ex
-
-docker push "${FULL_NAME}"
diff --git a/ci/images/update.sh b/ci/images/update.sh
deleted file mode 100755
index 7be5172..0000000
--- a/ci/images/update.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/bash
-# build and upload docker image(s) into registry
-#
-# this is a simple wrapper around build.sh and update.sh
-#
-# to build & upload all images: ./update.sh */
-
-if [[ $# -le 0 ]]; then
- echo "usage: $0 IMAGE..."
- exit 1
-fi
-set -e
-
-for ARG in "$@"
-do
- IMAGE=${ARG%/}
- echo "Building $IMAGE..."
- ./build.sh $IMAGE
- echo "Pushing $IMAGE..."
- ./push.sh $IMAGE
-done
-
diff --git a/ci/images/vars.sh b/ci/images/vars.sh
deleted file mode 100755
index f2ea465..0000000
--- a/ci/images/vars.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/bin/bash
-# define common variables for image build scripts
-
-KNOT_BRANCH="${KNOT_BRANCH:-3.1}"
-
-REGISTRY="registry.nic.cz/knot/knot-resolver/ci"
-IMAGE=$1
-if [ -z "${IMAGE}" ]; then
- echo "image name not provided"
- exit 1
-fi
-TAG="knot-${KNOT_BRANCH}"
-FULL_NAME="${REGISTRY}/${IMAGE}:${TAG}"
diff --git a/ci/pkgtest.yaml b/ci/pkgtest.yaml
index b7b87c3..2ac4d4c 100644
--- a/ci/pkgtest.yaml
+++ b/ci/pkgtest.yaml
@@ -119,7 +119,8 @@ nixos-unstable:pkgbuild:
- docker
- linux
- ${PLATFORM}
- image: nixos/nix
+ # https://github.com/NixOS/nix/issues/10648#issuecomment-2101993746
+ image: docker.io/nixos/nix:latest-${PLATFORM}
variables:
NIX_PATH: nixpkgs=https://github.com/nixos/nixpkgs/archive/nixos-unstable.tar.gz
diff --git a/contrib/dynarray.h b/contrib/dynarray.h
deleted file mode 100644
index 7cbb686..0000000
--- a/contrib/dynarray.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (C) CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
- * SPDX-License-Identifier: GPL-3.0-or-later
- */
-
-/*!
- * \brief Simple write-once allocation-optimal dynamic array.
- *
- * Include it into your .c file
- *
- * prefix - identifier prefix, e.g. ptr -> struct ptr_dynarray, ptr_dynarray_add(), ...
- * ntype - data type to be stored. Let it be a number, pointer or small struct
- * initial_capacity - how many data items will be allocated on stack and copied with assignment
- *
- * prefix_dynarray_add() - add a data item
- * prefix_dynarray_fix() - call EVERYTIME the array is copied from some already invalid stack
- * prefix_dynarray_free() - call EVERYTIME you dismiss all copies of the array
- *
- */
-
-#include <stdlib.h>
-#include <assert.h>
-
-#pragma once
-
-#define DYNARRAY_VISIBILITY_STATIC static
-#define DYNARRAY_VISIBILITY_PUBLIC
-#define DYNARRAY_VISIBILITY_LIBRARY __public__
-
-#define dynarray_declare(prefix, ntype, visibility, initial_capacity) \
- typedef struct prefix ## _dynarray { \
- ssize_t capacity; \
- ssize_t size; \
- ntype *(*arr)(struct prefix ## _dynarray *dynarray); \
- ntype init[initial_capacity]; \
- ntype *_arr; \
- } prefix ## _dynarray_t; \
- \
- visibility ntype *prefix ## _dynarray_arr(prefix ## _dynarray_t *dynarray); \
- visibility void prefix ## _dynarray_add(prefix ## _dynarray_t *dynarray, \
- ntype const *to_add); \
- visibility void prefix ## _dynarray_free(prefix ## _dynarray_t *dynarray);
-
-#define dynarray_foreach(prefix, ntype, ptr, array) \
- for (ntype *ptr = prefix ## _dynarray_arr(&(array)); \
- ptr < prefix ## _dynarray_arr(&(array)) + (array).size; ptr++)
-
-#define dynarray_define(prefix, ntype, visibility) \
- \
- static void prefix ## _dynarray_free__(struct prefix ## _dynarray *dynarray) \
- { \
- if (dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)) { \
- free(dynarray->_arr); \
- } \
- } \
- \
- __attribute__((unused)) \
- visibility ntype *prefix ## _dynarray_arr(struct prefix ## _dynarray *dynarray) \
- { \
- assert(dynarray->size <= dynarray->capacity); \
- return (dynarray->capacity <= sizeof(dynarray->init) / sizeof(*dynarray->init) ? \
- dynarray->init : dynarray->_arr); \
- } \
- \
- static ntype *prefix ## _dynarray_arr_init__(struct prefix ## _dynarray *dynarray) \
- { \
- assert(dynarray->capacity == sizeof(dynarray->init) / sizeof(*dynarray->init)); \
- return dynarray->init; \
- } \
- \
- static ntype *prefix ## _dynarray_arr_arr__(struct prefix ## _dynarray *dynarray) \
- { \
- assert(dynarray->capacity > sizeof(dynarray->init) / sizeof(*dynarray->init)); \
- return dynarray->_arr; \
- } \
- \
- __attribute__((unused)) \
- visibility void prefix ## _dynarray_add(struct prefix ## _dynarray *dynarray, \
- ntype const *to_add) \
- { \
- if (dynarray->capacity < 0) { \
- return; \
- } \
- if (dynarray->capacity == 0) { \
- dynarray->capacity = sizeof(dynarray->init) / sizeof(*dynarray->init); \
- dynarray->arr = prefix ## _dynarray_arr_init__; \
- } \
- if (dynarray->size >= dynarray->capacity) { \
- ssize_t new_capacity = dynarray->capacity * 2 + 1; \
- ntype *new_arr = calloc(new_capacity, sizeof(ntype)); \
- if (new_arr == NULL) { \
- prefix ## _dynarray_free__(dynarray); \
- dynarray->capacity = dynarray->size = -1; \
- return; \
- } \
- if (dynarray->capacity > 0) { \
- memcpy(new_arr, prefix ## _dynarray_arr(dynarray), \
- dynarray->capacity * sizeof(ntype)); \
- } \
- prefix ## _dynarray_free__(dynarray); \
- dynarray->_arr = new_arr; \
- dynarray->capacity = new_capacity; \
- dynarray->arr = prefix ## _dynarray_arr_arr__; \
- } \
- prefix ## _dynarray_arr(dynarray)[dynarray->size++] = *to_add; \
- } \
- \
- __attribute__((unused)) \
- visibility void prefix ## _dynarray_free(struct prefix ## _dynarray *dynarray) \
- { \
- prefix ## _dynarray_free__(dynarray); \
- memset(dynarray, 0, sizeof(*dynarray)); \
- }
diff --git a/contrib/dynarray.spdx b/contrib/dynarray.spdx
deleted file mode 100644
index 02911c9..0000000
--- a/contrib/dynarray.spdx
+++ /dev/null
@@ -1,10 +0,0 @@
-SPDXVersion: SPDX-2.1
-DataLicense: CC0-1.0
-SPDXID: SPDXRef-DOCUMENT
-DocumentName: knotdns-dynarray
-DocumentNamespace: http://spdx.org/spdxdocs/spdx-v2.1-ce6423dd-ac6a-4e78-90c3-5cbdef1e252c
-
-PackageName: knotdns-dynarray
-PackageDownloadLocation: git+https://gitlab.nic.cz/knot/knot-dns.git@48c8b4f38cf5f7bf505c79b56adf7580688f6d3d#src/contrib/dynarray.h
-PackageOriginator: Organization: Knot DNS contributors
-PackageLicenseDeclared: GPL-3.0-or-later
diff --git a/daemon/bindings/net.c b/daemon/bindings/net.c
index f1fa6f3..0075d0f 100644
--- a/daemon/bindings/net.c
+++ b/daemon/bindings/net.c
@@ -470,7 +470,7 @@ static int net_interfaces(lua_State *L)
/* Hardware address. */
char *p = buf;
for (int k = 0; k < sizeof(iface.phys_addr); ++k) {
- sprintf(p, "%.2x:", (uint8_t)iface.phys_addr[k]);
+ (void)sprintf(p, "%.2x:", (uint8_t)iface.phys_addr[k]);
p += 3;
}
p[-1] = '\0';
@@ -794,7 +794,7 @@ static int net_tls_client(lua_State *L)
/* Sort the strings for easier comparison later. */
if (newcfg->ca_files.len) {
qsort(&newcfg->ca_files.at[0], newcfg->ca_files.len,
- sizeof(newcfg->ca_files.at[0]), strcmp_p);
+ array_member_size(newcfg->ca_files), strcmp_p);
}
}
lua_pop(L, 1);
@@ -834,7 +834,7 @@ static int net_tls_client(lua_State *L)
/* Sort the raw strings for easier comparison later. */
if (newcfg->pins.len) {
qsort(&newcfg->pins.at[0], newcfg->pins.len,
- sizeof(newcfg->pins.at[0]), cmp_sha256);
+ array_member_size(newcfg->pins), cmp_sha256);
}
}
lua_pop(L, 1);
@@ -1042,7 +1042,11 @@ static int net_tls_sticket_secret_file(lua_State *L)
STR(net_tls_sticket_MIN_SECRET_LEN) " bytes",
file_name);
}
- fclose(fp);
+ if (fclose(fp) == EOF) {
+ lua_error_p(L,
+ "net.tls_sticket_secret_file - reading of file '%s' failed",
+ file_name);
+ }
struct network *net = &the_worker->engine->net;
diff --git a/daemon/engine.c b/daemon/engine.c
index 1d387ea..8c00a5b 100644
--- a/daemon/engine.c
+++ b/daemon/engine.c
@@ -52,9 +52,6 @@
#define TCP_BACKLOG_DEFAULT 128
#endif
-/* Cleanup engine state every 5 minutes */
-const size_t CLEANUP_TIMER = 5*60*1000;
-
/* Execute byte code */
#define l_dobytecode(L, arr, len, name) \
(luaL_loadbuffer((L), (arr), (len), (name)) || lua_pcall((L), 0, LUA_MULTRET, 0))
@@ -223,7 +220,6 @@ static int l_log_groups(lua_State *L)
goto bad_call;
kr_log_group_reset();
- int idx = 1;
lua_pushnil(L);
while (lua_next(L, 1) != 0) {
const char *grp_str = lua_tostring(L, -1);
@@ -237,7 +233,6 @@ static int l_log_groups(lua_State *L)
kr_log_warning(SYSTEM, "WARNING: unknown log group '%s'\n", lua_tostring(L, -1));
}
- ++idx;
lua_pop(L, 1);
}
}
@@ -611,7 +606,7 @@ int init_lua(struct engine *engine) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat" /* %1$ is not in C standard */
/* Save original package.path to package._path */
- snprintf(l_paths, MAXPATHLEN - 1,
+ (void)snprintf(l_paths, MAXPATHLEN - 1,
"if package._path == nil then package._path = package.path end\n"
"package.path = '%1$s/?.lua;%1$s/?/init.lua;'..package._path\n"
"if package._cpath == nil then package._cpath = package.cpath end\n"
diff --git a/daemon/io.c b/daemon/io.c
index 6d548d7..9299ff2 100644
--- a/daemon/io.c
+++ b/daemon/io.c
@@ -151,7 +151,7 @@ static int family_to_freebind_option(sa_family_t sa_family, int *level, int *nam
#define LOG_NO_FB kr_log_error(NETWORK, "your system does not support 'freebind', " \
"please remove it from your configuration\n")
switch (sa_family) {
- case AF_INET:
+ case AF_INET: // NOLINT(bugprone-branch-clone): The branches are only cloned for specific macro configs
*level = IPPROTO_IP;
#if defined(IP_FREEBIND)
*name = IP_FREEBIND;
@@ -510,7 +510,7 @@ static ssize_t tls_send(const uint8_t *buf, const size_t len, struct session *se
}
#endif
-static void _tcp_accept(uv_stream_t *master, int status, bool tls, bool http)
+static void tcp_accept_internal(uv_stream_t *master, int status, bool tls, bool http)
{
if (status != 0) {
return;
@@ -631,18 +631,18 @@ static void _tcp_accept(uv_stream_t *master, int status, bool tls, bool http)
static void tcp_accept(uv_stream_t *master, int status)
{
- _tcp_accept(master, status, false, false);
+ tcp_accept_internal(master, status, false, false);
}
static void tls_accept(uv_stream_t *master, int status)
{
- _tcp_accept(master, status, true, false);
+ tcp_accept_internal(master, status, true, false);
}
#if ENABLE_DOH2
static void https_accept(uv_stream_t *master, int status)
{
- _tcp_accept(master, status, true, true);
+ tcp_accept_internal(master, status, true, true);
}
#endif
@@ -834,16 +834,25 @@ void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *bu
len_s = 0;
}
uint32_t len_n = htonl(len_s);
- fwrite(&len_n, sizeof(len_n), 1, out);
- if (len_s > 0)
- fwrite(message, len_s, 1, out);
+ if (fwrite(&len_n, sizeof(len_n), 1, out) != 1)
+ goto finish;
+ if (len_s > 0) {
+ if (fwrite(message, len_s, 1, out) != 1)
+ goto finish;
+ }
} else {
- if (message)
- fprintf(out, "%s", message);
- if (message || !args->quiet)
- fprintf(out, "\n");
- if (!args->quiet)
- fprintf(out, "> ");
+ if (message) {
+ if (fprintf(out, "%s", message) < 0)
+ goto finish;
+ }
+ if (message || !args->quiet) {
+ if (fprintf(out, "\n") < 0)
+ goto finish;
+ }
+ if (!args->quiet) {
+ if (fprintf(out, "> ") < 0)
+ goto finish;
+ }
}
/* Duplicate command and output to logs */
@@ -865,7 +874,7 @@ void io_tty_process_input(uv_stream_t *stream, ssize_t nread, const uv_buf_t *bu
finish:
/* Close if redirected */
if (stream_fd != STDIN_FILENO) {
- fclose(out);
+ (void)fclose(out);
}
}
diff --git a/daemon/main.c b/daemon/main.c
index 41a55ad..a346a5c 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -425,9 +425,9 @@ int main(int argc, char **argv)
{
kr_log_group_reset();
if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) {
- kr_log_error(SYSTEM, "failed to to set output buffering (ignored): %s\n",
+ kr_log_error(SYSTEM, "failed to set output buffering (ignored): %s\n",
strerror(errno));
- fflush(stderr);
+ (void)fflush(stderr);
}
if (strcmp("linux", OPERATING_SYSTEM) != 0)
kr_log_warning(SYSTEM, "Knot Resolver is tested on Linux, other platforms might exhibit bugs.\n"
@@ -490,7 +490,7 @@ int main(int argc, char **argv)
if (ret) {
kr_log_error(SYSTEM, "failed to get or set file-descriptor limit: %s\n",
strerror(errno));
- } else if (rlim.rlim_cur < 512*1024) {
+ } else if (rlim.rlim_cur < (rlim_t)512 * 1024) {
kr_log_warning(SYSTEM, "warning: hard limit for number of file-descriptors is only %ld but recommended value is 524288\n",
(long)rlim.rlim_cur);
}
diff --git a/daemon/meson.build b/daemon/meson.build
index 68a2646..8446b82 100644
--- a/daemon/meson.build
+++ b/daemon/meson.build
@@ -65,4 +65,5 @@ kresd = executable(
export_dynamic: true,
install: true,
install_dir: get_option('sbindir'),
+ install_rpath: rpath,
)
diff --git a/daemon/proxyv2.c b/daemon/proxyv2.c
index aedbb91..8197003 100644
--- a/daemon/proxyv2.c
+++ b/daemon/proxyv2.c
@@ -279,6 +279,7 @@ ssize_t proxy_process_header(struct proxy_result *out, struct session *s,
&addr->ipv6_addr.dst_addr,
sizeof(out->dst_addr.ip6.sin6_addr.s6_addr));
break;
+ default:; /* Keep zero from initializer. */
}
/* Process additional information */
@@ -287,7 +288,7 @@ ssize_t proxy_process_header(struct proxy_result *out, struct session *s,
case TLV_TYPE_SSL:
out->has_tls = true;
break;
- /* TODO: add more TLV types if needed */
+ default:; /* Ignore others - add more if needed */
}
}
diff --git a/daemon/session.c b/daemon/session.c
index ed0ff68..91d3c39 100644
--- a/daemon/session.c
+++ b/daemon/session.c
@@ -13,7 +13,7 @@
#include "daemon/proxyv2.h"
#include "lib/generic/queue.h"
-#define TLS_CHUNK_SIZE (16 * 1024)
+#define TLS_CHUNK_SIZE ((size_t)16 * 1024)
/* Initial max frame size: https://tools.ietf.org/html/rfc7540#section-6.5.2 */
#define HTTP_MAX_FRAME_SIZE 16384
diff --git a/daemon/tls.c b/daemon/tls.c
index 2e1631b..0ab3968 100644
--- a/daemon/tls.c
+++ b/daemon/tls.c
@@ -23,7 +23,7 @@
#include "daemon/worker.h"
#include "daemon/session.h"
-#define EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE (60*60*24*7)
+#define EPHEMERAL_CERT_EXPIRATION_SECONDS_RENEW_BEFORE ((time_t)60*60*24*7)
#define GNUTLS_PIN_MIN_VERSION 0x030400
#define VERBOSE_MSG(cl_side, ...)\
@@ -659,7 +659,7 @@ static int str_replace(char **where_ptr, const char *with)
return kr_ok();
}
-static time_t _get_end_entity_expiration(gnutls_certificate_credentials_t creds)
+static time_t get_end_entity_expiration(gnutls_certificate_credentials_t creds)
{
gnutls_datum_t data;
gnutls_x509_crt_t cert = NULL;
@@ -731,7 +731,7 @@ int tls_certificate_set(struct network *net, const char *tls_cert, const char *t
return kr_error(EINVAL);
}
/* record the expiration date: */
- tls_credentials->valid_until = _get_end_entity_expiration(tls_credentials->credentials);
+ tls_credentials->valid_until = get_end_entity_expiration(tls_credentials->credentials);
/* Exchange the x509 credentials */
struct tls_credentials *old_credentials = net->tls_credentials;
diff --git a/daemon/tls.h b/daemon/tls.h
index af1f5c9..c30444b 100644
--- a/daemon/tls.h
+++ b/daemon/tls.h
@@ -30,7 +30,7 @@
* So it takes 2 RTT.
* As we use session tickets, there are additional messages, add one RTT mode.
*/
- #define TLS_MAX_HANDSHAKE_TIME (KR_CONN_RTT_MAX * 3)
+ #define TLS_MAX_HANDSHAKE_TIME (KR_CONN_RTT_MAX * (uint64_t)3)
/** Transport session (opaque). */
struct session;
diff --git a/daemon/tls_ephemeral_credentials.c b/daemon/tls_ephemeral_credentials.c
index ff4682f..2b928fa 100644
--- a/daemon/tls_ephemeral_credentials.c
+++ b/daemon/tls_ephemeral_credentials.c
@@ -17,19 +17,19 @@
#define EPHEMERAL_PRIVKEY_FILENAME "ephemeral_key.pem"
#define INVALID_HOSTNAME "dns-over-tls.invalid"
-#define EPHEMERAL_CERT_EXPIRATION_SECONDS (60*60*24*90)
+#define EPHEMERAL_CERT_EXPIRATION_SECONDS ((time_t)60*60*24*90)
/* This is an attempt to grab an exclusive, advisory, non-blocking
* lock based on a filename. At the moment it's POSIX-only, but it
* should be abstract enough of an interface to make an implementation
* for non-posix systems if anyone cares. */
typedef int lock_t;
-static bool _lock_is_invalid(lock_t lock)
+static bool lock_is_invalid(lock_t lock)
{
return lock == -1;
}
/* a blocking lock on a given filename */
-static lock_t _lock_filename(const char *fname)
+static lock_t lock_filename(const char *fname)
{
lock_t lockfd = open(fname, O_RDONLY|O_CREAT, 0400);
if (lockfd == -1)
@@ -41,9 +41,9 @@ static lock_t _lock_filename(const char *fname)
}
return lockfd; /* for cleanup later */
}
-static void _lock_unlock(lock_t *lock, const char *fname)
+static void lock_unlock(lock_t *lock, const char *fname)
{
- if (lock && !_lock_is_invalid(*lock)) {
+ if (lock && !lock_is_invalid(*lock)) {
flock(*lock, LOCK_UN);
close(*lock);
*lock = -1;
@@ -61,8 +61,8 @@ static gnutls_x509_privkey_t get_ephemeral_privkey (void)
/* Take a lock to ensure that two daemons started concurrently
* with a shared cache don't both create the same privkey: */
- lock = _lock_filename(EPHEMERAL_PRIVKEY_FILENAME ".lock");
- if (_lock_is_invalid(lock)) {
+ lock = lock_filename(EPHEMERAL_PRIVKEY_FILENAME ".lock");
+ if (lock_is_invalid(lock)) {
kr_log_error(TLS, "unable to lock lockfile " EPHEMERAL_PRIVKEY_FILENAME ".lock\n");
goto done;
}
@@ -91,7 +91,7 @@ static gnutls_x509_privkey_t get_ephemeral_privkey (void)
}
data.size = stat.st_size;
bytes_read = read(datafd, data.data, stat.st_size);
- if (bytes_read != stat.st_size) {
+ if (bytes_read < 0 || bytes_read != stat.st_size) {
kr_log_error(TLS, "unable to read ephemeral private key\n");
goto bad_data;
}
@@ -141,7 +141,7 @@ static gnutls_x509_privkey_t get_ephemeral_privkey (void)
}
}
done:
- _lock_unlock(&lock, EPHEMERAL_PRIVKEY_FILENAME ".lock");
+ lock_unlock(&lock, EPHEMERAL_PRIVKEY_FILENAME ".lock");
if (datafd != -1) {
close(datafd);
}
@@ -219,7 +219,7 @@ struct tls_credentials * tls_get_ephemeral_credentials(struct engine *engine)
if ((privkey = get_ephemeral_privkey()) == NULL) {
goto failure;
}
- if ((cert = get_ephemeral_cert(privkey, creds->ephemeral_servicename, now - 60*15, creds->valid_until)) == NULL) {
+ if ((cert = get_ephemeral_cert(privkey, creds->ephemeral_servicename, now - ((time_t)60 * 15), creds->valid_until)) == NULL) {
goto failure;
}
if ((err = gnutls_certificate_set_x509_key(creds->credentials, &cert, 1, privkey)) < 0) {
diff --git a/daemon/tls_session_ticket-srv.c b/daemon/tls_session_ticket-srv.c
index b198903..26d4186 100644
--- a/daemon/tls_session_ticket-srv.c
+++ b/daemon/tls_session_ticket-srv.c
@@ -188,7 +188,7 @@ static void tst_key_check(uv_timer_t *timer, bool force_update)
const uint64_t remain_ms = (tv_sec_next - now.tv_sec - 1) * (uint64_t)1000
+ ms_until_second + 1;
/* ^ +1 because we don't want to wake up half a millisecond before the epoch! */
- if (kr_fails_assert(remain_ms < (TST_KEY_LIFETIME + 1 /*rounding tolerance*/) * 1000))
+ if (kr_fails_assert(remain_ms < ((uint64_t)TST_KEY_LIFETIME + 1 /*rounding tolerance*/) * 1000))
return;
kr_log_debug(TLS, "session ticket: epoch %"PRIu64
", scheduling rotation check in %"PRIu64" ms\n",
diff --git a/daemon/udp_queue.c b/daemon/udp_queue.c
index 1f8ff39..7ed600a 100644
--- a/daemon/udp_queue.c
+++ b/daemon/udp_queue.c
@@ -110,11 +110,11 @@ void udp_queue_push(int fd, struct kr_request *req, struct qr_task *task)
/* Get a valid correct queue. */
if (fd >= state.udp_queues_len) {
const int new_len = fd + 1;
- state.udp_queues = realloc(state.udp_queues,
- sizeof(state.udp_queues[0]) * new_len);
+ state.udp_queues = realloc(state.udp_queues, // NOLINT(bugprone-suspicious-realloc-usage): we just abort() below, so it's fine
+ sizeof(state.udp_queues[0]) * new_len); // NOLINT(bugprone-sizeof-expression): false-positive
if (!state.udp_queues) abort();
memset(state.udp_queues + state.udp_queues_len, 0,
- sizeof(state.udp_queues[0]) * (new_len - state.udp_queues_len));
+ sizeof(state.udp_queues[0]) * (new_len - state.udp_queues_len)); // NOLINT(bugprone-sizeof-expression): false-positive
state.udp_queues_len = new_len;
}
if (unlikely(state.udp_queues[fd] == NULL))
diff --git a/daemon/worker.c b/daemon/worker.c
index 8b6b49e..12c08f1 100644
--- a/daemon/worker.c
+++ b/daemon/worker.c
@@ -195,7 +195,7 @@ static inline struct mempool *pool_borrow(struct worker_ctx *worker)
{
/* The implementation used to have extra caching layer,
* but it didn't work well. Now it's very simple. */
- return mp_new(16 * 1024);
+ return mp_new((size_t)16 * 1024);
}
/** Return a mempool. */
static inline void pool_release(struct worker_ctx *worker, struct mempool *mp)
diff --git a/daemon/zimport.c b/daemon/zimport.c
index af21a15..39799b6 100644
--- a/daemon/zimport.c
+++ b/daemon/zimport.c
@@ -98,7 +98,7 @@ static int key_get(char buf[KEY_LEN], const knot_dname_t *name,
char *lf = (char *)knot_dname_lf(name, (uint8_t *)buf);
if (kr_fails_assert(lf && key_p))
return kr_error(EINVAL);
- int len = lf[0];
+ int len = (unsigned char)lf[0];
lf++; // point to start of data
*key_p = lf;
// Check that LF is right-aligned to KNOT_DNAME_MAXLEN in buf.
@@ -282,7 +282,7 @@ do_digest:
// hexdump the hash for logging
char hash_str[digs[i].size * 2 + 1];
for (ssize_t j = 0; j < digs[i].size; ++j)
- sprintf(hash_str + 2*j, "%02x", digs[i].data[j]);
+ (void)sprintf(hash_str + 2*j, "%02x", digs[i].data[j]);
if (!z_import->digests[i].expected) {
kr_log_error(PREFILL, "no ZONEMD found; computed hash: %s\n",
@@ -560,7 +560,7 @@ int zi_zone_import(const zi_config_t config)
if (kr_fails_assert(c && c->zone_file))
return kr_error(EINVAL);
- knot_mm_t *pool = mm_ctx_mempool2(1024 * 1024);
+ knot_mm_t *pool = mm_ctx_mempool2((size_t)1024 * 1024);
zone_import_ctx_t *z_import = mm_calloc(pool, 1, sizeof(*z_import));
if (!z_import) return kr_error(ENOMEM);
z_import->pool = pool;
diff --git a/lib/cache/api.c b/lib/cache/api.c
index f71a8d0..7327903 100644
--- a/lib/cache/api.c
+++ b/lib/cache/api.c
@@ -517,7 +517,7 @@ static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry,
goto return_needs_pkt;
const knot_dname_t *encloser = rr->owner; /**< the closest encloser name */
for (int i = 0; i < wild_labels; ++i) {
- encloser = knot_wire_next_label(encloser, NULL);
+ encloser = knot_dname_next_label(encloser);
}
/* Construct the key under which RRs will be stored,
diff --git a/lib/cache/peek.c b/lib/cache/peek.c
index e1901ac..f0bb79c 100644
--- a/lib/cache/peek.c
+++ b/lib/cache/peek.c
@@ -174,6 +174,7 @@ int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt)
knot_db_val_bound(v), new_ttl);
return ret == kr_ok() ? KR_STATE_DONE : ctx->state;
}
+ default:; // Continue below
}
/* We have to try proving from NSEC*. */
@@ -359,7 +360,7 @@ static int peek_encloser(
/** Name of the closest (provable) encloser. */
const knot_dname_t *clencl_name = qry->sname;
for (int l = sname_labels; l > clencl_labels; --l)
- clencl_name = knot_wire_next_label(clencl_name, NULL);
+ clencl_name = knot_dname_next_label(clencl_name);
/**** 3. source of synthesis checks, in case the next closer name was covered.
**** 3a. We want to query for NSEC* of source of synthesis (SS) or its
diff --git a/lib/dnssec.c b/lib/dnssec.c
index 12b8f20..eb4b33b 100644
--- a/lib/dnssec.c
+++ b/lib/dnssec.c
@@ -362,7 +362,7 @@ static int kr_rrset_validate_with_key(kr_rrset_validation_ctx_t *vctx,
const int covered_labels = knot_dname_labels(covered->owner, NULL)
- knot_dname_is_wildcard(covered->owner);
- for (uint16_t i = 0; i < vctx->rrs->len; ++i) {
+ for (size_t i = 0; i < vctx->rrs->len; ++i) {
/* Consider every RRSIG that matches and comes from the same query. */
const knot_rrset_t *rrsig = vctx->rrs->at[i]->rr;
const bool ok = vctx->rrs->at[i]->qry_uid == vctx->qry_uid
diff --git a/lib/dnssec/nsec.c b/lib/dnssec/nsec.c
index 8b17247..be34d92 100644
--- a/lib/dnssec/nsec.c
+++ b/lib/dnssec/nsec.c
@@ -16,7 +16,7 @@
#include "lib/defines.h"
#include "lib/dnssec/nsec.h"
#include "lib/utils.h"
-#include "resolve.h"
+#include "lib/resolve.h"
int kr_nsec_children_in_zone_check(const uint8_t *bm, uint16_t bm_size)
{
@@ -81,15 +81,13 @@ static int dname_cmp(const knot_dname_t *d1, const knot_dname_t *d2)
dname_reverse(d1, d1_len, d1_rev_arr);
dname_reverse(d2, d2_len, d2_rev_arr);
- int res = 0;
- while (res == 0 && d1_rev != NULL) {
- res = lf_cmp(d1_rev, d2_rev);
- d1_rev = knot_wire_next_label(d1_rev, NULL);
- d2_rev = knot_wire_next_label(d2_rev, NULL);
- }
-
- kr_require(res != 0 || d2_rev == NULL);
- return res;
+ do {
+ int res = lf_cmp(d1_rev, d2_rev);
+ if (res != 0 || d1_rev[0] == '\0')
+ return res;
+ d1_rev = knot_dname_next_label(d1_rev);
+ d2_rev = knot_dname_next_label(d2_rev);
+ } while (true);
}
@@ -251,7 +249,7 @@ int kr_nsec_negative(const ranked_rr_array_t *rrrs, uint32_t qry_uid,
ssynth[1] = '*';
const knot_dname_t *clencl = sname;
for (int l = sname_labels; l > clencl_labels; --l)
- clencl = knot_wire_next_label(clencl, NULL);
+ clencl = knot_dname_next_label(clencl);
(void)!!knot_dname_store(&ssynth[2], clencl);
// Try to (dis)prove the source of synthesis by a covering or matching NSEC.
diff --git a/lib/dnssec/nsec3.c b/lib/dnssec/nsec3.c
index 4199f25..4ff2750 100644
--- a/lib/dnssec/nsec3.c
+++ b/lib/dnssec/nsec3.c
@@ -143,7 +143,7 @@ static int closest_encloser_match(int *flags, const knot_rrset_t *nsec3,
goto fail;
}
- const knot_dname_t *encloser = knot_wire_next_label(name, NULL);
+ const knot_dname_t *encloser = knot_dname_next_label(name);
*skipped = 1;
/* Avoid doing too much work on SHA1, mitigating:
@@ -154,7 +154,7 @@ static int closest_encloser_match(int *flags, const knot_rrset_t *nsec3,
const int max_labels = knot_dname_labels(nsec3->owner, NULL) - 1
+ kr_nsec3_max_depth(&params);
for (int l = knot_dname_labels(encloser, NULL); l > max_labels; --l) {
- encloser = knot_wire_next_label(encloser, NULL);
+ encloser = knot_dname_next_label(encloser);
++(*skipped);
}
@@ -174,7 +174,7 @@ static int closest_encloser_match(int *flags, const knot_rrset_t *nsec3,
if (!encloser[0])
break;
- encloser = knot_wire_next_label(encloser, NULL);
+ encloser = knot_dname_next_label(encloser);
++(*skipped);
}
@@ -404,7 +404,7 @@ static int closest_encloser_proof(const knot_pkt_t *pkt,
for (unsigned j = 0; j < skipped; ++j) {
if (kr_fails_assert(next_closer[0]))
return kr_error(EINVAL);
- next_closer = knot_wire_next_label(next_closer, NULL);
+ next_closer = knot_dname_next_label(next_closer);
}
for (unsigned j = 0; j < sec->count; ++j) {
const knot_rrset_t *rrset_j = knot_pkt_rr(sec, j);
@@ -425,7 +425,7 @@ static int closest_encloser_proof(const knot_pkt_t *pkt,
if ((flags & FLG_CLOSEST_PROVABLE_ENCLOSER) && (flags & FLG_NAME_COVERED) && next_closer) {
if (encloser_name && next_closer[0])
- *encloser_name = knot_wire_next_label(next_closer, NULL);
+ *encloser_name = knot_dname_next_label(next_closer);
if (matching_encloser_nsec3)
*matching_encloser_nsec3 = matching;
if (covering_next_nsec3)
@@ -569,7 +569,7 @@ int kr_nsec3_wildcard_answer_response_check(const knot_pkt_t *pkt, knot_section_
for (int i = 0; i < trim_to_next; ++i) {
if (kr_fails_assert(sname[0]))
return kr_error(EINVAL);
- sname = knot_wire_next_label(sname, NULL);
+ sname = knot_dname_next_label(sname);
}
int flags = 0;
diff --git a/lib/dnssec/signature.c b/lib/dnssec/signature.c
index aadb5cb..12ed09e 100644
--- a/lib/dnssec/signature.c
+++ b/lib/dnssec/signature.c
@@ -208,7 +208,7 @@ static int sign_ctx_add_records(dnssec_sign_ctx_t *ctx, const knot_rrset_t *cove
for (int j = 0; j < trim_labels; ++j) {
if (kr_fails_assert(beginp[0]))
return kr_error(EINVAL);
- beginp = (uint8_t *) knot_wire_next_label(beginp, NULL);
+ beginp = (uint8_t *) knot_dname_next_label(beginp);
if (kr_fails_assert(beginp))
return kr_error(EFAULT);
}
diff --git a/lib/dnssec/ta.c b/lib/dnssec/ta.c
index becf7d8..13659c1 100644
--- a/lib/dnssec/ta.c
+++ b/lib/dnssec/ta.c
@@ -28,9 +28,9 @@ const knot_dname_t * kr_ta_closest(const struct kr_context *ctx, const knot_dnam
kr_require(ctx && name);
if (type == KNOT_RRTYPE_DS && name[0] != '\0') {
/* DS is parent-side record, so the parent name needs to be covered. */
- name = knot_wire_next_label(name, NULL);
+ name = knot_dname_next_label(name);
}
- while (name) {
+ do {
struct kr_context *ctx_nc = (struct kr_context *)/*const-cast*/ctx;
if (kr_ta_get(ctx_nc->trust_anchors, name)) {
return name;
@@ -38,9 +38,12 @@ const knot_dname_t * kr_ta_closest(const struct kr_context *ctx, const knot_dnam
if (kr_ta_get(ctx_nc->negative_anchors, name)) {
return NULL;
}
- name = knot_wire_next_label(name, NULL);
- }
- return NULL;
+ if (name[0] == '\0') {
+ return NULL;
+ } else {
+ name = knot_dname_next_label(name);
+ }
+ } while (true);
}
/* @internal Create DS from DNSKEY, caller MUST free dst if successful. */
diff --git a/lib/generic/array.h b/lib/generic/array.h
index 9f35118..9bea546 100644
--- a/lib/generic/array.h
+++ b/lib/generic/array.h
@@ -113,7 +113,7 @@ static inline void array_std_free(void *baton, void *p)
* Mempool usage: pass kr_memreserve and a knot_mm_t* .
* @return 0 if success, <0 on failure */
#define array_reserve_mm(array, n, reserve, baton) \
- (reserve)((baton), (void **) &(array).at, sizeof((array).at[0]), (n), &(array).cap)
+ (reserve)((baton), (void **) &(array).at, array_member_size((array)), (n), &(array).cap)
/**
* Push value at the end of the array, resize it if necessary.
@@ -122,9 +122,9 @@ static inline void array_std_free(void *baton, void *p)
* @return element index on success, <0 on failure
*/
#define array_push_mm(array, val, reserve, baton) \
- (int)((array).len < (array).cap ? ((array).at[(array).len] = val, (array).len++) \
+ (int)((array).len < (array).cap ? ((array).at[(array).len] = (val), (array).len++) \
: (array_reserve_mm(array, ((array).cap + 1), reserve, baton) < 0 ? -1 \
- : ((array).at[(array).len] = val, (array).len++)))
+ : ((array).at[(array).len] = (val), (array).len++)))
/**
* Push value at the end of the array, resize it if necessary (plain malloc/free).
@@ -152,6 +152,12 @@ static inline void array_std_free(void *baton, void *p)
* @warning Undefined if the array is empty.
*/
#define array_tail(array) \
- (array).at[(array).len - 1]
+ (array).at[(array).len - 1]
+
+/**
+ * Return the size of a singular member in the array.
+ */
+#define array_member_size(array) \
+ (sizeof((array).at[0])) // NOLINT(bugprone-sizeof-expression): usually a false-positive
/** @} */
diff --git a/lib/generic/lru.h b/lib/generic/lru.h
index 448c1b9..1c1dd81 100644
--- a/lib/generic/lru.h
+++ b/lib/generic/lru.h
@@ -130,7 +130,10 @@
#define lru_get_new(table, key_, len_, is_new) \
(__typeof__((table)->pdata_t)) \
lru_get_impl(&(table)->lru, (key_), (len_), \
- sizeof(*(table)->pdata_t), true, is_new)
+ lru_member_size((table)), true, is_new)
+
+#define lru_member_size(table) \
+ (sizeof(*(table)->pdata_t)) // NOLINT(bugprone-sizeof-expression): usually a false-positive
/**
* @brief Apply a function to every item in LRU.
diff --git a/lib/generic/queue.c b/lib/generic/queue.c
index 5bed153..29609dd 100644
--- a/lib/generic/queue.c
+++ b/lib/generic/queue.c
@@ -62,7 +62,7 @@ void * queue_push_impl(struct queue *q)
if (t->begin * 2 >= t->cap) {
/* Utilization is below 50%, so let's shift (no overlap).
* (size_t cast is to avoid unintended sign-extension) */
- memcpy(t->data, t->data + t->begin * q->item_size,
+ memcpy(t->data, t->data + t->begin * (size_t)q->item_size,
(size_t) (t->end - t->begin) * (size_t) q->item_size);
t->end -= t->begin;
t->begin = 0;
@@ -76,7 +76,7 @@ void * queue_push_impl(struct queue *q)
kr_require(t->end < t->cap);
++(q->len);
++(t->end);
- return t->data + q->item_size * (t->end - 1);
+ return t->data + (size_t)q->item_size * (t->end - 1);
}
/* Return pointer to the space for the new element. */
@@ -98,8 +98,8 @@ void * queue_push_head_impl(struct queue *q)
* Computations here are simplified due to h->begin == 0.
* (size_t cast is to avoid unintended sign-extension) */
const int cnt = h->end;
- memcpy(h->data + (h->cap - cnt) * q->item_size, h->data,
- (size_t) cnt * (size_t) q->item_size);
+ memcpy(h->data + ((size_t)h->cap - cnt) * q->item_size, h->data,
+ (size_t)cnt * (size_t)q->item_size);
h->begin = h->cap - cnt;
h->end = h->cap;
} else {
@@ -113,7 +113,7 @@ void * queue_push_head_impl(struct queue *q)
kr_require(h->begin > 0);
--(h->begin);
++(q->len);
- return h->data + q->item_size * h->begin;
+ return h->data + (size_t)q->item_size * h->begin;
}
void queue_pop_impl(struct queue *q)
diff --git a/lib/generic/queue.h b/lib/generic/queue.h
index 3fa52ce..fc2a86f 100644
--- a/lib/generic/queue.h
+++ b/lib/generic/queue.h
@@ -71,7 +71,7 @@
/** @brief Initialize a queue. You can malloc() it the usual way. */
#define queue_init(q) do { \
(void)(((__typeof__(((q).pdata_t)))0) == (void *)0); /* typecheck queue_t */ \
- queue_init_impl(&(q).queue, sizeof(*(q).pdata_t)); \
+ queue_init_impl(&(q).queue, queue_member_size((q))); \
} while (false)
/** @brief De-initialize a queue: make it invalid and free any inner allocations. */
@@ -105,6 +105,10 @@
#define queue_len(q) \
((const size_t)(q).queue.len)
+/** @brief Return the size of a single element in the queue. */
+#define queue_member_size(q) \
+ (sizeof(*(q).pdata_t)) // NOLINT(bugprone-sizeof-expression): usually a false-positive
+
/** @brief Type for queue iterator, parametrized by value type.
* It's a simple structure that owns no other resources.
diff --git a/lib/generic/trie.c b/lib/generic/trie.c
index f9aceda..21254eb 100644
--- a/lib/generic/trie.c
+++ b/lib/generic/trie.c
@@ -470,6 +470,10 @@ static int ns_longer_alloc(nstack_t *ns)
memcpy(st, ns->stack, ns->len * sizeof(node_t *));
} else {
st = realloc(ns->stack, new_size);
+ if (st == NULL) {
+ free(ns->stack); // left behind by realloc, callers bail out
+ ns->stack = NULL;
+ }
}
if (st == NULL)
return KNOT_ENOMEM;
diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c
index dfb7c87..656bc2d 100644
--- a/lib/layer/iterate.c
+++ b/lib/layer/iterate.c
@@ -51,7 +51,7 @@ static const knot_dname_t *minimized_qname(struct kr_query *query, uint16_t *qty
int cut_labels = knot_dname_labels(query->zone_cut.name, NULL);
int qname_labels = knot_dname_labels(qname, NULL);
while(qname[0] && qname_labels > cut_labels + 1) {
- qname = knot_wire_next_label(qname, NULL);
+ qname = knot_dname_next_label(qname);
qname_labels -= 1;
}
@@ -825,7 +825,10 @@ static int process_answer(knot_pkt_t *pkt, struct kr_request *req)
}
} else if (!query->parent) {
/* Answer for initial query */
- const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0);
+ const bool to_wire = ((pkt_class & (PKT_NXDOMAIN|PKT_NODATA)) != 0)
+ /* We need to cover the case of positive wildcard answer
+ * with over-limit NSEC3 iterations. */
+ || query->flags.DNSSEC_WEXPAND;
state = pick_authority(pkt, req, to_wire);
if (state != kr_ok()) {
return KR_STATE_FAIL;
diff --git a/lib/layer/validate.c b/lib/layer/validate.c
index 3bdb205..af20b2e 100644
--- a/lib/layer/validate.c
+++ b/lib/layer/validate.c
@@ -709,7 +709,7 @@ static int check_validation_result(kr_layer_t *ctx, const knot_pkt_t *pkt, ranke
invalid_entry = entry;
break;
} else if (kr_rank_test(entry->rank, KR_RANK_MISSING) &&
- !invalid_entry) {
+ !invalid_entry) { // NOLINT(bugprone-branch-clone)
invalid_entry = entry;
} else if (kr_rank_test(entry->rank, KR_RANK_OMIT)) {
continue;
diff --git a/lib/log.c b/lib/log.c
index 9c8c7a6..9fb16e9 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -124,7 +124,7 @@ void kr_log_fmt(enum kr_log_group group, kr_log_level_t level, const char *file,
}
va_start(args, fmt);
- vfprintf(stream, fmt, args);
+ (void)vfprintf(stream, fmt, args);
va_end(args);
}
}
diff --git a/lib/resolve.c b/lib/resolve.c
index e24a40b..d8198c3 100644
--- a/lib/resolve.c
+++ b/lib/resolve.c
@@ -184,7 +184,7 @@ static void check_empty_nonterms(struct kr_query *qry, knot_pkt_t *pkt, struct k
* otherwise this would risk leaking information to parent if the NODATA TTD > zone cut TTD. */
int labels = knot_dname_labels(target, NULL) - knot_dname_labels(cut_name, NULL);
while (target[0] && labels > 2) {
- target = knot_wire_next_label(target, NULL);
+ target = knot_dname_next_label(target);
--labels;
}
for (int i = 0; i < labels; ++i) {
@@ -196,7 +196,7 @@ static void check_empty_nonterms(struct kr_query *qry, knot_pkt_t *pkt, struct k
break;
}
kr_assert(target[0]);
- target = knot_wire_next_label(target, NULL);
+ target = knot_dname_next_label(target);
}
kr_cache_commit(cache);
#endif
@@ -853,6 +853,8 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo
if (transport && !qry->flags.CACHED) {
if (!(request->state & KR_STATE_FAIL)) {
/* Do not complete NS address resolution on soft-fail. */
+ if (kr_fails_assert(packet->wire))
+ return KR_STATE_FAIL;
const int rcode = knot_wire_get_rcode(packet->wire);
if (rcode != KNOT_RCODE_SERVFAIL && rcode != KNOT_RCODE_REFUSED) {
qry->flags.AWAIT_IPV6 = false;
@@ -886,7 +888,7 @@ int kr_resolve_consume(struct kr_request *request, struct kr_transport **transpo
}
/* Pop query if resolved. */
- if (request->state == KR_STATE_YIELD) {
+ if (request->state == KR_STATE_YIELD) { // NOLINT(bugprone-branch-clone)
return KR_STATE_PRODUCE; /* Requery */
} else if (qry->flags.RESOLVED) {
kr_rplan_pop(rplan, qry);
@@ -1006,7 +1008,7 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query
int cut_labels = knot_dname_labels(qry->zone_cut.name, NULL);
int wanted_name_labels = knot_dname_labels(wanted_name, NULL);
while (wanted_name[0] && wanted_name_labels > cut_labels + name_offset) {
- wanted_name = knot_wire_next_label(wanted_name, NULL);
+ wanted_name = knot_dname_next_label(wanted_name);
wanted_name_labels -= 1;
}
minimized = (wanted_name != qry->sname);
@@ -1051,7 +1053,7 @@ static int forward_trust_chain_check(struct kr_request *request, struct kr_query
/* set `nods` */
if ((qry->stype == KNOT_RRTYPE_DS) &&
- knot_dname_is_equal(wanted_name, qry->sname)) {
+ knot_dname_is_equal(wanted_name, qry->sname)) { // NOLINT(bugprone-branch-clone)
nods = true;
} else if (resume && !ds_req) {
nods = false;
@@ -1232,11 +1234,11 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot
const knot_dname_t *parent = qry->parent->zone_cut.name;
if (parent[0] != '\0'
&& knot_dname_in_bailiwick(qry->sname, parent) >= 0) {
- requested_name = knot_wire_next_label(parent, NULL);
+ requested_name = knot_dname_next_label(parent);
}
- } else if ((qry->stype == KNOT_RRTYPE_DS) && (qry->sname[0] != '\0')) {
+ } else if ((qry->stype == KNOT_RRTYPE_DS) && (requested_name[0] != '\0')) {
/* If this is explicit DS query, start from encloser too. */
- requested_name = knot_wire_next_label(requested_name, NULL);
+ requested_name = knot_dname_next_label(requested_name);
}
int state = KR_STATE_FAIL;
@@ -1245,7 +1247,8 @@ static int zone_cut_check(struct kr_request *request, struct kr_query *qry, knot
if (state == KR_STATE_DONE || (state & KR_STATE_FAIL)) {
return state;
} else if (state == KR_STATE_CONSUME) {
- requested_name = knot_wire_next_label(requested_name, NULL);
+ kr_require(requested_name[0] != '\0');
+ requested_name = knot_dname_next_label(requested_name);
}
} while (state == KR_STATE_CONSUME);
@@ -1611,6 +1614,7 @@ int kr_resolve_finish(struct kr_request *request, int state)
knot_wire_clear_ad(wire);
knot_wire_clear_aa(wire);
knot_wire_set_rcode(wire, KNOT_RCODE_SERVFAIL);
+ default:; // Do nothing
}
}
}
diff --git a/lib/selection.c b/lib/selection.c
index c25782e..cce5d42 100644
--- a/lib/selection.c
+++ b/lib/selection.c
@@ -149,7 +149,7 @@ struct rtt_state get_rtt_state(const uint8_t *ip, size_t len,
knot_db_val_t key = cache_key(ip, len);
- if (cache->api->read(db, stats, &key, &value, 1)) {
+ if (cache->api->read(db, stats, &key, &value, 1)) { // NOLINT(bugprone-branch-clone)
state = default_rtt_state;
} else if (kr_fails_assert(value.len == sizeof(struct rtt_state))) {
// shouldn't happen but let's be more robust
diff --git a/lib/utils.c b/lib/utils.c
index 8b7e127..2a0635e 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -921,9 +921,8 @@ int kr_ranked_rrarray_add(ranked_rr_array_t *array, const knot_rrset_t *rr,
static int rdata_p_cmp(const void *rp1, const void *rp2)
{
/* Just correct types of the parameters and pass them dereferenced. */
- const knot_rdata_t
- *const *r1 = rp1,
- *const *r2 = rp2;
+ const knot_rdata_t *const *r1 = (const knot_rdata_t *const *)rp1;
+ const knot_rdata_t *const *r2 = (const knot_rdata_t *const *)rp2;
return knot_rdata_cmp(*r1, *r2);
}
int kr_ranked_rrarray_finalize(ranked_rr_array_t *array, uint32_t qry_uid, knot_mm_t *pool)
@@ -948,7 +947,7 @@ int kr_ranked_rrarray_finalize(ranked_rr_array_t *array, uint32_t qry_uid, knot_
} else {
/* Multiple RRs; first: sort the array. */
stashed->rr->additional = NULL;
- qsort(ra->at, ra->len, sizeof(ra->at[0]), rdata_p_cmp);
+ qsort((void *)ra->at, ra->len, array_member_size(*ra), rdata_p_cmp);
/* Prune duplicates: NULL all except the last instance. */
int dup_count = 0;
for (int i = 0; i + 1 < ra->len; ++i) {
diff --git a/lib/utils.h b/lib/utils.h
index fab13fe..e03b473 100644
--- a/lib/utils.h
+++ b/lib/utils.h
@@ -616,4 +616,10 @@ static inline size_t kr_dname_prefixlen(const uint8_t *name, unsigned nlabels)
#endif
);
}
+#if KNOT_VERSION_HEX < 0x030400
+static inline const knot_dname_t * knot_dname_next_label(const knot_dname_t *dname)
+{
+ return knot_wire_next_label(dname, NULL);
+}
+#endif
diff --git a/lib/zonecut.c b/lib/zonecut.c
index 2bbd26f..aea38e4 100644
--- a/lib/zonecut.c
+++ b/lib/zonecut.c
@@ -580,7 +580,7 @@ int kr_zonecut_find_cached(struct kr_context *ctx, struct kr_zonecut *cut,
trie_clear(cut->nsset);
/* Subtract label from QNAME. */
if (!is_root) {
- label = knot_wire_next_label(label, NULL);
+ label = knot_dname_next_label(label);
} else {
ret = kr_error(ENOENT);
break;
diff --git a/meson.build b/meson.build
index 8e22e17..47c234c 100644
--- a/meson.build
+++ b/meson.build
@@ -4,7 +4,7 @@ project(
'knot-resolver',
['c', 'cpp'],
license: 'GPLv3+',
- version: '5.7.2',
+ version: '5.7.3',
default_options: ['c_std=gnu11', 'b_ndebug=true'],
meson_version: '>=0.49',
)
@@ -59,6 +59,20 @@ systemd_unit_dir = prefix / 'lib' / 'systemd' / 'system'
systemd_tmpfiles_dir = prefix / 'lib' / 'tmpfiles.d'
systemd_sysusers_dir = prefix / 'lib' / 'sysusers.d'
+## RPath
+# When installing from sources into a non-standard prefix and the library is
+# shared/dynamic, we need to set the executables' RPATH so that they can find
+# `libkresd`, otherwise running them will fail with dynamic linkage errors
+auto_prefixes = ['/', '/usr', '/usr/local']
+rpath_opt = get_option('install_rpath')
+if (get_option('default_library') == 'static' or
+ rpath_opt == 'disabled' or
+ (rpath_opt == 'auto' and prefix in auto_prefixes))
+ rpath = ''
+else
+ rpath = prefix / get_option('libdir')
+endif
+
## Trust anchors
managed_ta = get_option('managed_ta') == 'enabled'
keyfile_default = etc_dir / get_option('keyfile_default')
diff --git a/meson_options.txt b/meson_options.txt
index 576d385..f09f46d 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -217,3 +217,15 @@ option(
value: 'auto',
description: 'cmocka unit tests',
)
+
+option(
+ 'install_rpath',
+ type: 'combo',
+ choices: [
+ 'auto',
+ 'enabled',
+ 'disabled',
+ ],
+ value: 'auto',
+ description: 'add rpath to the knot resolver executables',
+)
diff --git a/modules/bogus_log/meson.build b/modules/bogus_log/meson.build
index e2faed5..3fa8d3c 100644
--- a/modules/bogus_log/meson.build
+++ b/modules/bogus_log/meson.build
@@ -9,7 +9,7 @@ c_src_lint += bogus_log_src
bogus_log_mod = shared_module(
'bogus_log',
bogus_log_src,
- dependencies: libknot,
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
diff --git a/modules/dnstap/dnstap.c b/modules/dnstap/dnstap.c
index 7572667..07780fc 100644
--- a/modules/dnstap/dnstap.c
+++ b/modules/dnstap/dnstap.c
@@ -193,6 +193,7 @@ static int dnstap_log(kr_layer_t *ctx, enum dnstap_log_phase phase) {
m.socket_family = DNSTAP__SOCKET_FAMILY__INET6;
m.has_socket_family = true;
break;
+ default:;
}
}
diff --git a/modules/dnstap/meson.build b/modules/dnstap/meson.build
index e8a94bf..038bf3e 100644
--- a/modules/dnstap/meson.build
+++ b/modules/dnstap/meson.build
@@ -43,11 +43,10 @@ if build_dnstap
dnstap_mod = shared_module(
'dnstap',
dnstap_src,
- dependencies: [
+ dependencies: mod_deps + [
declare_dependency(sources: dnstap_pb),
libfstrm,
libprotobuf_c,
- libknot,
],
include_directories: mod_inc_dir,
name_prefix: '',
diff --git a/modules/edns_keepalive/meson.build b/modules/edns_keepalive/meson.build
index d125ec4..8370cdb 100644
--- a/modules/edns_keepalive/meson.build
+++ b/modules/edns_keepalive/meson.build
@@ -9,7 +9,7 @@ c_src_lint += edns_keepalive_src
edns_keepalive_mod = shared_module(
'edns_keepalive',
edns_keepalive_src,
- dependencies: libknot,
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
diff --git a/modules/extended_error/meson.build b/modules/extended_error/meson.build
index 15a1772..9de514a 100644
--- a/modules/extended_error/meson.build
+++ b/modules/extended_error/meson.build
@@ -9,9 +9,7 @@ c_src_lint += extended_error_src
extended_error_mod = shared_module(
'extended_error',
extended_error_src,
- dependencies: [
- libknot,
- ],
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
diff --git a/modules/hints/hints.c b/modules/hints/hints.c
index a3f2f30..2195ca3 100644
--- a/modules/hints/hints.c
+++ b/modules/hints/hints.c
@@ -194,9 +194,11 @@ static const knot_dname_t * raw_addr2reverse(const uint8_t *raw_addr, int family
#undef REV_MAXLEN
if (family == AF_INET) {
- snprintf(reverse_addr, sizeof(reverse_addr),
- "%d.%d.%d.%d.in-addr.arpa.",
- raw_addr[3], raw_addr[2], raw_addr[1], raw_addr[0]);
+ int ret = snprintf(reverse_addr, sizeof(reverse_addr),
+ "%d.%d.%d.%d.in-addr.arpa.",
+ raw_addr[3], raw_addr[2], raw_addr[1], raw_addr[0]);
+ if (kr_fails_assert(ret > 0 && ret <= sizeof(reverse_addr)))
+ return NULL;
} else if (family == AF_INET6) {
char *ra_it = reverse_addr;
for (int i = 15; i >= 0; --i) {
@@ -262,7 +264,10 @@ static int add_reverse_pair(struct kr_zonecut *hints, const char *name, const ch
return kr_error(EINVAL);
}
- return kr_zonecut_add(hints, key, ptr_name, knot_dname_size(ptr_name));
+ size_t dname_size = knot_dname_size(ptr_name);
+ if (kr_fails_assert(dname_size < INT_MAX))
+ return kr_error(EINVAL);
+ return kr_zonecut_add(hints, key, ptr_name, (int)dname_size);
}
/** For a given name, remove either one address or all of them (if == NULL).
@@ -276,7 +281,9 @@ static int del_pair(struct hints_data *data, const char *name, const char *addr)
if (!knot_dname_from_str(key, name, sizeof(key))) {
return kr_error(EINVAL);
}
- int key_len = knot_dname_size(key);
+ size_t key_len = knot_dname_size(key);
+ if (kr_fails_assert(key_len <= KNOT_DNAME_MAXLEN))
+ return kr_error(EINVAL);
if (addr) {
/* Remove the pair. */
@@ -286,7 +293,7 @@ static int del_pair(struct hints_data *data, const char *name, const char *addr)
}
const knot_dname_t *reverse_key = addr2reverse(addr);
- kr_zonecut_del(&data->reverse_hints, reverse_key, key, key_len);
+ kr_zonecut_del(&data->reverse_hints, reverse_key, key, (int)key_len);
return kr_zonecut_del(&data->hints, key,
kr_inaddr(&ia.ip), kr_inaddr_len(&ia.ip));
}
@@ -306,7 +313,7 @@ static int del_pair(struct hints_data *data, const char *name, const char *addr)
? AF_INET : AF_INET6;
const knot_dname_t *reverse_key = raw_addr2reverse(addr_val, family);
if (reverse_key != NULL) {
- kr_zonecut_del(&data->reverse_hints, reverse_key, key, key_len);
+ kr_zonecut_del(&data->reverse_hints, reverse_key, key, (int)key_len);
}
}
diff --git a/modules/hints/meson.build b/modules/hints/meson.build
index b837918..7e681f1 100644
--- a/modules/hints/meson.build
+++ b/modules/hints/meson.build
@@ -9,10 +9,7 @@ c_src_lint += hints_src
hints_mod = shared_module(
'hints',
hints_src,
- dependencies: [
- libknot,
- luajit,
- ],
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
@@ -21,5 +18,5 @@ hints_mod = shared_module(
)
config_tests += [
- ['hints', files('tests/hints.test.lua'), ['skip_asan']],
+ ['hints', files('tests/hints.test.lua')],
]
diff --git a/modules/http/meson.build b/modules/http/meson.build
index a36e9eb..7d89215 100644
--- a/modules/http/meson.build
+++ b/modules/http/meson.build
@@ -21,7 +21,7 @@ lua_mod_src += [
config_tests += [
['http', files('http.test.lua')],
['http.doh', files('http_doh.test.lua')],
- ['http.tls', files('test_tls/tls.test.lua')],
+ ['http.tls', files('test_tls/tls.test.lua'), ['skip_asan']],
]
# install static files
@@ -45,7 +45,7 @@ install_subdir(
)
# auxiliary debug library for HTTP module - doesn't compile on Cygwin
-if openssl.found() and host_machine.system() != 'cygwin'
+if openssl.found() and host_machine.system() not in [ 'cygwin', 'darwin' ]
debug_opensslkeylog_mod = shared_module(
'debug_opensslkeylog',
['debug_opensslkeylog.c'],
diff --git a/modules/meson.build b/modules/meson.build
index 3861225..48bd478 100644
--- a/modules/meson.build
+++ b/modules/meson.build
@@ -35,6 +35,13 @@ integr_tests += [
mod_inc_dir = include_directories('..', '../contrib',
luajit.get_pkgconfig_variable('includedir'))
+mod_deps = [
+ contrib_dep,
+ libknot,
+ libuv,
+ luajit,
+]
+
# handle more complex C/LUA modules separately
subdir('bogus_log')
# cookies module is not currently used
diff --git a/modules/nsid/meson.build b/modules/nsid/meson.build
index 354e70b..3c418bc 100644
--- a/modules/nsid/meson.build
+++ b/modules/nsid/meson.build
@@ -9,10 +9,7 @@ c_src_lint += nsid_src
nsid_mod = shared_module(
'nsid',
nsid_src,
- dependencies: [
- libknot,
- luajit,
- ],
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
diff --git a/modules/policy/lua-aho-corasick/.gitignore b/modules/policy/lua-aho-corasick/.gitignore
new file mode 100644
index 0000000..04fd221
--- /dev/null
+++ b/modules/policy/lua-aho-corasick/.gitignore
@@ -0,0 +1,6 @@
+*.d
+*.o
+*.a
+*.so
+*_dep.txt
+tests/testinput
diff --git a/modules/refuse_nord/meson.build b/modules/refuse_nord/meson.build
index 5142ded..7dc8b88 100644
--- a/modules/refuse_nord/meson.build
+++ b/modules/refuse_nord/meson.build
@@ -13,7 +13,7 @@ c_src_lint += refuse_nord_src
refuse_nord_mod = shared_module(
'refuse_nord',
refuse_nord_src,
- dependencies: libknot,
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
diff --git a/modules/stats/README.rst b/modules/stats/README.rst
index 7d423aa..014c9f0 100644
--- a/modules/stats/README.rst
+++ b/modules/stats/README.rst
@@ -89,6 +89,8 @@ Built-in counters keep track of number of queries and answers matching specific
+-----------------+----------------------------------+
| answer.slow | completed in more than 1500ms |
+-----------------+----------------------------------+
+| answer.sum_ms | sum of all latencies in ms |
++-----------------+----------------------------------+
+-----------------+----------------------------------+
| **Answer flags** |
diff --git a/modules/stats/meson.build b/modules/stats/meson.build
index cb4ccd6..e1f4a49 100644
--- a/modules/stats/meson.build
+++ b/modules/stats/meson.build
@@ -14,9 +14,7 @@ integr_tests += [
stats_mod = shared_module(
'stats',
stats_src,
- dependencies: [
- libknot,
- ],
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
name_prefix: '',
install: true,
diff --git a/modules/stats/stats.c b/modules/stats/stats.c
index ebb2877..3679615 100644
--- a/modules/stats/stats.c
+++ b/modules/stats/stats.c
@@ -42,11 +42,13 @@
X(answer,total) X(answer,noerror) X(answer,nodata) X(answer,nxdomain) X(answer,servfail) \
X(answer,cached) X(answer,1ms) X(answer,10ms) X(answer,50ms) X(answer,100ms) \
X(answer,250ms) X(answer,500ms) X(answer,1000ms) X(answer,1500ms) X(answer,slow) \
+ X(answer,sum_ms) \
X(answer,aa) X(answer,tc) X(answer,rd) X(answer,ra) X(answer, ad) X(answer,cd) \
X(answer,edns0) X(answer,do) \
X(query,edns) X(query,dnssec) \
- X(request,total) X(request,udp) X(request,tcp) X(request,xdp) \
- X(request,dot) X(request,doh) X(request,internal) \
+ X(request,total) X(request,total4) X(request,total6) X(request,internal) \
+ X(request,udp4) X(request,tcp4) X(request,xdp4) X(request,dot4) X(request,doh4) \
+ X(request,udp6) X(request,tcp6) X(request,xdp6) X(request,dot6) X(request,doh6) \
X(const,end)
enum const_metric {
@@ -63,6 +65,28 @@ static struct const_metric_elm const_metrics[] = {
CONST_METRICS(X)
#undef X
};
+
+/// These metrics are read-only views, each simply summing a pair of const_metrics items.
+struct sum_metric {
+ const char *key;
+ const size_t *val1, *val2;
+};
+static const struct sum_metric sum_metrics[] = {
+ // We're using this to aggregate v4 + v6 pairs.
+ #define DEF(proto) { \
+ .key = "request." #proto, \
+ .val1 = &const_metrics[metric_request_ ## proto ## 4].val, \
+ .val2 = &const_metrics[metric_request_ ## proto ## 6].val, \
+ }
+ DEF(udp),
+ DEF(tcp),
+ DEF(xdp),
+ DEF(dot),
+ DEF(doh),
+ #undef DEF
+};
+static const size_t sum_metrics_len = sizeof(sum_metrics) / sizeof(sum_metrics[0]);
+
/** @endcond */
/** @internal LRU hash of most frequent names. */
@@ -116,7 +140,7 @@ static inline int collect_key(char *key, const knot_dname_t *name, uint16_t type
if (key_len < 0) {
return kr_error(key_len);
}
- return key_len + sizeof(type);
+ return key_len + (int)sizeof(type);
}
static void collect_sample(struct stat_data *data, struct kr_rplan *rplan)
@@ -184,19 +208,26 @@ static int collect_transport(kr_layer_t *ctx)
}
/**
- * Count each transport only once,
+ * Apart from the "total" stats, count each transport only once,
* i.e. DoT does not count as TCP and XDP does not count as UDP.
+ * We have two counts for each - IPv6 and IPv4 separately.
*/
+ const bool isIPv6 = req->qsource.addr->sa_family == AF_INET6;
+ #define INC_PROTO(proto) \
+ stat_const_add(data, isIPv6 ? metric_request_ ## proto ## 6 \
+ : metric_request_ ## proto ## 4, 1)
+ INC_PROTO(total);
if (req->qsource.flags.http)
- stat_const_add(data, metric_request_doh, 1);
+ INC_PROTO(doh);
else if (req->qsource.flags.tls)
- stat_const_add(data, metric_request_dot, 1);
+ INC_PROTO(dot);
else if (req->qsource.flags.tcp)
- stat_const_add(data, metric_request_tcp, 1);
+ INC_PROTO(tcp);
else if (req->qsource.flags.xdp)
- stat_const_add(data, metric_request_xdp, 1);
+ INC_PROTO(xdp);
else
- stat_const_add(data, metric_request_udp, 1);
+ INC_PROTO(udp);
+ #undef INC_PROTO
return ctx->state;
}
@@ -220,6 +251,7 @@ static int collect(kr_layer_t *ctx)
/* Histogram of answer latency. */
struct kr_query *first = rplan->resolved.at[0];
uint64_t elapsed = kr_now() - first->timestamp_mono;
+ stat_const_add(data, metric_answer_sum_ms, elapsed);
if (elapsed <= 1) {
stat_const_add(data, metric_answer_1ms, 1);
} else if (elapsed <= 10) {
@@ -272,6 +304,7 @@ static int collect(kr_layer_t *ctx)
* Set nominal value of a key.
*
* Input: { key, val }
+ * Aggregate metrics can't be set.
*
*/
static char* stats_set(void *env, struct kr_module *module, const char *args)
@@ -313,26 +346,36 @@ static char* stats_get(void *env, struct kr_module *module, const char *args)
struct stat_data *data = module->data;
/* Expecting CHAR_BIT to be 8, this is a safe bet */
- char *ret = malloc(3 * sizeof(size_t) + 2);
- if (!ret) {
- return NULL;
- }
+ char *str_value = NULL;
+ int ret = 0;
/* Check if it exists in const map. */
for (unsigned i = 0; i < metric_const_end; ++i) {
if (strcmp(const_metrics[i].key, args) == 0) {
- sprintf(ret, "%zu", const_metrics[i].val);
- return ret;
+ ret = asprintf(&str_value, "%zu", const_metrics[i].val);
+ if (ret < 0)
+ return NULL;
+ return str_value;
+ }
+ }
+ /* Check if it exists in aggregate metrics. */
+ for (int i = 0; i < sum_metrics_len; ++i) {
+ const struct sum_metric *smi = &sum_metrics[i];
+ if (strcmp(smi->key, args) == 0) {
+ ret = asprintf(&str_value, "%zu", *smi->val1 + *smi->val2);
+ if (ret < 0)
+ return NULL;
+ return str_value;
}
}
/* Check in variable map */
trie_val_t *val = trie_get_try(data->trie, args, strlen(args));
- if (!val) {
- free(ret);
+ if (!val)
return NULL;
- }
- sprintf(ret, "%zu", (size_t) *val);
- return ret;
+ ret = asprintf(&str_value, "%zu", (size_t) *val);
+ if (ret < 0)
+ return NULL;
+ return str_value;
}
/** Checks whether:
@@ -356,9 +399,9 @@ static int list_entry(const char *key, uint32_t key_len, trie_val_t *val, void *
struct list_entry_context *ctx = baton;
if (!key_matches_prefix(key, key_len, ctx->key_prefix, ctx->key_prefix_len))
return 0;
- size_t number = (size_t) *val;
+ size_t number = (size_t)*val;
auto_free char *key_nt = strndup(key, key_len);
- json_append_member(ctx->root, key_nt, json_mknumber(number));
+ json_append_member(ctx->root, key_nt, json_mknumber((double)number));
return 0;
}
@@ -375,7 +418,14 @@ static char* stats_list(void *env, struct kr_module *module, const char *args)
for (unsigned i = 0; i < metric_const_end; ++i) {
struct const_metric_elm *elm = &const_metrics[i];
if (!args || strncmp(elm->key, args, args_len) == 0) {
- json_append_member(root, elm->key, json_mknumber(elm->val));
+ json_append_member(root, elm->key, json_mknumber((double)elm->val));
+ }
+ }
+ for (int i = 0; i < sum_metrics_len; ++i) {
+ const struct sum_metric *elm = &sum_metrics[i];
+ if (!args || strncmp(elm->key, args, args_len) == 0) {
+ size_t val = *elm->val1 + *elm->val2;
+ json_append_member(root, elm->key, json_mknumber(val));
}
}
struct list_entry_context ctx = {
diff --git a/tests/config/meson.build b/tests/config/meson.build
index a739222..dc345a8 100644
--- a/tests/config/meson.build
+++ b/tests/config/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-3.0-or-later
config_tests += [
- ['basic', files('basic.test.lua'), ['skip_asan']],
- ['cache', files('cache.test.lua'), ['skip_asan']],
+ ['basic', files('basic.test.lua')],
+ ['cache', files('cache.test.lua')],
['net', files('net.test.lua'), ['config_net']],
['doh2', files('doh2.test.lua')],
['lru', files('lru.test.lua')],
diff --git a/tests/dnstap/src/dnstap-test/go.mod b/tests/dnstap/src/dnstap-test/go.mod
index 6b65088..2eb7287 100644
--- a/tests/dnstap/src/dnstap-test/go.mod
+++ b/tests/dnstap/src/dnstap-test/go.mod
@@ -1,6 +1,6 @@
module gitlab.nic.cz/knot/knot-resolver/tests/dnstap-test
-go 1.17
+go 1.15
require (
github.com/cloudflare/dns v0.0.0-20151007113418-e20ffa3da443
diff --git a/tests/dnstap/src/dnstap-test/go.sum b/tests/dnstap/src/dnstap-test/go.sum
deleted file mode 100644
index 1860f9e..0000000
--- a/tests/dnstap/src/dnstap-test/go.sum
+++ /dev/null
@@ -1,44 +0,0 @@
-github.com/cloudflare/dns v0.0.0-20151007113418-e20ffa3da443 h1:dYR6/V5rx/uaHsy4m1JuWfKYZO0r+G89BLD+XN7s9AI=
-github.com/cloudflare/dns v0.0.0-20151007113418-e20ffa3da443/go.mod h1:pa4p3oKOxzbXjrV5AGD1v5xjL7skv9BvO4J0Llo3P+s=
-github.com/dnstap/golang-dnstap v0.4.0 h1:KRHBoURygdGtBjDI2w4HifJfMAhhOqDuktAokaSa234=
-github.com/dnstap/golang-dnstap v0.4.0/go.mod h1:FqsSdH58NAmkAvKcpyxht7i4FoBjKu8E4JUPt8ipSUs=
-github.com/farsightsec/golang-framestream v0.3.0 h1:/spFQHucTle/ZIPkYqrfshQqPe2VQEzesH243TjIwqA=
-github.com/farsightsec/golang-framestream v0.3.0/go.mod h1:eNde4IQyEiA5br02AouhEHCu3p3UzrCdFR4LuQHklMI=
-github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
-github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
-github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
-github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
-github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
-github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/miekg/dns v1.1.31 h1:sJFOl9BgwbYAWOGEwr61FU28pqsBNdpRBnhGXtO06Oo=
-github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
-golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 h1:ObdrDkeb4kJdCP557AjRjq69pTHfNouLtWZG7j9rPN8=
-golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g=
-golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe h1:6fAMxZRR6sl1Uq8U61gxU+kPTs2tR8uOySCbBP7BN/M=
-golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
-golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
-google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
-google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
-google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
-google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
-google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
-google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
diff --git a/tests/dnstap/src/dnstap-test/run.sh b/tests/dnstap/src/dnstap-test/run.sh
index 37822b7..70d8225 100755
--- a/tests/dnstap/src/dnstap-test/run.sh
+++ b/tests/dnstap/src/dnstap-test/run.sh
@@ -8,16 +8,13 @@ echo "$GOPATH"
cd "$(dirname $0)"
DNSTAP_TEST=dnstap-test
-if [ -z "$GITLAB_CI" ]; then
- type -P go >/dev/null || exit 77
- echo "Building the dnstap test and its dependencies..."
- # some packages may be missing on the system right now
- go get .
-else
- # In CI we've prebuilt dependencies into the default GOPATH.
- # We're in a scratch container, so we just add the dnstap test inside.
- export GOPATH=/root/go
-fi
+go mod tidy
+
+type -P go >/dev/null || exit 77
+echo "Building the dnstap test and its dependencies..."
+# some packages may be missing on the system right now
+go get .
+
DTAP_DIR="$GOPATH/src"
DTAP="$DTAP_DIR/$DNSTAP_TEST"
mkdir -p "$DTAP_DIR"
diff --git a/tests/integration/deckard/.gitignore b/tests/integration/deckard/.gitignore
new file mode 100644
index 0000000..f8109bf
--- /dev/null
+++ b/tests/integration/deckard/.gitignore
@@ -0,0 +1,20 @@
+*.swp
+/env.sh
+
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+.hypothesis/
+.pytest_cache/
+.mypy_cache/
diff --git a/tests/integration/deckard/.gitlab-ci.yml b/tests/integration/deckard/.gitlab-ci.yml
new file mode 100644
index 0000000..2034cdd
--- /dev/null
+++ b/tests/integration/deckard/.gitlab-ci.yml
@@ -0,0 +1,130 @@
+image: $CI_REGISTRY/knot/knot-resolver/ci/debian-buster:knot-3.0
+variables:
+ LC_ALL: C.UTF-8
+
+stages:
+ - test
+
+.test: &test
+ stage: test
+ tags:
+ - docker
+ - linux
+ - amd64
+
+.privileged_test: &privileged_test
+ stage: test
+ tags:
+ - privileged
+
+test:augeas:
+ <<: *test
+ script:
+ - augparse pydnstest/deckard.aug
+
+test:flake8:
+ <<: *test
+ script:
+ - python3 -m flake8 --max-line-length=100 . && echo "OK, no flake8 errors detected"
+
+test:mypy:
+ <<: *test
+ script:
+ - ci/mypy-run.sh && echo "OK, no mypy error detected"
+
+test:pylint:
+ <<: *test
+ script:
+ - ci/pylint-run.sh
+
+test:rplint:
+ <<: *test
+ script:
+ - cp ci/common.sh /tmp
+ - cp ci/compare-rplint.sh /tmp
+ - /tmp/compare-rplint.sh
+
+test:unittests:
+ <<: *privileged_test
+ script:
+ - python3 -m pytest
+
+# There are no tests in the repo which use this feature but others do
+# and do not want to cause them breakage
+test:sanity:raw_id:
+ <<: *privileged_test
+ script:
+ - unshare -rn ci/raw_id_check.sh
+
+# changes in Deckard itself must not change result of tests
+test:comparative:kresd:
+ <<: *privileged_test
+ script:
+ # test kresd binary
+ - git clone --recurse-submodules -j8 --depth=1 https://gitlab.nic.cz/knot/knot-resolver.git /tmp/kresd-local-build
+ - pushd /tmp/kresd-local-build
+ - git log -1
+ - meson build_local --default-library=static --prefix=/tmp/.local
+ - ninja -C build_local install
+ - popd
+ # compare results from latest Deckard with results from merge base
+ - cp ci/common.sh /tmp
+ - cp ci/compare-tests.sh /tmp
+ - cp ci/junit-compare.py /tmp
+ - PATH=/tmp/.local/sbin:$PATH /tmp/compare-tests.sh $(pwd)/kresd_run.sh
+ artifacts:
+ when: always
+ expire_in: '1 hour'
+ paths:
+ - modified_tests
+ - base.xml
+ - head.xml
+
+# Run all tests on the latest kresd version to ensure that we not push tests
+# which do not work on latest kresd. It would lead to breakage in kresd CI.
+test:latest:kresd:
+ <<: *privileged_test
+ script:
+ - git clone --recurse-submodules -j8 --depth=1 https://gitlab.nic.cz/knot/knot-resolver.git kresd-local-build
+ - pushd kresd-local-build
+ - git log -1
+ - meson build_local --default-library=static --prefix="$PWD/../.local"
+ - ninja -C build_local install
+ - popd
+ - TMPDIR=$(pwd) PATH=$(pwd)/.local/sbin:$PATH ./kresd_run.sh -n $(nproc)
+ artifacts:
+ when: on_failure
+ expire_in: 1 week
+ paths:
+ - tmpdeckard*
+
+# sanity check that Unbound under Deckard still works
+# I've selected the only tests which are working
+# on kresd and Unbound 1.5.8 as well as 1.6.0
+test:sanity:unbound:
+ <<: *privileged_test
+ script:
+ - TMPDIR=$(pwd) ./unbound_run.sh --scenarios=sets/resolver/iter_hint_lame.rpl
+ - TMPDIR=$(pwd) ./unbound_run.sh --scenarios=sets/resolver/iter_lame_root.rpl
+ # these do not work with Unbound 1.5.8 which is in CI container
+ #- TESTS=sets/resolver/nsec_wildcard_answer_response.rpl ./unbound_run.sh
+ #- TESTS=sets/resolver/world_cz_lidovky_www.rpl ./unbound_run.sh
+ artifacts:
+ when: on_failure
+ expire_in: 1 week
+ paths:
+ - tmpdeckard*
+
+# sanity check that PowerDNS recursor under Deckard still works
+# I've selected couple tests which are working
+# on kresd and PowerDNS recursor 4.0.0~alpha2 as well as 4.0.4
+test:sanity:pdnsrecursor:
+ <<: *privileged_test
+ script:
+ - TMPDIR=$(pwd) ./pdns_run.sh --scenarios=sets/resolver/iter_recurse.rpl
+ - TMPDIR=$(pwd) ./pdns_run.sh --scenarios=sets/resolver/iter_tcbit.rpl
+ artifacts:
+ when: on_failure
+ expire_in: 1 week
+ paths:
+ - tmpdeckard*
diff --git a/tests/integration/deckard/.gitmodules b/tests/integration/deckard/.gitmodules
new file mode 100644
index 0000000..7a3c587
--- /dev/null
+++ b/tests/integration/deckard/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "contrib/libfaketime"]
+ path = contrib/libfaketime
+ url = git://github.com/wolfcw/libfaketime.git
diff --git a/tests/pytests/conftest.py b/tests/pytests/conftest.py
index 4c711f8..fcf4b05 100644
--- a/tests/pytests/conftest.py
+++ b/tests/pytests/conftest.py
@@ -86,7 +86,7 @@ def query_before(request): # whether to send an initial query
return request.param
-@pytest.mark.optionalhook
+@pytest.hookimpl(optionalhook=True)
def pytest_metadata(metadata): # filter potentially sensitive data from GitLab CI
keys_to_delete = []
for key in metadata.keys():
diff --git a/tests/pytests/test_tls.py b/tests/pytests/test_tls.py
index 3e1328a..2187efb 100644
--- a/tests/pytests/test_tls.py
+++ b/tests/pytests/test_tls.py
@@ -1,15 +1,8 @@
# SPDX-License-Identifier: GPL-3.0-or-later
"""TLS-specific tests"""
-import itertools
-import os
-from socket import AF_INET, AF_INET6
import ssl
-import sys
-
import pytest
-
-from kresd import make_kresd
import utils
@@ -41,43 +34,3 @@ def test_tls_cert_hostname_mismatch(kresd_tt, sock_family):
with pytest.raises(ssl.CertificateError):
ssock.connect(dest)
-
-
-@pytest.mark.skipif(sys.version_info < (3, 6),
- reason="requires python3.6 or higher")
-@pytest.mark.parametrize('sf1, sf2, sf3', itertools.product(
- [AF_INET, AF_INET6], [AF_INET, AF_INET6], [AF_INET, AF_INET6]))
-def test_tls_session_resumption(tmpdir, sf1, sf2, sf3):
- """Attempt TLS session resumption against the same kresd instance and a different one."""
- # TODO ensure that session can't be resumed after session ticket key regeneration
- # at the first kresd instance
-
- # NOTE TLS 1.3 is intentionally disabled for session resumption tests,
- # because python's SSLSocket.session isn't compatible with TLS 1.3
- # https://docs.python.org/3/library/ssl.html?highlight=ssl%20ticket#tls-1-3
-
- def connect(kresd, ctx, sf, session=None):
- sock, dest = kresd.stream_socket(sf, tls=True)
- ssock = ctx.wrap_socket(
- sock, server_hostname='transport-test-server.com', session=session)
- ssock.connect(dest)
- new_session = ssock.session
- assert new_session.has_ticket
- assert ssock.session_reused == (session is not None)
- utils.ping_alive(ssock)
- ssock.close()
- return new_session
-
- workdir = os.path.join(str(tmpdir), 'kresd')
- os.makedirs(workdir)
-
- with make_kresd(workdir, 'tt') as kresd:
- ctx = utils.make_ssl_context(
- verify_location=kresd.tls_cert_path, extra_options=[ssl.OP_NO_TLSv1_3])
- session = connect(kresd, ctx, sf1) # initial conn
- connect(kresd, ctx, sf2, session) # resume session on the same instance
-
- workdir2 = os.path.join(str(tmpdir), 'kresd2')
- os.makedirs(workdir2)
- with make_kresd(workdir2, 'tt') as kresd2:
- connect(kresd2, ctx, sf3, session) # resume session on a different instance
diff --git a/tests/pytests/utils.py b/tests/pytests/utils.py
index 4b995d4..8af71aa 100644
--- a/tests/pytests/utils.py
+++ b/tests/pytests/utils.py
@@ -99,7 +99,7 @@ def ping_alive(sock, msgid=None):
@contextmanager
def expect_kresd_close(rst_ok=False):
- with pytest.raises(BrokenPipeError):
+ with pytest.raises((BrokenPipeError, ssl.SSLEOFError)):
try:
time.sleep(0.2) # give kresd time to close connection with TCP FIN
yield
@@ -110,17 +110,12 @@ def expect_kresd_close(rst_ok=False):
pytest.fail("kresd didn't close the connection")
-def make_ssl_context(insecure=False, verify_location=None, extra_options=None):
- # set TLS v1.2+
- context = ssl.SSLContext(ssl.PROTOCOL_TLS)
- context.options |= ssl.OP_NO_SSLv2
- context.options |= ssl.OP_NO_SSLv3
- context.options |= ssl.OP_NO_TLSv1
- context.options |= ssl.OP_NO_TLSv1_1
-
- if extra_options is not None:
- for option in extra_options:
- context.options |= option
+def make_ssl_context(insecure=False, verify_location=None,
+ minimum_tls=ssl.TLSVersion.TLSv1_2,
+ maximum_tls=ssl.TLSVersion.MAXIMUM_SUPPORTED):
+ context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
+ context.minimum_version = minimum_tls
+ context.maximum_version = maximum_tls
if insecure:
# turn off certificate verification
diff --git a/tests/unit/meson.build b/tests/unit/meson.build
index b10789c..747f1d3 100644
--- a/tests/unit/meson.build
+++ b/tests/unit/meson.build
@@ -10,7 +10,7 @@ mock_cmodule_mod = shared_module(
'mock_cmodule',
mock_cmodule_src,
name_prefix: '',
- dependencies: libknot,
+ dependencies: mod_deps,
include_directories: mod_inc_dir,
)
@@ -20,10 +20,11 @@ foreach unit_test : unit_tests
unit_test[0],
unit_test[1],
dependencies: [
+ cmocka,
contrib_dep,
- libkres_dep,
libknot,
- cmocka,
+ libkres_dep,
+ libuv,
lmdb,
],
)
diff --git a/utils/cache_gc/categories.c b/utils/cache_gc/categories.c
index 19dec45..aaa1ae5 100644
--- a/utils/cache_gc/categories.c
+++ b/utils/cache_gc/categories.c
@@ -18,7 +18,7 @@ static bool rrtype_is_infrastructure(uint16_t r)
}
}
-static int get_random(int to)
+static unsigned int get_random(int to)
{
// We don't need these to be really unpredictable,
// but this should be cheap enough not to be noticeable.
diff --git a/utils/cache_gc/db.c b/utils/cache_gc/db.c
index fc4a2fd..c31ff22 100644
--- a/utils/cache_gc/db.c
+++ b/utils/cache_gc/db.c
@@ -9,11 +9,13 @@
#include <time.h>
#include <sys/stat.h>
+#define MDB_FILE "/data.mdb"
+
int kr_gc_cache_open(const char *cache_path, struct kr_cache *kres_db,
knot_db_t ** libknot_db)
{
- char cache_data[strlen(cache_path) + 10];
- snprintf(cache_data, sizeof(cache_data), "%s/data.mdb", cache_path);
+ char cache_data[strlen(cache_path) + sizeof(MDB_FILE)];
+ (void)snprintf(cache_data, sizeof(cache_data), "%s" MDB_FILE, cache_path);
struct stat st = { 0 };
if (stat(cache_path, &st) || !(st.st_mode & S_IFDIR)
diff --git a/utils/cache_gc/kr_cache_gc.c b/utils/cache_gc/kr_cache_gc.c
index 5978345..4097c80 100644
--- a/utils/cache_gc/kr_cache_gc.c
+++ b/utils/cache_gc/kr_cache_gc.c
@@ -8,20 +8,12 @@
// libknot includes
#include <libknot/libknot.h>
-// dynarray is inside libknot since 3.1, but it's differently named
-#ifdef knot_dynarray_declare
- #define dynarray_declare knot_dynarray_declare
- #define dynarray_define knot_dynarray_define
- #define dynarray_foreach knot_dynarray_foreach
-#else
- #include <contrib/dynarray.h>
-#endif
-
// resolver includes
#include <lib/cache/api.h>
#include <lib/cache/impl.h>
#include <lib/defines.h>
#include "lib/cache/cdb_lmdb.h"
+#include "lib/generic/array.h"
#include "lib/utils.h"
#include "kr_cache_gc.h"
@@ -43,41 +35,40 @@ static knot_db_val_t *dbval_copy(const knot_db_val_t * from)
}
// section: rrtype list
+typedef array_t(uint16_t) rrtype_array_t;
-dynarray_declare(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC, 64)
- dynarray_define(rrtype, uint16_t, DYNARRAY_VISIBILITY_STATIC)
-static void rrtypelist_add(rrtype_dynarray_t * arr, uint16_t add_type)
+static void rrtypelist_add(rrtype_array_t *arr, uint16_t add_type)
{
bool already_present = false;
- dynarray_foreach(rrtype, uint16_t, i, *arr) {
- if (*i == add_type) {
+ for (size_t i = 0; i < arr->len; i++) {
+ if (arr->at[i] == add_type) {
already_present = true;
break;
}
}
if (!already_present) {
- rrtype_dynarray_add(arr, &add_type);
+ kr_require(array_push(*arr, add_type) >= 0);
}
}
-static void rrtypelist_print(rrtype_dynarray_t * arr)
+static void rrtypelist_print(rrtype_array_t *arr)
{
char type_s[32] = { 0 };
- dynarray_foreach(rrtype, uint16_t, i, *arr) {
- knot_rrtype_to_string(*i, type_s, sizeof(type_s));
+ for (size_t i = 0; i < arr->len; i++) {
+ knot_rrtype_to_string(arr->at[i], type_s, sizeof(type_s));
printf(" %s", type_s);
}
printf("\n");
}
-dynarray_declare(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC, 256)
- dynarray_define(entry, knot_db_val_t *, DYNARRAY_VISIBILITY_STATIC)
-static void entry_dynarray_deep_free(entry_dynarray_t * d)
+typedef array_t(knot_db_val_t *) entry_array_t;
+
+static void entry_array_deep_free(entry_array_t *d)
{
- dynarray_foreach(entry, knot_db_val_t *, i, *d) {
- free(*i);
+ for (size_t i = 0; i < d->len; i++) {
+ free(d->at[i]);
}
- entry_dynarray_free(d);
+ array_clear(*d);
}
typedef struct {
@@ -98,7 +89,7 @@ int cb_compute_categories(const knot_db_val_t * key, gc_record_info_t * info,
typedef struct {
category_t limit_category;
- entry_dynarray_t to_delete;
+ entry_array_t to_delete;
size_t cfg_temp_keys_space;
size_t used_space;
size_t oversize_records;
@@ -117,7 +108,7 @@ int cb_delete_categories(const knot_db_val_t * key, gc_record_info_t * info,
ctx->oversize_records++;
free(todelete);
} else {
- entry_dynarray_add(&ctx->to_delete, &todelete);
+ kr_require(array_push(ctx->to_delete, todelete) >= 0);
ctx->used_space = used;
}
}
@@ -194,12 +185,12 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
// Mixing ^^ page usage and entry sizes (key+value lengths) didn't work
// too well, probably due to internal fragmentation after some GC cycles.
// Therefore let's scale this by the ratio of these two sums.
- ssize_t cats_sumsize = 0;
+ size_t cats_sumsize = 0;
for (int i = 0; i < CATEGORIES; ++i) {
cats_sumsize += cats.categories_sizes[i];
}
/* use less precise variant to avoid 32-bit overflow */
- ssize_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed;
+ size_t amount_tofree = cats_sumsize / 100 * cfg->cache_to_be_freed;
kr_log_debug(CACHE, "tofree: %zd / %zd\n", amount_tofree, cats_sumsize);
if (VERBOSE_STATUS) {
@@ -212,8 +203,11 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
}
category_t limit_category = CATEGORIES;
- while (limit_category > 0 && amount_tofree > 0) {
- amount_tofree -= cats.categories_sizes[--limit_category];
+ while (limit_category > 0) {
+ size_t cat_size = cats.categories_sizes[--limit_category];
+ if (cat_size > amount_tofree)
+ break;
+ amount_tofree -= cat_size;
}
printf("Cache analyzed in %.0lf msecs, %zu records, limit category is %d.\n",
@@ -226,13 +220,13 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
to_del.limit_category = limit_category;
ret = kr_gc_cache_iter(db, cfg, cb_delete_categories, &to_del);
if (ret != KNOT_EOK) {
- entry_dynarray_deep_free(&to_del.to_delete);
+ entry_array_deep_free(&to_del.to_delete);
kr_cache_gc_free_state(state);
return ret;
}
printf
("%zu records to be deleted using %.2lf MBytes of temporary memory, %zu records skipped due to memory limit.\n",
- to_del.to_delete.size, ((double)to_del.used_space / 1048576.0),
+ to_del.to_delete.len, ((double)to_del.used_space / 1048576.0),
to_del.oversize_records);
//// 4. execute the planned deletions.
@@ -242,23 +236,24 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
kr_timer_start(&timer_delete);
kr_timer_start(&timer_rw_txn);
- rrtype_dynarray_t deleted_rrtypes = { 0 };
+ rrtype_array_t deleted_rrtypes = { 0 };
ret = api->txn_begin(db, &txn, 0);
if (ret != KNOT_EOK) {
printf("Error starting R/W DB transaction (%s).\n",
knot_strerror(ret));
- entry_dynarray_deep_free(&to_del.to_delete);
+ entry_array_deep_free(&to_del.to_delete);
kr_cache_gc_free_state(state);
return ret;
}
- dynarray_foreach(entry, knot_db_val_t *, i, to_del.to_delete) {
- ret = api->del(&txn, *i);
+ for (size_t i = 0; i < to_del.to_delete.len; i++) {
+ knot_db_val_t *val = to_del.to_delete.at[i];
+ ret = api->del(&txn, val);
switch (ret) {
case KNOT_EOK:
deleted_records++;
- const int entry_type = kr_gc_key_consistent(**i);
+ const int entry_type = kr_gc_key_consistent(*val);
if (entry_type >= 0) // some "inconsistent" entries are OK
rrtypelist_add(&deleted_rrtypes, entry_type);
break;
@@ -267,8 +262,8 @@ int kr_cache_gc(kr_cache_gc_cfg_t *cfg, kr_cache_gc_state_t **state)
if (VERBOSE_STATUS) {
// kresd normally only inserts (or overwrites),
// so it's generally suspicious when a key goes missing.
- printf("Record already gone (key len %zu): ", (*i)->len);
- debug_printbin((*i)->data, (*i)->len);
+ printf("Record already gone (key len %zu): ", val->len);
+ debug_printbin(val->data, val->len);
printf("\n");
}
break;
@@ -316,8 +311,8 @@ finish:
printf("It took %.0lf msecs, %zu transactions (%s)\n\n",
kr_timer_elapsed(&timer_delete) * 1000, rw_txn_count, knot_strerror(ret));
- rrtype_dynarray_free(&deleted_rrtypes);
- entry_dynarray_deep_free(&to_del.to_delete);
+ array_clear(deleted_rrtypes);
+ entry_array_deep_free(&to_del.to_delete);
// OK, let's close it in this case.
kr_cache_gc_free_state(state);
diff --git a/utils/cache_gc/main.c b/utils/cache_gc/main.c
index 5adf19f..fe131cd 100644
--- a/utils/cache_gc/main.c
+++ b/utils/cache_gc/main.c
@@ -13,6 +13,7 @@
#include "kr_cache_gc.h"
static volatile int killed = 0;
+static volatile int exit_code = 0;
static void got_killed(int signum)
{
@@ -21,12 +22,10 @@ static void got_killed(int signum)
case 1:
break;
case 2:
- exit(5);
+ exit_code = 5;
break;
- case 3:
- abort();
default:
- kr_assert(false);
+ abort();
}
}
@@ -60,16 +59,20 @@ int main(int argc, char *argv[])
{
printf("Knot Resolver Cache Garbage Collector, version %s\n", PACKAGE_VERSION);
if (setvbuf(stdout, NULL, _IONBF, 0) || setvbuf(stderr, NULL, _IONBF, 0)) {
- fprintf(stderr, "Failed to to set output buffering (ignored): %s\n",
+ (void)fprintf(stderr, "Failed to to set output buffering (ignored): %s\n",
strerror(errno));
- fflush(stderr);
+ (void)fflush(stderr);
}
- signal(SIGTERM, got_killed);
- signal(SIGKILL, got_killed);
- signal(SIGPIPE, got_killed);
- signal(SIGCHLD, got_killed);
- signal(SIGINT, got_killed);
+ struct sigaction act = {
+ .sa_handler = got_killed,
+ .sa_flags = SA_RESETHAND,
+ };
+ sigemptyset(&act.sa_mask);
+ kr_assert(!sigaction(SIGTERM, &act, NULL));
+ kr_assert(!sigaction(SIGPIPE, &act, NULL));
+ kr_assert(!sigaction(SIGCHLD, &act, NULL));
+ kr_assert(!sigaction(SIGINT, &act, NULL));
kr_cache_gc_cfg_t cfg = {
.ro_txn_items = 200,
@@ -131,7 +134,6 @@ int main(int argc, char *argv[])
return 1;
}
- int exit_code = 0;
kr_cache_gc_state_t *gc_state = NULL;
bool last_espace = false;
do {
diff --git a/utils/cache_gc/meson.build b/utils/cache_gc/meson.build
index 40e127d..6ed86af 100644
--- a/utils/cache_gc/meson.build
+++ b/utils/cache_gc/meson.build
@@ -18,9 +18,12 @@ if build_utils
contrib_dep,
libkres_dep,
libknot,
+ libuv,
+ lmdb,
],
install: true,
install_dir: get_option('sbindir'),
+ install_rpath: rpath,
)
integr_tests += [
diff --git a/utils/client/.clang-tidy b/utils/client/.clang-tidy
new file mode 100644
index 0000000..46c666c
--- /dev/null
+++ b/utils/client/.clang-tidy
@@ -0,0 +1,2 @@
+---
+Checks: '-*'
diff --git a/utils/client/meson.build b/utils/client/meson.build
index 761c2cd..795cca3 100644
--- a/utils/client/meson.build
+++ b/utils/client/meson.build
@@ -33,5 +33,6 @@ if build_client
],
install: true,
install_dir: get_option('sbindir'),
+ install_rpath: rpath,
)
endif