'sources': [src_dir / 'lua-record.cc'],
'condition': dep_lua_records.found(),
},
- 'standalone-fuzz-target-runner': {
- 'sources': [src_dir / 'standalone_fuzz_target_runner.cc'],
- 'condition': get_option('fuzz-targets'),
- },
}
foreach name, info: conditional_sources
--- /dev/null
+../../NOTICE
\ No newline at end of file
+++ /dev/null
-../base32.hh
\ No newline at end of file
--- /dev/null
+../../../../ext/arc4random/meson.build
\ No newline at end of file
--- /dev/null
+lib_ipcrypt = static_library(
+ 'ipcrypt',
+ 'ipcrypt.c',
+ extra_files: [
+ 'ipcrypt.h',
+ ],
+)
+
+dep_ipcrypt = declare_dependency(
+ link_with: lib_ipcrypt,
+ include_directories: include_directories('.'),
+)
--- /dev/null
+../../../../ext/json11/meson.build
\ No newline at end of file
--- /dev/null
+lib_lmdb_safe = static_library(
+ 'lmdb-safe',
+ 'lmdb-safe.cc',
+ extra_files: [
+ 'lmdb-safe.hh',
+ ],
+ dependencies: [
+ dep_pdns,
+ dep_lmdb,
+ ],
+)
+
+dep_lmdb_safe = declare_dependency(
+ link_with: lib_lmdb_safe,
+ include_directories: include_directories('.'),
+)
--- /dev/null
+../../../../ext/luawrapper/meson.build
\ No newline at end of file
--- /dev/null
+../../../../ext/yahttp/meson.build
\ No newline at end of file
--- /dev/null
+../../../../../ext/yahttp/yahttp/meson.build
\ No newline at end of file
--- /dev/null
+#!/bin/sh
+
+echo 'R"FFIContent('
+cat $1 $2
+echo ')FFIContent"'
--- /dev/null
+project(
+ 'dnsdist',
+ ['c', 'cpp'],
+ version: run_command('../../builder-support' / 'gen-version', check: true).stdout().strip(),
+ license: 'GPLv2',
+ license_files: 'NOTICE',
+ meson_version: '>= 1.2.1',
+ default_options: [
+ 'buildtype=debugoptimized',
+ 'warning_level=2', # TODO Move this to 3 to enable -Wpedantic
+ 'cpp_std=c++17',
+ 'b_pie=true',
+ ],
+)
+add_project_arguments('-DDNSDIST', language: 'cpp')
+
+
+product_source_dir = meson.current_source_dir()
+product_build_dir = meson.current_build_dir()
+summary('Source Dir', product_source_dir, section: 'Build')
+summary('Build Dir', product_build_dir, section: 'Build')
+
+# Create the configuration object and dependencies list.
+conf = configuration_data()
+conf.set_quoted('PACKAGE_STRING', 'dnsdist ' + meson.project_version(), description: 'dnsdist version')
+conf.set_quoted('PACKAGE_VERSION', meson.project_version(), description: 'version')
+
+# Feature detection and system configuration
+subdir('meson' / 'config') # Config
+subdir('meson' / 'version') # Generate version define
+subdir('meson' / 'compiler-setup') # Common compiler setup
+subdir('meson' / 'summary') # Print a system/project summary
+subdir('meson' / 'sysconfdir') # Sysconfdir
+subdir('meson' / 'platform') # Platform detection
+subdir('meson' / 'timet-size') # Check the size of time_t
+subdir('meson' / 'timet-sign') # Check the sign of time_t
+subdir('meson' / 'atomics') # Check atomics support
+subdir('meson' / 'pthread-headers') # Check pthread headers
+subdir('meson' / 'pthread-setname') # Pthread setname madness
+subdir('meson' / 'pthread-np') # Pthread _np functions
+subdir('meson' / 'strerror') # Strerror_r
+subdir('meson' / 'lua') # Lua
+subdir('meson' / 'hardening') # Hardening
+subdir('meson' / 'net-libs') # Network Libraries
+subdir('meson' / 'tm-gmtoff') # Check for tm_gmtoff field in struct tm
+subdir('meson' / 'mmap') # Check for mmap
+subdir('meson' / 'libcap') # Libcap to drop capabilities
+subdir('meson' / 'libedit') # Libedit
+subdir('meson' / 'libsodium') # Libsodium
+subdir('meson' / 'libcrypto') # OpenSSL libcrypto
+subdir('meson' / 'libssl') # OpenSSL libssl
+subdir('meson' / 'libssl-providers') # OpenSSL libssl providers
+subdir('meson' / 'libsnmp') # SNMP
+subdir('meson' / 'clock-gettime') # Clock_gettime
+subdir('meson' / 'boost') # Boost
+subdir('meson' / 'boost-test') # Boost Testing Library
+subdir('meson' / 'reproducible') # Reproducible Builds
+subdir('meson' / 'libsystemd') # Systemd notification
+subdir('meson' / 'systemd') # Systemd and unit file handling
+subdir('meson' / 'code-coverage') # Code coverage
+subdir('meson' / 'auto-var-init') # Automatic Variable Initialization
+subdir('meson' / 'sanitizers') # Sanitizers
+subdir('meson' / 'various-functions') # Various Functions
+subdir('meson' / 'various-headers') # Various Headers
+subdir('meson' / 'dnstap') # DNSTAP through libfstream
+subdir('meson' / 'dnscrypt') # DNSCrypt through libsodium
+subdir('meson' / 'ipcipher') # IPCipher (requires libcrypto)
+subdir('meson' / 'cdb') # CDB
+subdir('meson' / 'ebpf') # eBPF
+subdir('meson' / 'gnutls') # GNUTLS
+subdir('meson' / 'h2o') # H2O
+subdir('meson' / 'lmdb') # LMDB
+subdir('meson' / 'nghttp2') # NGHTTP2
+subdir('meson' / 'quiche') # Quiche
+subdir('meson' / 're2') # RE2
+subdir('meson' / 'xsk') # BPF and XDP for XSK
+subdir('meson' / 'dot') # DNS over TLS
+subdir('meson' / 'doh2') # DNS over HTTP/2
+subdir('meson' / 'doq') # DNS over QUIC
+subdir('meson' / 'doh3') # DNS over HTTP/3
+
+common_sources = []
+
+fs = import('fs')
+src_dir = fs.is_dir('.') ? '.' : ''
+docs_dir = 'docs'
+# Toplevel includes
+dep_pdns = declare_dependency(include_directories: include_directories('.', src_dir))
+
+# Ext
+subdir('ext' / 'arc4random')
+subdir('ext' / 'ipcrypt')
+subdir('ext' / 'json11')
+subdir('ext' / 'luawrapper')
+subdir('ext' / 'protozero')
+subdir('ext' / 'yahttp')
+
+if get_option('lmdb').allowed()
+ subdir('ext' / 'lmdb-safe')
+endif
+
+common_sources += files(
+ src_dir / 'bpf-filter.cc',
+ src_dir / 'capabilities.cc',
+ src_dir / 'cdb.cc',
+ src_dir / 'channel.cc',
+ src_dir / 'coverage.cc',
+ src_dir / 'credentials.cc',
+ src_dir / 'dns.cc',
+ src_dir / 'dnscrypt.cc',
+ src_dir / 'dnsdist-async.cc',
+ src_dir / 'dnsdist-backend.cc',
+ src_dir / 'dnsdist-cache.cc',
+ src_dir / 'dnsdist-carbon.cc',
+ src_dir / 'dnsdist-configuration.cc',
+ src_dir / 'dnsdist-console.cc',
+ src_dir / 'dnsdist-crypto.cc',
+ src_dir / 'dnsdist-discovery.cc',
+ src_dir / 'dnsdist-dnscrypt.cc',
+ src_dir / 'dnsdist-dnsparser.cc',
+ src_dir / 'dnsdist-dnsquestion.cc',
+ src_dir / 'dnsdist-doh-common.cc',
+ src_dir / 'dnsdist-dynblocks.cc',
+ src_dir / 'dnsdist-dynbpf.cc',
+ src_dir / 'dnsdist-ecs.cc',
+ src_dir / 'dnsdist-edns.cc',
+ src_dir / 'dnsdist-frontend.cc',
+ src_dir / 'dnsdist-healthchecks.cc',
+ src_dir / 'dnsdist-idstate.cc',
+ src_dir / 'dnsdist-internal-queries.cc',
+ src_dir / 'dnsdist-kvs.cc',
+ src_dir / 'dnsdist-lbpolicies.cc',
+ src_dir / 'dnsdist-lua-actions.cc',
+ src_dir / 'dnsdist-lua-bindings.cc',
+ src_dir / 'dnsdist-lua-bindings-dnscrypt.cc',
+ src_dir / 'dnsdist-lua-bindings-dnsparser.cc',
+ src_dir / 'dnsdist-lua-bindings-dnsquestion.cc',
+ src_dir / 'dnsdist-lua-bindings-kvs.cc',
+ src_dir / 'dnsdist-lua-bindings-network.cc',
+ src_dir / 'dnsdist-lua-bindings-packetcache.cc',
+ src_dir / 'dnsdist-lua-bindings-protobuf.cc',
+ src_dir / 'dnsdist-lua-bindings-rings.cc',
+ src_dir / 'dnsdist-lua.cc',
+ src_dir / 'dnsdist-lua-ffi.cc',
+ src_dir / 'dnsdist-lua-hooks.cc',
+ src_dir / 'dnsdist-lua-inspection.cc',
+ src_dir / 'dnsdist-lua-inspection-ffi.cc',
+ src_dir / 'dnsdist-lua-network.cc',
+ src_dir / 'dnsdist-lua-rules.cc',
+ src_dir / 'dnsdist-lua-vars.cc',
+ src_dir / 'dnsdist-lua-web.cc',
+ src_dir / 'dnsdist-mac-address.cc',
+ src_dir / 'dnsdist-metrics.cc',
+ src_dir / 'dnsdist-nghttp2.cc',
+ src_dir / 'dnsdist-nghttp2-in.cc',
+ src_dir / 'dnsdist-protobuf.cc',
+ src_dir / 'dnsdist-protocols.cc',
+ src_dir / 'dnsdist-proxy-protocol.cc',
+ src_dir / 'dnsdist-query-count.cc',
+ src_dir / 'dnsdist-random.cc',
+ src_dir / 'dnsdist-resolver.cc',
+ src_dir / 'dnsdist-rings.cc',
+ src_dir / 'dnsdist-rule-chains.cc',
+ src_dir / 'dnsdist-rules.cc',
+ src_dir / 'dnsdist-secpoll.cc',
+ src_dir / 'dnsdist-session-cache.cc',
+ src_dir / 'dnsdist-snmp.cc',
+ src_dir / 'dnsdist-svc.cc',
+ src_dir / 'dnsdist-systemd.cc',
+ src_dir / 'dnsdist-tcp.cc',
+ src_dir / 'dnsdist-tcp-downstream.cc',
+ src_dir / 'dnsdist-web.cc',
+ src_dir / 'dnsdist-xsk.cc',
+ src_dir / 'dnsname.cc',
+ src_dir / 'dnsparser.cc',
+ src_dir / 'dnswriter.cc',
+ src_dir / 'dolog.cc',
+ src_dir / 'ednscookies.cc',
+ src_dir / 'ednsextendederror.cc',
+ src_dir / 'ednsoptions.cc',
+ src_dir / 'ednssubnet.cc',
+ src_dir / 'gettime.cc',
+ src_dir / 'ipcipher.cc',
+ src_dir / 'iputils.cc',
+ src_dir / 'libssl.cc',
+ src_dir / 'misc.cc',
+ src_dir / 'protozero.cc',
+ src_dir / 'proxy-protocol.cc',
+ src_dir / 'qtype.cc',
+ src_dir / 'remote_logger.cc',
+ src_dir / 'snmp-agent.cc',
+ src_dir / 'statnode.cc',
+ src_dir / 'svc-records.cc',
+ src_dir / 'tcpiohandler.cc',
+ src_dir / 'threadname.cc',
+ src_dir / 'uuid-utils.cc',
+ src_dir / 'xsk.cc',
+)
+
+conditional_sources = {
+ 'cdb': {
+ 'sources': [
+ src_dir / 'cdb.cc',
+ ],
+ 'condition': dep_cdb.found(),
+ },
+ 'dnstap': {
+ 'sources': [
+ src_dir / 'dnstap.cc',
+ src_dir / 'fstrm_logger.cc',
+ ],
+ 'condition': dep_dnstap.found(),
+ },
+ 'doh': {
+ 'sources': [
+ src_dir / 'doh.cc',
+ ],
+ 'condition': dep_libh2o_evloop.found(),
+ },
+ 'doh3': {
+ 'sources': [
+ src_dir / 'doh3.cc',
+ ],
+ 'condition': get_option('dns-over-http3'),
+ },
+ 'doq': {
+ 'sources': [
+ src_dir / 'doq.cc',
+ ],
+ 'condition': get_option('dns-over-quic'),
+ },
+ 'ipcipher': {
+ 'sources': [
+ src_dir / 'ipcipher.cc',
+ ],
+ 'condition': dep_libcrypto.found(),
+ },
+ 'quiche': {
+ 'sources': [
+ src_dir / 'doq-common.cc',
+ ],
+ 'condition': dep_libquiche.found(),
+ },
+}
+
+foreach name, info: conditional_sources
+ if info['condition']
+ common_sources += files(info['sources'])
+ endif
+endforeach
+
+mplexer_sources = [src_dir / 'pollmplexer.cc']
+if have_linux
+ mplexer_sources += src_dir / 'epollmplexer.cc'
+endif
+if have_darwin
+ mplexer_sources += src_dir / 'kqueuemplexer.cc'
+endif
+if have_openbsd
+ mplexer_sources += src_dir / 'kqueuemplexer.cc'
+endif
+if have_freebsd
+ mplexer_sources += src_dir / 'kqueuemplexer.cc'
+endif
+if have_sunos
+ mplexer_sources += src_dir / 'devpollmplexer.cc'
+ mplexer_sources += src_dir / 'portsmplexer.cc'
+endif
+
+# Generate config.h
+config_h = configure_file(configuration: conf, output: 'config.h')
+
+sh_program = find_program('sh')
+dep_no_config_in_source_check = custom_target(
+ input: [],
+ output: ['check absense of config.h file in source directory'],
+ command: [sh_program, '-c', 'test ! -e @SOURCE_ROOT@/config.h'],
+ build_always_stale: true,
+)
+dep_no_config_in_source = declare_dependency(
+ sources: dep_no_config_in_source_check
+)
+
+html_sources = [
+ src_dir / 'html/index.html',
+ src_dir / 'html/local.js',
+ src_dir / 'html/js/moment.min.js',
+ src_dir / 'html/js/rickshaw.min.js',
+ src_dir / 'html/js/d3.min.js',
+ src_dir / 'html/js/moment.min.js',
+ src_dir / 'html/lines.css',
+ src_dir / 'html/legend.css',
+ src_dir / 'html/detail.css',
+ src_dir / 'html/graph.css',
+ src_dir / 'html/powerdns-logo-220px.png',
+]
+
+incfiles = find_program('incfiles')
+
+htmlfiles = custom_target(
+ command: [incfiles, '@SOURCE_ROOT@'],
+ input: html_sources,
+ output: 'htmlfiles.h',
+ capture: true
+)
+
+dep_htmlfiles = declare_dependency(
+ sources: [htmlfiles],
+)
+
+generate_ffi_interface = find_program('generate-ffi-interface.sh')
+ffi_interface = custom_target(
+ command: [generate_ffi_interface, '@INPUT@'],
+ input: ['dnsdist-lua-ffi-interface.h', 'dnsdist-lua-inspection-ffi.h'],
+ output: 'dnsdist-lua-ffi-interface.inc',
+ capture: true
+)
+
+dep_ffi_interface = declare_dependency(
+ sources: [ffi_interface],
+)
+
+deps = [
+ dep_pdns,
+ dep_no_config_in_source,
+ dep_arc4random,
+ dep_boost,
+ dep_cdb,
+ dep_dnstap,
+ dep_ffi_interface,
+ dep_htmlfiles,
+ dep_ipcrypt,
+ dep_libcap,
+ dep_libcrypto,
+ dep_gnutls,
+ dep_libedit,
+ dep_libh2o_evloop,
+ dep_json11,
+ dep_libnghttp2,
+ dep_libquiche,
+ dep_libsnmp,
+ dep_libsodium,
+ dep_libssl,
+ dep_lmdb,
+ dep_lmdb_safe,
+ dep_lua,
+ dep_protozero,
+ dep_yahttp,
+ dep_libre2,
+ dep_threads,
+ dep_libbpf,
+ dep_libxdp,
+]
+
+libdnsdist_dnslabeltext_source = src_dir / 'dnslabeltext.rl'
+libdnsdist_dnslabeltext_gen = src_dir / 'dnslabeltext.cc'
+if not fs.is_file(libdnsdist_dnslabeltext_gen)
+ ragel = find_program('ragel', required: true)
+
+ summary('Ragel', ragel.found(), bool_yn: ragel.found(), section: 'DNS Labels')
+ summary('Ragel Path', ragel.full_path(), section: 'DNS Labels')
+ summary('Ragel Version', ragel.version(), section: 'DNS Labels')
+
+ ragel_generator = generator(
+ ragel,
+ output: '@BASENAME@.cc',
+ arguments: ['@INPUT@', '-o', '@OUTPUT@'],
+ )
+
+ libdnsdist_dnslabeltext_gen = ragel_generator.process(libdnsdist_dnslabeltext_source)
+endif
+
+libdnsdist_dnslabeltext = declare_dependency(
+ link_with: static_library(
+ 'dnsdist-dnslabeltext',
+ libdnsdist_dnslabeltext_gen,
+ dependencies: deps,
+ )
+)
+
+libdnsdist_common = declare_dependency(
+ link_with: static_library(
+ 'dnsdist-common',
+ common_sources,
+ config_h,
+ dependencies: [
+ deps,
+ libdnsdist_dnslabeltext,
+ ],
+ )
+)
+
+tools = {
+ 'dnsdist': {
+ 'main': src_dir / 'dnsdist.cc',
+ 'files-extra': [
+ mplexer_sources,
+ ],
+ 'manpages': ['dnsdist.1'],
+ 'deps-extra': [
+ dep_pdns,
+ dep_boost,
+ dep_lua,
+ dep_protozero,
+ dep_yahttp,
+ dep_json11,
+ dep_systemd,
+ ],
+ },
+}
+
+if get_option('fuzz-targets')
+ fuzz_extra_sources = []
+ fuzzer_ldflags = []
+ # https://github.com/harfbuzz/harfbuzz/pull/2549/files
+ if get_option('fuzzer_ldflags') == ''
+ fuzz_extra_sources += src_dir / 'standalone_fuzz_target_runner.cc'
+ else
+ fuzzer_ldflags += get_option('fuzzer_ldflags')
+ endif
+ tools += {
+ 'fuzz-target-dnsdistcache' : {
+ 'main': src_dir / 'fuzz_dnsdistcache.cc',
+ 'link_flags': fuzzer_ldflags,
+ 'files-extra': fuzz_extra_sources
+ },
+ }
+ if get_option('xsk').allowed() and dep_libbpf.found() and dep_libxdp.found()
+ tools += {
+ 'fuzz-target-xsk' : {
+ 'main': src_dir / 'fuzz_xsk.cc',
+ 'link_flags': fuzzer_ldflags,
+ 'files-extra': fuzz_extra_sources + [
+ src_dir / 'dnslabeltext.cc',
+ src_dir / 'dnsname.cc',
+ src_dir / 'gettime.cc',
+ src_dir / 'iputils.cc',
+ src_dir / 'misc.cc',
+ src_dir / 'xsk.cc'
+ ]
+ },
+ }
+ endif
+endif
+
+test_sources = []
+test_sources += files(
+ src_dir / 'test-base64_cc.cc',
+ src_dir / 'test-channel.cc',
+ src_dir / 'test-connectionmanagement_hh.cc',
+ src_dir / 'test-credentials_cc.cc',
+ src_dir / 'test-delaypipe_hh.cc',
+ src_dir / 'test-dnscrypt_cc.cc',
+ src_dir / 'test-dnsdistasync.cc',
+ src_dir / 'test-dnsdistbackend_cc.cc',
+ src_dir / 'test-dnsdistbackoff.cc',
+ src_dir / 'test-dnsdist_cc.cc',
+ src_dir / 'test-dnsdist-connections-cache.cc',
+ src_dir / 'test-dnsdist-dnsparser.cc',
+ src_dir / 'test-dnsdistdynblocks_hh.cc',
+ src_dir / 'test-dnsdistedns.cc',
+ src_dir / 'test-dnsdistkvs_cc.cc',
+ src_dir / 'test-dnsdistlbpolicies_cc.cc',
+ src_dir / 'test-dnsdist-lua-ffi.cc',
+ src_dir / 'test-dnsdistluanetwork.cc',
+ src_dir / 'test-dnsdistnghttp2_cc.cc',
+ src_dir / 'test-dnsdistnghttp2-in_cc.cc',
+ src_dir / 'test-dnsdistpacketcache_cc.cc',
+ src_dir / 'test-dnsdistrings_cc.cc',
+ src_dir / 'test-dnsdistrules_cc.cc',
+ src_dir / 'test-dnsdistsvc_cc.cc',
+ src_dir / 'test-dnsdisttcp_cc.cc',
+ src_dir / 'test-dnsparser_cc.cc',
+ src_dir / 'test-iputils_hh.cc',
+ src_dir / 'test-luawrapper.cc',
+ src_dir / 'test-mplexer.cc',
+ src_dir / 'test-proxy_protocol_cc.cc',
+ src_dir / 'test-sholder_hh.cc',
+)
+
+if get_option('unit-tests')
+ libdnsdist_test = declare_dependency(
+ link_whole: static_library(
+ 'dnsdist-test',
+ config_h,
+ test_sources,
+ dependencies: [
+ dep_boost,
+ dep_boost_test,
+ dep_lua,
+ ],
+ )
+ )
+ tools += {
+ 'testrunner': {
+ 'main': [
+ src_dir / 'testrunner.cc',
+ mplexer_sources,
+ ],
+ 'deps-extra': [
+ libdnsdist_test,
+ dep_boost_test,
+ ],
+ }
+ }
+endif
+
+man_pages = []
+foreach tool, info: tools
+ var_name = tool.underscorify()
+ main = files(info['main'])
+
+ export_dynamic = 'export-dynamic' in info ? info['export-dynamic'] : false
+ files_extra = 'files-extra' in info ? info['files-extra'] : []
+ deps_extra = 'deps-extra' in info ? info['deps-extra'] : []
+ link_args = 'link-args' in info ? info['link-args'] : []
+
+ set_variable(
+ var_name,
+ executable(
+ tool,
+ main,
+ config_h,
+ files_extra,
+ export_dynamic: export_dynamic,
+ link_args: link_args,
+ dependencies: [
+ libdnsdist_common,
+ deps_extra,
+ ],
+ )
+ )
+
+ if 'manpages' in info
+ foreach man_page: info['manpages']
+ man_pages += docs_dir / 'manpages' / (man_page + '.rst')
+ endforeach
+ endif
+endforeach
+
+# Man-pages.
+py = import('python')
+python = py.find_installation('python3', modules: 'venv', required: false)
+
+summary('Python', python.found(), bool_yn: true, section: 'Manual Pages')
+summary('Path', python.full_path(), section: 'Manual Pages')
+summary('Version', python.version(), section: 'Manual Pages')
+
+if python.found()
+ run_target(
+ 'man-pages',
+ command: [
+ python,
+ product_source_dir / docs_dir / 'generate-man-pages.py',
+ '--venv-name', 'venv-dnsdist-man-pages',
+ '--requirements-file', docs_dir / 'requirements.txt',
+ '--source-directory', docs_dir,
+ '--target-directory', 'dnsdist-man-pages',
+ ] + man_pages,
+ )
+endif
--- /dev/null
+#include <cstdint>
+
+int main()
+{
+ uint64_t val = 0;
+ __atomic_add_fetch(&val, 1, __ATOMIC_RELAXED);
+ return 0;
+}
--- /dev/null
+dep_atomics = dependency('', required: false)
+need_latomic = false
+
+prog = fs.read('atomic_add_fetch.cc')
+if not cxx.links(prog, name: '-latomic is not needed for using __atomic builtins')
+ lib_atomic = cxx.find_library('atomic', disabler: true, required: false)
+ if lib_atomic.found()
+ if cxx.links(prog, name: '-latomic is needed for using __atomic builtins', dependencies: lib_atomic)
+ need_latomic = true
+ dep_atomics = declare_dependency(dependencies: lib_atomic)
+ summary('Atomics Library', lib_atomic, section: 'System')
+ else
+ error('libatomic is needed and was found, but linking with it failed')
+ endif
+ else
+ error('libatomic is needed but could not be found')
+ endif
+else
+ dep_atomics = declare_dependency()
+endif
+
+summary('Need -latomic', need_latomic, bool_yn: true, section: 'System')
--- /dev/null
+auto_var_init = get_option('auto-var-init')
+
+if auto_var_init != 'disabled'
+ arg = '-ftrivial-auto-var-init=' + auto_var_init
+ if cxx.has_argument(arg)
+ add_project_arguments(arg, language: ['c', 'cpp'])
+ else
+ warning('Compiler does not support ' + arg + ', which is needed for automatic variable initialization')
+ auto_var_init = 'unsupported by compiler'
+ endif
+endif
+
+summary('Auto Var Init', auto_var_init, section: 'Configuration')
--- /dev/null
+dep_boost_test = dependency('', required: false)
+if get_option('unit-tests')
+ dep_boost_test = dependency('boost', modules: ['unit_test_framework'], required: true)
+ summary('Test', dep_boost_test.found(), bool_yn: true, section: 'Boost')
+endif
--- /dev/null
+dep_boost = dependency('boost', version: '>= 1.54', required: true)
+# conf.set('BOOST_CONTAINER_USE_STD_EXCEPTIONS', true, description: 'Boost use std exceptions')
+add_project_arguments('-DBOOST_CONTAINER_USE_STD_EXCEPTIONS', language: ['c', 'cpp'])
+summary('Boost', dep_boost.found(), bool_yn: true, section: 'Boost')
+summary('Version', dep_boost.version(), section: 'Boost')
--- /dev/null
+dep_cdb = dependency('', required: false)
+
+dep_cdb = dependency('libcdb', required: false)
+
+if not dep_cdb.found()
+ if cxx.has_header('cdb.h', required: true)
+ if cxx.has_function('cdb_find', args: ['-lcdb'])
+ dep_cdb = declare_dependency(link_args: ['-lcdb'])
+ endif
+ endif
+endif
+
+conf.set('HAVE_CDB', dep_cdb.found(), description: 'Whether we have CDB')
+
+summary('CDB', dep_cdb.found(), bool_yn: true, section: 'Key-Value')
+
+if dep_cdb.found()
+ summary('CDB version', dep_cdb.version(), bool_yn: true, section: 'Key-Value')
+endif
--- /dev/null
+found = cxx.has_function('clock_gettime')
+dep_rt = dependency('', required: false)
+
+if not found
+ dep_rt = cxx.find_library('rt', required: true)
+ found = cxx.has_function('clock_gettime', dependencies: dep_rt)
+endif
+
+conf.set('HAVE_CLOCK_GETTIME', found, description: 'Have clock_gettime')
+summary('clock_gettime', true, bool_yn: true, section: 'System')
+
+if dep_rt.found()
+ summary('rt library', dep_rt.name(), bool_yn: true, section: 'System')
+ summary('rt library version', dep_rt.version(), bool_yn: true, section: 'System')
+endif
--- /dev/null
+coverage = get_option('b_coverage')
+
+if coverage
+ if get_option('buildtype') != 'debug'
+ warning('Coverage is enabled, using `builtype=debug` would produce better reports')
+ endif
+
+ if cxx.has_argument('-U_FORTIFY_SOURCE')
+ add_project_arguments('-U_FORTIFY_SOURCE', language: ['c', 'cpp'])
+ endif
+endif
+
+summary('Code Coverage', coverage, bool_yn: true, section: 'Configuration')
--- /dev/null
+# Don't limit the number of errors when using clang. This is useful to not cut out the
+# error output when using an LSP server like clangd.
+if meson.get_compiler('cpp').get_id() == 'clang'
+ add_project_arguments('-ferror-limit=0', language: ['c', 'cpp'])
+endif
+
+add_project_arguments(
+ '-Wshadow',
+ '-Wmissing-declarations',
+ '-Wredundant-decls',
+ '-Wno-ignored-attributes',
+ '-fvisibility=hidden',
+ language: ['c', 'cpp'],
+)
+
+cxx = meson.get_compiler('cpp')
+system = target_machine.system()
--- /dev/null
+add_project_arguments('-DHAVE_CONFIG_H', language: ['c', 'cpp'])
--- /dev/null
+dep_dlopen = declare_dependency()
+
+if not cxx.has_function('dlopen')
+ dep_dlopen = dependency('dl', required: false)
+
+ if not dep_dlopen.found()
+ dep_dlopen = cxx.find_library('dl', required: true)
+
+ if not cxx.has_function('dlopen', dependencies: dep_dlopen)
+ error('Your system does not support dlopen')
+ endif
+ endif
+endif
+
+summary('dlopen', dep_dlopen.found(), bool_yn: true, section: 'System')
--- /dev/null
+opt_dnscrypt = get_option('dnscrypt')
+
+if opt_dnscrypt.enabled() and not dep_libsodium.found()
+ error('DNSCrypt support requested but libsodium is not available')
+endif
+
+conf.set('HAVE_DNSCRYPT', opt_dnscrypt.allowed() and dep_libsodium.found(), description: 'DNSCrypt support')
+summary('DNSCrypt support', opt_dnscrypt.allowed() and dep_libsodium.found(), bool_yn: true, section: 'Crypto')
--- /dev/null
+opt_dnstap = get_option('dnstap')
+dep_dnstap = dependency('libfstrm', required: opt_dnstap)
+
+if dep_dnstap.found()
+ funcs = [
+ 'fstrm_tcp_writer_init',
+ ]
+
+ foreach func: funcs
+ has = cxx.has_function(func, dependencies: dep_dnstap)
+ conf.set('HAVE_' + func.to_upper(), has, description: 'Have libfstram ' + func)
+ endforeach
+endif
+
+conf.set('HAVE_FSTRM', dep_dnstap.found(), description: 'libfstrm')
+summary('DNSTAP', dep_dnstap.found(), bool_yn: true, section: 'Configuration')
+
--- /dev/null
+opt_doh2 = get_option('dns-over-https')
+conf.set('HAVE_DNS_OVER_HTTPS', opt_doh2, description: 'DNS over HTTP/2 (DoH)')
+
+if opt_doh2
+ if not dep_libssl.found() and not dep_gnutls.found()
+ error('DNS over HTTP/2 support was requested but neither OpenSSL libssl nor GnuTLS support is enabled')
+ endif
+ if not dep_libnghttp2.found() and not dep_libh2o_evloop.found()
+ error('DNS over HTTP/2 support was requested but neither nghttp2 not libh2o-evloop support is enabled')
+ endif
+endif
+
+summary('DNS over HTTP/2', opt_doh2, bool_yn: true, section: 'Configuration')
--- /dev/null
+opt_doh3 = get_option('dns-over-http3')
+conf.set('HAVE_DNS_OVER_HTTP3', opt_doh3, description: 'DNS over HTTP/3 (DoH3)')
+
+if opt_doh3
+ if not dep_libquiche.found()
+ error('DNS over HTTP/3 support was requested but Quiche support is not enabled')
+ endif
+endif
+
+summary('DNS over HTTP/3', opt_doh3, bool_yn: true, section: 'Configuration')
--- /dev/null
+opt_doq = get_option('dns-over-quic')
+conf.set('HAVE_DNS_OVER_QUIC', opt_doq, description: 'DNS over QUIC (DoQ)')
+
+if opt_doq
+ if not dep_libquiche.found()
+ error('DNS over QUIC support was requested but Quiche support is not enabled')
+ endif
+endif
+
+summary('DNS over QUIC', opt_doq, bool_yn: true, section: 'Configuration')
--- /dev/null
+opt_dot = get_option('dns-over-tls')
+conf.set('HAVE_DNS_OVER_TLS', opt_dot, description: 'DNS over TLS (DoT)')
+
+if opt_dot and not dep_libssl.found() and not dep_gnutls.found()
+ error('DNS over TLS support was requested but neither OpenSSL libssl nor GnuTLS support is enabled')
+endif
+
+summary('DNS over TLS', opt_dot, bool_yn: true, section: 'Configuration')
--- /dev/null
+if get_option('ebpf').allowed()
+ if cxx.check_header('linux/bpf.h') and cxx.get_define('SO_ATTACH_BPF', prefix: '#include "sys/socket.h"') != ''
+ conf.set('HAVE_EBPF', true, description: 'eBPF')
+ summary('eBPF', true, bool_yn: true, section: 'eBPF')
+ else
+ summary('eBPF', false, bool_yn: true, section: 'eBPF')
+ endif
+endif
--- /dev/null
+opt_gnutls = get_option('tls-gnutls')
+dep_gnutls = dependency('gnutls', version: '>= 3.1.11', required: opt_gnutls)
+
+if dep_gnutls.found()
+ funcs = [
+ 'gnutls_memset',
+ 'gnutls_session_set_verify_cert',
+ 'gnutls_session_get_verify_cert_status',
+ 'gnutls_alpn_set_protocols',
+ ]
+
+ foreach func: funcs
+ has = cxx.has_function(func, dependencies: dep_gnutls)
+ conf.set('HAVE_' + func.to_upper(), has, description: 'Have GnuTLS ' + func)
+ endforeach
+endif
+
+conf.set('HAVE_GNUTLS', dep_gnutls.found(), description: 'GnuTLS')
+summary('GnuTLS', dep_gnutls.found(), bool_yn: true, section: 'Crypto')
--- /dev/null
+opt_h2o = get_option('h2o')
+dep_libh2o_evloop = dependency('libh2o-evloop', required: opt_h2o)
+
+if dep_libh2o_evloop.found()
+ funcs = [
+ 'h2o_socket_get_ssl_server_name',
+ ]
+
+ foreach func: funcs
+ has = cxx.has_function(func, dependencies: dep_libh2o_evloop)
+ conf.set('HAVE_' + func.to_upper(), has, description: 'Have h2o ' + func)
+ endforeach
+endif
+
+conf.set('HAVE_LIBH2OEVLOOP', dep_libh2o_evloop.found(), description: 'H2O library with event loop support for DNS over HTTP/2')
+summary('H2O library with event loop support for DNS over HTTP/2', dep_libh2o_evloop.found(), bool_yn: true, section: 'DNS over HTTP/2')
--- /dev/null
+opt_cf = get_option('hardening-experimental-cf')
+
+support_cf_prot = opt_cf != 'disabled' and cxx.has_argument('-fcf-protection=' + opt_cf)
+if support_cf_prot
+ add_project_arguments('-fcf-protection=' + opt_cf, language: ['c', 'cpp'])
+elif opt_cf != 'disabled'
+ error('Control Flow Protection was explicitly requested but is not supported by the compiler')
+endif
+
+summary('Control Flow Protection', support_cf_prot, bool_yn: true, section: 'Hardening')
--- /dev/null
+fortify_source_opt = get_option('hardening-fortify-source')
+fortify_source = fortify_source_opt != 'disabled'
+fortify_source_level = 0
+
+if fortify_source and get_option('buildtype') == 'debug'
+ error('Source fortification was requested but it requires compiling with optimization. ' +
+ 'A debug buildtype was requested, try setting buildtype=debugoptimized instead')
+endif
+
+if fortify_source
+ fortify_source_level = 2
+ if fortify_source_opt == 'auto'
+ fortify_source_level = 3
+ else
+ fortify_source_level = fortify_source_opt.to_int()
+ endif
+
+ variants = [3, 2, 1]
+ foreach variant: variants
+ variant_str = variant.to_string()
+ if fortify_source_level == variant
+ if cxx.has_argument('-D_FORTIFY_SOURCE=' + variant_str)
+ add_project_arguments('-U_FORTIFY_SOURCE', '-D_FORTIFY_SOURCE=' + variant_str, language: ['c', 'cpp'])
+ break
+ else
+ fortify_source_level = fortify_source_level - 1
+ endif
+ endif
+ endforeach
+endif
+
+fortify_source = fortify_source and fortify_source_level != 0
+summary('Source Fortification', fortify_source, bool_yn: true, section: 'Hardening')
+
+if fortify_source
+ summary('Source Fortification Level', fortify_source_level, section: 'Hardening')
+endif
--- /dev/null
+opt_hardening = get_option('hardening')
+if opt_hardening.enabled() or opt_hardening.auto()
+ hardening_features = []
+
+ # PIE
+ opt_pie = get_option('b_pie')
+ if not opt_pie and opt_hardening.enabled()
+ error('Hardening was requested but building position independent executables is disabled')
+ endif
+ hardening_features += [[opt_pie, 'Building position independent executables (PIEs)']]
+ conf.set('PIE', opt_pie, description: 'Build a Position Independent Executable (PIE)')
+ summary('PIE', opt_pie, bool_yn: true, section: 'Hardening')
+
+ subdir('stack-prot') # Stack Protector
+ subdir('stack-smashing-prot') # Stack-Smashing Protection
+ subdir('relro') # RELRO
+
+ foreach feature: hardening_features
+ available = feature[0]
+ name = feature[1]
+
+ if not available
+ if opt_hardening.auto()
+ warning(name + ' is disabled or not supported')
+ else
+ error('Failing because ' + name + ' is not supported but hardening was requested')
+ endif
+ endif
+ endforeach
+endif
+
+subdir('fortify-source') # Fortify Source
+subdir('control-flow') # Control Flow Protection
+subdir('stack-clash-prot') # Stack Clash Protection
--- /dev/null
+have_relro = true
+variants = [
+ '-Wl,-z,relro',
+ '-Wl,-z,now',
+]
+
+foreach variant: variants
+ if cxx.has_link_argument(variant)
+ hardening_features += [[true, 'RELRO (' + variant + ')']]
+ add_project_link_arguments(variant, language: ['c', 'cpp'])
+ else
+ have_relro = false
+ endif
+endforeach
+
+summary('RELRO', have_relro, bool_yn: true, section: 'Hardening')
--- /dev/null
+opt_scp = get_option('hardening-experimental-scp')
+
+support_scp = not opt_scp.disabled() and cxx.has_argument('-fstack-clash-protection')
+if support_scp
+ add_project_arguments('-fstack-clash-protection', language: ['c', 'cpp'])
+elif opt_scp.enabled()
+ error('Stack Clash Protection was explicitly requested but is not supported by the compiler')
+endif
+
+summary('Stack Clash Protection', support_scp, bool_yn: true, section: 'Hardening')
--- /dev/null
+support_stack_protector = cxx.has_argument('-fstack-protector')
+
+if support_stack_protector
+ add_project_arguments('-fstack-protector', language: ['c', 'cpp'])
+endif
+
+hardening_features += [[support_stack_protector, 'Stack Protector']]
+summary('Stack Protector', support_stack_protector, bool_yn: true, section: 'Hardening')
--- /dev/null
+support_stack_smashing_protector = cxx.has_argument('--param=ssp-buffer-size=4')
+if support_stack_smashing_protector
+ add_project_arguments('--param=ssp-buffer-size=4', language: ['c', 'cpp'])
+endif
+
+hardening_features += [[support_stack_smashing_protector, 'Stack Smashing Protection']]
+summary('Stack Smashing Protection', support_stack_smashing_protector, bool_yn: true, section: 'Hardening')
+if support_stack_smashing_protector
+ summary('SSP Buffer Size', 4, section: 'Hardening')
+endif
--- /dev/null
+opt_ipcipher = get_option('ipcipher')
+
+if not dep_libcrypto.found() and opt_ipcipher.enabled()
+ error('ipcipher support was requested but libcrypto is not available')
+endif
+
+enable_ipcipher = dep_libcrypto.found() and not opt_ipcipher.disabled()
+conf.set('HAVE_IPCIPHER', enable_ipcipher, description: 'ipcipher support')
+summary('ipcipher', enable_ipcipher, bool_yn: true, section: 'Configuration')
--- /dev/null
+opt_kiss_rng = get_option('rng-kiss')
+conf.set('HAVE_KISS_RNG', opt_kiss_rng, description: 'Use the unsafe KISS RNG')
+summary('Unsafe KISS RNG', opt_kiss_rng, bool_yn: true, section: 'Configuration')
--- /dev/null
+opt_libcap = get_option('libcap')
+dep_libcap = dependency('libcap', required: opt_libcap)
+
+conf.set('HAVE_LIBCAP', dep_libcap.found(), description: 'libcap support')
+summary('libcap support', dep_libcap.found(), bool_yn: true, section: 'Capabilities')
--- /dev/null
+#include <openssl/bn.h>
+
+int main()
+{
+ BN_new();
+ return 0;
+}
--- /dev/null
+prefix = '''
+#include <stdarg.h>
+#include <stddef.h>
+'''
+found = cxx.has_header(
+ 'openssl/ecdsa.h',
+ dependencies: dep_libcrypto,
+ prefix: prefix,
+ required: false
+)
+
+if found
+ syms = [
+ 'NID_X9_62_prime256v1',
+ 'NID_secp384r1',
+ ]
+
+ foreach sym: syms
+ found = cxx.has_header_symbol(
+ 'openssl/evp.h',
+ sym,
+ dependencies: dep_libcrypto,
+ required: false
+ )
+
+ if not found
+ break
+ endif
+ endforeach
+endif
+
+conf.set('HAVE_LIBCRYPTO_ECDSA', found, description: 'OpenSSL libcrypto ECDSA')
+summary('OpenSSL libcrypto ECDSA', found, bool_yn: true, section: 'Crypto')
--- /dev/null
+syms = [
+ 'ED25519',
+ 'ED448',
+]
+
+found = false
+foreach sym: syms
+ has = cxx.has_header_symbol(
+ 'openssl/evp.h',
+ 'NID_' + sym,
+ dependencies: dep_libcrypto,
+ required: false,
+ )
+
+ conf.set('HAVE_LIBCRYPTO_' + sym, has, description: 'OpenSSL libcrypto ' + sym)
+ summary('OpenSSL libcrypto ' + sym, has, bool_yn: true, section: 'Crypto')
+
+ if has
+ found = true
+ endif
+endforeach
+
+conf.set('HAVE_LIBCRYPTO_EDDSA', found, description: 'OpenSSL EdDSA support')
+summary('OpenSSL libcrypto EdDSA', found, bool_yn: true, section: 'Crypto')
--- /dev/null
+opt_libcrypto = get_option('libcrypto')
+opt_libcrypto_path = get_option('libcrypto-path')
+dep_libcrypto = dependency('', required: false)
+
+ssldirs = []
+
+if opt_libcrypto.disabled()
+ if opt_libcrypto_path != ''
+ warning('The libcrypto option is set to `disabled` ' +
+ 'but a path (' + opt_libcrypto_path + ') was given ' +
+ 'for libcrypto-path: It is going to be ignored.')
+ endif
+
+ summary('OpenSSL libcrypto', false, bool_yn: true, section: 'Crypto')
+ subdir_done()
+endif
+
+# Give precedence to the custom path passed in by the user. If not, the try to find
+# libcrypto using the mechanisms provided by meson (e.g. pkg-config). If that cannot be
+# found, then look in some hard-coded paths below.
+if opt_libcrypto_path == ''
+ dep_libcrypto = dependency('libcrypto', required: false)
+else
+ ssldirs = [opt_libcrypto_path]
+endif
+
+if not dep_libcrypto.found()
+ warning('Could not find the libcrypto dependency, going to try to find it manually')
+
+ if ssldirs.length() == 0
+ # Could not find libcrypto through pkg-config and no custom directory was passed to
+ # find the library and its headers, so try to find it in some default locations.
+ ssldirs = [
+ '/usr/local/ssl',
+ '/usr/lib/ssl',
+ '/usr/ssl',
+ '/usr/pkg',
+ '/usr/local',
+ '/usr'
+ ]
+ endif
+
+ foreach dir: ssldirs
+ have = cxx.has_header(dir / 'include/openssl/crypto.h')
+ if have
+ dep_libcrypto = declare_dependency(
+ compile_args: ['-L' + dir / 'lib'],
+ link_args: ['-lcrypto'],
+ include_directories: include_directories(dir / 'include', is_system: false),
+ )
+ break
+ endif
+ endforeach
+endif
+
+if not dep_libcrypto.found()
+ err_msg = 'Could not find libcrypto in ' + ', '.join(ssldirs)
+
+ if opt_libcrypto == 'auto'
+ # We could not find libcrypto anywhere, and the user did not require it.
+ warning(err_msg)
+ summary('OpenSSL libcrypto', false, bool_yn: true, section: 'Crypto')
+ subdir_done()
+ endif
+
+ error(err_msg)
+endif
+
+if not cxx.links(fs.read('bn_new.cc'), name: 'libcrypto test program', dependencies: dep_libcrypto)
+ err_msg = 'Cannot link against libcrypto'
+
+ if opt_libcrypto == 'auto'
+ # We could not link against libcrypto, and the user did not require it.
+ warning(err_msg)
+ summary('OpenSSL libcrypto', false, bool_yn: true, section: 'Crypto')
+ subdir_done()
+ endif
+
+ error(err_msg)
+endif
+
+funcs = [
+ 'RAND_bytes',
+ 'RAND_pseudo_bytes',
+ 'CRYPTO_memcmp',
+ 'OPENSSL_init_crypto',
+ 'EVP_MD_CTX_new',
+ 'EVP_MD_CTX_free',
+ 'RSA_get0_key',
+ 'OCSP_basic_sign',
+]
+
+foreach func: funcs
+ has = cxx.has_function(func, dependencies: dep_libcrypto)
+ conf.set('HAVE_' + func.to_upper(), has, description: 'Have libcrypto ' + func)
+endforeach
+
+prefix = '''
+#include <stdarg.h>
+#include <stddef.h>
+'''
+has = cxx.has_header_symbol(
+ 'openssl/kdf.h',
+ 'EVP_PKEY_CTX_set1_scrypt_salt',
+ dependencies: dep_libcrypto,
+ prefix: prefix,
+ required: false,
+)
+conf.set(
+ 'HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT',
+ has,
+ description: 'Have libcrypto EVP_PKEY_CTX_set1_scrypt_salt',
+)
+
+conf.set('HAVE_LIBCRYPTO', dep_libcrypto.found(), description: 'OpenSSL libcrypto')
+summary('OpenSSL libcrypto', dep_libcrypto.found(), bool_yn: true, section: 'Crypto')
+
+subdir('ecdsa') # ECDSA
+subdir('eddsa') # EDDSA
--- /dev/null
+conf.set_quoted('PKGLIBDIR', get_option('libdir'), description: 'Modules directory')
--- /dev/null
+opt_libedit = get_option('libedit')
+dep_libedit = dependency('libedit', required: opt_libedit)
+
+conf.set('HAVE_LIBEDIT', dep_libedit.found(), description: 'libedit support')
+summary('libedit support', dep_libedit.found(), bool_yn: true, section: 'Edit')
--- /dev/null
+opt_libsnmp = get_option('snmp')
+
+dep_libsnmp = declare_dependency()
+
+if get_option('snmp')
+ snmp_config = find_program('net-snmp-config', required: true)
+ snmp_ldflags_res = run_command(snmp_config, '--netsnmp-agent-libs', check: true)
+ snmp_ldflags = snmp_ldflags_res.stdout().strip().split()
+
+ dep_libsnmp = declare_dependency(
+ link_args: snmp_ldflags,
+ )
+
+ if dep_libsnmp.found()
+ funcs = [
+ 'snmp_select_info2',
+ ]
+
+ foreach func: funcs
+ define = 'HAVE_' + func.to_upper()
+ have_func = cxx.has_function(func, dependencies: dep_libsnmp, prefix: '''#include <net-snmp/net-snmp-config.h>
+ #include <net-snmp/definitions.h>
+ #include <net-snmp/types.h>
+ #include <net-snmp/utilities.h>
+ #include <net-snmp/config_api.h>
+ #include <net-snmp/session_api.h>''')
+ conf.set(define, have_func, description: 'Have libsnmp ' + func)
+ endforeach
+ endif
+endif
+
+conf.set('HAVE_NET_SNMP', dep_libsnmp.found(), description: 'libsnmp')
+summary('SNMP', dep_libsnmp.found(), bool_yn: true, section: 'Configuration')
--- /dev/null
+opt_libsodium = get_option('libsodium')
+dep_libsodium = dependency('libsodium', required: opt_libsodium)
+
+if dep_libsodium.found()
+ funcs = [
+ 'crypto_box_easy_afternm',
+ 'crypto_box_curve25519xchacha20poly1305_easy',
+ 'randombytes_stir',
+ 'sodium_memcmp',
+ 'crypto_shorthash'
+ ]
+
+ foreach func: funcs
+ define = 'HAVE_' + func.to_upper()
+ have_func = cxx.has_function(func, dependencies: dep_libsodium)
+ conf.set(define, have_func, description: 'Have libsodium ' + func)
+ endforeach
+endif
+
+conf.set('HAVE_LIBSODIUM', dep_libsodium.found(), description: 'libsodium support')
+summary('libsodium support', dep_libsodium.found(), bool_yn: true, section: 'Crypto')
--- /dev/null
+opt_libssl_providers = get_option('tls-libssl-providers')
+
+if opt_libssl_providers
+ opt_libssl = get_option('tls-libssl')
+ if not opt_libssl.allowed()
+ error('OpenSSL TLS providers requested but libssl is not enabled')
+ endif
+ dep_libssl_3_later = dependency('libssl >= 3.0', required: false)
+
+ if not dep_libssl_3_later.found()
+ error('OpenSSL TLS providers requested but libssl is not >= 3.0')
+ endif
+
+ conf.set('HAVE_TLS_PROVIDERS', dep_libssl_3_later.found(), description: 'OpenSSL libssl providers')
+ summary('OpenSSL libssl providers', dep_libssl_3_later.found(), bool_yn: true, section: 'Crypto')
+endif
--- /dev/null
+opt_libssl = get_option('tls-libssl')
+dep_libssl = dependency('libssl', required: opt_libssl)
+
+if dep_libssl.found()
+ funcs = [
+ 'SSL_CTX_set_ciphersuites',
+ 'SSL_CTX_set_num_tickets',
+ 'SSL_CTX_set_keylog_callback',
+ 'SSL_CTX_get0_privatekey',
+ 'SSL_set_hostflags',
+ 'SSL_CTX_set_alpn_protos',
+ 'SSL_CTX_set_next_proto_select_cb',
+ 'SSL_get0_alpn_selected',
+ 'SSL_get0_next_proto_negotiated',
+ 'SSL_CTX_set_alpn_select_cb',
+ 'SSL_CTX_use_cert_and_key',
+ ]
+
+ foreach func: funcs
+ has = cxx.has_function(func, dependencies: dep_libssl)
+ conf.set('HAVE_' + func.to_upper(), has, description: 'Have OpenSSL libssl ' + func)
+ endforeach
+endif
+
+has = cxx.has_header_symbol(
+ 'openssl/ssl.h',
+ 'SSL_CTX_set_min_proto_version',
+ dependencies: dep_libssl,
+)
+conf.set(
+ 'HAVE_SSL_CTX_SET_MIN_PROTO_VERSION',
+ has,
+ description: 'Have OpenSSL libssl SSL_CTX_set_min_proto_version',
+)
+conf.set(
+ 'OPENSSL_NO_ENGINE',
+ true,
+ description: 'Disable engine support for auth in libssl.cc',
+)
+
+conf.set('HAVE_LIBSSL', dep_libssl.found(), description: 'OpenSSL libssl')
+summary('OpenSSL libssl', dep_libssl.found(), bool_yn: true, section: 'Crypto')
--- /dev/null
+opt_systemd = get_option('systemd')
+
+dep_systemd = dependency('libsystemd', required: opt_systemd)
+conf.set('HAVE_SYSTEMD', dep_systemd.found(), description: 'libsystemd')
+summary('libsystemd', dep_systemd.found(), bool_yn: true, section: 'Configuration')
+
+if dep_systemd.found()
+ summary('Lib Version', dep_systemd.version(), section: 'Systemd')
+endif
--- /dev/null
+opt_lmdb = get_option('lmdb')
+dep_lmdb = dependency('lmdb', required: opt_lmdb)
+
+conf.set('HAVE_LMDB', dep_lmdb.found(), description: 'Whether we have LMDB')
+summary('LMDB', dep_lmdb.found(), bool_yn: true, section: 'Key-Value')
+if dep_lmdb.found()
+ summary('LMDB version', dep_lmdb.version(), bool_yn: true, section: 'Key-Value')
+endif
--- /dev/null
+opt_lua = get_option('lua')
+dep_lua = dependency('', required: false)
+
+if opt_lua == 'auto' or opt_lua == 'luajit'
+ dep_lua = dependency(
+ 'luajit',
+ version: '>= 2.0.2',
+ required: opt_lua == 'luajit',
+ not_found_message: 'LuaJIT not found',
+ )
+endif
+
+if not dep_lua.found() and (opt_lua == 'auto' or opt_lua == 'lua')
+ variants = [
+ 'lua5.3',
+ 'lua-5.3',
+ 'lua53',
+ 'lua5.2',
+ 'lua-5.2',
+ 'lua52',
+ 'lua5.1',
+ 'lua-5.1',
+ 'lua51',
+ 'lua',
+ ]
+
+ foreach variant: variants
+ dep_lua = dependency(variant, version: '>= 5.1', required: false)
+ if dep_lua.found()
+ break
+ endif
+ endforeach
+endif
+
+if not dep_lua.found()
+ error('No Lua implementation was found')
+endif
+
+have_luahpp = cxx.has_header('lua.hpp', dependencies: dep_lua)
+
+conf.set('HAVE_LUA', dep_lua.found(), description: 'Lua')
+conf.set('HAVE_LUA_HPP', have_luahpp, description: 'Have <lua.hpp>')
+
+if dep_lua.found() and dep_lua.name() == 'luajit'
+ # export all symbols with default visibility, to be able to use the Lua FFI interface
+ add_project_link_arguments('-rdynamic', language: ['c', 'cpp'])
+endif
+
+summary('Lua', dep_lua.found(), bool_yn: true, section: 'Lua')
+summary('Implementation', dep_lua.name(), section: 'Lua')
+summary('Version', dep_lua.version(), section: 'Lua')
+summary('Have <lua.hpp>', have_luahpp, bool_yn: true, section: 'Lua')
--- /dev/null
+mman_h = cxx.has_header('sys/mman.h', required: false)
+have_mmap = mman_h and cxx.has_function('mmap', prefix: '''#include <sys/mman.h>''')
+
+conf.set('HAVE_MMAP', have_mmap, description: 'Have mmap')
+
+summary('Have <sys/mman.h>', mman_h, bool_yn: true, section: 'Function mmap')
+summary('mmap', have_mmap, bool_yn: true, section: 'Function mmap')
--- /dev/null
+netlib_deps = []
+
+variants = [
+ ['inet_aton', 'resolv'],
+ ['gethostbyname', 'nsl'],
+ ['socket', 'socket'],
+ ['gethostent', 'nsl'],
+]
+
+foreach variant: variants
+ func_name = variant[0]
+ lib_name = variant[1]
+
+ found = cxx.has_function(func_name)
+ if not found
+ lib = cxx.find_library(lib_name, required: true)
+ if not cxx.has_function(func_name, dependencies: lib)
+ error('Cannot find function ' + func_name + ', searched library `' + lib_name + '`')
+ endif
+ netlib_deps += lib
+ found = lib.name() + ' ' + lib.version()
+ endif
+
+ summary(func_name, found, bool_yn: true, section: 'Networking Functions')
+endforeach
+
+dep_netlibs = declare_dependency(dependencies: netlib_deps)
+
+variants = [
+ 'recvmmsg',
+ 'sendmmsg',
+ 'accept4',
+]
+
+foreach variant: variants
+ found = cxx.has_function(variant)
+ define = 'HAVE_' + variant.to_upper()
+ conf.set(define, found, description: 'Have ' + variant)
+ summary(variant, found, bool_yn: true, section: 'Networking Functions')
+endforeach
+
+declared = cxx.has_header_symbol('ifaddrs.h', 'getifaddrs')
+conf.set('HAVE_GETIFADDRS', declared, description: 'Have getifaddrs')
+summary('getifaddrs', declared, bool_yn: true, section: 'Networking Functions')
--- /dev/null
+opt_libnghttp2 = get_option('nghttp2')
+dep_libnghttp2 = dependency('libnghttp2', required: opt_libnghttp2)
+
+if dep_libnghttp2.found()
+ funcs = [
+ 'nghttp2_check_header_value_rfc9113',
+ 'nghttp2_check_method',
+ 'nghttp2_check_path'
+ ]
+
+ foreach func: funcs
+ has = cxx.has_function(func, dependencies: dep_libnghttp2)
+ conf.set('HAVE_' + func.to_upper(), has, description: 'Have nghttp2 ' + func)
+ endforeach
+endif
+
+conf.set('HAVE_NGHTTP2', dep_libnghttp2.found(), description: 'nghttp2')
+summary('nghttp2', dep_libnghttp2.found(), bool_yn: true, section: 'DNS over HTTP/2')
--- /dev/null
+platforms = [
+ {
+ 'name': 'linux',
+ 'config-defines': [{ 'name': 'HAVE_LINUX', 'description': 'On Linux' }],
+ },
+ {
+ 'name': 'darwin',
+ 'config-defines': [{ 'name': 'HAVE_DARWIN', 'description': 'On Darwin/MacOS' }],
+ 'cmdline-defines': ['__APPLE_USE_RFC_3542', '_XOPEN_SOURCE', '_DARWIN_C_SOURCE'],
+ },
+ {
+ 'name': 'openbsd',
+ 'config-defines': [{ 'name': 'HAVE_OPENBSD', 'description': 'On OpenBSD' }],
+ },
+ {
+ 'name': 'freebsd',
+ 'config-defines': [{ 'name': 'HAVE_FREEBSD', 'description': 'On FreeBSD' }],
+ },
+ {
+ 'name': 'sunos',
+ 'config-defines': [
+ { 'name': 'HAVE_SOLARIS', 'description': 'On Solaris/SunOS' },
+ { 'name': 'NEED_POSIX_TYPEDEF', 'description': 'POSIX typedefs need to be defined' },
+ { 'name': 'NEED_INET_NTOP_PROTO', 'description': 'OS is so broken that it needs an additional prototype' },
+ ],
+ 'cmdline-defines': ['_REENTRANT'],
+ 'libraries': ['posix4'],
+ },
+]
+
+platform_deps = []
+
+foreach platform: platforms
+ name = platform['name']
+ set_variable('have_' + name, system == name)
+
+ config_defines = 'config-defines' in platform ? platform['config-defines'] : []
+ cmdline_defines = 'cmdline-defines' in platform ? platform['cmdline-defines'] : []
+ libraries = 'libraries' in platform ? platform['libraries'] : []
+
+ if system == name
+ platform_defines = []
+ foreach define: config_defines
+ define_name = define['name']
+ define_desc = define['description']
+ conf.set(define_name, true, description: define_desc)
+ platform_defines += define_name
+ endforeach
+
+ foreach cmdline_define: cmdline_defines
+ add_project_arguments('-D' + cmdline_define, language: ['c', 'cpp'])
+ endforeach
+
+ foreach library: libraries
+ platform_deps += cxx.find_library(library, required: true)
+ endforeach
+
+ summary('Platform Defines', platform_defines, section: 'System')
+ endif
+endforeach
+
+dep_platform = declare_dependency(
+ dependencies: platform_deps,
+)
--- /dev/null
+dep_threads = dependency('threads')
+
+have_pthread_h = cxx.check_header(
+ 'pthread.h',
+ dependencies: dep_threads,
+ required: true,
+)
+have_pthread_np_h = cxx.check_header(
+ 'pthread_np.h',
+ dependencies: dep_threads,
+ prefix: '#include <pthread.h>',
+)
+
+conf.set('HAVE_PTHREAD_NP_H', have_pthread_np_h, description: 'Have <pthread_np.h>')
+
+summary('Threads', dep_threads.found(), bool_yn: true, section: 'POSIX Threads')
+summary('Have <pthread.h>', have_pthread_h, bool_yn: true, section: 'POSIX Threads')
+summary('Have <pthread_np.h>', have_pthread_np_h, bool_yn: true, section: 'POSIX Threads')
--- /dev/null
+funcs = [
+ 'pthread_setaffinity_np',
+ 'pthread_getattr_np',
+ 'pthread_get_stackaddr_np',
+ 'pthread_get_stacksize_np',
+]
+
+foreach func: funcs
+ found = cxx.has_function(func, dependencies: dep_threads)
+ define = 'HAVE_' + func.to_upper()
+ conf.set(define, found, description: 'Have ' + func)
+ summary(func, found, bool_yn: true, section: 'POSIX Threads')
+endforeach
--- /dev/null
+variants = [
+ [
+ '2-arg pthread_setname_np',
+ 'HAVE_PTHREAD_SETNAME_NP_2',
+ 'pthread_setname_np takes 2 arguments (Linux/glibc, QNX, IBM)',
+ fs.read('pthread_setname_np_2args.cc'),
+ ],
+ [
+ '2-arg pthread_set_name_np',
+ 'HAVE_PTHREAD_SET_NAME_NP_2',
+ 'pthread_set_name_np takes 2 arguments and does not return void (FreeBSD, OpenBSD)',
+ fs.read('pthread_set_name_np_2args.cc'),
+ ],
+ [
+ '2-arg void pthread_set_name_np',
+ 'HAVE_PTHREAD_SET_NAME_NP_2_VOID',
+ 'pthread_set_name_np takes 2 arguments and returns void (FreeBSD, OpenBSD)',
+ fs.read('pthread_set_name_np_void_2args.cc'),
+ ],
+ [
+ '1-arg pthread_setname_np',
+ 'HAVE_PTHREAD_SETNAME_NP_1',
+ 'pthread_setname_np takes 1 argument (Darwin, MacOS)',
+ fs.read('pthread_setname_np_1arg.cc'),
+ ],
+ [
+ '3-arg pthread_setname_np',
+ 'HAVE_PTHREAD_SETNAME_NP_3',
+ 'pthread_setname_np takes 3 arguments (NetBSD)',
+ fs.read('pthread_setname_np_3args.cc'),
+ ],
+]
+
+found = false
+foreach variant: variants
+ variant_name = variant[0]
+ variant_define = variant[1]
+ variant_description = variant[2]
+ variant_program = variant[3]
+
+ if cxx.links(
+ variant_program,
+ name: variant_name,
+ dependencies: dep_threads,
+ args: have_pthread_np_h ? ['-DHAVE_PTHREAD_NP_H'] : []
+ )
+ found = true
+ conf.set(variant_define, true, description: variant_description)
+ summary('pthread_setname Variant', variant_define, section: 'POSIX Threads')
+ summary('Description', variant_description, section: 'POSIX Threads')
+ break
+ endif
+endforeach
+
+if not found
+ error('Could not find a suitable pthread_setname function')
+endif
--- /dev/null
+#include <pthread.h>
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
+int main()
+{
+ return pthread_set_name_np(pthread_self(), "foo");
+}
--- /dev/null
+#include <pthread.h>
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
+int main()
+{
+ pthread_set_name_np(pthread_self(), "foo");
+ return 0;
+}
--- /dev/null
+#include <pthread.h>
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
+int main()
+{
+ return pthread_setname_np("foo");
+}
--- /dev/null
+#include <pthread.h>
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
+int main()
+{
+ pthread_setname_np(pthread_self(), "foo");
+ return 0;
+}
--- /dev/null
+#include <pthread.h>
+#if HAVE_PTHREAD_NP_H
+#include <pthread_np.h>
+#endif
+
+int main()
+{
+ return pthread_setname_np(pthread_self(), "foo", NULL);
+}
--- /dev/null
+dep_libquiche = declare_dependency()
+opt_libquiche = get_option('quiche')
+
+if (get_option('dns-over-quic') or get_option('dns-over-http3')) and opt_libquiche.allowed()
+ dep_libquiche = dependency('quiche', version: '>= 0.22.0', required: opt_libquiche)
+
+ if dep_libquiche.found()
+ conf.set('HAVE_QUICHE_STREAM_ERROR_CODES', dep_libquiche.found(), description: 'if the Quiche API includes error code in quiche_conn_stream_recv and quiche_conn_stream_send')
+ else
+ dep_libquiche = dependency('quiche', version: '>= 0.15.0', required: opt_libquiche)
+ endif
+endif
+
+conf.set('HAVE_QUICHE', dep_libquiche.found(), description: 'quiche')
+summary('Quiche', dep_libquiche.found(), bool_yn: true, section: 'DNS over QUIC / HTTP3')
--- /dev/null
+opt_libre2 = get_option('re2')
+dep_libre2 = dependency('re2', required: opt_libre2)
+
+conf.set('HAVE_RE2', dep_libre2.found(), description: 're2')
+summary('Re2', dep_libre2.found(), bool_yn: true, section: 're2')
--- /dev/null
+opt_repro = get_option('reproducible')
+conf.set('REPRODUCIBLE', opt_repro, description: 'Reproducible builds')
+summary('Reproducible Builds', opt_repro, bool_yn: true, section: 'Reproducible Builds')
+
+if not opt_repro
+ id_prog = find_program('id', required: opt_repro)
+ id_prog_res = run_command(id_prog, '-u', '-n', check: true)
+ build_user = id_prog_res.stdout().strip()
+
+ build_host = ''
+ hostname_prog = find_program('hostname', required: opt_repro)
+ build_system = build_machine.system()
+ if build_system == 'sunos' or build_system == 'openbsd'
+ domainname_prog = find_program('domainname', required: opt_repro)
+
+ hostname_prog_res = run_command(hostname_prog, check: true)
+ domainname_prog_res = run_command(domainname_prog, check: true)
+
+ build_host_hostname = hostname_prog_res.stdout().strip()
+ build_host_domainname = domainname_prog_res.stdout().strip()
+
+ build_host = build_host_hostname + '.' + build_host_domainname
+ else
+ cmds = [
+ [hostname_prog, '-f'],
+ [hostname_prog],
+ ['echo', '\'localhost\''],
+ ]
+
+ found = false
+ foreach cmd: cmds
+ res = run_command(cmd, check: false)
+ if res.returncode() == 0
+ build_host = res.stdout().strip()
+ found = true
+ break
+ endif
+ endforeach
+
+ if not found
+ error('Reproducible builds requested but could not figure out a build host string on ' + build_system)
+ endif
+ endif
+
+ build_host = build_user + '@' + build_host
+ conf.set_quoted('BUILD_HOST', build_host, description: 'User and host who built PowerDNS')
+ summary('Build Host', build_host, section: 'Reproducible Builds')
+endif
--- /dev/null
+prog_single_pointer = fs.read('sanitizer_finish_switch_fiber_1ptr.cc')
+prog_three_pointers = fs.read('sanitizer_finish_switch_fiber_3ptrs.cc')
+
+single_pointer = false
+three_pointers = false
+
+if cxx.check_header('sanitizer/common_interface_defs.h', required: false)
+ if cxx.has_header_symbol('sanitizer/common_interface_defs.h', '__sanitizer_start_switch_fiber', required: false)
+ if cxx.compiles(prog_single_pointer, name: '__sanitizer_finish_switch_fiber with a single pointer')
+ single_pointer = true
+ endif
+
+ if cxx.compiles(prog_three_pointers, name: '__sanitizer_finish_switch_fiber with three pointers')
+ three_pointers = true
+ endif
+ else
+ warning('Address Sanitizer fiber switching is not available')
+ endif
+
+else
+ warning('Address Sanitizer requested but `sanitizer/common_interface_defs.h` ' +
+ 'is invalid or cannot be found. Address Sanitizer fiber switching is ' +
+ 'not available')
+endif
+
+if not single_pointer and not three_pointers
+ warning('Address Sanitizer fiber switching is not available due to an unknown API version')
+endif
+
+conf.set(
+ 'HAVE_FIBER_SANITIZER',
+ single_pointer or three_pointers,
+ description: 'Address Sanitizer fiber annotation interface is available',
+)
+conf.set(
+ 'HAVE_SANITIZER_FINISH_SWITCH_FIBER_SINGLE_PTR',
+ single_pointer,
+ description: 'Address Sanitizer: __sanitizer_finish_switch_fiber takes only a pointer',
+)
+conf.set(
+ 'HAVE_SANITIZER_FINISH_SWITCH_FIBER_THREE_PTRS',
+ three_pointers,
+ description: 'Address Sanitizer: __sanitizer_finish_switch_fiber takes three pointers',
+)
--- /dev/null
+#include <sanitizer/common_interface_defs.h>
+
+int main()
+{
+ __sanitizer_finish_switch_fiber(nullptr);
+ return 0;
+}
--- /dev/null
+#include <sanitizer/common_interface_defs.h>
+
+int main()
+{
+ __sanitizer_finish_switch_fiber(nullptr, nullptr, nullptr);
+ return 0;
+}
--- /dev/null
+opt_sanitize = get_option('b_sanitize')
+
+if opt_sanitize == 'address' or opt_sanitize == 'address,undefined'
+ subdir('address-sanitizer-fiber-switching')
+endif
+
+if opt_sanitize != 'none'
+ add_project_arguments('-fno-omit-frame-pointer', language: ['c', 'cpp'])
+endif
+
+summary('Sanitizers', opt_sanitize, bool_yn: true, section: 'Configuration')
--- /dev/null
+prog = fs.read('strerror_r.c')
+
+have_strerror_r_decl = cxx.has_header_symbol('string.h', 'strerror_r')
+have_strerror_r = cxx.has_function('strerror_r', prefix: '#include <string.h>')
+strerror_r_returns_charp = have_strerror_r and cxx.compiles(prog, name: 'strerror_r() returns char *')
+
+conf.set('HAVE_DECL_STRERROR_R', have_strerror_r_decl, description: 'Whether strerror_r is declared')
+conf.set('HAVE_STRERROR_R', have_strerror_r, description: 'Whether strerror_r is available')
+conf.set('STRERROR_R_CHAR_P', strerror_r_returns_charp, description: 'Whether strerror_r returns char *')
+
+summary('Symbol', have_strerror_r_decl, bool_yn: true, section: 'Function strerror_r')
+summary('Declaration', have_strerror_r, bool_yn: true, section: 'Function strerror_r')
+summary('Returns char *', strerror_r_returns_charp, bool_yn: true, section: 'Function strerror_r')
--- /dev/null
+#include <string.h>
+
+int main () {
+ char error_string[256];
+ char *ptr = strerror_r(-2, error_string, 256);
+ char c = *strerror_r(-2, error_string, 256);
+ return c != 0 && ptr != (void*) 0L;
+}
--- /dev/null
+summary('System', system, section: 'System')
+summary('C++ Compiler', cxx.get_id(), section: 'System')
+summary('C++ Compiler Version', cxx.version(), section: 'System')
+summary('C++ Compiler Command', ' '.join(cxx.cmd_array()), section: 'System')
+summary('Linker', cxx.get_linker_id(), section: 'System')
--- /dev/null
+conf.set_quoted('SYSCONFDIR', get_option('sysconfdir'), description: 'Configuration data directory')
--- /dev/null
+dep_systemd_prog = dependency('systemd', required: false)
+summary('Systemd', dep_systemd_prog.found(), bool_yn: true, section: 'Configuration')
+
+# Map systemd features to systemd/systemctl version.
+systemd_features = {
+ 'private_tmp': 183,
+ 'system_call_architectures': 209,
+ 'private_devices': 209,
+ 'restrict_address_families': 211,
+ 'protect_system': 214,
+ 'protect_home': 214,
+ 'restrict_realtime': 231,
+ 'memory_deny_write_execute': 231,
+ 'protect_control_groups': 232,
+ 'protect_kernel_modules': 232,
+ 'protect_kernel_tunables': 232,
+ 'remove_ipc': 232,
+ 'dynamic_user': 232,
+ 'private_users': 232,
+ 'protect_system_strict': 232,
+ 'restrict_namespaces': 233,
+ 'lock_personality': 235,
+ # while SystemCallFilter is technically available starting with 187,
+ # we use the pre-defined call filter sets that have been introduced later.
+ # Initial support for these landed in 231
+ # @filesystem @reboot @swap in 233
+ # @aio, @sync, @chown, @setuid, @memlock, @signal and @timer in 235
+ 'system_call_filter': 235,
+ 'percent_t': 236,
+ 'private_mounts': 239,
+ 'with_runtime_dir_env': 240,
+ 'protect_hostname': 242,
+ 'restrict_suidsgid': 242,
+ 'protect_kernel_logs': 244,
+ 'protect_clock': 245,
+ 'protect_proc': 247,
+ 'private_ipc': 248,
+}
+
+systemd_version = dep_systemd_prog.version()
+foreach feature, version: systemd_features
+ feature_name = 'have_systemd_' + feature
+ feature_value = systemd_version.version_compare('>=' + version.to_string())
+ set_variable(feature_name, feature_value)
+ conf.set(feature_name.to_upper(), feature_value, description: 'systemd feature: ' + feature)
+endforeach
+
+if dep_systemd_prog.found()
+ summary('Version', dep_systemd_prog.version(), section: 'Systemd')
+endif
--- /dev/null
+fs = import('fs')
+
+prog = fs.read('timet_sign.cc')
+timet_signed = cxx.compiles(prog, name: 'time_t is signed')
+
+if not timet_signed
+ error('time_t is unsigned, PowerDNS code relies on it being signed')
+endif
+
+summary('Signed time_t', timet_signed, bool_yn: true, section: 'System')
--- /dev/null
+#include <sys/types.h>
+
+int main()
+{
+ int foo[1 - 2 * !(((time_t)-1) < 0)];
+ (void)foo[0];
+ return 0;
+}
--- /dev/null
+timet_size = cxx.sizeof('time_t', prefix: '#include <sys/types.h>')
+
+if timet_size < 8
+ error('size of time_t is ' +
+ timet_size.to_string() +
+ ' which is not large enough to fix the y2k38 bug')
+endif
+
+summary('Size of time_t', timet_size, section: 'System')
--- /dev/null
+prefix = '''
+#include <sys/types.h>
+#include <time.h>
+'''
+
+has = cxx.has_member('struct tm', 'tm_gmtoff', prefix: prefix)
+conf.set('HAVE_TM_GMTOFF', has, description: 'Whether tm_gmtoff is available')
+summary('tm_gmtoff', has, bool_yn: true, section: 'System')
--- /dev/null
+funcs = [
+ 'strcasestr',
+ 'localtime_r',
+ 'gmtime_r',
+ 'recvmmsg',
+ 'sched_setscheduler',
+ 'getrandom',
+ 'arc4random',
+ 'getentropy',
+ 'arc4random_uniform',
+ 'arc4random_buf',
+ 'explicit_bzero',
+ 'explicit_memset',
+ 'memset_s',
+]
+
+foreach func: funcs
+ found = cxx.has_function(func)
+ define = 'HAVE_' + func.to_upper()
+ conf.set(define, found, description: 'Have ' + func)
+ summary(func, found, bool_yn: true, section: 'Various Functions')
+endforeach
--- /dev/null
+conf.set(
+ 'HAVE_SYS_RANDOM_H',
+ cxx.has_header('sys/random.h'),
+ description: 'Have sys/random.h',
+)
--- /dev/null
+gen_version_prog = find_program('gen-version', dirs: product_source_dir / 'builder-support', required: true)
+gen_version_prog_res = run_command(gen_version_prog, check: true)
+product_version = gen_version_prog_res.stdout().strip()
+conf.set_quoted('VERSION', product_version, description: 'Version')
--- /dev/null
+opt_xsk = get_option('xsk')
+if opt_xsk.allowed()
+ dep_libbpf = dependency('libbpf', required: opt_xsk)
+ dep_libxdp = dependency('libxdp', required: opt_xsk)
+
+ conf.set('HAVE_BPF', dep_libbpf.found(), description: 'BPF library')
+ conf.set('HAVE_XDP', dep_libxdp.found(), description: 'XDP library')
+ conf.set('HAVE_XSK', dep_libbpf.found() and dep_libxdp.found(), description: 'AF_XDP (XSK) support enabled')
+ summary('AF_XDP (XSK)', dep_libbpf.found() and dep_libxdp.found(), bool_yn: true, section: 'XSK')
+else
+ dep_libpf = declare_dependency()
+ dep_libxdp = declare_dependency()
+endif
--- /dev/null
+option('dnscrypt', type: 'feature', value: 'disabled', description: 'Enable DNSCrypt')
+option('libcap', type: 'feature', value: 'auto', description: 'Enable libcap for capabilities handling')
+option('libedit', type: 'feature', value: 'enabled', description: 'Enable libedit')
+option('libsodium', type: 'feature', value: 'auto', description: 'Enable libsodium')
+option('libcrypto', type: 'feature', value: 'auto', description: 'Enable OpenSSL libcrypto)')
+option('libcrypto-path', type: 'string', value: '', description: 'Custom path to find OpenSSL libcrypto')
+option('tls-gnutls', type: 'feature', value: 'auto', description: 'GnuTLS-based TLS')
+option('lua', type: 'combo', choices: ['auto', 'luajit', 'lua'], value: 'auto', description: 'Lua implementation to use')
+option('hardening', type: 'feature', value: 'auto', description: 'Compiler security checks')
+option('hardening-experimental-cf', type: 'combo', choices: ['disabled', 'full', 'branch', 'return', 'check'], value: 'disabled', description: 'Control Flow hardening')
+option('hardening-experimental-scp', type: 'feature', value: 'disabled', description: 'Stack Clash Protection')
+option('hardening-fortify-source', type: 'combo', choices: ['auto', 'disabled', '1', '2', '3'], value: '2', description: 'Source fortification level')
+option('ipcipher', type: 'feature', value: 'auto', description: 'IPCipher')
+#option('rng-kiss', type: 'boolean', value: false, description: 'Use the unsafe KISS RNG')
+option('tls-libssl', type: 'feature', value: 'auto', description: 'OpenSSL-based TLS')
+option('tls-libssl-providers', type: 'boolean', value: false, description: 'OpenSSL-based TLS with TLS providers')
+option('dns-over-tls', type: 'boolean', value: false, description: 'DNS over TLS (requires GnuTLS or OpenSSL)')
+option('dns-over-https', type: 'boolean', value: false, description: 'DNS over HTTP/2 (requires GnuTLS or OpenSSL)')
+option('dns-over-http3', type: 'boolean', value: false, description: 'Enable DNS over HTTP/3')
+option('dns-over-quic', type: 'boolean', value: false, description: 'Enable DNS over QUIC')
+option('unit-tests', type: 'boolean', value: false, description: 'Build and run unit tests')
+option('reproducible', type: 'boolean', value: false, description: 'Reproducible builds (for distro maintainers, makes debugging difficult)')
+option('systemd', type: 'feature', value: 'auto', description: 'Systemd notification (requires libsystemd)')
+option('systemd-service-user', type: 'string', value: 'dnsdist', description: 'Systemd service user (setuid and unit file; user is not created)')
+option('systemd-service-group', type: 'string', value: 'dnsdist', description: 'Systemd service group (setgid and unit file; group is not created)')
+option('auto-var-init', type: 'combo', value: 'disabled', choices: ['zero', 'pattern', 'disabled'], description: 'Enable initialization of automatic variables')
+option('snmp', type: 'boolean', value: false, description: 'Enable SNMP')
+option('dnstap', type: 'feature', value: 'auto', description: 'Enable DNSTAP support through libfstrm')
+option('h2o', type: 'feature', value: 'disabled', description: 'Enable H2O library with event loop support for DNS over HTTP/2')
+option('nghttp2', type: 'feature', value: 'auto', description: 'Enable nghttp2 library support for DNS over HTTP/2')
+option('cdb', type: 'feature', value: 'auto', description: 'CDB key-value store support')
+option('lmdb', type: 'feature', value: 'auto', description: 'LMDB key-value store support')
+option('quiche', type: 'feature', value: 'auto', description: 'Enable Quiche library support for DNS over QUIC and DNS over HTTP/3')
+option('re2', type: 'feature', value: 'auto', description: 'Enable re2 for regular expressions')
+option('xsk', type: 'feature', value: 'auto', description: 'Enable AF_XDP / XSK')
+option('fuzz-targets', type: 'boolean', value: false, description: 'Enable fuzzing targets')
+option('ebpf', type: 'feature', value: 'disabled', description: 'Enable eBPF support')
+option('fuzzer_ldflags', type: 'string', value: '', description: 'Linker flags used for the fuzzing targets (a path to the libFuzzer static library, for example)')
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifndef BOOST_TEST_DYN_LINK
#define BOOST_TEST_DYN_LINK
+#endif
#define BOOST_TEST_NO_MAIN
#include <boost/test/unit_test.hpp>