...
 
Commits (1289)
......@@ -26,6 +26,7 @@ luacov.*.out
_obj
/.build-depend
/autom4te.cache/*
/bench/bench_lru
/config.log
/config.h
/config.status
......@@ -38,6 +39,7 @@ _obj
/compile
/compile_commands.json
/depcomp
/distro/tests/*/.vagrant
/install-sh
/stamp-h1
/aclocal.m4
......@@ -49,7 +51,6 @@ _obj
/daemon/kresd
/daemon/lua/*.inc
/daemon/lua/trust_anchors.lua
/daemon/lua/zonefile.lua
/tests/test_array
/tests/test_lru
/tests/test_map
......@@ -60,10 +61,11 @@ _obj
/tests/test_zonecut
/tests/dnstap/src/dnstap-test/vendor/github.com/
/tests/dnstap/src/github.com/
.pytest_cache
kresd.amalg.c
libkres.amalg.c
/doc/kresd.8
/libkres.pc
/modules/version/version.lua
/tags
/coverage
/coverage.stats
This diff is collapsed.
......@@ -3,7 +3,7 @@
url = https://gitlab.labs.nic.cz/knot/deckard.git
[submodule "modules/policy/lua-aho-corasick"]
path = modules/policy/lua-aho-corasick
url = git://github.com/cloudflare/lua-aho-corasick.git
url = https://github.com/cloudflare/lua-aho-corasick.git
[submodule "tests/config/tapered"]
path = tests/config/tapered
url = https://github.com/telemachus/tapered.git
......@@ -3,6 +3,7 @@ new_read_globals = {
'help',
'quit',
'hostname',
'package_version',
'moduledir',
'user',
'verbose',
......@@ -51,6 +52,8 @@ new_globals = {
'view',
'stats',
'http',
'trust_anchors',
'bogus_log',
}
-- Luacheck < 0.18 doesn't support new_read_globals
......@@ -76,4 +79,5 @@ files['daemon/lua/kres-gen.lua'].ignore = {'631'} -- Allow overly long lines
-- Tests and scripts can use global variables
files['scripts'].ignore = {'111', '112', '113'}
files['tests'].ignore = {'111', '112', '113'}
files['modules/*/*_test.lua'].ignore = {'111', '112', '113', '122'}
\ No newline at end of file
files['modules/**/*.test.lua'].ignore = {'111', '112', '113', '121', '122'}
files['daemon/**/*.test.lua'].ignore = {'111', '112', '113', '121', '122'}
language: c
os:
- osx
addons:
homebrew:
packages:
- cmocka
- luajit
- libuv
compiler:
- clang
notifications:
email:
on_success: change
on_failure: change
slack:
rooms: cznic:xNJmvHU2xu2aGtN7Y2eqHKoD
on_success: change
on_failure: change
webhooks:
urls: https://webhooks.gitter.im/e/66485d8f591942052faa
on_success: always
on_failure: always
on_success: never
on_failure: never
matrix:
fast_finish: true
env:
global:
- PKG_CONFIG_PATH="${HOME}/.local/lib/pkgconfig"
- PATH="${HOME}/.local/bin:/usr/local/bin:${PATH}"
- LD_LIBRARY_PATH="${HOME}/.local/lib"
- KNOT_DNS_VERSION=v2.7.2
- DYLD_LIBRARY_PATH="${HOME}/.local/lib"
- MALLOC_CHECK_=3
- MALLOC_PERTURB_=223
before_script:
- echo $CFLAGS
- BOOTSTRAP_CLEANUP=1 ./scripts/bootstrap-depends.sh ${HOME}/.local
- rvm get stable || true
- git clone -b ${KNOT_DNS_VERSION} https://gitlab.labs.nic.cz/knot/knot-dns.git
- cd knot-dns
- autoreconf -fi
- ./configure --disable-static --disable-fastparser --disable-documentation --disable-daemon --disable-utilities --with-lmdb=no
- make -j2 install
- cd ..
script:
- CFLAGS="-O2 -g -fno-omit-frame-pointer -DDEBUG" make -j2 install check V=1 PREFIX=${HOME}/.local DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}
- ./daemon/kresd -h
- ./daemon/kresd -V
- echo "quit()" | ./daemon/kresd -a 127.0.0.1@53535 .
# Deckard should be OK just on Linux
# - CFLAGS="-O2 -g -fno-omit-frame-pointer -DDEBUG" make -j2 check-integration PREFIX=${HOME}/.local DYLD_LIBRARY_PATH=${DYLD_LIBRARY_PATH}
after_success:
- if test $TRAVIS_OS_NAME = linux; then coveralls -i lib -i daemon -x ".c" --gcov-options '\-lp'; fi
sudo: false
cache:
directories:
- ${HOME}/.local
- ${HOME}/.cache/pip
before_cache:
- rm -f ${HOME}/.local/sbin/kresd
- rm -f ${HOME}/.local/lib/libkres.*
- rm -rf ${HOME}/.local/include/libkres
- rm -rf ${HOME}/.local/lib/kdns_modules
# Intermediate container for Knot DNS build (not persistent)
FROM debian:stable AS knot-dns-build
ARG KNOT_DNS_VERSION=v2.7.2
# Build dependencies
ENV KNOT_DNS_BUILD_DEPS git-core build-essential libtool autoconf pkg-config \
libgnutls28-dev libprotobuf-dev libprotobuf-c-dev libfstrm-dev
ENV KNOT_RESOLVER_BUILD_DEPS build-essential pkg-config bsdmainutils liblmdb-dev \
libluajit-5.1-dev libuv1-dev libprotobuf-dev libprotobuf-c-dev \
libfstrm-dev luajit lua-sec lua-socket
ENV BUILDENV_DEPS ${KNOT_DNS_BUILD_DEPS} ${KNOT_RESOLVER_BUILD_DEPS}
RUN apt-get update -qq && \
apt-get -y -qqq install ${BUILDENV_DEPS}
# Install Knot DNS from sources
RUN git clone -b $KNOT_DNS_VERSION --depth=1 https://gitlab.labs.nic.cz/knot/knot-dns.git /tmp/knot-dns && \
cd /tmp/knot-dns && \
autoreconf -if && \
./configure --disable-static --disable-fastparser --disable-documentation \
--disable-daemon --disable-utilities --with-lmdb=no && \
make -j4 install && \
ldconfig
# Copy libknot, libdnssec, libzscanner to runtime
RUN mkdir -p /tmp/root/usr/local/include /tmp/root/usr/local/lib /tmp/root/usr/local/lib/pkgconfig && \
cp -rt /tmp/root/usr/local/include /usr/local/include/libknot /usr/local/include/libdnssec /usr/local/include/libzscanner && \
cp -rt /tmp/root/usr/local/lib /usr/local/lib/libknot* /usr/local/lib/libdnssec* /usr/local/lib/libzscanner* && \
cp -rt /tmp/root/usr/local/lib/pkgconfig /usr/local/lib/pkgconfig/libknot.pc /usr/local/lib/pkgconfig/libdnssec.pc /usr/local/lib/pkgconfig/libzscanner.pc
# Intermediate container with runtime dependencies
FROM debian:stable-slim AS runtime
# Install runtime dependencies
ENV KNOT_DNS_RUNTIME_DEPS libgnutls30
ENV KNOT_RESOLVER_RUNTIME_DEPS liblmdb0 luajit libluajit-5.1-2 libuv1 lua-sec lua-socket
ENV KNOT_RESOLVER_RUNTIME_DEPS_HTTP libjs-bootstrap libjs-d3 libjs-jquery lua-http lua-mmdb
ENV KNOT_RESOLVER_RUNTIME_DEPS_EXTRA libfstrm0 lua-cqueues
ENV RUNTIME_DEPS ${KNOT_DNS_RUNTIME_DEPS} ${KNOT_RESOLVER_RUNTIME_DEPS} ${KNOT_RESOLVER_RUNTIME_DEPS_HTTP} ${KNOT_RESOLVER_RUNTIME_DEPS_EXTRA}
RUN apt-get update -qq && \
apt-get install -y -qqq ${RUNTIME_DEPS} && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Intermediate container for Knot Resolver build
FROM knot-dns-build AS build
# Get Knot Resolver code from current directory
COPY . /tmp/knot-resolver
# Build Knot Resolver
ARG CFLAGS="-O2 -fstack-protector -g"
ENV LDFLAGS -Wl,--as-needed
RUN cd /tmp/knot-resolver && \
make "-j$(nproc)" && \
make install DESTDIR=/tmp/root && \
mkdir -p /tmp/root/etc/knot-resolver && \
cp ./etc/config.docker /tmp/root/etc/knot-resolver/kresd.conf && \
cp ./distro/common/root.keys /tmp/root/etc/knot-resolver/
# Final container
FROM runtime
MAINTAINER Knot Resolver team <knot-resolver-users@lists.nic.cz>
# Export DNS over UDP & TCP, DNS-over-TLS, web interface
EXPOSE 53/UDP 53/TCP 853/TCP 8053/TCP
CMD ["/usr/local/sbin/kresd", "-c", "/etc/knot-resolver/kresd.conf"]
# Fetch Knot Resolver + Knot DNS libraries from build image
COPY --from=build /tmp/root/ /
RUN ldconfig
SHELL=/bin/bash -o pipefail -o errexit
include config.mk
include platform.mk
......@@ -16,7 +18,7 @@ lint-lua: $(patsubst %.lua.in,%.lua,$(wildcard */*/*.lua.in))
.PHONY: all install check clean doc info lint
# Dependencies
KNOT_MINVER := 2.4.0
KNOT_MINVER := 2.7.2
$(eval $(call find_lib,libknot,$(KNOT_MINVER),yes))
$(eval $(call find_lib,libdnssec,$(KNOT_MINVER),yes))
$(eval $(call find_lib,libzscanner,$(KNOT_MINVER),yes))
......@@ -30,8 +32,6 @@ $(eval $(call find_lib,cmocka))
$(eval $(call find_bin,doxygen))
$(eval $(call find_bin,sphinx-build))
$(eval $(call find_pythonpkg,breathe))
$(eval $(call find_lib,libmemcached,1.0))
$(eval $(call find_lib,hiredis,,yes))
$(eval $(call find_lib,socket_wrapper))
$(eval $(call find_lib,libsystemd,227))
$(eval $(call find_lib,gnutls))
......@@ -84,8 +84,9 @@ endif
# Overview
info:
$(info Target: Knot DNS Resolver $(VERSION)-$(PLATFORM))
$(info Target: Knot Resolver $(VERSION)-$(PLATFORM))
$(info Compiler: $(CC) $(BUILD_CFLAGS))
$(info Linker: $(CCLD) $(BUILD_LDFLAGS))
$(info )
$(info Variables)
$(info ---------)
......@@ -115,11 +116,9 @@ info:
$(info [$(HAS_sphinx-build)] sphinx-build (doc))
$(info [$(HAS_breathe)] python-breathe (doc))
$(info [$(HAS_go)] go (modules/go, Go buildmode=c-shared support))
$(info [$(HAS_libmemcached)] libmemcached (modules/memcached))
$(info [$(HAS_hiredis)] hiredis (modules/redis))
$(info [$(HAS_cmocka)] cmocka (tests/unit))
$(info [$(HAS_libsystemd)] systemd (daemon))
$(info [$(HAS_nettle)] nettle (modules/cookies))
# $(info [$(HAS_nettle)] nettle (modules/cookies))
$(info [$(HAS_ltn12)] Lua socket ltn12 (trust anchor bootstrapping))
$(info [$(HAS_ssl.https)] Lua ssl.https (trust anchor bootstrapping))
$(info [$(HAS_libedit)] libedit (client))
......@@ -162,16 +161,19 @@ endif
endif
# Check if it has nettle to support DNS cookies
ifeq ($(HAS_nettle), yes)
BUILD_CFLAGS += -DENABLE_COOKIES
ENABLE_COOKIES := yes
endif
# temporarily turn off cookies
#ifeq ($(HAS_nettle), yes)
#BUILD_CFLAGS += -DENABLE_COOKIES
#ENABLE_COOKIES := yes
#endif
ENABLE_COOKIES := no
# Installation directories
$(DESTDIR)$(MODULEDIR):
$(INSTALL) -d $@
$(DESTDIR)$(ETCDIR):
$(INSTALL) -m 0750 -d $@
$(INSTALL) -m 0755 -d $@
# Sub-targets
include contrib/contrib.mk
......
This diff is collapsed.
# Knot DNS Resolver
# Knot Resolver
[![Build Status](https://gitlab.labs.nic.cz/knot/knot-resolver/badges/master/pipeline.svg?x)](https://gitlab.labs.nic.cz/knot/knot-resolver/commits/master)
[![Coverage Status](https://gitlab.labs.nic.cz/knot/knot-resolver/badges/master/coverage.svg?x)](https://knot.pages.labs.nic.cz/knot-resolver/)
[![Coverity](https://img.shields.io/coverity/scan/3912.svg)](https://scan.coverity.com/projects/3912)
[![Build Status](https://gitlab.labs.nic.cz/knot/knot-resolver/badges/nightly/pipeline.svg?x)](https://gitlab.labs.nic.cz/knot/knot-resolver/commits/nightly)
[![Coverage Status](https://gitlab.labs.nic.cz/knot/knot-resolver/badges/nightly/coverage.svg?x)](https://knot.pages.labs.nic.cz/knot-resolver/)
[![Documentation Status](https://readthedocs.org/projects/knot-resolver/badge/?version=latest)](https://readthedocs.org/projects/knot-resolver/?badge=latest)
[![Join the chat at gitter.im/CZ-NIC/knot-resolver](https://badges.gitter.im/Join%20Chat.svg?x)](https://gitter.im/CZ-NIC/knot-resolver?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Knot DNS Resolver is a caching full resolver implementation written in C and [LuaJIT][luajit], both a resolver library and a daemon. The core architecture is tiny and efficient, and provides a foundation and
a state-machine like API for extensions. There are four of those built-in - *iterator*, *validator* and two caching modules. Most of the [rich features](https://knot-resolver.readthedocs.io/en/latest/modules.html) are written in Lua(JIT) and C. Batteries are included, but optional.
Knot Resolver is a caching full resolver implementation written in C and [LuaJIT][luajit], both a resolver library and a daemon. The core architecture is tiny and efficient, and provides a foundation and
a state-machine like API for extensions. There are three modules built-in - *iterator*, *validator*, *cache*, and a few more are loaded by default. Most of the [rich features](https://knot-resolver.readthedocs.io/en/latest/modules.html) are written in Lua(JIT) and C. Batteries are included, but optional.
The LuaJIT modules, support DNS privacy and DNSSEC, and persistent cache with low memory footprint make it a great personal DNS resolver or a research tool to tap into DNS data. TL;DR it's the [OpenResty][openresty] of DNS.
Several cache backends (LMDB, Redis and Memcached), strong filtering rules, and auto-configuration with etcd make it a great large-scale resolver solution.
Strong filtering rules, and auto-configuration with etcd make it a great large-scale resolver solution.
The server adopts a [different scaling strategy][scaling] than the rest of the DNS recursors - no threading, shared-nothing architecture (except MVCC cache that may be shared) that allows you to pin instances on available CPU cores and grow by self-replication. You can start and stop additional nodes depending on the contention without downtime.
......@@ -20,20 +17,24 @@ It also has strong support for DNS over TCP, notably TCP Fast-Open, query pipeli
### Packages
Knot Resolver is packaged for
[Debian](https://packages.debian.org/sid/knot-resolver),
[Fedora](https://apps.fedoraproject.org/packages/knot-resolver/),
[Ubuntu](https://packages.ubuntu.com/zesty/knot-resolver),
[Homebrew](https://github.com/Homebrew/homebrew-core/blob/master/Formula/knot-resolver.rb) and
[NixOS/Nixpkgs](https://hydra.nixos.org/search?query=knot-resolver).
You can also find it as the default DNS resolver in our open-source router [Turris Omnia](https://omnia.turris.cz).
See the [Knot-resolver homepage](https://www.knot-resolver.cz/download/) for more information.
The latest stable packages for various distributions are available in our
[upstream repository](https://build.opensuse.org/package/show/home:CZ-NIC:knot-resolver-latest/knot-resolver).
Follow the
[installation instructions](https://software.opensuse.org//download.html?project=home%3ACZ-NIC%3Aknot-resolver-latest&package=knot-resolver)
to add this repository to your system.
Knot Resolver is also available from the following distributions' repositories.
<!-- [openSUSE](https://build.opensuse.org/package/show/server:dns/knot-resolver), (it seems to be in a bad shape) -->
* [Fedora and Fedora EPEL](https://apps.fedoraproject.org/packages/knot-resolver)
* [Debian stable](https://packages.debian.org/stable/knot-resolver),
[Debian testing](https://packages.debian.org/testing/knot-resolver),
[Debian unstable](https://packages.debian.org/sid/knot-resolver)
* [Ubuntu](https://packages.ubuntu.com/bionic/knot-resolver)
* [Arch Linux (AUR)](https://aur.archlinux.org/packages/knot-resolver)
### Building from sources
Knot DNS Resolver mainly [depends][depends] on Knot DNS libraries, [LuaJIT][luajit] and [libuv][libuv].
Knot Resolver mainly [depends][depends] on Knot DNS libraries, [LuaJIT][luajit] and [libuv][libuv].
See the [Building project][depends] documentation page for more information.
### Docker image
......@@ -41,10 +42,11 @@ See the [Building project][depends] documentation page for more information.
This is simple and doesn't require any dependencies or system modifications, just run:
```
$ docker run -it cznic/knot-resolver
$ docker run -Pit cznic/knot-resolver
```
See the build page [hub.docker.com/r/cznic/knot-resolver](https://hub.docker.com/r/cznic/knot-resolver/) for more information and options.
The images are meant as an easy way to try knot-resolver, and they're not designed for production use.
### Running
......@@ -56,9 +58,9 @@ $ kresd
See the documentation at [knot-resolver.readthedocs.io][doc] for more options.
[depends]: https://knot-resolver.readthedocs.io/en/latest/build.html
[doc]: https://knot-resolver.readthedocs.io/en/latest/index.html
[scaling]: https://knot-resolver.readthedocs.io/en/latest/daemon.html#scaling-out
[depends]: https://knot-resolver.readthedocs.io/en/stable/build.html
[doc]: https://knot-resolver.readthedocs.io/en/stable/index.html
[scaling]: https://knot-resolver.readthedocs.io/en/stable/daemon.html#scaling-out
[deckard]: https://gitlab.labs.nic.cz/knot/deckard
[luajit]: https://luajit.org/
[libuv]: http://libuv.org
......@@ -66,4 +68,7 @@ See the documentation at [knot-resolver.readthedocs.io][doc] for more options.
### Contacting us
[![Join the chat at https://gitter.im/CZ-NIC/knot-resolver](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/CZ-NIC/knot-resolver?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
- [GitLab issues](https://gitlab.labs.nic.cz/knot/knot-resolver/issues) (you may authenticate via GitHub)
- [mailing list](https://lists.nic.cz/cgi-bin/mailman/listinfo/knot-resolver-users)
- [![Join the chat at https://gitter.im/CZ-NIC/knot-resolver](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/CZ-NIC/knot-resolver?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
......@@ -5,13 +5,6 @@ bench_BIN := \
bench_DEPEND := $(libkres)
bench_LIBS := $(libkres_TARGET) $(libkres_LIBS)
# Platform-specific library injection
ifeq ($(PLATFORM),Darwin)
preload_syms := DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_LIBRARY_PATH="$(DYLD_LIBRARY_PATH):$(abspath lib)"
else
preload_syms := LD_LIBRARY_PATH="$(LD_LIBRARY_PATH):$(abspath lib)"
endif
# Make bench binaries
define make_bench
$(1)_CFLAGS := -fPIE
......@@ -28,8 +21,8 @@ $(foreach bench,$(bench_BIN),$(eval $(call make_bench,$(bench))))
bench-clean: $(foreach bench,$(bench_BIN),$(bench)-clean)
bench: $(foreach bench,$(bench_BIN),bench/$(bench))
@echo "Test LRU with increasing overfill, misses should increase ~ linearly" >&2
@./bench/bench_lru 23 bench/bench_lru_set1.tsv - 65536 # fill ~ 1
@./bench/bench_lru 23 bench/bench_lru_set1.tsv - 32768 # fill ~ 2
@./bench/bench_lru 23 bench/bench_lru_set1.tsv - 16384 # fill ~ 4
@./bench/bench_lru 23 bench/bench_lru_set1.tsv - 8192 # fill ~ 8
@./bench/bench_lru 23 bench/bench_lru_set1.tsv - 4096 # fill ~ 16
$(preload_syms) ./bench/bench_lru 23 bench/bench_lru_set1.tsv - 65536 # fill ~ 1
$(preload_syms) ./bench/bench_lru 23 bench/bench_lru_set1.tsv - 32768 # fill ~ 2
$(preload_syms) ./bench/bench_lru 23 bench/bench_lru_set1.tsv - 16384 # fill ~ 4
$(preload_syms) ./bench/bench_lru 23 bench/bench_lru_set1.tsv - 8192 # fill ~ 8
$(preload_syms) ./bench/bench_lru 23 bench/bench_lru_set1.tsv - 4096 # fill ~ 16
......@@ -212,7 +212,7 @@ int main(int argc, char ** argv)
p_err("\nload everything:\t");
time_get(&time);
for (size_t i = 0, ki = key_count - 1; i < run_count; ++i, --ki) {
unsigned *r = lru_get_new(lru, keys[ki].chars, keys[ki].len);
unsigned *r = lru_get_new(lru, keys[ki].chars, keys[ki].len, NULL);
if (!r || *r == 0)
++miss;
if (r)
......
Docker Build
------------
* debian-stable / debian-unstable
```
$ export KNOT_BRANCH=2.7
$ docker build -t registry.labs.nic.cz/knot/knot-resolver/ci/debian-stable:knot-$KNOT_BRANCH --build-arg KNOT_BRANCH=$KNOT_BRANCH debian-stable
$ docker build -t registry.labs.nic.cz/knot/knot-resolver/ci/debian-unstable:knot-$KNOT_BRANCH --build-arg KNOT_BRANCH=$KNOT_BRANCH debian-unstable
$ docker login registry.labs.nic.cz
$ docker push registry.labs.nic.cz/knot/knot-resolver/ci/debian-stable:knot-$KNOT_BRANCH
$ docker push registry.labs.nic.cz/knot/knot-resolver/ci/debian-unstable:knot-$KNOT_BRANCH
```
* fedora
```
$ docker build -t registry.labs.nic.cz/knot/knot-resolver/ci/fedora fedora
$ docker push registry.labs.nic.cz/knot/knot-resolver/ci/fedora
```
Clang in Debian stable is old so we have separate image with Clang.
This Dockerfile should be the same as ci/Dockerfile, with two differences:
- FROM points to debian:unstable
- last step adds Clang and its analysis tools
FROM debian:unstable
FROM debian:stable
MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
ARG KNOT_BRANCH=master
WORKDIR /root
CMD ["/bin/bash"]
RUN echo "deb http://ftp.debian.org/debian stretch-backports main" >> /etc/apt/sources.list
# generic cleanup
RUN apt-get update -qq
RUN apt-get upgrade -y -qqq
# Knot and Knot Resolver dependecies
RUN apt-get install -y -qqq make cmake pkg-config git build-essential bsdmainutils libtool autoconf make pkg-config liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev libidn11-dev protobuf-c-compiler libfstrm-dev pkg-config libuv1-dev libcmocka-dev libluajit-5.1-dev lua-sec lua-socket lua-http
RUN apt-get -t stretch-backports install -y git
RUN apt-get install -y -qqq make cmake pkg-config build-essential bsdmainutils libtool autoconf liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev libidn11-dev protobuf-c-compiler libfstrm-dev libuv1-dev libcmocka-dev libluajit-5.1-dev lua-sec lua-socket lua-http
# documentation dependecies
RUN apt-get install -y -qqq doxygen python3-sphinx python3-breathe python3-sphinx-rtd-theme
# Python packags required for Deckard CI
# Python: grab latest versions from PyPi
# (dnspython and Augeas binding in Debian packages are slow and buggy)
RUN apt-get install -y -qqq python3-pip wget
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
RUN pip3 install dnspython jinja2 pytest pytest-html pytest-xdist
# C dependencies for python-augeas
RUN apt-get install -y -qqq libaugeas-dev libffi-dev
......@@ -27,11 +36,11 @@ RUN pip3 install -r /tmp/deckard-req.txt
# build and install latest version of Knot DNS
# (kresd depends on libknot and libdnssec)
RUN git clone --depth=1 --branch=2.6 https://gitlab.labs.nic.cz/knot/knot-dns.git /tmp/knot
RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.labs.nic.cz/knot/knot-dns.git /tmp/knot
WORKDIR /tmp/knot
RUN pwd
RUN autoreconf -if
RUN ./configure
RUN ./configure --prefix=/usr
RUN make
RUN make install
RUN ldconfig
......@@ -46,18 +55,24 @@ RUN apt-get install luarocks -y -qqq
RUN luarocks install luacheck
# respdiff for kresd CI
RUN pip3 install dnspython python-augeas
RUN git clone --depth=1 https://gitlab.labs.nic.cz/knot/resolver-benchmarking.git /tmp/resolver-benchmarking
RUN mv /tmp/resolver-benchmarking/response_differences/respdiff /var/opt/respdiff
RUN pip3 install -r /tmp/resolver-benchmarking/requirements.txt
RUN rm -rf /tmp/resolver-benchmarking
RUN apt-get install lmdb-utils -y -qqq
RUN git clone --depth=1 https://gitlab.labs.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
# 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\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf
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
......@@ -70,5 +85,8 @@ RUN luarocks install luacov
# LuaJIT binary for stand-alone scripting
RUN apt-get install -y -qqq luajit
# clang for kresd CI
RUN apt-get install -y -qqq clang-5.0 clang-tools-5.0 clang-tidy-5.0
# OpenBuildService CLI tool
RUN apt-get install -y osc
# curl (API)
RUN apt-get install -y curl
FROM debian:stable
FROM debian:unstable
MAINTAINER Knot Resolver <knot-resolver@labs.nic.cz>
ARG KNOT_BRANCH=2.7
WORKDIR /root
CMD ["/bin/bash"]
......@@ -9,35 +10,21 @@ RUN apt-get update -qq
RUN apt-get upgrade -y -qqq
# Knot and Knot Resolver dependecies
RUN apt-get install -y -qqq make cmake pkg-config git build-essential bsdmainutils libtool autoconf make pkg-config liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev libidn11-dev protobuf-c-compiler libfstrm-dev pkg-config libuv1-dev libcmocka-dev libluajit-5.1-dev lua-sec lua-socket lua-http
# Python packags required for Deckard CI
# Python: grab latest versions from PyPi
# (dnspython and Augeas binding in Debian packages are slow and buggy)
RUN apt-get install -y -qqq python3-pip wget
RUN pip3 install --upgrade pip
RUN pip3 install pylint
RUN pip3 install pep8
# C dependencies for python-augeas
RUN apt-get install -y -qqq libaugeas-dev libffi-dev
# Python dependencies for Deckard
RUN wget https://gitlab.labs.nic.cz/knot/deckard/raw/master/requirements.txt -O /tmp/deckard-req.txt
RUN pip3 install -r /tmp/deckard-req.txt
RUN apt-get install -y -qqq make cmake pkg-config git build-essential bsdmainutils libtool autoconf liburcu-dev libgnutls28-dev libedit-dev liblmdb-dev libcap-ng-dev libsystemd-dev libidn11-dev protobuf-c-compiler libfstrm-dev libuv1-dev libcmocka-dev libluajit-5.1-dev lua-sec lua-socket lua-http
# build and install latest version of Knot DNS
# (kresd depends on libknot and libdnssec)
RUN git clone --depth=1 --branch=2.6 https://gitlab.labs.nic.cz/knot/knot-dns.git /tmp/knot
RUN git clone --depth=1 --branch=$KNOT_BRANCH https://gitlab.labs.nic.cz/knot/knot-dns.git /tmp/knot
WORKDIR /tmp/knot
RUN pwd
RUN autoreconf -if
RUN ./configure
RUN ./configure --prefix=/usr
RUN make
RUN make install
RUN ldconfig
# Valgrind for kresd CI
RUN apt-get install valgrind -y -qqq
RUN apt-get install valgrind wget -y -qqq
RUN wget https://raw.githubusercontent.com/LuaJIT/LuaJIT/v2.0.4/src/lj.supp -O /lj.supp
# TODO: rebuild LuaJIT with Valgrind support
......@@ -45,27 +32,12 @@ RUN wget https://raw.githubusercontent.com/LuaJIT/LuaJIT/v2.0.4/src/lj.supp -O /
RUN apt-get install luarocks -y -qqq
RUN luarocks install luacheck
# respdiff for kresd CI
RUN pip3 install dnspython python-augeas
RUN git clone --depth=1 https://gitlab.labs.nic.cz/knot/resolver-benchmarking.git /tmp/resolver-benchmarking
RUN mv /tmp/resolver-benchmarking/response_differences/respdiff /var/opt/respdiff
RUN pip3 install -r /tmp/resolver-benchmarking/requirements.txt
RUN rm -rf /tmp/resolver-benchmarking
# 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\nremote-control:\n control-enable: no\n" >> /etc/unbound/unbound.conf
# BIND for respdiff
RUN apt-get install bind9 -y -qqq
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 install luacov
# LuaJIT binary for stand-alone scripting
RUN apt-get install -y -qqq luajit
\ No newline at end of file
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
Docker image based on debian-unstable specifically for newer Clang.
FROM fedora:29
WORKDIR "/tmp"
CMD ["/bin/bash"]
RUN dnf install -y mock rpkg git
# for scripts/make-distrofiles.sh
RUN dnf install -y dpkg-dev perl-Digest-*
# add OBS repo with Knot DNS to mock
RUN curl -Lo obs-epel7.repo 'https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/CentOS_7_EPEL/home:CZ-NIC:knot-resolver-testing.repo'
RUN sed -i -e "/^config_opts\[.yum.conf.]/r obs-epel7.repo" /etc/mock/epel-7-x86_64.cfg
RUN curl -Lo obs-fedora.repo 'https://download.opensuse.org/repositories/home:CZ-NIC:knot-resolver-testing/Fedora_29/home:CZ-NIC:knot-resolver-testing.repo'
RUN sed -i -e "/^config_opts\[.yum.conf.]/r obs-fedora.repo" /etc/mock/fedora-29-x86_64.cfg
# cache packages in mock to speed up CI tests
# This would require privileged build: https://github.com/moby/moby/issues/1916
# RUN dnf download --source knot-resolver
# RUN mock --no-clean --dnf --old-chroot -r epel-7-x86_64 --rebuild knot-resolver-*.src.rpm
# RUN mock --no-clean --old-chroot -r fedora-29-x86_64 --rebuild knot-resolver-*.src.rpm
# RUN rm *.src.rpm
#!/bin/bash
python3 -m flake8 --max-line-length=100 tests/pytests
FLAKE8=$?
ci/pytests/pylint-run.sh
PYLINT=$?
if [ $PYLINT -ne 0 ]; then
exit 1
fi
if [ $FLAKE8 -ne 0 ]; then
exit 1
fi
exit 0
#!/usr/bin/env bash
set -e
# Find Python modules and standalone Python scripts
FILES=$(find ./tests/pytests \
-type d -exec test -e '{}/__init__.py' \; -print -prune -o \
-name '*.py' -print)
python3 -m pylint -j 0 --rcfile ./tests/pytests/pylintrc ${FILES}
#!/bin/bash
# Execute extended, long-running test suite
python3 -m pytest -ra --capture=no tests/pytests/conn_flood.py
#!/bin/bash
python3 -m pytest --html pytests.html --self-contained-html -dn 24 tests/pytests
-- Refer to manual: https://knot-resolver.readthedocs.io/en/latest/daemon.html#configuration
-- Listen on localhost and external interface
net.listen('127.0.0.1', 5353)
net.listen('::1', 5353)
net.listen('127.0.0.1', 8853, { tls = true })
net.listen('::1', 8853, { tls = true })
net.ipv6=false
-- Auto-maintain root TA
trust_anchors.file = '.local/etc/kresd/root.keys'
trust_anchors.file = '.local/etc/knot-resolver/root.keys'
-- Large cache size, so we don't need to flush often
-- This can be larger than available RAM, least frequently accessed
......@@ -22,4 +21,4 @@ modules = {
'stats', -- Track internal statistics
}
verbose(false)
verbose(true)
[sendrecv]
# in seconds
timeout = 5
timeout = 11
# number of queries to run simultaneously
jobs = 64
# in seconds (float); delay each query by a random time (uniformly distributed) between min and max; set max to 0 to disable
time_delay_min = 0
time_delay_max = 0
[servers]
names = kresd, bind, unbound
......@@ -12,19 +15,25 @@ names = kresd, bind, unbound
# each symbolic name in [servers] section refers to config section
# containing IP address and port of particular server
[kresd]
ip = ::1
ip = 127.0.0.1
port = 5353
transport = tcp
graph_color = #00a2e2
restart_script = ./ci/respdiff/restart-kresd.sh
[bind]
ip = 127.0.0.1
port = 53533
transport = udp
graph_color = #e2a000
restart_script = ./ci/respdiff/restart-bind.sh
[unbound]
ip = 127.0.0.1
port = 53535
transport = udp
graph_color = #218669
restart_script = ./ci/respdiff/restart-unbound.sh
[diff]
# symbolic name of server under test
......@@ -32,11 +41,10 @@ transport = udp
target = kresd
# fields and comparison methods used when comparing two DNS messages
criteria = opcode, rcode, flags, question, qname, qtype, answertypes, answerrrsigs
criteria = opcode, rcode, flags, question, answertypes, answerrrsigs
# other supported criteria values: authority, additional, edns, nsid
[report]
# diffsum reports mismatches in field values in this order
# if particular message has multiple mismatches, it is counted only once into category with highest weight
field_weights = opcode, qcase, qtype, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
field_weights = timeout, malformed, opcode, question, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
[sendrecv]
# in seconds
timeout = 5
timeout = 11
# number of queries to run simultaneously
jobs = 64
# in seconds (float); delay each query by a random time (uniformly distributed) between min and max; set max to 0 to disable
time_delay_min = 0
time_delay_max = 0
[servers]
names = kresd, bind, unbound
......@@ -12,19 +15,25 @@ names = kresd, bind, unbound
# each symbolic name in [servers] section refers to config section
# containing IP address and port of particular server
[kresd]
ip = ::1
ip = 127.0.0.1
port = 8853
transport = tls
graph_color = #00a2e2
restart_script = ./ci/respdiff/restart-kresd.sh
[bind]
ip = 127.0.0.1
port = 53533
transport = udp
graph_color = #e2a000
restart_script = ./ci/respdiff/restart-bind.sh
[unbound]
ip = 127.0.0.1
port = 53535
transport = udp
graph_color = #218669
restart_script = ./ci/respdiff/restart-unbound.sh
[diff]
# symbolic name of server under test
......@@ -32,11 +41,10 @@ transport = udp
target = kresd
# fields and comparison methods used when comparing two DNS messages
criteria = opcode, rcode, flags, question, qname, qtype, answertypes, answerrrsigs
criteria = opcode, rcode, flags, question, answertypes, answerrrsigs
# other supported criteria values: authority, additional, edns, nsid
[report]
# diffsum reports mismatches in field values in this order
# if particular message has multiple mismatches, it is counted only once into category with highest weight
field_weights = opcode, qcase, qtype, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
field_weights = timeout, malformed, opcode, question, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
[sendrecv]
# in seconds
timeout = 5
timeout = 11
# number of queries to run simultaneously
jobs = 64
# in seconds (float); delay each query by a random time (uniformly distributed) between min and max; set max to 0 to disable
time_delay_min = 0
time_delay_max = 0
[servers]
names = kresd, bind, unbound
......@@ -12,19 +15,25 @@ names = kresd, bind, unbound
# each symbolic name in [servers] section refers to config section
# containing IP address and port of particular server
[kresd]
ip = ::1
ip = 127.0.0.1
port = 5353
transport = udp
graph_color = #00a2e2
restart_script = ./ci/respdiff/restart-kresd.sh
[bind]
ip = 127.0.0.1
port = 53533
transport = udp
graph_color = #e2a000
restart_script = ./ci/respdiff/restart-bind.sh
[unbound]
ip = 127.0.0.1
port = 53535
transport = udp
graph_color = #218669
restart_script = ./ci/respdiff/restart-unbound.sh
[diff]
# symbolic name of server under test
......@@ -32,11 +41,10 @@ transport = udp
target = kresd
# fields and comparison methods used when comparing two DNS messages
criteria = opcode, rcode, flags, question, qname, qtype, answertypes, answerrrsigs
criteria = opcode, rcode, flags, question, answertypes, answerrrsigs
# other supported criteria values: authority, additional, edns, nsid
[report]
# diffsum reports mismatches in field values in this order
# if particular message has multiple mismatches, it is counted only once into category with highest weight
field_weights = opcode, qcase, qtype, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
field_weights = timeout, malformed, opcode, question, rcode, flags, answertypes, answerrrsigs, answer, authority, additional, edns, nsid
#!/bin/sh
service bind9 restart
#!/bin/sh
exec > /dev/null
exec 2>&1
PREFIX=$(pwd)/.local
killall -w kresd
rm -f '*.mdb'
LD_LIBRARY_PATH=$PREFIX/lib $PREFIX/sbin/kresd -f 1 -q -c $(pwd)/ci/respdiff/kresd.config &>>kresd.log &
# wait until socket is receiving connections
sleep 1
#!/bin/sh
service unbound restart
......@@ -3,7 +3,9 @@
# respdiff scripts must be present in /var/opt/respdiff
set -o errexit -o nounset -o xtrace
wget https://gitlab.labs.nic.cz/knot/knot-resolver/snippets/69/raw?inline=false -O /tmp/queries.txt
NDIFFREPRO=3
wget -qO- https://gitlab.labs.nic.cz/knot/respdiff/snippets/238/raw?inline=false | head -n 5000 > /tmp/queries.txt
mkdir results
rm -rf respdiff.db
......@@ -11,4 +13,13 @@ CONFIG="$(pwd)/ci/respdiff/respdiff-${1}.conf"
/var/opt/respdiff/qprep.py respdiff.db < /tmp/queries.txt
time /var/opt/respdiff/orchestrator.py respdiff.db -c "${CONFIG}"
time /var/opt/respdiff/msgdiff.py respdiff.db -c "${CONFIG}"
for i in $(seq $NDIFFREPRO); do
time /var/opt/respdiff/diffrepro.py -c "${CONFIG}" respdiff.db
done
/var/opt/respdiff/diffsum.py respdiff.db -c "${CONFIG}" > results/respdiff.txt
/var/opt/respdiff/histogram.py respdiff.db -c "${CONFIG}" -o results/histogram.svg
: minimize LMDB and log size so they can be effectively archived
mkdir results/respdiff.db
mdb_copy -c respdiff.db results/respdiff.db
xz -9 results/respdiff.db/data.mdb
xz kresd.log
......@@ -7,5 +7,5 @@ service bind9 start && service bind9 status;
# dig @localhost -p 53533
#run kresd
LD_LIBRARY_PATH=$PREFIX/lib $PREFIX/sbin/kresd -f 1 -q -c $(pwd)/ci/respdiff/kresd.config &
LD_LIBRARY_PATH=$PREFIX/lib $PREFIX/sbin/kresd -f 1 -q -c $(pwd)/ci/respdiff/kresd.config &>kresd.log &
# dig @localhost -p 5353
#!/usr/bin/python3
import json
import time
import sys
import requests
BRANCH_API_ENDPOINT = "https://api.travis-ci.com/repos/CZ-NIC/knot-resolver/branches/{branch}"
JOB_URL = "https://travis-ci.com/CZ-NIC/knot-resolver/jobs/{job_id}"
TIMEOUT = 600 # 10 mins max
POLL_DELAY = 15
job_id = None
def exit(msg='', code=1):
print(msg, file=sys.stderr)
if job_id is not None:
print(JOB_URL.format(job_id=job_id))
sys.exit(code)
end_time = time.time() + TIMEOUT
while time.time() < end_time:
response = requests.get(
BRANCH_API_ENDPOINT.format(branch=sys.argv[1]),
headers={"Accept": "application/vnd.travis-ci.2.1+json"})
if response.status_code == 404:
pass # not created yet?
elif response.status_code == 200:
data = json.loads(response.content.decode('utf-8'))
state = data['branch']['state']
try:
job_id = data['branch']['job_ids'][0]
except KeyError:
pass
if state == "errored":
exit("Travis CI Result: ERRORED!")
elif state == "passed":
exit("Travis CI Result: PASSED!", code=0)
else:
exit("API Response Code: {code}".format(response.status_code), code=2)
time.sleep(POLL_DELAY)
exit("Timed out!")
......@@ -90,7 +90,7 @@ const char *get_type_name(const char *value)
static void complete_function(EditLine * el)
{
//Add left parenthesis to function name.
//Add left parenthesis to function name.
el_insertstr(el, "(");
}
......@@ -392,7 +392,7 @@ static int interact()
//Create necessary folders.
char *dirs[3] =
{ afmt("%s/.local", home), afmt("%s/.local/share", home),
afmt("%s/.local/share/kresd/", home)
afmt("%s/.local/share/knot-resolver/", home)
};
bool ok = true;
for (int i = 0; i < 3; i++) {
......@@ -403,12 +403,12 @@ static int interact()
}
if (ok) {
hist_file =
afmt("%s/.local/share/kresd/" HISTORY_FILE, home);
afmt("%s/.local/share/knot-resolver/" HISTORY_FILE, home);
}
} else {
if (!mkdir(afmt("%s/kresd/", data_home), 0755)
if (!mkdir(afmt("%s/knot-resolver/", data_home), 0755)
|| errno == EEXIST) {
hist_file = afmt("%s/kresd/" HISTORY_FILE, data_home);
hist_file = afmt("%s/knot-resolver/" HISTORY_FILE, data_home);
}
}
......
# Project
MAJOR := 1
MINOR := 5
PATCH := 1
EXTRA :=
ABIVER := 4
MAJOR := 3
MINOR := 2
PATCH := 0
EXTRA ?=
ABIVER := 9
BUILDMODE := dynamic
HARDENING := yes
......@@ -18,11 +18,12 @@ PKGCONFIGDIR ?= $(LIBDIR)/pkgconfig
MANDIR ?= $(PREFIX)/share/man
INCLUDEDIR ?= $(PREFIX)/include
MODULEDIR ?= $(LIBDIR)/kdns_modules
ETCDIR ?= $(PREFIX)/etc/kresd
ETCDIR ?= $(PREFIX)/etc/knot-resolver
ROOTHINTS ?= $(ETCDIR)/root.hints
COVERAGE_STAGE ?= gcov
COVERAGE_STATSDIR ?= $(CURDIR)/coverage.stats
TOPSRCDIR := $(CURDIR)
KEYFILE_DEFAULT ?=
# Tools
CC ?= cc
......@@ -33,11 +34,12 @@ INSTALL := install
# Flags
BUILD_LDFLAGS += $(LDFLAGS)
BUILD_CFLAGS := $(CFLAGS) -std=c99 -D_GNU_SOURCE -Wno-unused -Wtype-limits -Wformat -Wformat-security -Wall -I$(abspath .) -I$(abspath lib/generic) -I$(abspath contrib) -I$(abspath contrib/lmdb)
BUILD_CFLAGS := $(CFLAGS) $(CPPFLAGS) -std=c99 -D_GNU_SOURCE
BUILD_CFLAGS += -Wno-unused -Wtype-limits -Wformat -Wformat-security -Wall
BUILD_CFLAGS += -I$(abspath .) -I$(abspath lib/generic) -I$(abspath contrib)
BUILD_CFLAGS += -DPACKAGE_VERSION="\"$(VERSION)\"" -DPREFIX="\"$(PREFIX)\"" -DMODULEDIR="\"$(MODULEDIR)\""
BUILD_CFLAGS += -fvisibility=hidden
ifeq (,$(findstring -O,$(CFLAGS)))
BUILD_CFLAGS += -O2
endif
ifeq (,$(findstring -fsanitize=address,$(CFLAGS)))
BUILD_CFLAGS += -D_FORTIFY_SOURCE=2
endif
......@@ -23,9 +23,9 @@
#define MAX_BIN_DATA_LEN ((INT32_MAX / 8) * 5)
/*! \brief Base32hex padding character. */
const uint8_t base32hex_pad = '=';
/*! \brief Base32hex alphabet. */
const uint8_t base32hex_enc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
static const uint8_t base32hex_pad = '=';
/*! \brief Base32hex alphabet. Beware: original code was upper-case. */
static const uint8_t base32hex_enc[] = "0123456789abcdefghijklmnopqrstuv";
/*! \brief Indicates bad Base32hex character. */
#define KO 255
......@@ -33,7 +33,7 @@ const uint8_t base32hex_enc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
#define PD 32
/*! \brief Transformation and validation table for decoding Base32hex. */
const uint8_t base32hex_dec[256] = {
static const uint8_t base32hex_dec[256] = {
[ 0] = KO, [ 43] = KO, ['V'] = 31, [129] = KO, [172] = KO, [215] = KO,
[ 1] = KO, [ 44] = KO, ['W'] = KO, [130] = KO, [173] = KO, [216] = KO,
[ 2] = KO, [ 45] = KO, ['X'] = KO, [131] = KO, [174] = KO, [217] = KO,
......@@ -205,3 +205,85 @@ int32_t base32hex_decode(const uint8_t *in,
return (bin - out);
}
int32_t base32hex_encode(const uint8_t *in,
const uint32_t in_len,
uint8_t *out,
const uint32_t out_len)
{
// Checking inputs.
if (in == NULL || out == NULL) {
return -1;
}
if (in_len > MAX_BIN_DATA_LEN || out_len < ((in_len + 4) / 5) * 8) {
return -1;
}
uint8_t rest_len = in_len % 5;
const uint8_t *stop = in + in_len - rest_len;
uint8_t *text = out;
// Encoding loop takes 5 bytes and creates 8 characters.
while (in < stop) {
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
text[4] = base32hex_enc[(in[2] & 0x0F) << 1 | in[3] >> 7];
text[5] = base32hex_enc[(in[3] & 0x7C) >> 2];
text[6] = base32hex_enc[(in[3] & 0x03) << 3 | in[4] >> 5];
text[7] = base32hex_enc[in[4] & 0x1F];
text += 8;
in += 5;
}
// Processing of padding, if any.
switch (rest_len) {
case 4:
text[0] = base32hex_enc[in[0] >> 3];
text[1] = base32hex_enc[(in[0] & 0x07) << 2 | in[1] >> 6];
text[2] = base32hex_enc[(in[1] & 0x3E) >> 1];
text[3] = base32hex_enc[(in[1] & 0x01) << 4 | in[2] >> 4];
text[4] = base32hex_enc[(in