origcflags="$CFLAGS"
-AC_PREREQ(2.69)
+AC_PREREQ([2.69])
AC_INIT([tinc], m4_esyscmd_s((git describe || echo UNKNOWN) | sed 's/release-//'))
AC_CONFIG_SRCDIR([src/tincd.c])
AM_INIT_AUTOMAKE([std-options subdir-objects nostdinc silent-rules -Wall])
dnl Checks for programs.
AC_PROG_CC
-AC_PROG_CC_STDC
+AC_PROG_CC_C99
AC_PROG_CPP
AC_PROG_INSTALL
+AC_PROG_LN_S
AM_PROG_CC_C_O
dnl Check whether to enable code coverage testing, and if so, clear the default CFLAGS.
*mingw*)
mingw=true
AC_DEFINE(HAVE_MINGW, 1, [MinGW])
- LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi"
+ LIBS="$LIBS -lws2_32 -lgdi32 -lcrypt32 -liphlpapi -lwinpthread"
LDFLAGS="$LDFLAGS -static"
CPPFLAGS="$CPPFLAGS -DMINIUPNP_STATICLIB"
;;
AC_ARG_ENABLE([hardening], AS_HELP_STRING([--disable-hardening], [disable compiler and linker hardening flags]))
AS_IF([test "x$enable_hardening" != "xno"],
- [AX_CHECK_COMPILE_FLAG([-DFORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -DFORTIFY_SOURCE=2"])
+ [AX_CHECK_COMPILE_FLAG([-D_FORTIFY_SOURCE=2], [CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2"])
AX_CHECK_COMPILE_FLAG([-fwrapv], [CPPFLAGS="$CPPFLAGS -fwrapv"],
AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CPPFLAGS="$CPPFLAGS -fno-strict-overflow"]))
case $host_os in
*mingw*)
AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"])
AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"])
+ AX_CHECK_LINK_FLAG([-lssp], [LDFLAGS="$LDFLAGS -lssp"])
;;
*)
AX_CHECK_COMPILE_FLAG([-fPIE], [CPPFLAGS="$CPPFLAGS -fPIE"])
esac
AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"])
AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"])
+ AX_CHECK_COMPILE_FLAG([-W -Wextra -pedantic -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],
+ [CPPFLAGS="$CPPFLAGS -W -Wextra -pedantic -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"])
]
);
dnl These are defined in files in m4/
-dnl AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], [])
-dnl AC_ARG_WITH(openssl, AC_HELP_STRING([--without-openssl], [disable support for OpenSSL])], [])
+dnl AC_ARG_WITH(libgcrypt, AS_HELP_STRING([--with-libgcrypt], [enable use of libgcrypt instead of OpenSSL])], [])
+dnl AC_ARG_WITH(openssl, AS_HELP_STRING([--without-openssl], [disable support for OpenSSL])], [])
tinc_CURSES
tinc_READLINE
/*
autoconnect.c -- automatic connection establishment
- Copyright (C) 2017 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2017-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "system.h"
+#include "autoconnect.h"
#include "connection.h"
#include "crypto.h"
#include "logger.h"
#include "node.h"
#include "xalloc.h"
-static void make_new_connection() {
+static void make_new_connection(void) {
/* Select a random node we haven't connected to yet. */
uint32_t count = 0;
}
}
-static void connect_to_unreachable() {
+static void connect_to_unreachable(void) {
/* Select a random known node. The rationale is that if there are many
* reachable nodes, and only a few unreachable nodes, we don't want all
* reachable nodes to try to connect to the unreachable ones at the
}
}
-static void drop_superfluous_outgoing_connection() {
+static void drop_superfluous_outgoing_connection(void) {
/* Choose a random outgoing connection to a node that has at least one other connection. */
uint32_t count = 0;
}
}
-static void drop_superfluous_pending_connections() {
+static void drop_superfluous_pending_connections(void) {
for list_each(outgoing_t, o, &outgoing_list) {
/* Only look for connections that are waiting to be retried later. */
bool found = false;
}
}
-void do_autoconnect() {
+void do_autoconnect(void) {
/* Count number of active connections. */
uint32_t nc = 0;
/*
device.c -- Interaction BSD tun/tap device
Copyright (C) 2001-2005 Ivo Timmermans,
- 2001-2021 Guus Sliepen <guus@tinc-vpn.org>
+ 2001-2022 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
This program is free software; you can redistribute it and/or modify
return false;
}
- struct ctl_info info = {};
+ struct ctl_info info;
+
+ memset(&info, 0, sizeof(info));
strlcpy(info.ctl_name, UTUN_CONTROL_NAME, sizeof(info.ctl_name));
#ifndef TUNEMU_H
#define TUNEMU_H
-#include "system.h"
+#include "../system.h"
typedef char tunemu_device[7];
+/*
+ crypto.c -- stub cipher handling functions
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
#include "cipher.h"
#include "xalloc.h"
#ifndef DISABLE_LEGACY
-cipher_t *cipher_alloc() {
+cipher_t *cipher_alloc(void) {
return xzalloc(sizeof(cipher_t));
}
/*
cipher.h -- header file cipher.c
- Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
typedef struct cipher cipher_t;
-extern cipher_t *cipher_alloc() __attribute__((__malloc__));
+extern cipher_t *cipher_alloc(void) __attribute__((__malloc__));
extern void cipher_free(cipher_t **cipher);
extern bool cipher_open_by_name(cipher_t *cipher, const char *name);
extern bool cipher_open_by_nid(cipher_t *cipher, int nid);
1998-2005 Ivo Timmermans
2000 Cris van Pelt
2010-2011 Julien Muchembled <jm@jmuchemb.eu>
- 2000-2021 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
2013 Florent Clairambault <florent@clairambault.fr>
This program is free software; you can redistribute it and/or modify
.delete = (splay_action_t) free_config,
};
-splay_tree_t *create_configuration() {
+splay_tree_t *create_configuration(void) {
splay_tree_t *tree = splay_alloc_tree(NULL, NULL);
init_configuration(tree);
return tree;
splay_insert(config_tree, cfg);
}
-config_t *lookup_config(splay_tree_t *config_tree, char *variable) {
- config_t cfg, *found;
+config_t *lookup_config(splay_tree_t *config_tree, const char *variable) {
+ const config_t cfg = {
+ .variable = (char *)variable,
+ .file = NULL,
+ .line = 0,
+ };
- cfg.variable = variable;
- cfg.file = NULL;
- cfg.line = 0;
-
- found = splay_search_closest_greater(config_tree, &cfg);
+ config_t *found = splay_search_closest_greater(config_tree, &cfg);
if(!found) {
return NULL;
/*
conf.h -- header for conf.c
Copyright (C) 1998-2005 Ivo Timmermans
- 2000-2013 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
extern bool bypass_security;
extern list_t cmdline_conf;
-extern splay_tree_t *create_configuration();
+extern splay_tree_t *create_configuration(void);
extern void init_configuration(splay_tree_t *);
extern void exit_configuration(splay_tree_t **config_tree);
extern config_t *new_config(void) __attribute__((__malloc__));
extern void free_config(config_t *config);
extern void config_add(splay_tree_t *config_tree, config_t *config);
-extern config_t *lookup_config(splay_tree_t *config_tree, char *variable);
+extern config_t *lookup_config(splay_tree_t *config_tree, const char *variable);
extern config_t *lookup_config_next(splay_tree_t *config_tree, const config_t *config);
extern bool get_config_bool(const config_t *config, bool *result);
extern bool get_config_int(const config_t *config, int *result);
#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
typedef struct connection_status_t {
- bool pinged: 1; /* sent ping */
- bool unused_active: 1;
- bool connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */
- bool unused_termreq: 1; /* the termination of this connection was requested */
- bool remove_unused: 1; /* Set to 1 if you want this connection removed */
- bool timeout_unused: 1; /* 1 if gotten timeout */
- bool encryptout: 1; /* 1 if we can encrypt outgoing traffic */
- bool decryptin: 1; /* 1 if we have to decrypt incoming traffic */
- bool mst: 1; /* 1 if this connection is part of a minimum spanning tree */
- bool control: 1; /* 1 if this is a control connection */
- bool pcap: 1; /* 1 if this is a control connection requesting packet capture */
- bool log: 1; /* 1 if this is a control connection requesting log dump */
- bool invitation: 1; /* 1 if this is an invitation */
- bool invitation_used: 1; /* 1 if the invitation has been consumed */
- bool tarpit: 1; /* 1 if the connection should be added to the tarpit */
- uint32_t unused: 17;
+ uint32_t pinged: 1; /* sent ping */
+ uint32_t unused_active: 1;
+ uint32_t connecting: 1; /* 1 if we are waiting for a non-blocking connect() to finish */
+ uint32_t unused_termreq: 1; /* the termination of this connection was requested */
+ uint32_t remove_unused: 1; /* Set to 1 if you want this connection removed */
+ uint32_t timeout_unused: 1; /* 1 if gotten timeout */
+ uint32_t encryptout: 1; /* 1 if we can encrypt outgoing traffic */
+ uint32_t decryptin: 1; /* 1 if we have to decrypt incoming traffic */
+ uint32_t mst: 1; /* 1 if this connection is part of a minimum spanning tree */
+ uint32_t control: 1; /* 1 if this is a control connection */
+ uint32_t pcap: 1; /* 1 if this is a control connection requesting packet capture */
+ uint32_t log: 1; /* 1 if this is a control connection requesting log dump */
+ uint32_t invitation: 1; /* 1 if this is an invitation */
+ uint32_t invitation_used: 1; /* 1 if the invitation has been consumed */
+ uint32_t tarpit: 1; /* 1 if the connection should be added to the tarpit */
} connection_status_t;
#include "ecdsa.h"
+/*
+ digest.c -- stub digest handling functions
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
#include "digest.h"
#include "xalloc.h"
#ifndef DISABLE_LEGACY
-digest_t *digest_alloc() {
+digest_t *digest_alloc(void) {
return xzalloc(sizeof(digest_t));
}
/*
digest.h -- header file digest.c
- Copyright (C) 2007-2016 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
extern bool digest_open_by_name(digest_t *digest, const char *name, size_t maclength);
extern bool digest_open_by_nid(digest_t *digest, int nid, size_t maclength);
-extern digest_t *digest_alloc() __attribute__((__malloc__));
+extern digest_t *digest_alloc(void) __attribute__((__malloc__));
extern void digest_free(digest_t **digest);
extern void digest_close(digest_t *digest);
extern bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) __attribute__((__warn_unused_result__));
/*
dropin.c -- a set of drop-in replacements for libc functions
Copyright (C) 2000-2005 Ivo Timmermans,
- 2000-2018 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return 0;
}
#endif
-
-#ifndef HAVE_NANOSLEEP
-int nanosleep(const struct timespec *req, struct timespec *rem) {
- (void)rem;
- struct timeval tv = {req->tv_sec, req->tv_nsec / 1000};
- return select(0, NULL, NULL, NULL, &tv);
-}
-#endif
/*
dropin.h -- header file for dropin.c
Copyright (C) 2000-2005 Ivo Timmermans,
- 2000-2016 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
extern int gettimeofday(struct timeval *, void *);
#endif
-#ifndef HAVE_NANOSLEEP
-extern int nanosleep(const struct timespec *req, struct timespec *rem);
-#endif
-
#ifndef timeradd
#define timeradd(a, b, r) do {\
(r)->tv_sec = (a)->tv_sec + (b)->tv_sec;\
size_t len = strlen(p);
if(len != 43) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %zu for public key!", len);
+ logger(DEBUG_ALWAYS, LOG_ERR, "Invalid size %lu for public key!", (unsigned long)len);
return 0;
}
len = b64decode_tinc(p, ecdsa->public, len);
if(len != 32) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %zu", len);
+ logger(DEBUG_ALWAYS, LOG_ERR, "Invalid format of public key! len = %lu", (unsigned long)len);
free(ecdsa);
return 0;
}
/*
event.c -- I/O, timeout and signal event handling
- Copyright (C) 2012-2021 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2012-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
#include "system.h"
-#include "dropin.h"
+
+#include <assert.h>
#ifdef HAVE_SYS_EPOLL_H
#include <sys/epoll.h>
#endif
+#include "dropin.h"
#include "event.h"
#include "utils.h"
#include "net.h"
static bool running;
#ifdef HAVE_SYS_EPOLL_H
-static inline int event_epoll_init() {
+static inline int event_epoll_init(void) {
/* NOTE: 1024 limit is only used on ancient (pre 2.6.27) kernels.
Decent kernels will ignore this value making it unlimited.
epoll_create1 might be better, but these kernels would not be supported
static io_t signalio;
static int pipefd[2] = {-1, -1};
-static signal_t *signal_handle[NSIG + 1] = {};
+static signal_t *signal_handle[NSIG + 1] = {NULL};
static void signal_handler(int signum) {
unsigned char num = signum;
- write(pipefd[1], &num, 1);
+
+ if(write(pipefd[1], &num, 1) != 1) {
+ // Pipe full or broken, nothing we can do about it.
+ }
}
static void signalio_handler(void *data, int flags) {
}
#else
+ assert(WSA_WAIT_EVENT_0 == 0);
while(running) {
struct timeval diff;
break;
}
- if(result < WSA_WAIT_EVENT_0 || result >= WSA_WAIT_EVENT_0 + event_count - event_offset) {
+ if(result >= event_count - event_offset) {
return false;
}
/* Look up io in the map by index. */
- event_index = result - WSA_WAIT_EVENT_0 + event_offset;
+ event_index = result + event_offset;
io_t *io = io_map[event_index];
if(io->fd == -1) {
/*
fd_device.c -- Interaction with Android tun fd
Copyright (C) 2001-2005 Ivo Timmermans,
- 2001-2021 Guus Sliepen <guus@tinc-vpn.org>
+ 2001-2022 Guus Sliepen <guus@tinc-vpn.org>
2009 Grzegorz Dymarek <gregd72002@googlemail.com>
2016-2020 Pacien TRAN-GIRARD <pacien@pacien.net>
msg.msg_controllen = sizeof(cmsgbuf);
if((ret = recvmsg(socket, &msg, 0)) < 1) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Could not read from unix socket (error %zd)!", ret);
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not read from unix socket (error %ld)!", (long)ret);
return -1;
}
}
if(cmsgptr->cmsg_len != CMSG_LEN(sizeof(device_fd))) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG data length: %zu, expected %zu!",
- cmsgptr->cmsg_len, CMSG_LEN(sizeof(device_fd)));
+ logger(DEBUG_ALWAYS, LOG_ERR, "Wrong CMSG data length: %lu, expected %lu!",
+ (unsigned long)cmsgptr->cmsg_len, (unsigned long)CMSG_LEN(sizeof(device_fd)));
return -1;
}
/*
fsck.c -- Check the configuration files for problems
- Copyright (C) 2014-2021 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2014-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#ifdef HAVE_MINGW
typedef int uid_t;
-static uid_t getuid() {
+static uid_t getuid(void) {
return 0;
}
}
#endif // HAVE_MINGW
-static char *read_node_name() {
+static char *read_node_name(void) {
if(access(tinc_conf, R_OK) == 0) {
return get_my_name(true);
}
return true;
}
-static bool check_script_confdir() {
+static bool check_script_confdir(void) {
char fname[PATH_MAX];
DIR *dir = opendir(confbase);
}
}
-static bool check_scripts_and_configs() {
+static bool check_scripts_and_configs(void) {
// Check whether scripts are executable.
if(!check_script_confdir()) {
return false;
/*
cipher.c -- Symmetric block cipher handling
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
+#include "../system.h"
#include "cipher.h"
-#include "logger.h"
-#include "xalloc.h"
+#include "../cipher.h"
+#include "../logger.h"
+#include "../xalloc.h"
static struct {
const char *name;
};
static bool nametocipher(const char *name, int *algo, int *mode) {
- size_t i;
-
- for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
+ for(size_t i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(ciphertable[i].name && !strcasecmp(name, ciphertable[i].name)) {
*algo = ciphertable[i].algo;
*mode = ciphertable[i].mode;
}
static bool nidtocipher(int nid, int *algo, int *mode) {
- size_t i;
-
- for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
+ for(size_t i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(nid == ciphertable[i].nid) {
*algo = ciphertable[i].algo;
*mode = ciphertable[i].mode;
}
static bool ciphertonid(int algo, int mode, int *nid) {
- size_t i;
-
- for(i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
+ for(size_t i = 0; i < sizeof(ciphertable) / sizeof(*ciphertable); i++) {
if(algo == ciphertable[i].algo && mode == ciphertable[i].mode) {
*nid = ciphertable[i].nid;
return true;
return cipher_open(cipher, algo, mode);
}
-bool cipher_open_blowfish_ofb(cipher_t *cipher) {
- return cipher_open(cipher, GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB);
-}
-
void cipher_close(cipher_t *cipher) {
if(cipher->handle) {
gcry_cipher_close(cipher->handle);
return cipher->blklen;
}
-void cipher_get_key(const cipher_t *cipher, void *key) {
- memcpy(key, cipher->key, cipher->keylen + cipher->blklen);
-}
-
bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) {
+ (void)encrypt;
+
memcpy(cipher->key, key, cipher->keylen + cipher->blklen);
gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen);
}
bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) {
- memcpy(cipher->key,
- key + len - cipher->keylen,
- cipher->keylen);
- gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen);
-
- memcpy(cipher->key + cipher->keylen,
- key + len - cipher->blklen - cipher->keylen,
- cipher->blklen);
- gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
-
- return true;
-}
-
-bool cipher_regenerate_key(cipher_t *cipher, bool encrypt) {
- gcry_create_nonce(cipher->key, cipher->keylen + cipher->blklen);
+ (void)encrypt;
+ memcpy(cipher->key, (char *)key + len - cipher->keylen, cipher->keylen);
gcry_cipher_setkey(cipher->handle, cipher->key, cipher->keylen);
+
+ memcpy((char *)cipher->key + cipher->keylen, (char *)key + len - cipher->blklen - cipher->keylen, cipher->blklen);
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
return true;
}
if(cipher->padding) {
- if((err = gcry_cipher_encrypt(cipher->handle, outdata + inlen, cipher->blklen, pad, cipher->blklen))) {
+ if((err = gcry_cipher_encrypt(cipher->handle, (char *)outdata + inlen, cipher->blklen, pad, cipher->blklen))) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", gcry_strerror(err));
return false;
}
/*
cipher.h -- header file cipher.c
- Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
+#include "../system.h"
#include <gcrypt.h>
-#define CIPHER_MAX_BLOCK_SIZE 32
-#define CIPHER_MAX_IV_SIZE 16
-#define CIPHER_MAX_KEY_SIZE 32
-
-typedef struct cipher {
+struct cipher {
gcry_cipher_hd_t handle;
uint8_t *key;
int nid;
uint16_t keylen;
uint16_t blklen;
bool padding;
-} cipher_t;
-
-extern bool cipher_open_by_name(struct cipher *, const char *);
-extern bool cipher_open_by_nid(struct cipher *, int);
-extern bool cipher_open_blowfish_ofb(struct cipher *);
-extern void cipher_close(struct cipher *);
-extern size_t cipher_keylength(const struct cipher *);
-extern void cipher_get_key(const struct cipher *, void *);
-extern bool cipher_set_key(struct cipher *, void *, bool);
-extern bool cipher_set_key_from_rsa(struct cipher *, void *, size_t, bool);
-extern bool cipher_regenerate_key(struct cipher *, bool);
-extern bool cipher_encrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot);
-extern bool cipher_decrypt(struct cipher *, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot);
-extern int cipher_get_nid(const struct cipher *);
-extern bool cipher_active(const struct cipher *);
+};
#endif
/*
crypto.c -- Cryptographic miscellaneous functions and initialisation
- Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
+#include "../system.h"
#include <gcrypt.h>
-#include "crypto.h"
+#include "../crypto.h"
-void crypto_init() {
+void crypto_init(void) {
}
-void crypto_exit() {
+void crypto_exit(void) {
}
void randomize(void *out, size_t outlen) {
+++ /dev/null
-#ifndef TINC_GCRYPT_CRYPTO_H
-#define TINC_GCRYPT_CRYPTO_H
-
-/*
- crypto.h -- header for crypto.c
- Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-extern void crypto_init();
-extern void crypto_exit();
-extern void randomize(void *, size_t);
-
-#endif
/*
digest.c -- Digest handling
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
+#include "../system.h"
#include "digest.h"
-#include "logger.h"
+#include "../digest.h"
+#include "../logger.h"
static struct {
const char *name;
};
static bool nametodigest(const char *name, enum gcry_md_algos *algo) {
- int i;
-
- for(i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
+ for(size_t i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(digesttable[i].name && !strcasecmp(name, digesttable[i].name)) {
*algo = digesttable[i].algo;
return true;
}
static bool nidtodigest(int nid, enum gcry_md_algos *algo) {
- for(int i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
+ for(size_t i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(nid == digesttable[i].nid) {
*algo = digesttable[i].algo;
return true;
}
static bool digesttonid(enum gcry_md_algos algo, int *nid) {
- for(int i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
+ for(size_t i = 0; i < sizeof(digesttable) / sizeof(*digesttable); i++) {
if(algo == digesttable[i].algo) {
*nid = digesttable[i].nid;
return true;
unsigned int len = gcry_md_get_algo_dlen(algo);
- if(maclength > len || maclength < 0) {
+ if(maclength > len) {
digest->maclength = len;
} else {
digest->maclength = maclength;
return digest_open(digest, algo, maclength);
}
-bool digest_open_sha1(digest_t *digest, size_t maclength) {
- return digest_open(digest, GCRY_MD_SHA1, maclength);
-}
-
void digest_close(digest_t *digest) {
if(digest->hmac) {
gcry_md_close(digest->hmac);
/*
digest.h -- header file digest.c
- Copyright (C) 2007-2009 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <gcrypt.h>
-#define DIGEST_MAX_SIZE 64
-
typedef struct digest {
enum gcry_md_algos algo;
int nid;
gcry_md_hd_t hmac;
} digest_t;
-extern bool digest_open_by_name(struct digest *, const char *name, size_t maclength);
-extern bool digest_open_by_nid(struct digest *, int nid, size_t maclength);
-extern bool digest_open_sha1(struct digest *, size_t maclength);
-extern void digest_close(struct digest *);
-extern bool digest_create(struct digest *, const void *indata, size_t inlen, void *outdata);
-extern bool digest_verify(struct digest *, const void *indata, size_t inlen, const void *digestdata);
-extern bool digest_set_key(struct digest *, const void *key, size_t len);
-extern int digest_get_nid(const struct digest *);
-extern size_t digest_length(const struct digest *);
-extern bool digest_active(const struct digest *);
-
#endif
+/*
+ pem.c -- PEM encoding and decoding
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "../system.h"
+
#include "pem.h"
-#include "utils.h"
+#include "../utils.h"
// Base64 decoding table
// Heavily based on code by Jouni Malinen <j@w1.fi>
// https://web.mit.edu/freebsd/head/contrib/wpa/src/utils/base64.c
static size_t b64encode(char *dst, const void *src, const size_t length) {
- const uint8_t *end = src + length;
+ const uint8_t *end = (const uint8_t *)src + length;
const uint8_t *in = src;
char *pos = dst;
#ifndef TINC_GCRYPT_PEM_H
#define TINC_GCRYPT_PEM_H
+/*
+ pem.h -- PEM encoding and decoding
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
#include "../system.h"
bool pem_decode(FILE *fp, const char *header, uint8_t *buf, size_t size, size_t *outsize);
/*
rsa.c -- RSA key handling
- Copyright (C) 2007-2012 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
+#include "../system.h"
#include <gcrypt.h>
-#include "logger.h"
-#include "rsa.h"
#include "pem.h"
-#include "xalloc.h"
+
+#include "rsa.h"
+#include "../logger.h"
+#include "../rsa.h"
+#include "../xalloc.h"
// BER decoding functions
if(**p & 0x80) {
size_t result = 0;
- int len = *(*p)++ & 0x7f;
+ size_t len = *(*p)++ & 0x7f;
(*buflen)--;
if(len > *buflen) {
return mpi ? !err : true;
}
-rsa_t *rsa_set_hex_public_key(char *n, char *e) {
+rsa_t *rsa_set_hex_public_key(const char *n, const char *e) {
rsa_t *rsa = xzalloc(sizeof(rsa_t));
- gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL)
- ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL);
+ gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL);
+
+ if(!err) {
+ err = gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL);
+ }
if(err) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno));
return rsa;
}
-rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) {
+rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) {
rsa_t *rsa = xzalloc(sizeof(rsa_t));
- gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL)
- ? : gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL)
- ? : gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL);
+ gcry_error_t err = gcry_mpi_scan(&rsa->n, GCRYMPI_FMT_HEX, n, 0, NULL);
+
+ if(!err) {
+ err = gcry_mpi_scan(&rsa->e, GCRYMPI_FMT_HEX, e, 0, NULL);
+ }
+
+ if(!err) {
+ err = gcry_mpi_scan(&rsa->d, GCRYMPI_FMT_HEX, d, 0, NULL);
+ }
if(err) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while reading RSA public key: %s", gcry_strerror(errno));
return rsa;
}
-size_t rsa_size(rsa_t *rsa) {
+size_t rsa_size(const rsa_t *rsa) {
return (gcry_mpi_get_nbits(rsa->n) + 7) / 8;
}
// TODO: get rid of this macro, properly clean up gcry_ structures after use
#define check(foo) { gcry_error_t err = (foo); if(err) {logger(DEBUG_ALWAYS, LOG_ERR, "gcrypt error %s/%s at %s:%d", gcry_strsource(err), gcry_strerror(err), __FILE__, __LINE__); return false; }}
-bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
+bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) {
gcry_mpi_t inmpi;
check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL));
size_t out_bytes = (gcry_mpi_get_nbits(outmpi) + 7) / 8;
size_t pad = len - MIN(out_bytes, len);
+ unsigned char *pout = out;
for(; pad; --pad) {
- *(char *)out++ = 0;
+ *pout++ = 0;
}
- check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
+ check(gcry_mpi_print(GCRYMPI_FMT_USG, pout, len, NULL, outmpi));
return true;
}
-bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
+bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) {
gcry_mpi_t inmpi;
check(gcry_mpi_scan(&inmpi, GCRYMPI_FMT_USG, in, len, NULL));
gcry_mpi_powm(outmpi, inmpi, rsa->d, rsa->n);
size_t pad = len - (gcry_mpi_get_nbits(outmpi) + 7) / 8;
+ unsigned char *pout = out;
for(; pad; --pad) {
- *(char *)out++ = 0;
+ *pout++ = 0;
}
- check(gcry_mpi_print(GCRYMPI_FMT_USG, out, len, NULL, outmpi));
+ check(gcry_mpi_print(GCRYMPI_FMT_USG, pout, len, NULL, outmpi));
return true;
}
/*
rsa.h -- RSA key handling
- Copyright (C) 2007 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <gcrypt.h>
+#define TINC_RSA_INTERNAL
typedef struct rsa {
gcry_mpi_t n;
gcry_mpi_t e;
/*
rsagen.c -- RSA key generation and export
- Copyright (C) 2008-2012 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2008-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "system.h"
+#include "../system.h"
#include <gcrypt.h>
#include <assert.h>
-#include "../rsagen.h"
-#include "xalloc.h"
#include "rsa.h"
#include "pem.h"
+#include "../rsagen.h"
+#include "../xalloc.h"
// ASN.1 tags.
typedef enum {
der += len;
}
- assert(der - derbuf == derlen);
+ assert((size_t)(der - derbuf) == derlen);
return derlen;
}
/*
hash.h -- header file for hash.c
- Copyright (C) 2012 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2012-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
t keys[n]; \
const void *values[n]; \
} hash_ ## t; \
- static uint32_t inline hash_modulo_ ## t(uint32_t hash) { \
+ static inline uint32_t hash_modulo_ ## t(uint32_t hash) { \
return hash & (n - 1); \
} \
- void hash_insert_ ## t (hash_ ##t *hash, const t *key, const void *value) { \
+ static inline void hash_insert_ ## t (hash_ ##t *hash, const t *key, const void *value) { \
uint32_t i = hash_modulo_ ## t(hash_function_ ## t(key)); \
for(uint8_t f=0; f< (HASH_SEARCH_ITERATIONS - 1); f++){ \
if(hash->values[i] == NULL || !memcmp(key, &hash->keys[i], sizeof(t))) { \
memcpy(&hash->keys[i], key, sizeof(t)); \
hash->values[i] = value; \
} \
- void *hash_search_ ## t (const hash_ ##t *hash, const t *key) { \
+ static inline void *hash_search_ ## t (const hash_ ##t *hash, const t *key) { \
uint32_t i = hash_modulo_ ## t(hash_function_ ## t(key)); \
for(uint8_t f=0; f<HASH_SEARCH_ITERATIONS; f++){ \
if(!memcmp(key, &hash->keys[i], sizeof(t))) { \
} \
return NULL; \
} \
- void hash_delete_ ## t (hash_ ##t *hash, const t *key) { \
+ static inline void hash_delete_ ## t (hash_ ##t *hash, const t *key) { \
uint32_t i = hash_modulo_ ## t(hash_function_ ## t(key)); \
for(uint8_t f=0; f<HASH_SEARCH_ITERATIONS; f++){ \
if(!memcmp(key, &hash->keys[i], sizeof(t))) { \
if(++i == n) i = 0; \
} \
} \
- void hash_clear_ ## t(hash_ ##t *hash) { \
+ static inline void hash_clear_ ## t(hash_ ##t *hash) { \
memset(hash->values, 0, n * sizeof(*hash->values)); \
memset(hash->keys, 0, n * sizeof(*hash->keys)); \
}
*/
#ifdef HAVE_MINGW
-#define WINVER WindowsXP
+#define WINVER 0x0600
+#define _WIN32_WINNT 0x0600
#define WIN32_LEAN_AND_MEAN
#endif
/*
info.c -- Show information about a node, subnet or address
- Copyright (C) 2012-2017 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2012-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "system.h"
#include "control_common.h"
+#include "info.h"
+#include "logger.h"
#include "subnet.h"
#include "tincctl.h"
-#include "info.h"
#include "utils.h"
void logger(int level, int priority, const char *format, ...) {
/*
invitation.c -- Create and accept invitations
- Copyright (C) 2013-2017 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2013-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
fclose(f);
}
-char *get_my_hostname() {
+static char *get_my_hostname(void) {
char *hostname = NULL;
char *port = NULL;
char *hostport = NULL;
}
static int sock;
-static char cookie[18];
+static char cookie[18], hash[18];
static sptps_t sptps;
static char *data;
static size_t datalen;
static bool success = false;
-static char cookie[18], hash[18];
-
static char *get_line(const char **data) {
if(!data || !*data) {
return NULL;
static bool invitation_send(void *handle, uint8_t type, const void *vdata, size_t len) {
(void)handle;
(void)type;
- const uint8_t *data = vdata;
+ const char *data = vdata;
while(len) {
ssize_t result = send(sock, data, len, 0);
}
if(!port || !*port) {
- port = "655";
+ static char default_port[] = "655";
+ port = default_port;
}
if(!b64decode_tinc(slash, hash, 24) || !b64decode_tinc(slash + 24, cookie, 24)) {
/*
invitation.h -- header for invitation.c.
- Copyright (C) 2013 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2013-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/*
logger.c -- logging code
- Copyright (C) 2004-2017 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2004-2022 Guus Sliepen <guus@tinc-vpn.org>
2004-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
}
if(umbilical && do_detach) {
- write(umbilical, message, strlen(message));
- write(umbilical, "\n", 1);
+ size_t len = strlen(message);
+
+ if(write(umbilical, message, len) != (ssize_t)len || write(umbilical, "\n", 1) != 1) {
+ // Other end broken, nothing we can do about it.
+ }
}
}
size_t len = strlen(message);
- if(send_request(c, "%d %d %zu", CONTROL, REQ_LOG, len)) {
+ if(send_request(c, "%d %d %lu", CONTROL, REQ_LOG, (unsigned long)len)) {
send_meta(c, message, len);
}
}
}
}
-void reopenlogger() {
+void reopenlogger(void) {
if(logmode != LOGMODE_FILE) {
return;
}
abort();
}
- logger(DEBUG_META, LOG_DEBUG, "Sending %zu bytes of metadata to %s (%s)",
- length, c->name, c->hostname);
+ logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of metadata to %s (%s)",
+ (unsigned long)length, c->name, c->hostname);
if(c->protocol_minor >= 2) {
return sptps_send_record(&c->sptps, 0, buffer, length);
abort();
}
- logger(DEBUG_META, LOG_DEBUG, "Sending %zu bytes of raw metadata to %s (%s)",
- length, c->name, c->hostname);
+ logger(DEBUG_META, LOG_DEBUG, "Sending %lu bytes of raw metadata to %s (%s)",
+ (unsigned long)length, c->name, c->hostname);
buffer_add(&c->outbuf, buffer, length);
/*
device.c -- Interaction with Windows tap driver in a MinGW environment
Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2018 Guus Sliepen <guus@tinc-vpn.org>
+ 2002-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
char *iface = NULL;
static const char *device_info = "Windows tap device";
-extern char *myport;
-
-static void device_issue_read() {
+static void device_issue_read(void) {
int status;
for(;;) {
}
if(!memcmp(&ignore_src, DATA(packet) + 6, sizeof(ignore_src))) {
- logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %zd bytes from %s", lenin, device_info);
+ logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Ignoring loopback packet of %ld bytes from %s", (long)lenin, device_info);
return false;
}
/*
net_packet.c -- Handles in- and outgoing VPN packets
Copyright (C) 1998-2005 Ivo Timmermans,
- 2000-2021 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
2010 Timothy Redaelli <timothy@redaelli.eu>
2010 Brandon Black <blblack@gmail.com>
overhead += sizeof(to->id) + sizeof(from->id);
}
- uint8_t buf[len + overhead];
- uint8_t *buf_ptr = buf;
+ char buf[len + overhead];
+ char *buf_ptr = buf;
if(relay_supported) {
if(direct) {
vpn_packet_t packet;
if(len > sizeof(packet.data)) {
- logger(DEBUG_TRAFFIC, LOG_INFO, "Truncating probe length %zu to %s (%s)", len, n->name, n->hostname);
+ logger(DEBUG_TRAFFIC, LOG_INFO, "Truncating probe length %lu to %s (%s)", (unsigned long)len, n->name, n->hostname);
len = sizeof(packet.data);
}
packet.len = len;
packet.priority = 0;
- logger(DEBUG_TRAFFIC, LOG_INFO, "Sending UDP probe length %zu to %s (%s)", len, n->name, n->hostname);
+ logger(DEBUG_TRAFFIC, LOG_INFO, "Sending UDP probe length %lu to %s (%s)", (unsigned long)len, n->name, n->hostname);
send_udppacket(n, &packet);
}
int ip_mtu;
socklen_t ip_mtu_len = sizeof(ip_mtu);
- if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) {
+ if(getsockopt(sock, IPPROTO_IP, IP_MTU, (void *)&ip_mtu, &ip_mtu_len)) {
logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno));
close(sock);
return MTU;
on the precise MTU as we are approaching it.
The last probe of the cycle is always 1 byte in size - this is to make sure we'll get at least one
reply per cycle so that we can make progress. */
- offset = (length_t) powf(interval, multiplier * cycle_position / ((float) probes_per_cycle - 1.0f));
+ offset = lrintf(powf(interval, multiplier * cycle_position / (float)(probes_per_cycle - 1)));
}
length_t maxmtu = n->maxmtu;
}
id[sizeof(id) - 1] = 0;
- send_request(c, "%d %d %s %s %s %d %d %zu %d %x %x %s %s %d %d %d %d %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_NODES,
+ send_request(c, "%d %d %s %s %s %d %d %lu %d %x %x %s %s %d %d %d %d %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, CONTROL, REQ_DUMP_NODES,
n->name, id, n->hostname ? n->hostname : "unknown port unknown",
#ifdef DISABLE_LEGACY
0, 0, 0UL,
#else
- cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), digest_length(n->outdigest),
+ cipher_get_nid(n->outcipher), digest_get_nid(n->outdigest), (unsigned long)digest_length(n->outdigest),
#endif
n->outcompression, n->options, bitfield_to_int(&n->status, sizeof(n->status)),
n->nexthop ? n->nexthop->name : "-", n->via && n->via->name ? n->via->name : "-", n->distance,
#include "subnet.h"
typedef struct node_status_t {
- bool unused_active: 1; /* 1 if active (not used for nodes) */
- bool validkey: 1; /* 1 if we currently have a valid key for him */
- bool waitingforkey: 1; /* 1 if we already sent out a request */
- bool visited: 1; /* 1 if this node has been visited by one of the graph algorithms */
- bool reachable: 1; /* 1 if this node is reachable in the graph */
- bool indirect: 1; /* 1 if this node is not directly reachable by us */
- bool sptps: 1; /* 1 if this node supports SPTPS */
- bool udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */
- bool send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */
- bool udppacket: 1; /* 1 if the most recently received packet was UDP */
- bool validkey_in: 1; /* 1 if we have sent a valid key to him */
- bool has_address: 1; /* 1 if we know an external address for this node */
- bool ping_sent: 1; /* 1 if we sent a UDP probe but haven't received the reply yet */
- uint32_t unused: 19;
+ uint32_t unused_active: 1; /* 1 if active (not used for nodes) */
+ uint32_t validkey: 1; /* 1 if we currently have a valid key for him */
+ uint32_t waitingforkey: 1; /* 1 if we already sent out a request */
+ uint32_t visited: 1; /* 1 if this node has been visited by one of the graph algorithms */
+ uint32_t reachable: 1; /* 1 if this node is reachable in the graph */
+ uint32_t indirect: 1; /* 1 if this node is not directly reachable by us */
+ uint32_t sptps: 1; /* 1 if this node supports SPTPS */
+ uint32_t udp_confirmed: 1; /* 1 if the address is one that we received UDP traffic on */
+ uint32_t send_locally: 1; /* 1 if the next UDP packet should be sent on the local network */
+ uint32_t udppacket: 1; /* 1 if the most recently received packet was UDP */
+ uint32_t validkey_in: 1; /* 1 if we have sent a valid key to him */
+ uint32_t has_address: 1; /* 1 if we know an external address for this node */
+ uint32_t ping_sent: 1; /* 1 if we sent a UDP probe but haven't received the reply yet */
} node_status_t;
typedef struct node_t {
#include <wincrypt.h>
HCRYPTPROV prov;
-void random_init(void) {
+static void random_init(void) {
if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
fprintf(stderr, "CryptAcquireContext() failed!\n");
abort();
}
}
-void random_exit(void) {
+static void random_exit(void) {
CryptReleaseContext(prov, 0);
}
/*
cipher.c -- Symmetric block cipher handling
- Copyright (C) 2007-2017 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <openssl/err.h>
#include <openssl/evp.h>
+#include "cipher.h"
#include "../cipher.h"
#include "../logger.h"
#ifndef TINC_OPENSSL_CIPHER_H
#define TINC_OPENSSL_CIPHER_H
+/*
+ cipher.h -- header file cipher.c
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
#include <openssl/evp.h>
struct cipher {
#include <wincrypt.h>
HCRYPTPROV prov;
-void random_init(void) {
+static void random_init(void) {
if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
fprintf(stderr, "CryptAcquireContext() failed!\n");
abort();
}
}
-void random_exit(void) {
+static void random_exit(void) {
CryptReleaseContext(prov, 0);
}
/*
digest.h -- header file digest.c
- Copyright (C) 2013 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2013-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/*
rsa.c -- RSA key handling
- Copyright (C) 2007-2021 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
// Set RSA keys
-rsa_t *rsa_set_hex_public_key(char *n, char *e) {
+rsa_t *rsa_set_hex_public_key(const char *n, const char *e) {
BIGNUM *bn_n = NULL;
BIGNUM *bn_e = NULL;
return rsa;
}
-rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) {
+rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) {
BIGNUM *bn_n = NULL;
BIGNUM *bn_e = NULL;
BIGNUM *bn_d = NULL;
return RSA_size(rsa);
}
-bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) {
+bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) {
if((size_t)RSA_public_encrypt((int) len, in, out, rsa, RSA_NO_PADDING) == len) {
return true;
}
return false;
}
-bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
+bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) {
if((size_t)RSA_private_decrypt((int) len, in, out, rsa, RSA_NO_PADDING) == len) {
return true;
}
/*
rsagen.c -- RSA key generation and export
- Copyright (C) 2008-2013 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2008-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "system.h"
+
#include <openssl/pem.h>
#include <openssl/err.h>
static bool install_service(void) {
char command[4096] = "\"";
- SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"};
+ char description_buffer[] = "Virtual Private Network daemon";
+ SERVICE_DESCRIPTION description = {description_buffer};
manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
io_t stop_io;
-DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID data, LPVOID context) {
+static DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID data, LPVOID context) {
(void)type;
(void)data;
(void)context;
return NO_ERROR;
}
-VOID WINAPI run_service(DWORD argc, LPTSTR *argv) {
+static VOID WINAPI run_service(DWORD argc, LPTSTR *argv) {
extern int main2(int argc, char **argv);
status.dwServiceType = SERVICE_WIN32;
/*
protocol.c -- handle the meta-protocol, basic functions
Copyright (C) 1999-2005 Ivo Timmermans,
- 2000-2013 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/* Request names */
-static char (*request_name[]) = {
+static const char (*request_name[]) = {
"ID", "METAKEY", "CHALLENGE", "CHAL_REPLY", "ACK",
"STATUS", "ERROR", "TERMREQ",
"PING", "PONG",
/*
protocol_auth.c -- handle the meta-protocol, authentication
Copyright (C) 1999-2005 Ivo Timmermans,
- 2000-2017 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
// Read the new node's Name from the file
char buf[1024] = "";
- fgets(buf, sizeof(buf), f);
+
+ if(!fgets(buf, sizeof(buf), f)) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not read invitation file %s\n", cookie);
+ return false;
+ }
+
size_t buflen = strlen(buf);
// Strip whitespace at the end
to->status.validkey_in = true;
- return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY,
+ return send_request(to->nexthop->connection, "%d %s %s %s %d %d %lu %d", ANS_KEY,
myself->name, to->name, key,
cipher_get_nid(to->incipher),
digest_get_nid(to->indigest),
- digest_length(to->indigest),
+ (unsigned long)digest_length(to->indigest),
to->incompression);
#endif
}
char address[MAX_STRING_SIZE] = "";
char port[MAX_STRING_SIZE] = "";
int cipher, digest;
- size_t maclength;
+ unsigned long maclength;
int compression;
node_t *from, *to;
- if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %zu %d "MAX_STRING" "MAX_STRING,
+ if(sscanf(request, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %d %d %lu %d "MAX_STRING" "MAX_STRING,
from_name, to_name, key, &cipher, &digest, &maclength,
&compression, address, port) < 7) {
logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ANS_KEY", c->name,
/*
protocol_misc.c -- handle the meta-protocol, miscellaneous functions
Copyright (C) 1999-2005 Ivo Timmermans,
- 2000-2013 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
}
static bool random_early_drop(connection_t *c) {
- if(c->outbuf.len > maxoutbufsize / 2) {
- if((c->outbuf.len - maxoutbufsize / 2) > prng((maxoutbufsize) / 2)) {
+ if(c->outbuf.len > (size_t)maxoutbufsize / 2) {
+ if((c->outbuf.len - (size_t)maxoutbufsize / 2) > prng((size_t)maxoutbufsize / 2)) {
return true;
}
}
return true;
}
- if(!send_request(c, "%d %zu", SPTPS_PACKET, len)) {
+ if(!send_request(c, "%d %lu", SPTPS_PACKET, (unsigned long)len)) {
return false;
}
todo = ntohs(ip.ip_len) - ip_size;
if(ether_size + ip_size + todo != packet->len) {
- logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%zu)", packet->len, ether_size + ip_size + todo);
+ logger(DEBUG_TRAFFIC, LOG_WARNING, "Length of packet (%d) doesn't match length in IPv4 header (%lu)", packet->len, (unsigned long)(ether_size + ip_size + todo));
return;
}
/*
rsa.h -- RSA key handling
- Copyright (C) 2007-2013 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#endif
extern void rsa_free(rsa_t *rsa);
-extern rsa_t *rsa_set_hex_public_key(char *n, char *e) __attribute__((__malloc__));
-extern rsa_t *rsa_set_hex_private_key(char *n, char *e, char *d) __attribute__((__malloc__));
+extern rsa_t *rsa_set_hex_public_key(const char *n, const char *e) __attribute__((__malloc__));
+extern rsa_t *rsa_set_hex_private_key(const char *n, const char *e, const char *d) __attribute__((__malloc__));
extern rsa_t *rsa_read_pem_public_key(FILE *fp) __attribute__((__malloc__));
extern rsa_t *rsa_read_pem_private_key(FILE *fp) __attribute__((__malloc__));
extern size_t rsa_size(const rsa_t *rsa);
-extern bool rsa_public_encrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__));
-extern bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) __attribute__((__warn_unused_result__));
+extern bool rsa_public_encrypt(rsa_t *rsa, const void *in, size_t len, void *out) __attribute__((__warn_unused_result__));
+extern bool rsa_private_decrypt(rsa_t *rsa, const void *in, size_t len, void *out) __attribute__((__warn_unused_result__));
#endif
/*
script.c -- call an external script
Copyright (C) 1999-2005 Ivo Timmermans,
- 2000-2018 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
if(format) {
va_list ap;
va_start(ap, format);
- vasprintf(&env->entries[env->n], format, ap);
+
+ if(vasprintf(&env->entries[env->n], format, ap) == -1) {
+ // Assume we are out of memory.
+ abort();
+ }
+
va_end(ap);
} else {
env->entries[env->n] = NULL;
free(env->entries[pos]);
va_list ap;
va_start(ap, format);
- vasprintf(&env->entries[pos], format, ap);
+
+ if(vasprintf(&env->entries[pos], format, ap) == -1) {
+ abort();
+ }
+
va_end(ap);
}
device.c -- Interaction with Solaris tun device
Copyright (C) 2001-2005 Ivo Timmermans,
2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- 2001-2014 Guus Sliepen <guus@tinc-vpn.org>
+ 2001-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
{
/* Remove muxes just in case they are left over from a crashed tincd */
- struct lifreq ifr = {};
+ struct lifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name));
if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) {
int arp_fd = -1;
if(device_type == DEVICE_TYPE_TAP) {
- struct lifreq ifr = {};
+ struct lifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
if(ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not set flags on %s %s!", device_info, device);
close(arp_fd);
}
- struct lifreq ifr = {};
+ struct lifreq ifr;
+
+ memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name));
static void close_device(void) {
if(iface) {
- struct lifreq ifr = {};
+ struct lifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.lifr_name, iface, sizeof(ifr.lifr_name));
if(ioctl(ip_fd, SIOCGLIFMUXID, &ifr) >= 0) {
/*
sptps_test.c -- Simple Peer-to-Peer Security test program
- Copyright (C) 2011-2013 Guus Sliepen <guus@tinc-vpn.org>,
+ Copyright (C) 2011-2022 Guus Sliepen <guus@tinc-vpn.org>,
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
fputc('\n', stderr);
}
-static void usage() {
+static void usage(void) {
fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name);
fprintf(stderr, "Valid options are:\n"
" --help Display this help and exit.\n"
/*
sptps_speed.c -- SPTPS benchmark
- Copyright (C) 2013-2014 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2013-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "ecdh.h"
#include "ecdsa.h"
#include "ecdsagen.h"
+#include "meta.h"
+#include "protocol.h"
#include "sptps.h"
// Symbols necessary to link with logger.o
-bool send_request(void *c, const char *msg, ...) {
+bool send_request(struct connection_t *c, const char *msg, ...) {
+ (void)c;
+ (void)msg;
return false;
}
-struct list_t *connection_list = NULL;
-bool send_meta(void *c, const char *msg, int len) {
+
+list_t connection_list;
+
+bool send_meta(struct connection_t *c, const void *msg, size_t len) {
+ (void)c;
+ (void)msg;
+ (void)len;
return false;
}
char *logfilename = NULL;
struct timeval now;
static bool send_data(void *handle, uint8_t type, const void *data, size_t len) {
+ (void)type;
int fd = *(int *)handle;
send(fd, data, len, 0);
return true;
}
static bool receive_record(void *handle, uint8_t type, const void *data, uint16_t len) {
+ (void)handle;
+ (void)type;
+ (void)data;
+ (void)len;
return true;
}
double rate;
unsigned int count;
-static void clock_start() {
+static void clock_start(void) {
count = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
}
return 1;
}
- struct pollfd pfd[2] = {{fd[0], POLLIN}, {fd[1], POLLIN}};
+ struct pollfd pfd[2] = {{fd[0], POLLIN, 0}, {fd[1], POLLIN, 0}};
fprintf(stderr, "SPTPS/TCP authenticate for %lg seconds: ", duration);
/*
sptps_test.c -- Simple Peer-to-Peer Security test program
- Copyright (C) 2011-2014 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2011-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "crypto.h"
#include "ecdsa.h"
+#include "meta.h"
+#include "protocol.h"
#include "sptps.h"
#include "utils.h"
#endif
// Symbols necessary to link with logger.o
-bool send_request(void *c, const char *msg, ...) {
+bool send_request(struct connection_t *c, const char *msg, ...) {
(void)c;
(void)msg;
return false;
}
-struct list_t *connection_list = NULL;
+list_t connection_list;
-bool send_meta(void *c, const char *msg, int len) {
+bool send_meta(struct connection_t *c, const void *msg, size_t len) {
(void)c;
(void)msg;
(void)len;
static bool writeonly;
static int in = 0;
static int out = 1;
-static int addressfamily = AF_UNSPEC;
+int addressfamily = AF_UNSPEC;
static bool send_data(void *handle, uint8_t type, const void *data, size_t len) {
(void)type;
bin2hex(data, hex, len);
if(verbose) {
- fprintf(stderr, "Sending %zu bytes of data:\n%s\n", len, hex);
+ fprintf(stderr, "Sending %lu bytes of data:\n%s\n", (unsigned long)len, hex);
}
const int *sock = handle;
+ const char *p = data;
- if((size_t)send(*sock, data, len, 0) != len) {
- return false;
+ while(len) {
+ ssize_t sent = send(*sock, p, len, 0);
+
+ if(sent <= 0) {
+ fprintf(stderr, "Error sending data: %s\n", strerror(errno));
+ return false;
+ }
+
+ p += sent;
+ len -= sent;
}
return true;
fprintf(stderr, "Received type %d record of %u bytes:\n", type, len);
}
- if(!writeonly) {
- write(out, data, len);
+ if(writeonly) {
+ return true;
+ }
+
+ const char *p = data;
+
+ while(len) {
+ ssize_t written = write(out, p, len);
+
+ if(written <= 0) {
+ fprintf(stderr, "Error writing received data: %s\n", strerror(errno));
+ return false;
+ }
+
+ p += written;
+ len -= written;
}
return true;
const char *program_name;
-static void usage() {
- fprintf(stderr, "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n\n", program_name);
- fprintf(stderr, "Valid options are:\n"
+static void usage(void) {
+ static const char *message =
+ "Usage: %s [options] my_ed25519_key_file his_ed25519_key_file [host] port\n"
+ "\n"
+ "Valid options are:\n"
" -d, --datagram Enable datagram mode.\n"
" -q, --quit Quit when EOF occurs on stdin.\n"
" -r, --readonly Only send data from the socket to stdout.\n"
" -v, --verbose Display debug messages.\n"
" -4 Use IPv4.\n"
" -6 Use IPv6.\n"
- "\n");
- fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n");
+ "\n"
+ "Report bugs to tinc@tinc-vpn.org.\n";
+
+ fprintf(stderr, message, program_name);
}
#ifdef HAVE_MINGW
// separate thread between the stdin and the sptps loop way below. This thread
// reads stdin and sends its content to the main thread through a TCP socket,
// which can be properly select()'ed.
-void *stdin_reader_thread(void *arg) {
+static void *stdin_reader_thread(void *arg) {
struct sockaddr_in sa;
socklen_t sa_size = sizeof(sa);
fprintf(stderr, "New connection received from :%d\n", ntohs(sa.sin_port));
}
- uint8_t buf[1024];
+ char buf[1024];
ssize_t nread;
while((nread = read(STDIN_FILENO, buf, sizeof(buf))) > 0) {
fprintf(stderr, "Read %lld bytes from input\n", nread);
}
- uint8_t *start = buf;
+ char *start = buf;
ssize_t nleft = nread;
while(nleft) {
closesocket(stdin_sock_fd);
stdin_sock_fd = -1;
+ return NULL;
}
-int start_input_reader() {
+static int start_input_reader(void) {
if(stdin_sock_fd != -1) {
fprintf(stderr, "stdin thread can only be started once.\n");
return -1;
} else {
fprintf(stderr, "Listening...\n");
- uint8_t buf[65536];
+ char buf[65536];
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
if(verbose) {
char hex[len * 2 + 1];
bin2hex(buf, hex, len);
- fprintf(stderr, "Received %zd bytes of data:\n%s\n", len, hex);
+ fprintf(stderr, "Received %ld bytes of data:\n%s\n", (long)len, hex);
}
- if(packetloss && prng(100) < packetloss) {
+ if(packetloss && (int)prng(100) < packetloss) {
if(verbose) {
fprintf(stderr, "Dropped.\n");
}
/*
subnet.c -- handle subnet lookups and lists
- Copyright (C) 2000-2017 Guus Sliepen <guus@tinc-vpn.org>,
+ Copyright (C) 2000-2022 Guus Sliepen <guus@tinc-vpn.org>,
2000-2005 Ivo Timmermans
This program is free software; you can redistribute it and/or modify
hash_clear(mac_t, &mac_cache);
}
-void subnet_cache_flush(subnet_t *subnet) {
+static void subnet_cache_flush(subnet_t *subnet) {
switch(subnet->type) {
case SUBNET_IPV4:
if(subnet->net.ipv4.prefixlength == 32) {
void subnet_update(node_t *owner, subnet_t *subnet, bool up) {
char netstr[MAXNETSTR];
- char *name, *address, *port;
+ char *address, *port;
char empty[] = "";
// Prepare environment variables to be passed to the script
int env_subnet = environment_add(&env, NULL);
int env_weight = environment_add(&env, NULL);
- name = up ? "subnet-up" : "subnet-down";
+ const char *name = up ? "subnet-up" : "subnet-down";
if(!subnet) {
for splay_each(subnet_t, subnet, &owner->subnet_tree) {
/*
tincctl.c -- Controlling a running tincd
- Copyright (C) 2007-2021 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2007-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
bool tty = true;
bool confbasegiven = false;
char *scriptinterpreter = NULL;
-char *scriptextension = "";
+static char defaultextension[] = "";
+char *scriptextension = defaultextension;
static char *prompt;
char *device = NULL;
char *iface = NULL;
};
static void version(void) {
- printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE,
- BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
- printf("Features:"
+ static const char *message =
+ "%s version %s (built %s %s, protocol %d.%d)\n"
+ "Features:"
#ifdef HAVE_READLINE
- " readline"
+ " readline"
#endif
#ifdef HAVE_CURSES
- " curses"
+ " curses"
#endif
#ifndef DISABLE_LEGACY
- " legacy_protocol"
+ " legacy_protocol"
#endif
- "\n\n");
- printf("Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
- "See the AUTHORS file for a complete list.\n\n"
- "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
- "and you are welcome to redistribute it under certain conditions;\n"
- "see the file COPYING for details.\n");
+ "\n\n"
+ "Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
+ "See the AUTHORS file for a complete list.\n"
+ "\n"
+ "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
+ "and you are welcome to redistribute it under certain conditions;\n"
+ "see the file COPYING for details.\n";
+
+ printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
}
static void usage(bool status) {
if(status) {
fprintf(stderr, "Try `%s --help\' for more information.\n", program_name);
} else {
- printf("Usage: %s [options] command\n\n", program_name);
- printf("Valid options are:\n"
- " -b, --batch Don't ask for anything (non-interactive mode).\n"
- " -c, --config=DIR Read configuration options from DIR.\n"
- " -n, --net=NETNAME Connect to net NETNAME.\n"
- " --pidfile=FILENAME Read control cookie from FILENAME.\n"
- " --force Force some commands to work despite warnings.\n"
- " --help Display this help and exit.\n"
- " --version Output version information and exit.\n"
- "\n"
- "Valid commands are:\n"
- " init [name] Create initial configuration files.\n"
- " get VARIABLE Print current value of VARIABLE\n"
- " set VARIABLE VALUE Set VARIABLE to VALUE\n"
- " add VARIABLE VALUE Add VARIABLE with the given VALUE\n"
- " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n"
- " start [tincd options] Start tincd.\n"
- " stop Stop tincd.\n"
- " restart [tincd options] Restart tincd.\n"
- " reload Partially reload configuration of running tincd.\n"
- " pid Show PID of currently running tincd.\n"
+ static const char *message =
+ "Usage: %s [options] command\n"
+ "\n"
+ "Valid options are:\n"
+ " -b, --batch Don't ask for anything (non-interactive mode).\n"
+ " -c, --config=DIR Read configuration options from DIR.\n"
+ " -n, --net=NETNAME Connect to net NETNAME.\n"
+ " --pidfile=FILENAME Read control cookie from FILENAME.\n"
+ " --force Force some commands to work despite warnings.\n"
+ " --help Display this help and exit.\n"
+ " --version Output version information and exit.\n"
+ "\n"
+ "Valid commands are:\n"
+ " init [name] Create initial configuration files.\n"
+ " get VARIABLE Print current value of VARIABLE\n"
+ " set VARIABLE VALUE Set VARIABLE to VALUE\n"
+ " add VARIABLE VALUE Add VARIABLE with the given VALUE\n"
+ " del VARIABLE [VALUE] Remove VARIABLE [only ones with watching VALUE]\n"
+ " start [tincd options] Start tincd.\n"
+ " stop Stop tincd.\n"
+ " restart [tincd options] Restart tincd.\n"
+ " reload Partially reload configuration of running tincd.\n"
+ " pid Show PID of currently running tincd.\n"
#ifdef DISABLE_LEGACY
- " generate-keys Generate a new Ed25519 public/private key pair.\n"
+ " generate-keys Generate a new Ed25519 public/private key pair.\n"
#else
- " generate-keys [bits] Generate new RSA and Ed25519 public/private key pairs.\n"
- " generate-rsa-keys [bits] Generate a new RSA public/private key pair.\n"
+ " generate-keys [bits] Generate new RSA and Ed25519 public/private key pairs.\n"
+ " generate-rsa-keys [bits] Generate a new RSA public/private key pair.\n"
#endif
- " generate-ed25519-keys Generate a new Ed25519 public/private key pair.\n"
- " dump Dump a list of one of the following things:\n"
- " [reachable] nodes - all known nodes in the VPN\n"
- " edges - all known connections in the VPN\n"
- " subnets - all known subnets in the VPN\n"
- " connections - all meta connections with ourself\n"
- " [di]graph - graph of the VPN in dotty format\n"
- " invitations - outstanding invitations\n"
- " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n"
- " purge Purge unreachable nodes\n"
- " debug N Set debug level\n"
- " retry Retry all outgoing connections\n"
- " disconnect NODE Close meta connection with NODE\n"
+ " generate-ed25519-keys Generate a new Ed25519 public/private key pair.\n"
+ " dump Dump a list of one of the following things:\n"
+ " [reachable] nodes - all known nodes in the VPN\n"
+ " edges - all known connections in the VPN\n"
+ " subnets - all known subnets in the VPN\n"
+ " connections - all meta connections with ourself\n"
+ " [di]graph - graph of the VPN in dotty format\n"
+ " invitations - outstanding invitations\n"
+ " info NODE|SUBNET|ADDRESS Give information about a particular NODE, SUBNET or ADDRESS.\n"
+ " purge Purge unreachable nodes\n"
+ " debug N Set debug level\n"
+ " retry Retry all outgoing connections\n"
+ " disconnect NODE Close meta connection with NODE\n"
#ifdef HAVE_CURSES
- " top Show real-time statistics\n"
+ " top Show real-time statistics\n"
#endif
- " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n"
- " log [level] Dump log output [up to the specified level]\n"
- " export Export host configuration of local node to standard output\n"
- " export-all Export all host configuration files to standard output\n"
- " import Import host configuration file(s) from standard input\n"
- " exchange Same as export followed by import\n"
- " exchange-all Same as export-all followed by import\n"
- " invite NODE [...] Generate an invitation for NODE\n"
- " join INVITATION Join a VPN using an INVITATION\n"
- " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n"
- " fsck Check the configuration files for problems.\n"
- " sign [FILE] Generate a signed version of a file.\n"
- " verify NODE [FILE] Verify that a file was signed by the given NODE.\n"
- "\n");
- printf("Report bugs to tinc@tinc-vpn.org.\n");
+ " pcap [snaplen] Dump traffic in pcap format [up to snaplen bytes per packet]\n"
+ " log [level] Dump log output [up to the specified level]\n"
+ " export Export host configuration of local node to standard output\n"
+ " export-all Export all host configuration files to standard output\n"
+ " import Import host configuration file(s) from standard input\n"
+ " exchange Same as export followed by import\n"
+ " exchange-all Same as export-all followed by import\n"
+ " invite NODE [...] Generate an invitation for NODE\n"
+ " join INVITATION Join a VPN using an INVITATION\n"
+ " network [NETNAME] List all known networks, or switch to the one named NETNAME.\n"
+ " fsck Check the configuration files for problems.\n"
+ " sign [FILE] Generate a signed version of a file.\n"
+ " verify NODE [FILE] Verify that a file was signed by the given NODE.\n"
+ "\n"
+ "Report bugs to tinc@tinc-vpn.org.\n";
+
+ printf(message, program_name);
}
}
if(filename[0] != '/') {
#endif
+
/* The directory is a relative path or a filename. */
- getcwd(directory, sizeof(directory));
+ if(!getcwd(directory, sizeof(directory))) {
+ fprintf(stderr, "Could not get current directory: %s\n", strerror(errno));
+ return NULL;
+ }
if((size_t)snprintf(buf2, sizeof(buf2), "%s" SLASH "%s", directory, filename) >= sizeof(buf2)) {
fprintf(stderr, "Filename too long: %s" SLASH "%s\n", directory, filename);
return true;
}
-bool sendline(int fd, char *format, ...) {
+bool sendline(int fd, const char *format, ...) {
static char buffer[4096];
char *p = buffer;
ssize_t blen;
while(recvline(fd, line, sizeof(line))) {
int code, req;
- size_t len;
- int n = sscanf(line, "%d %d %zd", &code, &req, &len);
+ unsigned long len;
+ int n = sscanf(line, "%d %d %lu", &code, &req, &len);
gettimeofday(&tv, NULL);
if(n != 3 || code != CONTROL || req != REQ_PCAP || len > sizeof(data)) {
#endif
- char *default_c = "tincd";
-
if(slash++) {
xasprintf(&c, "%.*stincd", (int)(slash - program_name), program_name);
} else {
- c = default_c;
+ c = xstrdup("tincd");
}
int nargc = 0;
int status = spawnvp(_P_WAIT, c, nargv);
free(nargv);
-
- if(c != default_c) {
- free(c);
- }
+ free(c);
if(status == -1) {
fprintf(stderr, "Error starting %s: %s\n", c, strerror(errno));
if(socketpair(AF_UNIX, SOCK_STREAM, 0, pfd)) {
fprintf(stderr, "Could not create umbilical socket: %s\n", strerror(errno));
free(nargv);
-
- if(c != default_c) {
- free(c);
- }
-
+ free(c);
return 1;
}
if(pid == -1) {
fprintf(stderr, "Could not fork: %s\n", strerror(errno));
free(nargv);
-
- if(c != default_c) {
- free(c);
- }
-
+ free(c);
return 1;
}
len--;
}
- write(2, buf, len);
+ if(write(2, buf, len) != len) {
+ // Nothing we can do about it.
+ }
}
if(len) {
fprintf(stderr, "Error starting %s\n", c);
}
- if(c != default_c) {
- free(c);
- }
+ free(c);
return failed ? EXIT_FAILURE : EXIT_SUCCESS;
#endif
char nexthop[4096];
int cipher, digest, maclength, compression, distance, socket, weight;
short int pmtu, minmtu, maxmtu;
- unsigned int options, status_int;
+ unsigned int options;
+ uint32_t status_int;
node_status_t status;
long int last_state_change;
int udp_ping_rtt;
switch(req) {
case REQ_DUMP_NODES: {
- int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %x %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes);
+ int n = sscanf(line, "%*d %*d %4095s %4095s %4095s port %4095s %d %d %d %d %x %"PRIx32" %4095s %4095s %d %hd %hd %hd %ld %d %"PRIu64" %"PRIu64" %"PRIu64" %"PRIu64, node, id, host, port, &cipher, &digest, &maclength, &compression, &options, &status_int, nexthop, via, &distance, &pmtu, &minmtu, &maxmtu, &last_state_change, &udp_ping_rtt, &in_packets, &in_bytes, &out_packets, &out_bytes);
if(n != 22) {
fprintf(stderr, "Unable to parse node dump from tincd: %s\n", line);
#ifdef HAVE_READLINE
rl_readline_name = "tinc";
+ rl_basic_word_break_characters = "\t\n ";
rl_completion_entry_function = complete_nothing;
rl_attempted_completion_function = completion;
rl_filename_completion_desired = 0;
if(tty) {
free(copy);
free(line);
- rl_basic_word_break_characters = "\t\n ";
line = readline(prompt);
copy = line ? xstrdup(line) : NULL;
} else {
return result;
}
-static void cleanup() {
+static void cleanup(void) {
free(tinc_conf);
free(hosts_dir);
free_names();
/*
tincctl.h -- header for tincctl.c.
- Copyright (C) 2011-2016 Guus Sliepen <guus@tinc-vpn.org>
+ Copyright (C) 2011-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
extern size_t rstrip(char *value);
extern char *get_my_name(bool verbose);
extern bool connect_tincd(bool verbose);
-extern bool sendline(int fd, char *format, ...);
+extern bool sendline(int fd, const char *format, ...);
extern bool recvline(int fd, char *line, size_t len);
extern int check_port(const char *name);
-extern FILE *fopenmask(const char *filename, const char *mode, mode_t perms);
extern ecdsa_t *get_pubkey(FILE *f);
#endif
/*
tincd.c -- the main file for tincd
Copyright (C) 1998-2005 Ivo Timmermans
- 2000-2021 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2022 Guus Sliepen <guus@tinc-vpn.org>
2008 Max Rijevski <maksuf@gmail.com>
2009 Michael Tokarev <mjt@tls.msk.ru>
2010 Julien Muchembled <jm@jmuchemb.eu>
fprintf(stderr, "Try `%s --help\' for more information.\n",
program_name);
else {
- printf("Usage: %s [option]...\n\n", program_name);
- printf(" -c, --config=DIR Read configuration options from DIR.\n"
- " -D, --no-detach Don't fork and detach.\n"
- " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n"
- " -n, --net=NETNAME Connect to net NETNAME.\n"
+ static const char *message =
+ "Usage: %s [option]...\n"
+ "\n"
+ " -c, --config=DIR Read configuration options from DIR.\n"
+ " -D, --no-detach Don't fork and detach.\n"
+ " -d, --debug[=LEVEL] Increase debug level or set it to LEVEL.\n"
+ " -n, --net=NETNAME Connect to net NETNAME.\n"
#ifdef HAVE_MLOCKALL
- " -L, --mlock Lock tinc into main memory.\n"
+ " -L, --mlock Lock tinc into main memory.\n"
#endif
- " --logfile[=FILENAME] Write log entries to a logfile.\n"
- " -s --syslog Use syslog instead of stderr with --no-detach.\n"
- " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n"
- " --bypass-security Disables meta protocol security, for debugging.\n"
- " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n"
+ " --logfile[=FILENAME] Write log entries to a logfile.\n"
+ " -s --syslog Use syslog instead of stderr with --no-detach.\n"
+ " --pidfile=FILENAME Write PID and control socket cookie to FILENAME.\n"
+ " --bypass-security Disables meta protocol security, for debugging.\n"
+ " -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n"
#ifndef HAVE_MINGW
- " -R, --chroot chroot to NET dir at startup.\n"
- " -U, --user=USER setuid to given USER at startup.\n"
+ " -R, --chroot chroot to NET dir at startup.\n"
+ " -U, --user=USER setuid to given USER at startup.\n"
#endif
- " --help Display this help and exit.\n"
- " --version Output version information and exit.\n\n");
- printf("Report bugs to tinc@tinc-vpn.org.\n");
+ " --help Display this help and exit.\n"
+ " --version Output version information and exit.\n"
+ "\n"
+ "Report bugs to tinc@tinc-vpn.org.\n";
+
+ fprintf(stderr, message, program_name);
}
}
# define setpriority(level) (setpriority(PRIO_PROCESS, 0, (level)))
#endif
-static void cleanup() {
+static void cleanup(void) {
splay_empty_tree(&config_tree);
list_empty_list(&cmdline_conf);
free_names();
}
if(show_version) {
- printf("%s version %s (built %s %s, protocol %d.%d)\n", PACKAGE,
- BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
- printf("Features:"
+ static const char *message =
+ "%s version %s (built %s %s, protocol %d.%d)\n"
+ "Features:"
#ifdef HAVE_OPENSSL
- " openssl"
+ " openssl"
#endif
#ifdef HAVE_LIBGCRYPT
- " libgcrypt"
+ " libgcrypt"
#endif
#ifdef HAVE_LZO
- " comp_lzo"
+ " comp_lzo"
#endif
#ifdef HAVE_ZLIB
- " comp_zlib"
+ " comp_zlib"
#endif
#ifdef HAVE_LZ4
- " comp_lz4"
+ " comp_lz4"
#endif
#ifndef DISABLE_LEGACY
- " legacy_protocol"
+ " legacy_protocol"
#endif
#ifdef ENABLE_JUMBOGRAMS
- " jumbograms"
+ " jumbograms"
#endif
#ifdef ENABLE_TUNEMU
- " tunemu"
+ " tunemu"
#endif
#ifdef HAVE_MINIUPNPC
- " miniupnpc"
+ " miniupnpc"
#endif
#ifdef ENABLE_UML
- " uml"
+ " uml"
#endif
#ifdef ENABLE_VDE
- " vde"
+ " vde"
#endif
- "\n\n");
- printf("Copyright (C) 1998-2021 Ivo Timmermans, Guus Sliepen and others.\n"
- "See the AUTHORS file for a complete list.\n\n"
- "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
- "and you are welcome to redistribute it under certain conditions;\n"
- "see the file COPYING for details.\n");
+ "\n\n"
+ "Copyright (C) 1998-2021 Ivo Timmermans, Guus Sliepen and others.\n"
+ "See the AUTHORS file for a complete list.\n"
+ "\n"
+ "tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
+ "and you are welcome to redistribute it under certain conditions;\n"
+ "see the file COPYING for details.\n";
+ printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
return 0;
}
make_names(true);
atexit(cleanup);
- chdir(confbase);
+ if(chdir(confbase) == -1) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not change to configuration directory: %s", strerror(errno));
+ return 1;
+ }
#ifdef HAVE_MINGW
logger(DEBUG_ALWAYS, LOG_NOTICE, "Ready");
if(umbilical) { // snip!
- write(umbilical, "", 1);
+ if(write(umbilical, "", 1) != 1) {
+ // Pipe full or broken, nothing we can do about it.
+ }
+
close(umbilical);
umbilical = 0;
}
/*
device.c -- UML network socket
Copyright (C) 2002-2005 Ivo Timmermans,
- 2002-2017 Guus Sliepen <guus@tinc-vpn.org>
+ 2002-2022 Guus Sliepen <guus@tinc-vpn.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return true;
}
-void close_device(void) {
+static void close_device(void) {
if(listen_fd >= 0) {
close(listen_fd);
listen_fd = -1;
return false;
}
- write(request_fd, &data_sun, sizeof(data_sun));
+ if(write(request_fd, &data_sun, sizeof(data_sun)) != sizeof(data_sun)) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Error while responding to request from %s %s: %s", device_info, device, strerror(errno));
+ event_exit();
+ return false;
+ }
+
device_fd = data_fd;
logger(DEBUG_ALWAYS, LOG_INFO, "Connection with UML established");
/*
upnp.c -- UPnP-IGD client
- Copyright (C) 2015-2018 Guus Sliepen <guus@tinc-vpn.org>,
+ Copyright (C) 2015-2022 Guus Sliepen <guus@tinc-vpn.org>,
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "upnp.h"
+#include "system.h"
-#ifndef HAVE_MINGW
#include <pthread.h>
-#endif
#include "miniupnpc/miniupnpc.h"
#include "miniupnpc/upnpcommands.h"
#include "miniupnpc/upnperrors.h"
-#include "system.h"
#include "logger.h"
#include "names.h"
#include "net.h"
#include "netutl.h"
#include "utils.h"
+#include "upnp.h"
static bool upnp_tcp;
static bool upnp_udp;
free(port);
}
-static void upnp_refresh() {
+static void upnp_refresh(void) {
logger(DEBUG_PROTOCOL, LOG_INFO, "[upnp] Discovering IGD devices");
int error;
get_config_int(lookup_config(&config_tree, "UPnPDiscoverWait"), &upnp_discover_wait);
get_config_int(lookup_config(&config_tree, "UPnPRefreshPeriod"), &upnp_refresh_period);
-#ifdef HAVE_MINGW
- HANDLE handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)upnp_thread, NULL, 0, NULL);
-
- if(!handle) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread");
- }
-
-#else
pthread_t thread;
int error = pthread_create(&thread, NULL, upnp_thread, NULL);
if(error) {
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to start UPnP-IGD client thread: [%d] %s", error, strerror(error));
}
-
-#endif
}
See <http://creativecommons.org/publicdomain/zero/1.0/>. */
-#include <stdint.h>
+#include "system.h"
#include "crypto.h"