--indent=tab=8
--convert-tabs
---exclude=src/lib
+--exclude=subprojects
+--exclude=build
+--recursive
-i
-j
-f
-xg
-k3
-w
+--formatted
+
/test/*.log
/test/*.trs
/test/splice
-/test/testlib.sh
Makefile
Makefile.in
core*
heaptrack.*
*.tar.gz*
+/subprojects/*
+!/subprojects/*.wrap
+
--- /dev/null
+dir_compl = dir_data / 'bash-completion' / 'completions'
+
+install_data(
+ 'tinc',
+ install_dir: dir_compl,
+)
+
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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)')
+
--- /dev/null
+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
+
--- /dev/null
+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,
+)
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
-
#ifndef HAVE_DAEMON
extern int daemon(int, int);
#endif
--- /dev/null
+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,
+)
+
#include <sys/epoll.h>
#endif
-#include "dropin.h"
#include "event.h"
#include "utils.h"
#include "net.h"
--- /dev/null
+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)
+
#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
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"
--- /dev/null
+#!/bin/sh
+
+git describe --always --tags --match='release-*' "$@" | sed 's/release-//'
--- /dev/null
+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',
+)
+
--- /dev/null
+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
+
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;
--- /dev/null
+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
+
--- /dev/null
+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)
+
#ifdef HAVE_ZLIB
#define ZLIB_CONST
#include <zlib.h>
-#include <assert.h>
#endif
#include LZO1X_H
#endif
-#ifdef LZ4_H
-#include LZ4_H
+#ifdef HAVE_LZ4
+#include <lz4.h>
#endif
#include "address_cache.h"
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 *);
#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;
--- /dev/null
+src_lib_crypto = files(
+ 'crypto.c',
+ 'prf.c',
+)
+
+dep_crypto = dependency('', required: false)
+
+cdata.set('DISABLE_LEGACY', 1)
+
--- /dev/null
+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)
+
--- /dev/null
+src_tincd += files('device.c')
+
#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;
(void)len;
return false;
}
-char *logfilename = NULL;
bool do_detach = false;
struct timeval now;
#include "protocol.h"
#include "sptps.h"
#include "utils.h"
+#include "names.h"
#ifndef HAVE_MINGW
#define closesocket(s) close(s)
return false;
}
-char *logfilename = NULL;
bool do_detach = false;
struct timeval now;
{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"
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "../config.h"
+#include "config.h"
#include "have.h"
#include LZO1X_H
#endif
-#ifdef LZ4_H
-#include LZ4_H
+#ifdef HAVE_LZ4
+#include <lz4.h>
#endif
#ifndef HAVE_MINGW
#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__;
--- /dev/null
+#define GIT_DESCRIPTION "@VCS_TAG@"
+
--- /dev/null
+[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
+
--- /dev/null
+[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
+
--- /dev/null
+[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
+
--- /dev/null
+[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
+
--- /dev/null
+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)
+
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize two nodes
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize and test one node
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
foo_dir=$(peer_directory foo)
foo_host=$foo_dir/hosts/foo
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize one node
#!/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
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 &
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Just test whether the executables work
tincd foo --help
-if [ -e "$SPTPS_TEST" ]; then
- $SPTPS_TEST --help
+if [ -e "$SPTPS_TEST_PATH" ]; then
+ "$SPTPS_TEST_PATH" --help
fi
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize three nodes
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize one node
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize one node
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize one node
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize two nodes
--- /dev/null
+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
+
#!/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
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initializing server node
#!/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
}
) | timeout 10 nc localhost $foo_port
) && exit 1
- test $? = $EXIT_TIMEOUT
+ test $? = "$EXIT_TIMEOUT"
if [ -z "$expected" ]; then
test -z "$result"
#!/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
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
(
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"
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
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() {
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
}
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
}
#!/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 $$
(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 }'
)
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() {
(
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
}
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
}
# 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).
#!/bin/sh
-. ./testlib.sh
+# shellcheck disable=SC1090
+. "$TESTLIB_PATH"
echo [STEP] Initialize one node