Add support for meson build system
authorKirill Isakov <bootctl@gmail.com>
Wed, 23 Mar 2022 05:52:51 +0000 (11:52 +0600)
committerKirill Isakov <bootctl@gmail.com>
Wed, 23 Mar 2022 05:52:51 +0000 (11:52 +0600)
54 files changed:
.astylerc
.gitignore
bash_completion.d/meson.build [new file with mode: 0644]
doc/meson.build [new file with mode: 0644]
meson.build [new file with mode: 0644]
meson_options.txt [new file with mode: 0644]
src/bsd/meson.build [new file with mode: 0644]
src/chacha-poly1305/meson.build [new file with mode: 0644]
src/dropin.h
src/ed25519/meson.build [new file with mode: 0644]
src/event.c
src/gcrypt/meson.build [new file with mode: 0644]
src/getopt.c
src/getopt1.c
src/git_tag.sh [new file with mode: 0755]
src/include/meson.build [new file with mode: 0644]
src/linux/meson.build [new file with mode: 0644]
src/linux/uml_device.c [moved from src/uml_device.c with 97% similarity]
src/meson.build [new file with mode: 0644]
src/mingw/meson.build [new file with mode: 0644]
src/net_packet.c
src/nolegacy/meson.build [new file with mode: 0644]
src/openssl/meson.build [new file with mode: 0644]
src/solaris/meson.build [new file with mode: 0644]
src/sptps_keypair.c
src/sptps_speed.c
src/sptps_test.c
src/system.h
src/tincd.c
src/version.c
src/version_git.h.in [new file with mode: 0644]
subprojects/lz4.wrap [new file with mode: 0644]
subprojects/lzo2.wrap [new file with mode: 0644]
subprojects/openssl.wrap [new file with mode: 0644]
subprojects/zlib.wrap [new file with mode: 0644]
systemd/meson.build [new file with mode: 0644]
test/algorithms.test
test/basic.test
test/command-fsck.test
test/commandline.test
test/compression.test
test/executables.test
test/import-export.test
test/invite-join.test
test/invite-offline.test
test/invite-tinc-up.test
test/legacy-protocol.test
test/meson.build [new file with mode: 0644]
test/ns-ping.test
test/scripts.test
test/security.test
test/sptps-basic.test
test/testlib.sh [moved from test/testlib.sh.in with 84% similarity]
test/variables.test

index dc381a2..4b89b18 100644 (file)
--- a/.astylerc
+++ b/.astylerc
@@ -1,6 +1,8 @@
 --indent=tab=8
 --convert-tabs
---exclude=src/lib
+--exclude=subprojects
+--exclude=build
+--recursive
 -i
 -j
 -f
@@ -10,3 +12,5 @@
 -xg
 -k3
 -w
+--formatted
+
index 40094c4..7dd71eb 100644 (file)
 /test/*.log
 /test/*.trs
 /test/splice
-/test/testlib.sh
 Makefile
 Makefile.in
 core*
 heaptrack.*
 *.tar.gz*
+/subprojects/*
+!/subprojects/*.wrap
+
diff --git a/bash_completion.d/meson.build b/bash_completion.d/meson.build
new file mode 100644 (file)
index 0000000..2e221e7
--- /dev/null
@@ -0,0 +1,7 @@
+dir_compl = dir_data / 'bash-completion' / 'completions'
+
+install_data(
+  'tinc',
+  install_dir: dir_compl,
+)
+
diff --git a/doc/meson.build b/doc/meson.build
new file mode 100644 (file)
index 0000000..fefb1b8
--- /dev/null
@@ -0,0 +1,62 @@
+man_pages = [
+  'tinc-gui.8.in',
+  'tinc.8.in',
+  'tinc.conf.5.in',
+  'tincd.8.in',
+]
+
+info_pages = [
+  'tinc.texi',
+]
+
+info_includes = [
+  'tincinclude.texi.in',
+]
+
+man_conf = configuration_data()
+man_conf.set_quoted('PACKAGE', meson.project_name())
+man_conf.set_quoted('VERSION', meson.project_version())
+man_conf.set_quoted('localstatedir', dir_local_state)
+man_conf.set_quoted('runstatedir', dir_run_state)
+man_conf.set_quoted('sysconfdir', dir_sysconf)
+
+foreach man_src : man_pages
+  man = configure_file(
+    input: man_src,
+    output: '@BASENAME@',
+    configuration: man_conf,
+  )
+  install_man(man)
+endforeach
+
+prog_makeinfo = find_program('makeinfo', required: opt_docs)
+if not prog_makeinfo.found()
+  subdir_done()
+endif
+
+foreach inc : info_includes
+  configure_file(
+    input: inc,
+    output: '@BASENAME@',
+    configuration: man_conf,
+  )
+endforeach
+
+info_cmd = [
+  prog_makeinfo,
+  '-P', '@BUILD_ROOT@/doc',
+  '@INPUT@',
+  '--output', '@OUTPUT@',
+]
+
+foreach page : info_pages
+  custom_target(
+    'info-page-' + page,
+    input: page,
+    output: '@BASENAME@.info',
+    command: info_cmd,
+    install: true,
+    install_dir: dir_info,
+  )
+endforeach
+
diff --git a/meson.build b/meson.build
new file mode 100644 (file)
index 0000000..9f55c9e
--- /dev/null
@@ -0,0 +1,124 @@
+project('tinc', 'c',
+  version: run_command('./src/git_tag.sh', check: true).stdout().strip(),
+  license: 'GPL-2.0-or-later',
+  meson_version: '>=0.51',
+  default_options: [
+    'c_std=c11',
+    'warning_level=3',
+    'buildtype=debugoptimized',
+  ],
+)
+
+dir_run_state = get_option('runstatedir')
+opt_crypto = get_option('crypto')
+opt_curses = get_option('curses')
+opt_docs = get_option('docs')
+opt_harden = get_option('hardening')
+opt_jumbograms = get_option('jumbograms')
+opt_lz4 = get_option('lz4')
+opt_lzo = get_option('lzo')
+opt_miniupnpc = get_option('miniupnpc')
+opt_readline = get_option('readline')
+opt_static = get_option('static')
+opt_systemd = get_option('systemd')
+opt_tests = get_option('tests')
+opt_tunemu = get_option('tunemu')
+opt_uml = get_option('uml')
+opt_vde = get_option('vde')
+opt_zlib = get_option('zlib')
+
+meson_version = meson.version()
+
+cc = meson.get_compiler('c')
+os_name = host_machine.system()
+cc_name = cc.get_id()
+
+cc_defs = ['-D_GNU_SOURCE']
+cc_flags = [cc_defs]
+ld_flags = []
+
+if opt_static.auto()
+  static = os_name == 'windows'
+else
+  static = opt_static.enabled()
+endif
+
+if static
+  ld_flags += '-static'
+endif
+
+if opt_harden
+  cc_flags += [
+    '-D_FORTIFY_SOURCE=2',
+    '-fwrapv',
+    '-fno-strict-overflow',
+    '-Wreturn-type',
+    '-Wold-style-definition',
+    '-Wmissing-declarations',
+    '-Wmissing-prototypes',
+    '-Wstrict-prototypes',
+    '-Wredundant-decls',
+    '-Wbad-function-cast',
+    '-Wwrite-strings',
+    '-fdiagnostics-show-option',
+    '-fstrict-aliasing',
+    '-Wmissing-noreturn',
+  ]
+  if cc_name == 'clang'
+    cc_flags += '-Qunused-arguments'
+  endif
+  ld_flags += ['-Wl,-z,relro', '-Wl,-z,now']
+  if os_name == 'windows'
+    ld_flags += ['-Wl,--dynamicbase', '-Wl,--nxcompat']
+  endif
+endif
+
+cc_flags = cc.get_supported_arguments(cc_flags)
+ld_flags = cc.get_supported_link_arguments(ld_flags)
+
+add_project_arguments(cc_flags, language: 'c')
+add_project_link_arguments(ld_flags, language: 'c')
+
+build_root = meson.current_build_dir()
+src_root = meson.current_source_dir()
+
+prefix = get_option('prefix')
+dir_bin = prefix / get_option('bindir')
+dir_data = prefix / get_option('datadir')
+dir_info = prefix / get_option('infodir')
+dir_lib = prefix / get_option('libdir')
+dir_local_state = prefix / get_option('localstatedir')
+dir_locale = prefix / get_option('localedir')
+dir_man = prefix / get_option('mandir')
+dir_sbin = prefix / get_option('sbindir')
+dir_sysconf = prefix / get_option('sysconfdir')
+
+if dir_run_state == ''
+  dir_run_state = dir_local_state / 'run'
+endif
+
+if not opt_docs.disabled()
+  subdir('doc')
+endif
+
+subdir('src')
+
+if not opt_tests.disabled()
+  subdir('test')
+endif
+
+subdir('bash_completion.d')
+
+if os_name == 'linux' and not opt_systemd.disabled()
+  subdir('systemd')
+endif
+
+prog_reformat = find_program('astyle', native: true, required: false)
+if prog_reformat.found()
+  run_target('reformat', command: [
+    prog_reformat,
+    '--options=@SOURCE_ROOT@/.astylerc',
+    '@SOURCE_ROOT@/*.c', '@SOURCE_ROOT@/*.h',
+  ])
+endif
+
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644 (file)
index 0000000..bb463ce
--- /dev/null
@@ -0,0 +1,91 @@
+option('runstatedir',
+       type: 'string',
+       value: '',
+       description: 'state directory for sockets, PID files')
+
+option('docs',
+       type: 'feature',
+       value: 'auto',
+       description: 'generate documentation')
+
+option('tests',
+       type: 'feature',
+       value: 'auto',
+       description: 'enable tests')
+
+option('hardening',
+       type: 'boolean',
+       value: true,
+       description: 'add compiler and linker hardening flags')
+
+option('static',
+       type: 'feature',
+       value: 'auto',
+       description: 'statically link dependencies (auto: YES on Windows, NO everywhere else)')
+
+option('systemd',
+       type: 'feature',
+       value: 'auto',
+       description: 'install systemd service files')
+
+option('systemd_dir',
+       type: 'string',
+       value: '',
+       description: 'systemd service directory (defaults to $prefix/lib/systemd/system)')
+
+option('crypto',
+       type: 'combo',
+       choices: ['openssl', 'gcrypt', 'nolegacy'],
+       value: 'openssl',
+       description: 'which cryptographic library to use')
+
+option('miniupnpc',
+       type: 'feature',
+       value: 'disabled',
+       description: 'miniupnpc support')
+
+option('lzo',
+       type: 'feature',
+       value: 'auto',
+       description: 'lzo compression support')
+
+option('lz4',
+       type: 'feature',
+       value: 'auto',
+       description: 'lz4 compression support')
+
+option('curses',
+       type: 'feature',
+       value: 'auto',
+       description: 'curses support')
+
+option('readline',
+       type: 'feature',
+       value: 'auto',
+       description: 'readline support')
+
+option('zlib',
+       type: 'feature',
+       value: 'auto',
+       description: 'zlib compression support')
+
+option('uml',
+       type: 'boolean',
+       value: false,
+       description: 'User Mode Linux support')
+
+option('tunemu',
+       type: 'feature',
+       value: 'auto',
+       description: 'support for the tunemu driver')
+
+option('vde',
+       type: 'feature',
+       value: 'auto',
+       description: 'support for Virtual Distributed Ethernet')
+
+option('jumbograms',
+       type: 'boolean',
+       value: false,
+       description: 'support for jumbograms (packets up to 9000 bytes)')
+
diff --git a/src/bsd/meson.build b/src/bsd/meson.build
new file mode 100644 (file)
index 0000000..690e737
--- /dev/null
@@ -0,0 +1,26 @@
+check_headers += [
+  'net/if_tap.h',
+  'net/if_tun.h',
+  'net/if_utun.h',
+  'net/tap/if_tap.h',
+  'net/tun/if_tun.h',
+]
+
+check_functions += [
+  'devname',
+  'fdevname',
+]
+
+src_tincd += files('device.c')
+
+if os_name == 'darwin'
+  dep_tunemu = dependency('tunemu', required: opt_tunemu, static: static)
+  dep_pcap = dependency('pcap', required: opt_tunemu, static: static)
+
+  if dep_tunemu.found() and dep_pcap.found()
+    deps_tincd += [dep_tunemu, dep_pcap]
+    src_tincd += files('tunemu.c')
+    cdata.set('ENABLE_TUNEMU', 1)
+  endif
+endif
+
diff --git a/src/chacha-poly1305/meson.build b/src/chacha-poly1305/meson.build
new file mode 100644 (file)
index 0000000..d8fd74c
--- /dev/null
@@ -0,0 +1,14 @@
+src_chacha_poly = files(
+  'chacha-poly1305.c',
+  'chacha.c',
+  'poly1305.c',
+)
+
+lib_chacha_poly = static_library(
+  'chacha_poly',
+  sources: src_chacha_poly,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
index 14783ff..2aa6df1 100644 (file)
@@ -21,8 +21,6 @@
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
-
 #ifndef HAVE_DAEMON
 extern int daemon(int, int);
 #endif
diff --git a/src/ed25519/meson.build b/src/ed25519/meson.build
new file mode 100644 (file)
index 0000000..9542c0f
--- /dev/null
@@ -0,0 +1,22 @@
+src_ed25519 = files(
+  'ecdh.c',
+  'ecdsa.c',
+  'ecdsagen.c',
+  'fe.c',
+  'ge.c',
+  'key_exchange.c',
+  'keypair.c',
+  'sc.c',
+  'sha512.c',
+  'sign.c',
+  'verify.c',
+)
+
+lib_ed25519 = static_library(
+  'ed25519',
+  sources: src_ed25519,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
index 899b62a..5d0bcef 100644 (file)
@@ -25,7 +25,6 @@
 #include <sys/epoll.h>
 #endif
 
-#include "dropin.h"
 #include "event.h"
 #include "utils.h"
 #include "net.h"
diff --git a/src/gcrypt/meson.build b/src/gcrypt/meson.build
new file mode 100644 (file)
index 0000000..ac93c80
--- /dev/null
@@ -0,0 +1,22 @@
+src_lib_crypto = files(
+  'cipher.c',
+  'crypto.c',
+  'digest.c',
+  'pem.c',
+  'prf.c',
+  'rsa.c',
+  'rsagen.c',
+)
+
+# Under current MinGW, flags specified in libgcrypt.pc fail on static build
+if static and os_name == 'windows'
+  dep_crypto = []
+  foreach lib : ['libgcrypt', 'gpg-error']
+    dep_crypto += cc.find_library(lib, static: true)
+  endforeach
+else
+  dep_crypto = dependency('libgcrypt', static: static)
+endif
+
+cdata.set('HAVE_LIBGCRYPT', 1)
+
index 5d5fb59..a8c5b49 100644 (file)
@@ -30,9 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #define _NO_PROTO
 #endif
 
-#ifdef HAVE_CONFIG_H
-#include "../config.h"
-#endif
+#include "config.h"
 
 #if !defined (__STDC__) || !__STDC__
 /* This is a separate conditional since some stdc systems
index 3ccb150..be2280e 100644 (file)
@@ -19,9 +19,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 \f
-#ifdef HAVE_CONFIG_H
-#include "../config.h"
-#endif
+#include "config.h"
 
 #include "getopt.h"
 
diff --git a/src/git_tag.sh b/src/git_tag.sh
new file mode 100755 (executable)
index 0000000..25677e2
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+git describe --always --tags --match='release-*' "$@" | sed 's/release-//'
diff --git a/src/include/meson.build b/src/include/meson.build
new file mode 100644 (file)
index 0000000..55da167
--- /dev/null
@@ -0,0 +1,9 @@
+configure_file(output: 'config.h', configuration: cdata)
+
+src_lib_tinc += vcs_tag(
+  command: './git_tag.sh',
+  fallback: 'unknown',
+  input: '../version_git.h.in',
+  output: 'version_git.h',
+)
+
diff --git a/src/linux/meson.build b/src/linux/meson.build
new file mode 100644 (file)
index 0000000..5725b4a
--- /dev/null
@@ -0,0 +1,15 @@
+check_headers += [
+  'linux/if_tun.h',
+  'sys/epoll.h',
+  'netpacket/packet.h',
+]
+
+check_functions += 'recvmmsg'
+
+src_tincd += files('device.c')
+
+if opt_uml
+  src_tincd += files('uml_device.c')
+  cdata.set('ENABLE_UML', 1)
+endif
+
similarity index 97%
rename from src/uml_device.c
rename to src/linux/uml_device.c
index f35ae0d..dafe5b2 100644 (file)
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "system.h"
+#include "../system.h"
 
 #include <sys/un.h>
 
-#include "conf.h"
-#include "device.h"
-#include "names.h"
-#include "net.h"
-#include "logger.h"
-#include "utils.h"
-#include "route.h"
-#include "xalloc.h"
+#include "../conf.h"
+#include "../device.h"
+#include "../names.h"
+#include "../net.h"
+#include "../logger.h"
+#include "../utils.h"
+#include "../route.h"
+#include "../xalloc.h"
 
 static int listen_fd = -1;
 static int request_fd = -1;
diff --git a/src/meson.build b/src/meson.build
new file mode 100644 (file)
index 0000000..c9f5d59
--- /dev/null
@@ -0,0 +1,399 @@
+inc_conf = include_directories('include')
+
+cdata = configuration_data()
+
+cdata.set_quoted('PACKAGE', meson.project_name())
+cdata.set_quoted('VERSION', meson.project_version())
+cdata.set_quoted('CONFDIR', dir_sysconf)
+cdata.set_quoted('RUNSTATEDIR', dir_run_state)
+cdata.set_quoted('LOCALSTATEDIR', dir_local_state)
+cdata.set_quoted('SBINDIR', dir_sbin)
+
+cdata.set('HAVE_' + os_name.to_upper(), 1)
+
+foreach attr : ['malloc', 'nonnull', 'warn_unused_result']
+  cc.has_function_attribute(attr)
+endforeach
+
+check_headers = [
+  'arpa/inet.h',
+  'arpa/nameser.h',
+  'dirent.h',
+  'getopt.h',
+  'inttypes.h',
+  'net/ethernet.h',
+  'net/if.h',
+  'net/if_arp.h',
+  'net/if_types.h',
+  'netdb.h',
+  'netinet/icmp6.h',
+  'netinet/if_ether.h',
+  'netinet/in.h',
+  'netinet/in6.h',
+  'netinet/in_systm.h',
+  'netinet/ip.h',
+  'netinet/ip6.h',
+  'netinet/ip_icmp.h',
+  'netinet/tcp.h',
+  'resolv.h',
+  'stddef.h',
+  'sys/file.h',
+  'sys/ioctl.h',
+  'sys/mman.h',
+  'sys/param.h',
+  'sys/resource.h',
+  'sys/socket.h',
+  'sys/stat.h',
+  'sys/time.h',
+  'sys/types.h',
+  'sys/un.h',
+  'sys/wait.h',
+  'syslog.h',
+  'termios.h',
+]
+
+check_functions = [
+  'asprintf',
+  'daemon',
+  'fchmod',
+  'fork',
+  'gettimeofday',
+  'mlockall',
+  'putenv',
+  'strsignal',
+  'unsetenv',
+]
+
+check_types = [
+  'struct arphdr',
+  'struct ether_arp',
+  'struct ether_header',
+  'struct icmp',
+  'struct icmp6_hdr',
+  'struct ip',
+  'struct ip6_hdr',
+  'struct nd_neighbor_solicit',
+  'struct nd_opt_hdr',
+]
+
+subdir('ed25519')
+subdir('chacha-poly1305')
+
+src_lib_tinc = [
+  'conf.c',
+  'dropin.c',
+  'keys.c',
+  'list.c',
+  'names.c',
+  'netutl.c',
+  'script.c',
+  'splay_tree.c',
+  'sptps.c',
+  'subnet_parse.c',
+  'utils.c',
+  'version.c',
+  'xoshiro.c',
+  'logger.c',
+]
+
+src_tinc = [
+  'fsck.c',
+  'ifconfig.c',
+  'info.c',
+  'invitation.c',
+  'tincctl.c',
+  'top.c',
+]
+
+src_tincd = [
+  'address_cache.c',
+  'autoconnect.c',
+  'buffer.c',
+  'compression.h',
+  'conf_net.c',
+  'connection.c',
+  'control.c',
+  'dummy_device.c',
+  'edge.c',
+  'event.c',
+  'fd_device.c',
+  'graph.c',
+  'meta.c',
+  'multicast_device.c',
+  'net.c',
+  'net_packet.c',
+  'net_setup.c',
+  'net_socket.c',
+  'node.c',
+  'process.c',
+  'protocol.c',
+  'protocol_auth.c',
+  'protocol_edge.c',
+  'protocol_key.c',
+  'protocol_misc.c',
+  'protocol_subnet.c',
+  'raw_socket_device.c',
+  'route.c',
+  'subnet.c',
+  'tincd.c',
+]
+
+cc_flags_tincd = cc_flags
+
+deps_common = []
+deps_tinc = []
+deps_tincd = [cc.find_library('m', required: false)]
+
+if os_name in ['linux', 'android']
+  subdir('linux')
+elif os_name.endswith('bsd') or os_name in ['dragonfly', 'darwin']
+  subdir('bsd')
+elif os_name == 'sunos'
+  subdir('solaris')
+elif os_name == 'windows'
+  subdir('mingw')
+endif
+
+foreach h : check_headers
+  if cc.has_header(h)
+    cdata.set('HAVE_' + h.to_upper().underscorify(),
+              1,
+              description: '#include <' + h + '>')
+  endif
+endforeach
+
+confdata = configuration_data()
+confdata.merge_from(cdata)
+configure_file(output: 'meson_config.h', configuration: confdata)
+
+have_prefix = '''
+  #include "@0@/src/meson_config.h"
+  #include "@1@/have.h"
+'''.format(build_root, meson.current_source_dir())
+
+foreach f : check_functions
+  if f == 'fork' and os_name == 'windows'
+    message('MinGW does not have correct definition for fork()')
+  else
+    if cc.has_function(f, prefix: have_prefix, args: cc_defs)
+      cdata.set('HAVE_' + f.to_upper(),
+                1,
+                description: 'function ' + f)
+    endif
+  endif
+endforeach
+
+if cc.has_function('res_init', prefix: '''
+  #include <netinet/in.h>
+  #include <resolv.h>
+''', args: cc_defs)
+  cdata.set('HAVE_DECL_RES_INIT', 1)
+endif
+
+foreach type : check_types
+  if cc.has_type(type, prefix: have_prefix, args: cc_defs)
+    name = 'HAVE_' + type.to_upper().underscorify()
+    cdata.set(name, 1, description: type)
+  endif
+endforeach
+
+if not cdata.has('HAVE_GETOPT_H') or not cc.has_function('getopt_long', prefix: have_prefix, args: cc_defs)
+  src_lib_tinc += ['getopt.c', 'getopt1.c']
+endif
+
+if not opt_miniupnpc.disabled()
+  dep_miniupnpc = dependency('miniupnpc', required: false, static: static)
+  if not dep_miniupnpc.found()
+    # No pkg-config files on MinGW
+    dep_miniupnpc = cc.find_library('miniupnpc', required: opt_miniupnpc, static: static)
+  endif
+  if dep_miniupnpc.found()
+    src_tincd += 'upnp.c'
+    deps_tincd += [
+      dependency('threads', static: static),
+      dep_miniupnpc,
+    ]
+    if static
+      cc_flags_tincd += '-DMINIUPNP_STATICLIB'
+    endif
+    cdata.set('HAVE_MINIUPNPC', 1)
+  endif
+endif
+
+if opt_curses.auto() and os_name == 'windows'
+  message('curses does not link under MinGW')
+else
+  # The meta-dependency covers more alternatives, but is only available in 0.54+
+  curses_name = meson_version.version_compare('>=0.54') ? 'curses' : 'ncurses'
+  dep_curses = dependency(curses_name, required: opt_curses, static: static)
+  if dep_curses.found()
+    cdata.set('HAVE_CURSES', 1)
+    deps_tinc += dep_curses
+  endif
+endif
+
+# Some distributions do not supply pkg-config files for readline
+if opt_readline.auto() and os_name == 'windows'
+  message('readline does not link under MinGW')
+else
+  dep_readline = dependency('readline', required: opt_readline, static: static)
+  if not dep_readline.found()
+    dep_readline = cc.find_library('readline', required: opt_readline, static: static)
+  endif
+  if dep_readline.found() and \
+     cc.has_header('readline/readline.h', dependencies: dep_readline) and \
+     cc.has_header('readline/history.h', dependencies: dep_readline)
+    cdata.set('HAVE_READLINE', 1)
+    deps_tinc += dep_readline
+  endif
+endif
+
+dep_zlib = dependency('zlib',
+                      required: opt_zlib,
+                      static: static,
+                      fallback: ['zlib', 'zlib_dep'])
+if dep_zlib.found()
+  cdata.set('HAVE_ZLIB', 1)
+  deps_tincd += dep_zlib
+endif
+
+if not opt_lzo.disabled()
+  dep_lzo = dependency('lzo2', required: false, static: static)
+  if not dep_lzo.found()
+    dep_lzo = cc.find_library('lzo2', required: opt_lzo, static: static)
+  endif
+  if not dep_lzo.found()
+    dep_lzo = dependency('lzo2',
+                         required: false,
+                         static: static,
+                         fallback: ['lzo2', 'lzo2_dep'])
+  endif
+  if dep_lzo.found()
+    if dep_lzo.type_name() == 'internal' or cc.has_header('lzo/lzo1x.h', dependencies: dep_lzo)
+      cdata.set('LZO1X_H', '<lzo/lzo1x.h>')
+    elif cc.has_header('lzo1x.h', dependencies: dep_lzo)
+      cdata.set('LZO1X_H', '<lzo1x.h>')
+    else
+      msg = 'lzo1x.h not found'
+      if opt_lzo.auto()
+        warning(msg)
+      else
+        error(msg)
+      endif
+    endif
+    if cdata.has('LZO1X_H')
+      cdata.set('HAVE_LZO', 1)
+      deps_tincd += dep_lzo
+    endif
+  endif
+endif
+
+dep_lz4 = dependency('liblz4',
+                     required: opt_lz4,
+                     static: static,
+                     fallback: ['lz4', 'liblz4_dep'])
+if dep_lz4.found()
+  deps_tincd += dep_lz4
+  cdata.set('HAVE_LZ4', 1)
+endif
+
+dep_vde = dependency('vdeplug', required: opt_vde, static: static)
+dep_dl = cc.find_library('dl', required: opt_vde)
+if dep_vde.found() and dep_dl.found()
+  cdata.set('ENABLE_VDE', 1)
+  src_tincd += 'vde_device.c'
+  deps_tincd += [dep_dl, dep_vde]
+endif
+
+if opt_jumbograms
+  cdata.set('ENABLE_JUMBOGRAMS', 1)
+endif
+
+subdir(opt_crypto)
+
+if opt_crypto != 'nolegacy'
+  src_lib_crypto += ['cipher.c', 'digest.c']
+endif
+
+subdir('include')
+
+lib_crypto = static_library(
+  'tinc_crypto',
+  sources: src_lib_crypto,
+  dependencies: dep_crypto,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
+deps_lib_tinc = [deps_common, dep_crypto]
+
+lib_tinc = static_library(
+  'tinc',
+  sources: src_lib_tinc,
+  dependencies: deps_lib_tinc,
+  link_with: [lib_ed25519, lib_chacha_poly, lib_crypto],
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
+exe_tinc = executable(
+  'tinc',
+  sources: src_tinc,
+  dependencies: [deps_lib_tinc, deps_tinc],
+  link_with: lib_tinc,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  install: true,
+  install_dir: dir_sbin,
+)
+
+exe_tincd = executable(
+  'tincd',
+  sources: src_tincd,
+  dependencies: [deps_lib_tinc, deps_tincd],
+  link_with: lib_tinc,
+  c_args: cc_flags_tincd,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  install: true,
+  install_dir: dir_sbin,
+)
+
+exe_sptps_test = executable(
+  'sptps_test',
+  sources: 'sptps_test.c',
+  dependencies: deps_lib_tinc,
+  link_with: lib_tinc,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
+exe_sptps_keypair = executable(
+  'sptps_keypair',
+  sources: 'sptps_keypair.c',
+  dependencies: deps_lib_tinc,
+  link_with: lib_tinc,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
+if os_name == 'linux'
+  dep_rt = cc.find_library('rt')
+
+  exe_sptps_speed = executable(
+    'sptps_speed',
+    sources: 'sptps_speed.c',
+    dependencies: [deps_lib_tinc, dep_rt],
+    link_with: lib_tinc,
+    implicit_include_directories: false,
+    include_directories: inc_conf,
+    build_by_default: false,
+  )
+
+  benchmark('sptps_speed', exe_sptps_speed, timeout: 90)
+endif
+
diff --git a/src/mingw/meson.build b/src/mingw/meson.build
new file mode 100644 (file)
index 0000000..796d62b
--- /dev/null
@@ -0,0 +1,14 @@
+win_common_libs = ['ws2_32', 'iphlpapi', 'winpthread']
+
+if opt_harden
+  win_common_libs += 'ssp'
+endif
+
+foreach libname : win_common_libs
+  deps_common += cc.find_library(libname)
+endforeach
+
+src_tincd += files('device.c')
+
+cdata.set('HAVE_MINGW', 1)
+
index 459b241..eb438b0 100644 (file)
@@ -25,7 +25,6 @@
 #ifdef HAVE_ZLIB
 #define ZLIB_CONST
 #include <zlib.h>
-#include <assert.h>
 
 #endif
 
@@ -33,8 +32,8 @@
 #include LZO1X_H
 #endif
 
-#ifdef LZ4_H
-#include LZ4_H
+#ifdef HAVE_LZ4
+#include <lz4.h>
 #endif
 
 #include "address_cache.h"
@@ -65,11 +64,15 @@ int keylifetime = 0;
 static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
 #endif
 
+#ifdef HAVE_LZ4
+
 #ifdef HAVE_LZ4_BUILTIN
 static LZ4_stream_t lz4_stream;
 #else
 static void *lz4_state = NULL;
-#endif /* HAVE_LZ4_BUILTIN */
+#endif // HAVE_LZ4_BUILTIN
+
+#endif // HAVE_LZ4
 
 static void send_udppacket(node_t *, vpn_packet_t *);
 
@@ -252,8 +255,6 @@ static length_t compress_packet_lz4(uint8_t *dest, const uint8_t *source, length
 
 #ifdef HAVE_LZO
 static length_t compress_packet_lzo(uint8_t *dest, const uint8_t *source, length_t len, compression_level_t level) {
-       assert(level == COMPRESS_LZO_LO || level == COMPRESS_LZO_HI);
-
        lzo_uint lzolen = MAXSIZE;
        int result;
 
diff --git a/src/nolegacy/meson.build b/src/nolegacy/meson.build
new file mode 100644 (file)
index 0000000..323a831
--- /dev/null
@@ -0,0 +1,9 @@
+src_lib_crypto = files(
+  'crypto.c',
+  'prf.c',
+)
+
+dep_crypto = dependency('', required: false)
+
+cdata.set('DISABLE_LEGACY', 1)
+
diff --git a/src/openssl/meson.build b/src/openssl/meson.build
new file mode 100644 (file)
index 0000000..34c4fff
--- /dev/null
@@ -0,0 +1,37 @@
+src_lib_crypto = files(
+  'cipher.c',
+  'crypto.c',
+  'digest.c',
+  'log.c',
+  'prf.c',
+  'rsa.c',
+  'rsagen.c',
+)
+
+# OpenBSD's 'OpenSSL' is actually LibreSSL. pkg-config on OpenBSD 7.0 reports
+# it as OpenSSL 1.0, but it has everything we need (unlike 'real' OpenSSL 1.0).
+
+if os_name == 'openbsd'
+  names = ['openssl', 'eopenssl30', 'eopenssl11']
+  min_ver = '>=1.0.0'
+else
+  names = ['openssl', 'openssl11']
+  min_ver = '>=1.1.0'
+endif
+
+if meson_version.version_compare('>=0.60')
+  dep_crypto = dependency(names, version: min_ver, static: static)
+else
+  foreach name : names
+    dep_crypto = dependency(name, version: min_ver, static: static, required: false)
+    if dep_crypto.found()
+      break
+    endif
+  endforeach
+  if not dep_crypto.found()
+    dep_crypto = dependency('', static: static, fallback: ['openssl', 'openssl_dep'])
+  endif
+endif
+
+cdata.set('HAVE_OPENSSL', 1)
+
diff --git a/src/solaris/meson.build b/src/solaris/meson.build
new file mode 100644 (file)
index 0000000..f657428
--- /dev/null
@@ -0,0 +1,2 @@
+src_tincd += files('device.c')
+
index 22433b9..d762724 100644 (file)
@@ -24,8 +24,7 @@
 #include "crypto.h"
 #include "ecdsagen.h"
 #include "logger.h"
-
-static char *program_name;
+#include "names.h"
 
 void logger(debug_t level, int priority, const char *format, ...) {
        (void)level;
index cc05b86..53cff4d 100644 (file)
@@ -45,7 +45,6 @@ bool send_meta(struct connection_t *c, const void *msg, size_t len) {
        (void)len;
        return false;
 }
-char *logfilename = NULL;
 bool do_detach = false;
 struct timeval now;
 
index 0f62af0..1da0571 100644 (file)
@@ -35,6 +35,7 @@
 #include "protocol.h"
 #include "sptps.h"
 #include "utils.h"
+#include "names.h"
 
 #ifndef HAVE_MINGW
 #define closesocket(s) close(s)
@@ -56,7 +57,6 @@ bool send_meta(struct connection_t *c, const void *msg, size_t len) {
        return false;
 }
 
-char *logfilename = NULL;
 bool do_detach = false;
 struct timeval now;
 
@@ -136,8 +136,6 @@ static struct option const long_options[] = {
        {NULL, 0, NULL, 0}
 };
 
-const char *program_name;
-
 static void usage(void) {
        static const char *message =
                "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n"
index b3d9e0a..0224fbe 100644 (file)
@@ -21,7 +21,7 @@
     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#include "../config.h"
+#include "config.h"
 
 #include "have.h"
 
index 7c30a26..4310181 100644 (file)
@@ -33,8 +33,8 @@
 #include LZO1X_H
 #endif
 
-#ifdef LZ4_H
-#include LZ4_H
+#ifdef HAVE_LZ4
+#include <lz4.h>
 #endif
 
 #ifndef HAVE_MINGW
index d0af1cc..31b04d7 100644 (file)
@@ -19,7 +19,6 @@
 
 #include "version.h"
 #include "version_git.h"
-#include "../config.h"
 
 /* This file is always rebuilt (even if there are no changes) so that the following is updated */
 const char *const BUILD_DATE = __DATE__;
diff --git a/src/version_git.h.in b/src/version_git.h.in
new file mode 100644 (file)
index 0000000..ef3ed6c
--- /dev/null
@@ -0,0 +1,2 @@
+#define GIT_DESCRIPTION "@VCS_TAG@"
+
diff --git a/subprojects/lz4.wrap b/subprojects/lz4.wrap
new file mode 100644 (file)
index 0000000..c151ad0
--- /dev/null
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = lz4-1.9.3
+source_url = https://github.com/lz4/lz4/archive/v1.9.3.tar.gz
+source_filename = lz4-1.9.3.tgz
+source_hash = 030644df4611007ff7dc962d981f390361e6c97a34e5cbc393ddfbe019ffe2c1
+patch_url = https://wrapdb.mesonbuild.com/v2/lz4_1.9.3-1/get_patch
+patch_filename = lz4-1.9.3-1-wrap.zip
+patch_hash = 5a0e6e5797a51d23d5dad0009d36dfebe354b5e5eef2a1302d29788b1ee067c1
+
+[provide]
+liblz4 = liblz4_dep
+
diff --git a/subprojects/lzo2.wrap b/subprojects/lzo2.wrap
new file mode 100644 (file)
index 0000000..2b100f4
--- /dev/null
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = lzo-2.10
+source_url = https://www.oberhumer.com/opensource/lzo/download/lzo-2.10.tar.gz
+source_filename = lzo-2.10.tar.gz
+source_hash = c0f892943208266f9b6543b3ae308fab6284c5c90e627931446fb49b4221a072
+patch_filename = lzo2_2.10-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/lzo2_2.10-1/get_patch
+patch_hash = 181cf865ea5317b6e8822c71385325328863489a4e5f49177ff67fd13ea1220e
+
+[provide]
+lzo2 = lzo2_dep
+
diff --git a/subprojects/openssl.wrap b/subprojects/openssl.wrap
new file mode 100644 (file)
index 0000000..274b544
--- /dev/null
@@ -0,0 +1,14 @@
+[wrap-file]
+directory = openssl-3.0.2
+source_url = https://www.openssl.org/source/openssl-3.0.2.tar.gz
+source_filename = openssl-3.0.2.tar.gz
+source_hash = 98e91ccead4d4756ae3c9cde5e09191a8e586d9f4d50838e7ec09d6411dfdb63
+patch_filename = openssl_3.0.2-1_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/openssl_3.0.2-1/get_patch
+patch_hash = 762ab4ea94d02178d6a1d3eb63409c2c4d61315d358391cdac62df15211174d4
+
+[provide]
+libcrypto = libcrypto_dep
+libssl = libssl_dep
+openssl = openssl_dep
+
diff --git a/subprojects/zlib.wrap b/subprojects/zlib.wrap
new file mode 100644 (file)
index 0000000..3773781
--- /dev/null
@@ -0,0 +1,12 @@
+[wrap-file]
+directory = zlib-1.2.11
+source_url = http://zlib.net/fossils/zlib-1.2.11.tar.gz
+source_filename = zlib-1.2.11.tar.gz
+source_hash = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1
+patch_filename = zlib_1.2.11-6_patch.zip
+patch_url = https://wrapdb.mesonbuild.com/v2/zlib_1.2.11-6/get_patch
+patch_hash = f7c24c5698ce787294910ad431f94088102d35ddaf88542d04add1e54afa9212
+
+[provide]
+zlib = zlib_dep
+
diff --git a/systemd/meson.build b/systemd/meson.build
new file mode 100644 (file)
index 0000000..f2b4d04
--- /dev/null
@@ -0,0 +1,28 @@
+dep_systemd = dependency('systemd', required: opt_systemd)
+if not dep_systemd.found()
+  subdir_done()
+endif
+
+dir_systemd = get_option('systemd_dir')
+if dir_systemd == ''
+  if meson_version.version_compare('>=0.58')
+    dir_systemd = dep_systemd.get_variable('systemdsystemunitdir', pkgconfig_define: ['prefix', prefix])
+  else
+    dir_systemd = dep_systemd.get_pkgconfig_variable('systemdsystemunitdir', define_variable: ['prefix', prefix])
+  endif
+endif
+
+systemd_conf = configuration_data()
+systemd_conf.set('sysconfdir', dir_sysconf)
+systemd_conf.set('sbindir', dir_sbin)
+
+configure_file(input: 'tinc.service.in',
+               output: 'tinc.service',
+               configuration: systemd_conf,
+               install_dir: dir_systemd)
+
+configure_file(input: 'tinc@.service.in',
+               output: 'tinc@.service',
+               configuration: systemd_conf,
+               install_dir: dir_systemd)
+
index d069010..9dd722c 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize two nodes
 
index 87c5784..31f2755 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize and test one node
 
index 8457baa..daf9291 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 foo_dir=$(peer_directory foo)
 foo_host=$foo_dir/hosts/foo
index ba3d717..800dbfc 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize one node
 
index f0952a4..ac92541 100755 (executable)
@@ -1,11 +1,12 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 require_root "$0" "$@"
-test -e /dev/net/tun || exit $EXIT_SKIP_TEST
-ip netns list || exit $EXIT_SKIP_TEST
-command -v socat || exit $EXIT_SKIP_TEST
+test -e /dev/net/tun || exit "$EXIT_SKIP_TEST"
+ip netns list || exit "$EXIT_SKIP_TEST"
+command -v socat || exit "$EXIT_SKIP_TEST"
 
 ip_foo=192.168.1.1
 ip_bar=192.168.1.2
@@ -106,7 +107,7 @@ for level in $levels; do
   wait_script foo hosts/bar-up
   wait_script bar hosts/foo-up
 
-  try_limit_time 60 sh <<EOF
+  sh <<EOF
     set -eu
     ip netns exec foo socat -u TCP4-LISTEN:$recv_port_foo,reuseaddr OPEN:"$tmp_file",creat &
     ip netns exec bar socat -u OPEN:"$ref_file" TCP4:$ip_foo:$recv_port_foo,retry=30 &
index 96aad99..390d2c7 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Just test whether the executables work
 
@@ -8,6 +9,6 @@ tinc foo --help
 
 tincd foo --help
 
-if [ -e "$SPTPS_TEST" ]; then
-  $SPTPS_TEST --help
+if [ -e "$SPTPS_TEST_PATH" ]; then
+  "$SPTPS_TEST_PATH" --help
 fi
index 9fdfa49..6fe303f 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize three nodes
 
index 7915581..be2af2b 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize one node
 
index aea39b4..8e53513 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize one node
 
index a288d6e..14d5a60 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize one node
 
index 396fc56..9c44f79 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize two nodes
 
diff --git a/test/meson.build b/test/meson.build
new file mode 100644 (file)
index 0000000..4b12f2e
--- /dev/null
@@ -0,0 +1,63 @@
+tests = [
+  'basic.test',
+  'commandline.test',
+  'executables.test',
+  'import-export.test',
+  'invite-join.test',
+  'invite-offline.test',
+  'invite-tinc-up.test',
+  'scripts.test',
+  'security.test',
+  'variables.test',
+]
+
+if opt_crypto != 'nolegacy'
+  tests += 'algorithms.test'
+  tests += 'legacy-protocol.test'
+endif
+
+if os_name != 'windows'
+  tests += 'sptps-basic.test'
+endif
+
+if os_name == 'linux'
+  tests += 'ns-ping.test'
+endif
+
+exe_splice = executable(
+  'splice',
+  sources: 'splice.c',
+  dependencies: deps_common,
+  implicit_include_directories: false,
+  include_directories: inc_conf,
+  build_by_default: false,
+)
+
+env = environment()
+env.set('TINC_PATH', exe_tinc.full_path())
+env.set('TINCD_PATH', exe_tincd.full_path())
+env.set('SPTPS_TEST_PATH', exe_sptps_test.full_path())
+env.set('SPTPS_KEYPAIR_PATH', exe_sptps_keypair.full_path())
+env.set('SPLICE_PATH', exe_splice.full_path())
+env.set('TESTLIB_PATH', src_root / 'test' / 'testlib.sh')
+
+deps_test = [
+  exe_tinc,
+  exe_tincd,
+  exe_splice,
+  exe_sptps_test,
+  exe_sptps_keypair,
+]
+
+test_wd = meson.current_build_dir()
+
+foreach test_name : tests
+  target = find_program(test_name, native: true)
+  test(test_name,
+       target,
+       timeout: 5 * 60,
+       env: env,
+       depends: deps_test,
+       workdir: test_wd)
+endforeach
+
index 8e10d11..33e7270 100755 (executable)
@@ -1,10 +1,11 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 require_root "$0" "$@"
-test -e /dev/net/tun || exit $EXIT_SKIP_TEST
-ip netns list || exit $EXIT_SKIP_TEST
+test -e /dev/net/tun || exit "$EXIT_SKIP_TEST"
+ip netns list || exit "$EXIT_SKIP_TEST"
 
 ip_foo=192.168.1.1
 ip_bar=192.168.1.2
index a76356a..ff0e565 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initializing server node
 
index ee7bd46..fb783b0 100755 (executable)
@@ -1,18 +1,19 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Skip this test if tools are missing
 
-command -v nc >/dev/null || exit $EXIT_SKIP_TEST
-command -v timeout >/dev/null || exit $EXIT_SKIP_TEST
+command -v nc >/dev/null || exit "$EXIT_SKIP_TEST"
+command -v timeout >/dev/null || exit "$EXIT_SKIP_TEST"
 
 foo_port=30050
 bar_port=30051
 
 # usage: splice protocol_version
 splice() {
-  ./splice foo localhost $foo_port bar localhost $bar_port "$1" &
+  "$SPLICE_PATH" foo localhost $foo_port bar localhost $bar_port "$1" &
   sleep 10
 }
 
@@ -28,7 +29,7 @@ send_with_timeout() {
     ) | timeout 10 nc localhost $foo_port
   ) && exit 1
 
-  test $? = $EXIT_TIMEOUT
+  test $? = "$EXIT_TIMEOUT"
 
   if [ -z "$expected" ]; then
     test -z "$result"
index 56e3cd0..0eb285b 100755 (executable)
@@ -1,10 +1,11 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Skip this test if we did not compile sptps_test
 
-test -e "$SPTPS_TEST" -a -e "$SPTPS_KEYPAIR" || exit $EXIT_SKIP_TEST
+test -e "$SPTPS_TEST" -a -e "$SPTPS_KEYPAIR_PATH" || exit "$EXIT_SKIP_TEST"
 
 port=30080
 
@@ -16,8 +17,8 @@ client_pub="$DIR_FOO/client.pub"
 echo [STEP] Generate keys
 
 mkdir -p "$DIR_FOO"
-$SPTPS_KEYPAIR "$server_priv" "$server_pub"
-$SPTPS_KEYPAIR "$client_priv" "$client_pub"
+"$SPTPS_KEYPAIR_PATH" "$server_priv" "$server_pub"
+"$SPTPS_KEYPAIR_PATH" "$client_priv" "$client_pub"
 
 echo [STEP] Test transfer of a simple file
 
@@ -25,20 +26,20 @@ reference=testlib.sh
 
 (
   sleep 3
-  $SPTPS_TEST -4 -q "$client_priv" "$server_pub" localhost $port <"$reference"
+  "$SPTPS_TEST_PATH" -4 -q "$client_priv" "$server_pub" localhost $port <"$reference"
 ) &
 
-$SPTPS_TEST -4 "$server_priv" "$client_pub" $port >"$DIR_FOO/out1"
+"$SPTPS_TEST_PATH" -4 "$server_priv" "$client_pub" $port >"$DIR_FOO/out1"
 diff -w "$DIR_FOO/out1" "$reference"
 
-$SPTPS_TEST -4 -q "$server_priv" "$client_pub" $port <"$reference" &
+"$SPTPS_TEST_PATH" -4 -q "$server_priv" "$client_pub" $port <"$reference" &
 sleep 3
-$SPTPS_TEST -4 "$client_priv" "$server_pub" localhost $port >"$DIR_FOO/out2"
+"$SPTPS_TEST_PATH" -4 "$client_priv" "$server_pub" localhost $port >"$DIR_FOO/out2"
 diff -w "$DIR_FOO/out2" "$reference"
 
 echo [STEP] Datagram mode
 
-$SPTPS_TEST -4 -dq "$server_priv" "$client_pub" $port <"$reference" &
+"$SPTPS_TEST_PATH" -4 -dq "$server_priv" "$client_pub" $port <"$reference" &
 sleep 3
-sleep 3 | $SPTPS_TEST -4 -dq "$client_priv" "$server_pub" localhost $port >"$DIR_FOO/out3"
+sleep 3 | "$SPTPS_TEST_PATH" -4 -dq "$client_priv" "$server_pub" localhost $port >"$DIR_FOO/out3"
 diff -w "$DIR_FOO/out3" "$reference"
similarity index 84%
rename from test/testlib.sh.in
rename to test/testlib.sh
index c63d27d..3d0f990 100644 (file)
@@ -16,14 +16,6 @@ realdir() {
   fi
 }
 
-tincd_path=$(realdir "../src/tincd@EXEEXT@")
-tinc_path=$(realdir "../src/tinc@EXEEXT@")
-
-# shellcheck disable=SC2034
-SPTPS_TEST=$(realdir "../src/sptps_test@EXEEXT@")
-# shellcheck disable=SC2034
-SPTPS_KEYPAIR=$(realdir "../src/sptps_keypair@EXEEXT@")
-
 # Exit status list
 # shellcheck disable=SC2034
 EXIT_FAILURE=1
@@ -182,22 +174,6 @@ expect_code() {
   fi
 }
 
-# Runs its arguments with timeout(1) or gtimeout(1) if either are installed.
-# Usage: try_limit_time 10 command --with --args
-if type timeout >/dev/null; then
-  try_limit_time() {
-    time=$1
-    shift
-    timeout "$time" "$@"
-  }
-else
-  try_limit_time() {
-    echo >&2 "timeout was not found, running without time limits!"
-    shift
-    "$@"
-  }
-fi
-
 # wc -l on mac prints whitespace before the actual number.
 # This is simplest cross-platform alternative without that behavior.
 count_lines() {
@@ -211,9 +187,9 @@ tinc() {
   shift
 
   case "$peer" in
-  foo) try_limit_time 30 "$tinc_path" -n "$net1" --config="$DIR_FOO" --pidfile="$DIR_FOO/pid" "$@" ;;
-  bar) try_limit_time 30 "$tinc_path" -n "$net2" --config="$DIR_BAR" --pidfile="$DIR_BAR/pid" "$@" ;;
-  baz) try_limit_time 30 "$tinc_path" -n "$net3" --config="$DIR_BAZ" --pidfile="$DIR_BAZ/pid" "$@" ;;
+  foo) "$TINC_PATH" -n "$net1" --config="$DIR_FOO" --pidfile="$DIR_FOO/pid" "$@" ;;
+  bar) "$TINC_PATH" -n "$net2" --config="$DIR_BAR" --pidfile="$DIR_BAR/pid" "$@" ;;
+  baz) "$TINC_PATH" -n "$net3" --config="$DIR_BAZ" --pidfile="$DIR_BAZ/pid" "$@" ;;
   *) bail "invalid command [[$peer $*]]" ;;
   esac
 }
@@ -225,9 +201,9 @@ tincd() {
   shift
 
   case "$peer" in
-  foo) try_limit_time 30 "$tincd_path" -n "$net1" --config="$DIR_FOO" --pidfile="$DIR_FOO/pid" --logfile="$DIR_FOO/log" -d5 "$@" ;;
-  bar) try_limit_time 30 "$tincd_path" -n "$net2" --config="$DIR_BAR" --pidfile="$DIR_BAR/pid" --logfile="$DIR_BAR/log" -d5 "$@" ;;
-  baz) try_limit_time 30 "$tincd_path" -n "$net3" --config="$DIR_BAZ" --pidfile="$DIR_BAZ/pid" --logfile="$DIR_BAZ/log" -d5 "$@" ;;
+  foo) "$TINCD_PATH" -n "$net1" --config="$DIR_FOO" --pidfile="$DIR_FOO/pid" --logfile="$DIR_FOO/log" -d5 "$@" ;;
+  bar) "$TINCD_PATH" -n "$net2" --config="$DIR_BAR" --pidfile="$DIR_BAR/pid" --logfile="$DIR_BAR/log" -d5 "$@" ;;
+  baz) "$TINCD_PATH" -n "$net3" --config="$DIR_BAZ" --pidfile="$DIR_BAZ/pid" --logfile="$DIR_BAZ/log" -d5 "$@" ;;
   *) bail "invalid command [[$peer $*]]" ;;
   esac
 }
@@ -319,7 +295,7 @@ EOF
 #!/bin/sh
 (
   cd "$PWD" || exit 1
-  SCRIPTNAME="$SCRIPTNAME" . ./testlib.sh
+  SCRIPTNAME="$SCRIPTNAME" . "$TESTLIB_PATH"
   $@
   echo "$script,\$$,$TINC_SCRIPT_VARS" >>"$script_log"
 ) >/dev/null 2>&1 || kill -TERM $$
@@ -384,7 +360,7 @@ wait_script() {
   (tail -n +"$line" -f "$script_log" >"$fifo") &
 
   new_line=$(
-    try_limit_time 60 sh -c "
+    sh -c "
       grep -n -m $count '^$script,' <'$fifo'
     " | awk -F: 'END { print $1 }'
   )
@@ -403,12 +379,6 @@ $((line + new_line))
 EOF
 }
 
-# Are we running tests in parallel?
-is_parallel() {
-  # Grep the make flags for any of: '-j', '-j5', '-j 42', but not 'n-j', '-junk'.
-  echo "$MAKEFLAGS" | grep -E -q '(^|[[:space:]])-j[[:digit:]]*([[:space:]]|$)'
-}
-
 # Cleanup after running each script.
 cleanup() {
   (
@@ -420,20 +390,6 @@ cleanup() {
     fi
 
     stop_all_tincs
-
-    # Ask nicely, then kill anything that's left.
-    if is_ci && ! is_parallel; then
-      kill_processes() {
-        signal=$1
-        shift
-        for process in "$@"; do
-          pkill -"SIG$signal" -x -u "$(id -u)" "$process"
-        done
-      }
-      echo >&2 "CI server detected, performing aggressive cleanup"
-      kill_processes TERM tinc tincd
-      kill_processes KILL tinc tincd
-    fi
   ) || true
 }
 
@@ -456,7 +412,7 @@ require_root() {
   else
     # Avoid these kinds of surprises outside CI. Just skip the test.
     echo "root is required for test $SCRIPTNAME, but we're a regular user; skipping"
-    exit $EXIT_SKIP_TEST
+    exit "$EXIT_SKIP_TEST"
   fi
 }
 
@@ -473,9 +429,7 @@ echo [STEP] Check for leftover tinc daemons and test directories
 # Cleanup leftovers from previous runs.
 stop_all_tincs
 
-if [ -d "$DIR_FOO" ]; then rm -rf "$DIR_FOO"; fi
-if [ -d "$DIR_BAR" ]; then rm -rf "$DIR_BAR"; fi
-if [ -d "$DIR_BAZ" ]; then rm -rf "$DIR_BAZ"; fi
+rm -rf "$DIR_FOO" "$DIR_BAR" "$DIR_BAZ"
 
 # Register cleanup function so we don't have to call it everywhere
 # (and failed scripts do not leave stray tincd running).
index 897059d..fffbd8c 100755 (executable)
@@ -1,6 +1,7 @@
 #!/bin/sh
 
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
 
 echo [STEP] Initialize one node