if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) {
if(!strcasecmp(type, "tun"))
- /* use default */;
+ /* use default */;
#ifdef HAVE_TUNEMU
else if(!strcasecmp(type, "tunemu"))
device_type = DEVICE_TYPE_TUNEMU;
#ifdef HAVE_TUNEMU
case DEVICE_TYPE_TUNEMU: {
char dynamic_name[256] = "";
- device_fd = tunemu_open(dynamic_name);
+ device_fd = tunemu_open(dynamic_name);
}
break;
#endif
device_type = DEVICE_TYPE_TUN;
case DEVICE_TYPE_TUN:
#ifdef TUNSIFHEAD
- {
+ {
const int zero = 0;
if(ioctl(device_fd, TUNSIFHEAD, &zero, sizeof zero) == -1) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "ioctl", strerror(errno));
iface = xstrdup(ifr.ifr_name);
}
}
-
+
#endif
break;
#ifdef HAVE_TUNEMU
case DEVICE_TYPE_TUNEMU:
- device_info = "BSD tunemu device";
+ device_info = "BSD tunemu device";
break;
#endif
}
default:
return false;
}
-
+
device_total_in += packet->len;
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Read packet of %d bytes from %s",
u_int32_t type;
struct iovec vector[2] = {{&type, sizeof type}, {packet->data + 14, packet->len - 14}};
int af;
-
+
af = (packet->data[12] << 8) + packet->data[13];
switch (af) {
}
break;
}
-
+
case DEVICE_TYPE_TAP:
if(write(device_fd, packet->data, packet->len) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Error while writing to %s %s: %s", device_info,
/*
* tunemu - Tun device emulation for Darwin
* Copyright (C) 2009 Friedrich Schöller <friedrich.schoeller@gmail.com>
- *
+ *
* 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 3 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, see <http://www.gnu.org/licenses/>.
- *
+ *
*/
#include "tunemu.h"
#define PPPPROTO_CTL 1
-#define PPP_IP 0x21
-#define PPP_IPV6 0x57
+#define PPP_IP 0x21
+#define PPP_IPV6 0x57
#define SC_LOOP_TRAFFIC 0x00000200
-#define PPPIOCNEWUNIT _IOWR('t', 62, int)
-#define PPPIOCSFLAGS _IOW('t', 89, int)
-#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl)
-#define PPPIOCATTCHAN _IOW('t', 56, int)
-#define PPPIOCGCHAN _IOR('t', 55, int)
-#define PPPIOCCONNECT _IOW('t', 58, int)
-#define PPPIOCGUNIT _IOR('t', 86, int)
+#define PPPIOCNEWUNIT _IOWR('t', 62, int)
+#define PPPIOCSFLAGS _IOW('t', 89, int)
+#define PPPIOCSNPMODE _IOW('t', 75, struct npioctl)
+#define PPPIOCATTCHAN _IOW('t', 56, int)
+#define PPPIOCGCHAN _IOR('t', 55, int)
+#define PPPIOCCONNECT _IOW('t', 58, int)
+#define PPPIOCGUNIT _IOR('t', 86, int)
struct sockaddr_ppp
{
/*
* tunemu - Tun device emulation for Darwin
* Copyright (C) 2009 Friedrich Schöller <friedrich.schoeller@gmail.com>
- *
+ *
* 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 3 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, see <http://www.gnu.org/licenses/>.
- *
+ *
*/
#ifndef TUNEMU_H
}
// Copy data into the buffer.
-
+
void buffer_add(buffer_t *buffer, const char *data, int size) {
memcpy(buffer_prepare(buffer, size), data, size);
}
1998-2005 Ivo Timmermans
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2010-2011 Julien Muchembled <jm@jmuchemb.eu>
- 2000 Cris van Pelt
+ 2000 Cris van Pelt
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 "conf.h"
#include "list.h"
#include "logger.h"
-#include "netutl.h" /* for str2address */
+#include "netutl.h" /* for str2address */
#include "protocol.h"
-#include "utils.h" /* for cp */
+#include "utils.h" /* for cp */
#include "xalloc.h"
splay_tree_t *config_tree;
-int pinginterval = 0; /* seconds between pings */
-int pingtimeout = 0; /* seconds to wait for response */
-char *confbase = NULL; /* directory in which all config files are */
-char *netname = NULL; /* name of the vpn network */
-list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */
+int pinginterval = 0; /* seconds between pings */
+int pingtimeout = 0; /* seconds to wait for response */
+char *confbase = NULL; /* directory in which all config files are */
+char *netname = NULL; /* name of the vpn network */
+list_t *cmdline_conf = NULL; /* global/host configuration values given at the command line */
static int config_compare(const config_t *a, const config_t *b) {
if(!newline)
return buf;
- *newline = '\0'; /* kill newline */
- if(newline > p && newline[-1] == '\r') /* and carriage return if necessary */
+ /* kill newline and carriage return if necessary */
+ *newline = '\0';
+ if(newline > p && newline[-1] == '\r')
newline[-1] = '\0';
return buf;
ignore = false;
continue;
}
-
+
if(!strncmp(line, "-----BEGIN", 10)) {
ignore = true;
continue;
xasprintf(&fname, "%s" SLASH "tinc.conf", confbase);
x = read_config_file(config_tree, fname);
- if(!x) { /* System error: complain */
+ if(!x)
logger(DEBUG_ALWAYS, LOG_ERR, "Failed to read `%s': %s", fname, strerror(errno));
- }
free(fname);
extern bool read_host_config(splay_tree_t *, const char *);
extern bool append_config_file(const char *, const char *, const char *);
-#endif /* __TINC_CONF_H__ */
+#endif /* __TINC_CONF_H__ */
#include "utils.h"
#include "xalloc.h"
-list_t *connection_list; /* Meta connections */
+list_t *connection_list;
connection_t *everyone;
void init_connections(void) {
buffer_clear(&c->inbuf);
buffer_clear(&c->outbuf);
-
+
if(event_initialized(&c->inevent))
event_del(&c->inevent);
#include "list.h"
#include "sptps.h"
-#define OPTION_INDIRECT 0x0001
-#define OPTION_TCPONLY 0x0002
-#define OPTION_PMTU_DISCOVERY 0x0004
-#define OPTION_CLAMP_MSS 0x0008
+#define OPTION_INDIRECT 0x0001
+#define OPTION_TCPONLY 0x0002
+#define OPTION_PMTU_DISCOVERY 0x0004
+#define OPTION_CLAMP_MSS 0x0008
#define OPTION_VERSION(x) ((x) >> 24) /* Top 8 bits are for protocol minor version */
typedef struct connection_status_t {
- unsigned int pinged:1; /* sent ping */
- unsigned int active:1; /* 1 if active.. */
- unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
- unsigned int unused_termreq:1; /* the termination of this connection was requested */
- unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */
- unsigned int timeout_unused:1; /* 1 if gotten timeout */
- unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */
- unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */
- unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */
- unsigned int control:1; /* 1 if this is a control connection */
- unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */
- unsigned int log:1; /* 1 if this is a control connection requesting log dump */
+ unsigned int pinged:1; /* sent ping */
+ unsigned int active:1; /* 1 if active.. */
+ unsigned int connecting:1; /* 1 if we are waiting for a non-blocking connect() to finish */
+ unsigned int unused_termreq:1; /* the termination of this connection was requested */
+ unsigned int remove_unused:1; /* Set to 1 if you want this connection removed */
+ unsigned int timeout_unused:1; /* 1 if gotten timeout */
+ unsigned int encryptout:1; /* 1 if we can encrypt outgoing traffic */
+ unsigned int decryptin:1; /* 1 if we have to decrypt incoming traffic */
+ unsigned int mst:1; /* 1 if this connection is part of a minimum spanning tree */
+ unsigned int control:1; /* 1 if this is a control connection */
+ unsigned int pcap:1; /* 1 if this is a control connection requesting packet capture */
+ unsigned int log:1; /* 1 if this is a control connection requesting log dump */
unsigned int unused:20;
} connection_status_t;
#include "node.h"
typedef struct connection_t {
- char *name; /* name he claims to have */
-
- union sockaddr_t address; /* his real (internet) ip */
- char *hostname; /* the hostname of its real ip */
- int protocol_major; /* used protocol */
- int protocol_minor; /* used protocol */
-
- int socket; /* socket used for this connection */
- uint32_t options; /* options for this connection */
- connection_status_t status; /* status info */
- int estimated_weight; /* estimation for the weight of the edge for this connection */
- struct timeval start; /* time this connection was started, used for above estimation */
- struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
-
- struct node_t *node; /* node associated with the other end */
- struct edge_t *edge; /* edge associated with this connection */
-
- rsa_t rsa; /* his public RSA key */
- ecdsa_t ecdsa; /* his public ECDSA key */
- cipher_t incipher; /* Cipher he will use to send data to us */
- cipher_t outcipher; /* Cipher we will use to send data to him */
+ char *name; /* name he claims to have */
+
+ union sockaddr_t address; /* his real (internet) ip */
+ char *hostname; /* the hostname of its real ip */
+ int protocol_major; /* used protocol */
+ int protocol_minor; /* used protocol */
+
+ int socket; /* socket used for this connection */
+ uint32_t options; /* options for this connection */
+ connection_status_t status; /* status info */
+ int estimated_weight; /* estimation for the weight of the edge for this connection */
+ struct timeval start; /* time this connection was started, used for above estimation */
+ struct outgoing_t *outgoing; /* used to keep track of outgoing connections */
+
+ struct node_t *node; /* node associated with the other end */
+ struct edge_t *edge; /* edge associated with this connection */
+
+ rsa_t rsa; /* his public RSA key */
+ ecdsa_t ecdsa; /* his public ECDSA key */
+ cipher_t incipher; /* Cipher he will use to send data to us */
+ cipher_t outcipher; /* Cipher we will use to send data to him */
digest_t indigest;
digest_t outdigest;
sptps_t sptps;
int incompression;
int outcompression;
- char *hischallenge; /* The challenge we sent to him */
+ char *hischallenge; /* The challenge we sent to him */
struct buffer_t inbuf;
struct buffer_t outbuf;
- struct event inevent; /* input event on this metadata connection */
- struct event outevent; /* output event on this metadata connection */
- int tcplen; /* length of incoming TCPpacket */
- int allow_request; /* defined if there's only one request possible */
+ struct event inevent; /* input event on this metadata connection */
+ struct event outevent; /* output event on this metadata connection */
+ int tcplen; /* length of incoming TCPpacket */
+ int allow_request; /* defined if there's only one request possible */
- time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */
+ time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */
- splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
+ splay_tree_t *config_tree; /* Pointer to configuration tree belonging to him */
} connection_t;
extern list_t *connection_list;
extern void connection_del(connection_t *);
extern bool dump_connections(struct connection_t *);
-#endif /* __TINC_CONNECTION_H__ */
+#endif /* __TINC_CONNECTION_H__ */
case REQ_DUMP_NODES:
return dump_nodes(c);
-
+
case REQ_DUMP_EDGES:
return dump_edges(c);
snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2))
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2))
continue;
len = sizeof adaptername;
iface = xstrdup(adaptername);
snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
-
+
/* Now we are going to open this device twice: once for reading and once for writing.
We do this because apparently it isn't possible to check for activity in the select() loop.
Furthermore I don't really know how to do it the "Windows" way. */
}
/* The parent opens the tap device for writing. */
-
+
device_handle = CreateFile(tapname, GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM , 0);
-
+
if(device_handle == INVALID_HANDLE_VALUE) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not open Windows tap device %s (%s) for writing: %s", device, iface, winerror(GetLastError()));
return false;
if(!reader_pid) {
/* The child opens the tap device for reading, blocking.
It passes everything it reads to the socket. */
-
+
char buf[MTU];
long inlen;
device, strerror(errno));
return false;
}
-
+
packet->len = inlen;
device_total_in += packet->len;
extern const devops_t vde_devops;
extern devops_t devops;
-#endif /* __TINC_DEVICE_H__ */
+#endif /* __TINC_DEVICE_H__ */
#ifndef HAVE_DAEMON
/*
Replacement for the daemon() function.
-
+
The daemon() function is for programs wishing to detach themselves
from the controlling terminal and run in the background as system
daemons.
size = 100;
buf = xmalloc(size);
- errno = 0; /* Success */
+ errno = 0; /* Success */
r = getcwd(buf, size);
/* getcwd returns NULL and sets errno to ERANGE if the bufferspace
is insufficient to contain the entire working directory. */
while(r == NULL && errno == ERANGE) {
free(buf);
- size <<= 1; /* double the size */
+ size <<= 1; /* double the size */
buf = xmalloc(size);
r = getcwd(buf, size);
}
extern int usleep(long long usec);
#endif
-#endif /* __DROPIN_H__ */
+#endif /* __DROPIN_H__ */
#include "utils.h"
#include "xalloc.h"
-splay_tree_t *edge_weight_tree; /* Tree with all edges, sorted on weight */
+splay_tree_t *edge_weight_tree;
static int edge_compare(const edge_t *a, const edge_t *b) {
return strcmp(a->to->name, b->to->name);
edge_t *lookup_edge(node_t *from, node_t *to) {
edge_t v;
-
+
v.from = from;
v.to = to;
struct node_t *to;
sockaddr_t address;
- uint32_t options; /* options turned on for this edge */
- int weight; /* weight of this edge */
+ uint32_t options; /* options turned on for this edge */
+ int weight; /* weight of this edge */
- struct connection_t *connection; /* connection associated with this edge, if available */
- struct edge_t *reverse; /* edge in the opposite direction, if available */
+ struct connection_t *connection; /* connection associated with this edge, if available */
+ struct edge_t *reverse; /* edge in the opposite direction, if available */
} edge_t;
-extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */
+extern splay_tree_t *edge_weight_tree; /* Tree with all known edges sorted on weight */
extern void init_edges(void);
extern void exit_edges(void);
extern edge_t *lookup_edge(struct node_t *, struct node_t *);
extern bool dump_edges(struct connection_t *);
-#endif /* __TINC_EDGE_H__ */
+#endif /* __TINC_EDGE_H__ */
uint16_t ar_hrd;
uint16_t ar_pro;
uint8_t ar_hln;
- uint8_t ar_pln;
- uint16_t ar_op;
+ uint8_t ar_pln;
+ uint16_t ar_op;
} __attribute__ ((__packed__));
-#define ARPOP_REQUEST 1
-#define ARPOP_REPLY 2
-#define ARPOP_RREQUEST 3
-#define ARPOP_RREPLY 4
-#define ARPOP_InREQUEST 8
-#define ARPOP_InREPLY 9
-#define ARPOP_NAK 10
+#define ARPOP_REQUEST 1
+#define ARPOP_REPLY 2
+#define ARPOP_RREQUEST 3
+#define ARPOP_RREPLY 4
+#define ARPOP_InREQUEST 8
+#define ARPOP_InREPLY 9
+#define ARPOP_NAK 10
#endif
#ifndef HAVE_STRUCT_ETHER_ARP
/* for old netdb.h */
#ifndef EAI_NODATA
-#define EAI_NODATA 1
+#define EAI_NODATA 1
#endif
#ifndef EAI_MEMORY
-#define EAI_MEMORY 2
+#define EAI_MEMORY 2
#endif
#ifndef EAI_FAMILY
-#define EAI_FAMILY 3
+#define EAI_FAMILY 3
#endif
default:
return "Unknown error";
}
-}
+}
#endif /* !HAVE_GAI_STRERROR */
#if !HAVE_DECL_FREEADDRINFO
struct addrinfo *ai;
ai = xmalloc_and_zero(sizeof(struct addrinfo) + sizeof(struct sockaddr_in));
-
+
ai->ai_addr = (struct sockaddr *)(ai + 1);
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_addr->sa_family = ai->ai_family = AF_INET;
((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
-
+
return ai;
}
*res = malloc_ai(port, htonl(0x00000000));
return 0;
}
-
+
if (!hostname) {
*res = malloc_ai(port, htonl(0x7f000001));
return 0;
}
-
+
hp = gethostbyname(hostname);
if(!hp || !hp->h_addr_list || !hp->h_addr_list[0])
#endif
#ifndef AI_NUMERICHOST
-#define AI_NUMERICHOST 4
+#define AI_NUMERICHOST 4
#endif
#ifndef HAVE_STRUCT_ADDRINFO
struct addrinfo {
- int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
- int ai_family; /* PF_xxx */
- int ai_socktype; /* SOCK_xxx */
- int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
- size_t ai_addrlen; /* length of ai_addr */
- char *ai_canonname; /* canonical name for hostname */
- struct sockaddr *ai_addr; /* binary address */
- struct addrinfo *ai_next; /* next structure in linked list */
+ int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
+ int ai_family; /* PF_xxx */
+ int ai_socktype; /* SOCK_xxx */
+ int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+ size_t ai_addrlen; /* length of ai_addr */
+ char *ai_canonname; /* canonical name for hostname */
+ struct sockaddr *ai_addr; /* binary address */
+ struct addrinfo *ai_next; /* next structure in linked list */
};
#endif /* !HAVE_STRUCT_ADDRINFO */
#if !HAVE_DECL_GETADDRINFO
-int getaddrinfo(const char *hostname, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res);
+int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res);
#endif /* !HAVE_GETADDRINFO */
#if !HAVE_DECL_GAI_STRERROR
}
hp = gethostbyaddr((char *)&sin->sin_addr, sizeof(struct in_addr), AF_INET);
-
+
if(!hp || !hp->h_name || !hp->h_name[0])
return EAI_NODATA;
-
+
len = snprintf(host, hostlen, "%s", hp->h_name);
if(len < 0 || len >= hostlen)
return EAI_MEMORY;
#define _FAKE_GETNAMEINFO_H
#if !HAVE_DECL_GETNAMEINFO
-int getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
- size_t hostlen, char *serv, size_t servlen, int flags);
+int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
#endif /* !HAVE_GETNAMEINFO */
#ifndef NI_MAXSERV
else
pad[i] = padbyte;
}
-
+
if(oneshot)
gcry_cipher_setiv(cipher->handle, cipher->key + cipher->keylen, cipher->blklen);
digest->maclength = len;
else
digest->maclength = maclength;
-
+
digest->algo = algo;
digest->hmac = NULL;
return *(*p)++;
}
}
-
+
static bool ber_read_sequence(unsigned char **p, size_t *buflen, size_t *result) {
int tag = ber_read_id(p, buflen);
if(mpi)
err = gcry_mpi_scan(mpi, GCRYMPI_FMT_USG, *p, len, NULL);
-
+
*p += len;
*buflen -= len;
/* Loop while todo_list is filled */
- for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */
+ for list_each(node_t, n, todo_list) { /* "n" is the node from which we start */
logger(DEBUG_SCARY_THINGS, LOG_DEBUG, " Examining edges from %s", n->name);
if(n->distance < 0)
abort();
- for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */
+ for splay_each(edge_t, e, n->edge_tree) { /* "e" is the edge connected to "from" */
if(!e->reverse)
continue;
extern void hash_clear(hash_t *);
extern void hash_resize(hash_t *, size_t n);
-#endif /* __TINC_HASH_H__ */
+#endif /* __TINC_HASH_H__ */
void logger(int level, int priority, const char *format, ...) {
va_list ap;
- va_start(ap, format);
- vfprintf(stderr, format, ap);
- va_end(ap);
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
}
char *strip_weight(char *netstr) {
char via[4096];
char nexthop[4096];
int code, req, cipher, digest, maclength, compression, distance;
- short int pmtu, minmtu, maxmtu;
+ short int pmtu, minmtu, maxmtu;
unsigned int options;
node_status_t status;
long int last_state_change;
if(sscanf(line, "%d %d %s", &code, &req, node) == 2)
break;
}
-
+
printf("Node: %s\n", item);
printf("Address: %s port %s\n", host, port);
#endif
uint8_t ip_tos;
uint16_t ip_len;
- uint16_t ip_id;
+ uint16_t ip_id;
uint16_t ip_off;
#define IP_RF 0x8000
#define IP_DF 0x4000
#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(a) \
- ((((__const uint32_t *) (a))[0] == 0) \
- && (((__const uint32_t *) (a))[1] == 0) \
- && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
+ ((((__const uint32_t *) (a))[0] == 0) \
+ && (((__const uint32_t *) (a))[1] == 0) \
+ && (((__const uint32_t *) (a))[2] == htonl (0xffff)))
#endif
#ifndef HAVE_STRUCT_IP6_HDR
static bool read_packet(vpn_packet_t *packet) {
int inlen;
-
+
switch(device_type) {
case DEVICE_TYPE_TUN:
inlen = read(device_fd, packet->data + 10, MTU - 10);
#define list_each(type, item, list) (type *item = (type *)1; item; item = NULL) for(list_node_t *node = (list)->head, *next; item = node ? node->data : NULL, next = node ? node->next : NULL, node; node = next)
-#endif /* __TINC_LIST_H__ */
+#endif /* __TINC_LIST_H__ */
void openlogger(const char *ident, logmode_t mode) {
logident = ident;
logmode = mode;
-
+
switch(mode) {
case LOGMODE_STDERR:
logpid = getpid();
#define __TINC_LOGGER_H__
typedef enum debug_t {
- DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */
+ DEBUG_NOTHING = 0, /* Quiet mode, only show starting/stopping of the daemon */
DEBUG_ALWAYS = 0,
- DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */
- DEBUG_ERROR = 2, /* Show error messages received from other hosts */
- DEBUG_STATUS = 2, /* Show status messages received from other hosts */
- DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */
- DEBUG_META = 4, /* Show contents of every request that is sent/received */
- DEBUG_TRAFFIC = 5, /* Show network traffic information */
- DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */
- DEBUG_SCARY_THINGS = 10 /* You have been warned */
+ DEBUG_CONNECTIONS = 1, /* Show (dis)connects of other tinc daemons via TCP */
+ DEBUG_ERROR = 2, /* Show error messages received from other hosts */
+ DEBUG_STATUS = 2, /* Show status messages received from other hosts */
+ DEBUG_PROTOCOL = 3, /* Show the requests that are sent/received */
+ DEBUG_META = 4, /* Show contents of every request that is sent/received */
+ DEBUG_TRAFFIC = 5, /* Show network traffic information */
+ DEBUG_PACKET = 6, /* Show contents of each packet that is being sent/received */
+ DEBUG_SCARY_THINGS = 10 /* You have been warned */
} debug_t;
typedef enum logmode_t {
logger(DEBUG_CONNECTIONS, LOG_ERR, "Proxy request rejected");
return false;
}
- } else
+ } else
receive_tcppacket(c, tcpbuffer, c->tcplen);
c->tcplen = 0;
continue;
extern void broadcast_meta(struct connection_t *, const char *, int);
extern bool receive_meta(struct connection_t *);
-#endif /* __TINC_META_H__ */
+#endif /* __TINC_META_H__ */
snprintf(regpath, sizeof regpath, "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, adapterid);
- if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2))
+ if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regpath, 0, KEY_READ, &key2))
continue;
len = sizeof adaptername;
snprintf(tapname, sizeof tapname, USERMODEDEVICEDIR "%s" TAPSUFFIX, device);
device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
}
-
+
if(device_handle == INVALID_HANDLE_VALUE) {
logger(DEBUG_ALWAYS, LOG_ERR, "%s (%s) is not a usable Windows tap device: %s", device, iface, winerror(GetLastError()));
return false;
#endif
} break;
#endif
-
+
default:
logger(DEBUG_ALWAYS, LOG_ERR, "Multicast for address family %hx unsupported", ai->ai_family);
goto error;
Copyright (C) 1998-2005 Ivo Timmermans,
2000-2012 Guus Sliepen <guus@tinc-vpn.org>
2006 Scott Lamb <slamb@slamb.org>
- 2011 Loïc Grenié <loic.grenie@gmail.com>
+ 2011 Loïc Grenié <loic.grenie@gmail.com>
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_config_options(config_tree, NULL);
- xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
- read_config_file(config_tree, fname);
- free(fname);
+ xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, myself->name);
+ read_config_file(config_tree, fname);
+ free(fname);
/* Parse some options that are allowed to be changed while tinc is running */
}
/* Try to make outgoing connections */
-
+
try_outgoing_connections();
/* Close connections to hosts that have a changed or deleted host config file */
#include "digest.h"
#ifdef ENABLE_JUMBOGRAMS
-#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
+#define MTU 9018 /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
#else
-#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
+#define MTU 1518 /* 1500 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
#endif
-#define MAXSIZE (MTU + 4 + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20) /* MTU + seqno + padding + HMAC + compressor overhead */
-#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128) /* Enough room for a request with a MAXSIZEd packet or a 8192 bits RSA key */
+/* MAXSIZE is the maximum size of an encapsulated packet: MTU + seqno + padding + HMAC + compressor overhead */
+#define MAXSIZE (MTU + 4 + CIPHER_MAX_BLOCK_SIZE + DIGEST_MAX_SIZE + MTU/64 + 20)
-#define MAXSOCKETS 8 /* Probably overkill... */
+/* MAXBUFSIZE is the maximum size of a request: enough for a MAXSIZEd packet or a 8192 bits RSA key */
+#define MAXBUFSIZE ((MAXSIZE > 2048 ? MAXSIZE : 2048) + 128)
+
+#define MAXSOCKETS 8 /* Probably overkill... */
typedef struct mac_t {
uint8_t x[6];
#endif
typedef struct vpn_packet_t {
- length_t len; /* the actual number of bytes in the `data' field */
- int priority; /* priority or TOS */
- uint32_t seqno; /* 32 bits sequence number (network byte order of course) */
+ length_t len; /* the actual number of bytes in the `data' field */
+ int priority; /* priority or TOS */
+ uint32_t seqno; /* 32 bits sequence number (network byte order of course) */
uint8_t data[MAXSIZE];
} vpn_packet_t;
extern CRITICAL_SECTION mutex;
#endif
-#endif /* __TINC_NET_H__ */
+#endif /* __TINC_NET_H__ */
static void send_mtu_probe_handler(int fd, short events, void *data) {
node_t *n = data;
int timeout = 1;
-
+
n->mtuprobes++;
if(!n->status.reachable || !n->status.validkey) {
if(len < 64)
len = 64;
-
+
vpn_packet_t packet;
memset(packet.data, 0, 14);
randomize(packet.data + 14, len - 14);
return -1;
#endif
}
-
+
return -1;
}
if(digest_active(&n->indigest)) {
inpkt->len -= n->indigest.maclength;
- if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) {
+ if(!digest_verify(&n->indigest, &inpkt->seqno, inpkt->len, (const char *)&inpkt->seqno + inpkt->len)) {
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Got unauthenticated packet from %s (%s)", n->name, n->hostname);
return;
}
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Error decrypting packet from %s (%s)", n->name, n->hostname);
return;
}
-
+
outpkt->len = outlen;
inpkt = outpkt;
}
return;
}
logger(DEBUG_ALWAYS, LOG_WARNING, "Lost %d packets from %s (%s)",
- inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
+ inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
memset(n->late, 0, replaywin);
} else if (inpkt->seqno <= n->received_seqno) {
if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) {
logger(DEBUG_ALWAYS, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
- n->name, n->hostname, inpkt->seqno, n->received_seqno);
+ n->name, n->hostname, inpkt->seqno, n->received_seqno);
return;
}
} else {
if(inpkt->seqno > n->received_seqno)
n->received_seqno = inpkt->seqno;
-
+
if(n->received_seqno > MAX_SEQNO)
regenerate_key();
if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)",
- n->name, n->hostname);
+ n->name, n->hostname);
return;
}
&& listen_socket[n->sock].sa.sa.sa_family == AF_INET) {
priority = origpriority;
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting outgoing packet priority to %d", priority);
- if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
+ if(setsockopt(listen_socket[n->sock].udp, SOL_IP, IP_TOS, &priority, sizeof(priority))) /* SO_PRIORITY doesn't seem to work */
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", strerror(errno));
}
#endif
send_packet(myself, packet);
// In TunnelServer mode, do not forward broadcast packets.
- // The MST might not be valid and create loops.
+ // The MST might not be valid and create loops.
if(tunnelserver || broadcast_mode == BMODE_NONE)
return;
break;
// In direct mode, we send copies to each node we know of.
- // However, this only reaches nodes that can be reached in a single hop.
+ // However, this only reaches nodes that can be reached in a single hop.
// We don't have enough information to forward broadcast packets in this case.
case BMODE_DIRECT:
if(from != myself)
pkt.len = len;
- sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
+ sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
n = lookup_node_udp(&from);
result = rsa_read_pem_public_key(&c->rsa, fp);
fclose(fp);
- if(!result)
+ if(!result)
logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno));
free(fname);
return result;
result = ecdsa_read_pem_private_key(&myself->connection->ecdsa, fp);
fclose(fp);
- if(!result)
+ if(!result)
logger(DEBUG_ALWAYS, LOG_ERR, "Reading ECDSA private key file `%s' failed: %s", fname, strerror(errno));
free(fname);
return result;
result = rsa_read_pem_private_key(&myself->connection->rsa, fp);
fclose(fp);
- if(!result)
+ if(!result)
logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno));
free(fname);
return result;
scriptinterpreter = NULL;
get_config_string(lookup_config(config_tree, "ScriptsInterpreter"), &scriptinterpreter);
-
+
free(scriptextension);
if(!get_config_string(lookup_config(config_tree, "ScriptsExtension"), &scriptextension))
#ifdef HAVE_MINGW
get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
-
+
if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) {
if(!strcasecmp(rmode, "router"))
routing_mode = RMODE_ROUTER;
listen_socket[i].tcp = i + 3;
#ifdef FD_CLOEXEC
- fcntl(i + 3, F_SETFD, FD_CLOEXEC);
+ fcntl(i + 3, F_SETFD, FD_CLOEXEC);
#endif
listen_socket[i].udp = setup_vpn_in_socket(&sa);
event_set(&c->inevent, c->socket, EV_READ | EV_PERSIST, handle_meta_connection_data, c);
event_set(&c->outevent, c->socket, EV_WRITE | EV_PERSIST, handle_meta_write, c);
event_add(&c->inevent, NULL);
-
+
configure_tcp(c);
connection_add(c);
scopeid = strchr(address, '%');
if(scopeid)
- *scopeid = '\0'; /* Descope. */
+ *scopeid = '\0'; /* Descope. */
if(addrstr)
*addrstr = xstrdup(address);
free(a->unknown.port);
}
}
-
+
void sockaddrunmap(sockaddr_t *sa) {
if(sa->sa.sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->in6.sin6_addr)) {
sa->in.sin_addr.s_addr = ((uint32_t *) & sa->in6.sin6_addr)[3];
extern void sockaddrfree(sockaddr_t *);
extern void sockaddrcpy(sockaddr_t *, const sockaddr_t *);
-#endif /* __TINC_NETUTL_H__ */
+#endif /* __TINC_NETUTL_H__ */
#include "utils.h"
#include "xalloc.h"
-splay_tree_t *node_tree; /* Known nodes, sorted by name */
+splay_tree_t *node_tree;
static hash_t *node_udp_cache;
node_t *myself;
if(timeout_initialized(&n->mtuevent))
event_del(&n->mtuevent);
-
+
if(n->hostname)
free(n->hostname);
#include "subnet.h"
typedef struct node_status_t {
- unsigned int unused_active:1; /* 1 if active (not used for nodes) */
- unsigned int validkey:1; /* 1 if we currently have a valid key for him */
- unsigned int waitingforkey:1; /* 1 if we already sent out a request */
- unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
- unsigned int reachable:1; /* 1 if this node is reachable in the graph */
- unsigned int indirect:1; /* 1 if this node is not directly reachable by us */
+ unsigned int unused_active:1; /* 1 if active (not used for nodes) */
+ unsigned int validkey:1; /* 1 if we currently have a valid key for him */
+ unsigned int waitingforkey:1; /* 1 if we already sent out a request */
+ unsigned int visited:1; /* 1 if this node has been visited by one of the graph algorithms */
+ unsigned int reachable:1; /* 1 if this node is reachable in the graph */
+ unsigned int indirect:1; /* 1 if this node is not directly reachable by us */
unsigned int sptps:1; /* 1 if this node supports SPTPS */
- unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */
+ unsigned int udp_confirmed:1; /* 1 if the address is one that we received UDP traffic on */
unsigned int unused:24;
} node_status_t;
typedef struct node_t {
- char *name; /* name of this node */
- uint32_t options; /* options turned on for this node */
+ char *name; /* name of this node */
+ uint32_t options; /* options turned on for this node */
- int sock; /* Socket to use for outgoing UDP packets */
- sockaddr_t address; /* his real (internet) ip to send UDP packets to */
- char *hostname; /* the hostname of its real ip */
+ int sock; /* Socket to use for outgoing UDP packets */
+ sockaddr_t address; /* his real (internet) ip to send UDP packets to */
+ char *hostname; /* the hostname of its real ip */
node_status_t status;
time_t last_state_change;
time_t last_req_key;
- ecdsa_t ecdsa; /* His public ECDSA key */
+ ecdsa_t ecdsa; /* His public ECDSA key */
sptps_t sptps;
- cipher_t incipher; /* Cipher for UDP packets */
- digest_t indigest; /* Digest for UDP packets */
+ cipher_t incipher; /* Cipher for UDP packets */
+ digest_t indigest; /* Digest for UDP packets */
- cipher_t outcipher; /* Cipher for UDP packets */
- digest_t outdigest; /* Digest for UDP packets */
+ cipher_t outcipher; /* Cipher for UDP packets */
+ digest_t outdigest; /* Digest for UDP packets */
- int incompression; /* Compressionlevel, 0 = no compression */
- int outcompression; /* Compressionlevel, 0 = no compression */
+ int incompression; /* Compressionlevel, 0 = no compression */
+ int outcompression; /* Compressionlevel, 0 = no compression */
int distance;
- struct node_t *nexthop; /* nearest node from us to him */
- struct edge_t *prevedge; /* nearest node from him to us */
- struct node_t *via; /* next hop for UDP packets */
+ struct node_t *nexthop; /* nearest node from us to him */
+ struct edge_t *prevedge; /* nearest node from him to us */
+ struct node_t *via; /* next hop for UDP packets */
- splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */
+ splay_tree_t *subnet_tree; /* Pointer to a tree of subnets belonging to this node */
- splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
+ splay_tree_t *edge_tree; /* Edges with this node as one of the endpoints */
- struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
+ struct connection_t *connection; /* Connection associated with this node (if a direct connection exists) */
- uint32_t sent_seqno; /* Sequence number last sent to this node */
- uint32_t received_seqno; /* Sequence number last received from this node */
- uint32_t farfuture; /* Packets in a row that have arrived from the far future */
- unsigned char* late; /* Bitfield marking late packets */
+ uint32_t sent_seqno; /* Sequence number last sent to this node */
+ uint32_t received_seqno; /* Sequence number last received from this node */
+ uint32_t farfuture; /* Packets in a row that have arrived from the far future */
+ unsigned char* late; /* Bitfield marking late packets */
- length_t mtu; /* Maximum size of packets to send to this node */
- length_t minmtu; /* Probed minimum MTU */
- length_t maxmtu; /* Probed maximum MTU */
- int mtuprobes; /* Number of probes */
- struct event mtuevent; /* Probe event */
+ length_t mtu; /* Maximum size of packets to send to this node */
+ length_t minmtu; /* Probed minimum MTU */
+ length_t maxmtu; /* Probed maximum MTU */
+ int mtuprobes; /* Number of probes */
+ struct event mtuevent; /* Probe event */
uint64_t in_packets;
uint64_t in_bytes;
extern bool dump_traffic(struct connection_t *);
extern void update_node_udp(node_t *, const sockaddr_t *);
-#endif /* __TINC_NODE_H__ */
+#endif /* __TINC_NODE_H__ */
unsigned char *out = outdata;
while(inlen--) {
- // Encrypt the new counter value if we need it
+ // Encrypt the new counter value if we need it
if(!cipher->counter->n) {
int len;
if(!EVP_EncryptUpdate(&cipher->ctx, cipher->counter->block, &len, cipher->counter->counter, cipher->cipher->block_size)) {
#include "crypto.h"
void crypto_init(void) {
- RAND_load_file("/dev/urandom", 1024);
+ RAND_load_file("/dev/urandom", 1024);
- ENGINE_load_builtin_engines();
- ENGINE_register_all_complete();
+ ENGINE_load_builtin_engines();
+ ENGINE_register_all_complete();
- OpenSSL_add_all_algorithms();
+ OpenSSL_add_all_algorithms();
}
void crypto_exit(void) {
logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL));
return false;
}
-
+
const EC_POINT *point = EC_KEY_get0_public_key(*ecdh);
if(!point) {
EC_KEY_free(*ecdh);
logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL));
return false;
}
-
+
int len = strlen(p);
unsigned char pubkey[len / 4 * 3 + 3];
const unsigned char *ppubkey = pubkey;
if(*ecdsa)
return true;
-
+
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
return false;
}
static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) {
digest_t digest;
-
+
if(!digest_open_by_nid(&digest, nid, -1))
return false;
if(*rsa)
return true;
-
+
*rsa = PEM_read_RSA_PUBKEY(fp, rsa, NULL, NULL);
if(*rsa)
if(*rsa)
return true;
-
+
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read RSA private key: %s", ERR_error_string(ERR_get_error(), NULL));
return false;
}
return true;
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA encryption: %s", ERR_error_string(ERR_get_error(), NULL));
- return false;
+ return false;
}
bool rsa_private_decrypt(rsa_t *rsa, void *in, size_t len, void *out) {
return true;
logger(DEBUG_ALWAYS, LOG_ERR, "Unable to perform RSA decryption: %s", ERR_error_string(ERR_get_error(), NULL));
- return false;
+ return false;
}
bool rsa_active(rsa_t *rsa) {
for(char **argp = g_argv + 1; *argp; argp++) {
char &space = strchr(*argp, ' ');
strncat(command, " ", sizeof command - strlen(command));
-
+
if(space)
strncat(command, "\"", sizeof command - strlen(command));
-
+
strncat(command, *argp, sizeof command - strlen(command));
if(space)
service = CreateService(manager, identname, identname,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
command, NULL, NULL, NULL, NULL, NULL);
-
+
if(!service) {
DWORD lasterror = GetLastError();
logger(DEBUG_ALWAYS, LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror));
}
event_loopexit(NULL);
- status.dwWaitHint = 30000;
- status.dwCurrentState = SERVICE_STOP_PENDING;
+ status.dwWaitHint = 30000;
+ status.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(statushandle, &status);
return NO_ERROR;
}
extern int main2(int argc, char **argv);
- status.dwServiceType = SERVICE_WIN32;
+ status.dwServiceType = SERVICE_WIN32;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
- status.dwWin32ExitCode = 0;
- status.dwServiceSpecificExitCode = 0;
- status.dwCheckPoint = 0;
+ status.dwWin32ExitCode = 0;
+ status.dwServiceSpecificExitCode = 0;
+ status.dwCheckPoint = 0;
- statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL);
+ statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL);
if (!statushandle) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError()));
err = 1;
} else {
- status.dwWaitHint = 30000;
- status.dwCurrentState = SERVICE_START_PENDING;
+ status.dwWaitHint = 30000;
+ status.dwCurrentState = SERVICE_START_PENDING;
SetServiceStatus(statushandle, &status);
- status.dwWaitHint = 0;
+ status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(statushandle, &status);
err = main2(argc, argv);
status.dwWaitHint = 0;
- status.dwCurrentState = SERVICE_STOPPED;
- //status.dwWin32ExitCode = err;
+ status.dwCurrentState = SERVICE_STOPPED;
+ //status.dwWin32ExitCode = err;
SetServiceStatus(statushandle, &status);
}
#ifdef HAVE_PUTENV
/* Set environment */
-
+
for(int i = 0; envp[i]; i++)
putenv(envp[i]);
#endif
#ifdef WEXITSTATUS
if(status != -1) {
- if(WIFEXITED(status)) { /* Child exited by itself */
+ if(WIFEXITED(status)) { /* Child exited by itself */
if(WEXITSTATUS(status)) {
logger(DEBUG_ALWAYS, LOG_ERR, "Script %s exited with non-zero status %d",
name, WEXITSTATUS(status));
return false;
}
- } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */
+ } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */
logger(DEBUG_ALWAYS, LOG_ERR, "Script %s was killed by signal %d (%s)",
name, WTERMSIG(status), strsignal(WTERMSIG(status)));
return false;
- } else { /* Something strange happened */
+ } else { /* Something strange happened */
logger(DEBUG_ALWAYS, LOG_ERR, "Script %s terminated abnormally", name);
return false;
}
extern bool init_service(void);
#endif
-#endif /* __TINC_PROCESS_H__ */
+#endif /* __TINC_PROCESS_H__ */
/* Request numbers */
typedef enum request_t {
- ALL = -1, /* Guardian for allow_request */
+ ALL = -1, /* Guardian for allow_request */
ID = 0, METAKEY, CHALLENGE, CHAL_REPLY, ACK,
STATUS, ERROR, TERMREQ,
PING, PONG,
REQ_PUBKEY, ANS_PUBKEY,
REQ_SPTPS,
REQ_PACKET,
- LAST /* Guardian for the highest request number */
+ LAST /* Guardian for the highest request number */
} request_t;
typedef struct past_request_t {
extern bool tcppacket_h(struct connection_t *, const char *);
extern bool control_h(struct connection_t *, const char *);
-#endif /* __TINC_PROTOCOL_H__ */
+#endif /* __TINC_PROTOCOL_H__ */
c->allow_request = CONTROL;
c->last_ping_time = time(NULL) + 3600;
- free(c->name);
- c->name = xstrdup("<control>");
+ free(c->name);
+ c->name = xstrdup("<control>");
return send_request(c, "%d %d %d", ACK, TINC_CTL_VERSION_CURRENT, getpid());
}
if(!cipher_open_blowfish_ofb(&c->outcipher))
return false;
-
+
if(!digest_open_sha1(&c->outdigest, -1))
return false;
cipher_get_nid(&c->outcipher),
digest_get_nid(&c->outdigest), c->outmaclength,
c->outcompression, hexkey);
-
+
c->status.encryptout = true;
return result;
}
logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself",
"DEL_EDGE", c->name, c->hostname);
contradicting_del_edge++;
- send_add_edge(c, e); /* Send back a correction */
+ send_add_edge(c, e); /* Send back a correction */
return true;
}
send_request(to->nexthop->connection, "%d %s %s %d", REQ_KEY, myself->name, to->name, REQ_PUBKEY);
return true;
}
- char label[25 + strlen(myself->name) + strlen(to->name)];
+ char label[25 + strlen(myself->name) + strlen(to->name)];
snprintf(label, sizeof label, "tinc UDP key expansion %s %s", myself->name, to->name);
sptps_stop(&to->sptps);
to->status.validkey = false;
to->status.waitingforkey = true;
to->last_req_key = time(NULL);
to->incompression = myself->incompression;
- return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record);
+ return sptps_start(&to->sptps, to, true, true, myself->connection->ecdsa, to->ecdsa, label, sizeof label, send_initial_sptps_data, receive_sptps_record);
}
return send_request(to->nexthop->connection, "%d %s %s", REQ_KEY, myself->name, to->name);
from->status.validkey = false;
from->status.waitingforkey = true;
from->last_req_key = time(NULL);
- sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record);
+ sptps_start(&from->sptps, from, false, true, myself->connection->ecdsa, from->ecdsa, label, sizeof label, send_sptps_data, receive_sptps_record);
sptps_receive_data(&from->sptps, buf, len);
return true;
}
/* Check if this key request is for us */
- if(to == myself) { /* Yes */
+ if(to == myself) { /* Yes */
/* Is this an extended REQ_KEY message? */
if(experimental && reqno)
return req_key_ext_h(c, request, from, reqno);
char from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE];
char key[MAX_STRING_SIZE];
- char address[MAX_STRING_SIZE] = "";
- char port[MAX_STRING_SIZE] = "";
+ char address[MAX_STRING_SIZE] = "";
+ char port[MAX_STRING_SIZE] = "";
int cipher, digest, maclength, compression, keylen;
node_t *from, *to;
bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) {
/* If there already is a lot of data in the outbuf buffer, discard this packet.
- We use a very simple Random Early Drop algorithm. */
+ We use a very simple Random Early Drop algorithm. */
if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX)
return true;
if(tunnelserver && owner != myself && owner != c->node) {
/* in case of tunnelserver, ignore indirect subnet deletion */
logger(DEBUG_PROTOCOL, LOG_WARNING, "Ignoring indirect %s from %s (%s) for %s",
- "DEL_SUBNET", c->name, c->hostname, subnetstr);
+ "DEL_SUBNET", c->name, c->hostname, subnetstr);
return true;
}
checksum += *p++;
len -= 2;
}
-
+
if(len)
checksum += *(uint8_t *)p;
static time_t lasttime = 0;
static int count = 0;
time_t now = time(NULL);
-
+
if(lasttime == now) {
if(count >= frequency)
return true;
if(oldmss <= newmss)
break;
-
+
logger(DEBUG_TRAFFIC, LOG_INFO, "Clamping MSS of packet from %s to %s to %d", source->name, via->name, newmss);
/* Update the MSS value and the checksum */
memcpy(&packet->data[0], &packet->data[6], sizeof tmp);
memcpy(&packet->data[6], &tmp, sizeof tmp);
}
-
+
static void age_subnets(int fd, short events, void *data) {
bool left = false;
time_t now = time(NULL);
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) {
struct ip ip = {0};
struct icmp icmp = {0};
-
+
struct in_addr ip_src;
struct in_addr ip_dst;
uint32_t oldlen;
if(ratelimit(3))
return;
-
+
/* Swap Ethernet source and destination addresses */
swap_mac_addresses(packet);
memcpy(&ip, packet->data + ether_size, ip_size);
/* Remember original source and destination */
-
+
ip_src = ip.ip_src;
ip_dst = ip.ip_dst;
if(oldlen >= IP_MSS - ip_size - icmp_size)
oldlen = IP_MSS - ip_size - icmp_size;
-
+
/* Copy first part of original contents to ICMP message */
-
+
memmove(packet->data + ether_size + ip_size + icmp_size, packet->data + ether_size, oldlen);
/* Fill in IPv4 header */
-
+
ip.ip_v = 4;
ip.ip_hl = ip_size / 4;
ip.ip_tos = 0;
ip.ip_dst = ip_src;
ip.ip_sum = inet_checksum(&ip, ip_size, ~0);
-
+
/* Fill in ICMP header */
-
+
icmp.icmp_type = type;
icmp.icmp_code = code;
icmp.icmp_cksum = 0;
-
+
icmp.icmp_cksum = inet_checksum(&icmp, icmp_size, ~0);
icmp.icmp_cksum = inet_checksum(packet->data + ether_size + ip_size + icmp_size, oldlen, icmp.icmp_cksum);
memcpy(packet->data + ether_size, &ip, ip_size);
memcpy(packet->data + ether_size + ip_size, &icmp, icmp_size);
-
+
packet->len = ether_size + ip_size + icmp_size + oldlen;
send_packet(source, packet);
int len, maxlen, todo;
uint8_t *offset;
uint16_t ip_off, origf;
-
+
memcpy(&ip, packet->data + ether_size, ip_size);
fragment.priority = packet->priority;
if(ip.ip_hl != ip_size / 4)
return;
-
+
todo = ntohs(ip.ip_len) - ip_size;
if(ether_size + ip_size + todo != packet->len) {
ip_off = ntohs(ip.ip_off);
origf = ip_off & ~IP_OFFMASK;
ip_off &= IP_OFFMASK;
-
+
while(todo) {
len = todo > maxlen ? maxlen : todo;
memcpy(fragment.data + ether_size + ip_size, offset, len);
send_packet(dest, &fragment);
ip_off += len / 8;
- }
+ }
}
static void route_ipv4_unicast(node_t *source, vpn_packet_t *packet) {
route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_UNKNOWN);
return;
}
-
+
if(subnet->owner == source) {
logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet looping back to %s (%s)!", source->name, source->hostname);
return;
logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
return;
}
-
+
if(directonly && subnet->owner != via)
return route_ipv4_unreachable(source, packet, ICMP_DEST_UNREACH, ICMP_NET_ANO);
}
clamp_mss(source, via, packet);
-
+
send_packet(subnet->owner, packet);
}
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, uint8_t type, uint8_t code) {
struct ip6_hdr ip6;
struct icmp6_hdr icmp6 = {0};
- uint16_t checksum;
+ uint16_t checksum;
struct {
- struct in6_addr ip6_src; /* source address */
- struct in6_addr ip6_dst; /* destination address */
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* destination address */
uint32_t length;
uint32_t next;
} pseudo;
if(ratelimit(3))
return;
-
+
/* Swap Ethernet source and destination addresses */
swap_mac_addresses(packet);
memcpy(&ip6, packet->data + ether_size, ip6_size);
/* Remember original source and destination */
-
+
pseudo.ip6_src = ip6.ip6_dst;
pseudo.ip6_dst = ip6.ip6_src;
if(type == ICMP6_PACKET_TOO_BIG)
icmp6.icmp6_mtu = htonl(pseudo.length);
-
+
if(pseudo.length >= IP_MSS - ip6_size - icmp6_size)
pseudo.length = IP_MSS - ip6_size - icmp6_size;
-
+
/* Copy first part of original contents to ICMP message */
-
+
memmove(packet->data + ether_size + ip6_size + icmp6_size, packet->data + ether_size, pseudo.length);
/* Fill in IPv6 header */
-
+
ip6.ip6_flow = htonl(0x60000000UL);
ip6.ip6_plen = htons(icmp6_size + pseudo.length);
ip6.ip6_nxt = IPPROTO_ICMPV6;
ip6.ip6_dst = pseudo.ip6_dst;
/* Fill in ICMP header */
-
+
icmp6.icmp6_type = type;
icmp6.icmp6_code = code;
icmp6.icmp6_cksum = 0;
/* Create pseudo header */
-
+
pseudo.length = htonl(icmp6_size + pseudo.length);
pseudo.next = htonl(IPPROTO_ICMPV6);
/* Generate checksum */
-
+
checksum = inet_checksum(&pseudo, sizeof pseudo, ~0);
checksum = inet_checksum(&icmp6, icmp6_size, checksum);
checksum = inet_checksum(packet->data + ether_size + ip6_size + icmp6_size, ntohl(pseudo.length) - icmp6_size, checksum);
memcpy(packet->data + ether_size, &ip6, ip6_size);
memcpy(packet->data + ether_size + ip6_size, &icmp6, icmp6_size);
-
+
packet->len = ether_size + ip6_size + ntohl(pseudo.length);
-
+
send_packet(source, packet);
}
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
via = (subnet->owner->via == myself) ? subnet->owner->nexthop : subnet->owner->via;
-
+
if(via == source) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Routing loop for packet from %s (%s)!", source->name, source->hostname);
return;
}
-
+
if(directonly && subnet->owner != via)
return route_ipv6_unreachable(source, packet, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_ADMIN);
}
clamp_mss(source, via, packet);
-
+
send_packet(subnet->owner, packet);
}
bool has_opt;
struct {
- struct in6_addr ip6_src; /* source address */
- struct in6_addr ip6_dst; /* destination address */
+ struct in6_addr ip6_src;
+ struct in6_addr ip6_dst;
uint32_t length;
uint32_t next;
} pseudo;
if(!checklength(source, packet, ether_size + ip6_size + ns_size))
return;
-
+
has_opt = packet->len >= ether_size + ip6_size + ns_size + opt_size + ETH_ALEN;
-
+
if(source != myself) {
logger(DEBUG_TRAFFIC, LOG_WARNING, "Got neighbor solicitation request from %s (%s) while in router mode!", source->name, source->hostname);
return;
/* Check if it is for our own subnet */
if(subnet->owner == myself)
- return; /* silently ignore */
+ return; /* silently ignore */
/* Create neighbor advertation reply */
- memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
- packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
+ memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
+ packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
- ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */
+ ip6.ip6_dst = ip6.ip6_src; /* swap destination and source protocoll address */
ip6.ip6_src = ns.nd_ns_target;
if(has_opt)
- memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
+ memcpy(packet->data + ether_size + ip6_size + ns_size + opt_size, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
ns.nd_ns_cksum = 0;
ns.nd_ns_type = ND_NEIGHBOR_ADVERT;
- ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */
+ ns.nd_ns_reserved = htonl(0x40000000UL); /* Set solicited flag */
opt.nd_opt_type = ND_OPT_TARGET_LINKADDR;
/* Create pseudo header */
/* Check if it is for our own subnet */
if(subnet->owner == myself)
- return; /* silently ignore */
+ return; /* silently ignore */
- memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
- packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
+ memcpy(packet->data, packet->data + ETH_ALEN, ETH_ALEN); /* copy destination address */
+ packet->data[ETH_ALEN * 2 - 1] ^= 0xFF; /* mangle source address so it looks like it's not from us */
- memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */
- memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */
- memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */
+ memcpy(&addr, arp.arp_tpa, sizeof addr); /* save protocol addr */
+ memcpy(arp.arp_tpa, arp.arp_spa, sizeof addr); /* swap destination and source protocol address */
+ memcpy(arp.arp_spa, &addr, sizeof addr); /* ... */
- memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */
- memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
+ memcpy(arp.arp_tha, arp.arp_sha, ETH_ALEN); /* set target hard/proto addr */
+ memcpy(arp.arp_sha, packet->data + ETH_ALEN, ETH_ALEN); /* add fake source hard addr */
arp.arp_op = htons(ARPOP_REPLY);
/* Copy structs on stack back to packet */
if(directonly && subnet->owner != via)
return;
-
+
if(via && packet->len > via->mtu && via != myself) {
logger(DEBUG_TRAFFIC, LOG_INFO, "Packet for %s (%s) length %d larger than MTU %d", subnet->owner->name, subnet->owner->hostname, packet->len, via->mtu);
uint16_t type = packet->data[12] << 8 | packet->data[13];
}
clamp_mss(source, via, packet);
-
+
send_packet(subnet->owner, packet);
}
if(!do_decrement_ttl(source, packet))
return;
+ uint16_t type = packet->data[12] << 8 | packet->data[13];
+
switch (routing_mode) {
case RMODE_ROUTER:
- {
- uint16_t type = packet->data[12] << 8 | packet->data[13];
-
- switch (type) {
- case ETH_P_ARP:
- route_arp(source, packet);
- break;
-
- case ETH_P_IP:
- route_ipv4(source, packet);
- break;
-
- case ETH_P_IPV6:
- route_ipv6(source, packet);
- break;
-
- default:
- logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type);
- break;
- }
+ switch (type) {
+ case ETH_P_ARP:
+ route_arp(source, packet);
+ break;
+
+ case ETH_P_IP:
+ route_ipv4(source, packet);
+ break;
+
+ case ETH_P_IPV6:
+ route_ipv6(source, packet);
+ break;
+
+ default:
+ logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot route packet from %s (%s): unknown type %hx", source->name, source->hostname, type);
+ break;
}
break;
/*
route.h -- header file for route.c
Copyright (C) 2000-2005 Ivo Timmermans
- 2000-2012 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2012 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 void route(struct node_t *, struct vpn_packet_t *);
-#endif /* __TINC_ROUTE_H__ */
+#endif /* __TINC_ROUTE_H__ */
rightbottom->left = child;
child->parent = rightbottom;
rightbottom = child;
-
+
if((root->left = child->right))
child->right->parent = root;
-
+
child->right = root;
root->parent = child;
rightbottom->left = root;
root->parent = rightbottom;
rightbottom = root;
-
+
root->left = NULL;
child->parent = NULL;
leftbottom->right = child;
child->parent = leftbottom;
leftbottom = child;
-
+
if((root->right = child->left))
child->left->parent = root;
-
+
child->left = root;
root->parent = child;
return tree->root;
}
-
+
static void splay_bottom_up(splay_tree_t *tree, splay_node_t *node) {
splay_node_t *parent, *grandparent, *greatgrandparent;
while((parent = node->parent)) {
if(!(grandparent = parent->parent)) { /* zig */
if(node == parent->left) {
- if((parent->left = node->right))
+ if((parent->left = node->right))
parent->left->parent = parent;
node->right = parent;
} else {
} else if(c > 0) {
if(node->right)
node = node->right;
- else
+ else
break;
} else {
break;
new = splay_alloc_node();
new->data = data;
-
+
if(result < 0)
splay_insert_before(tree, closest, new);
else
splay_insert_after(tree, closest, new);
- }
+ }
return new;
}
splay_insert_top(tree, node);
else {
closest = splay_search_closest_node(tree, node->data, &result);
-
+
if(!result)
return NULL;
s->buflen += toread;
len -= toread;
data += toread;
-
+
// Exit early if we don't have the full length.
if(s->buflen < 6)
return true;
hint.ai_socktype = SOCK_STREAM;
hint.ai_protocol = IPPROTO_TCP;
hint.ai_flags = initiator ? 0 : AI_PASSIVE;
-
+
if(getaddrinfo(initiator ? argv[3] : NULL, initiator ? argv[4] : argv[3], &hint, &ai) || !ai) {
fprintf(stderr, "getaddrinfo() failed: %s\n", strerror(errno));
return 1;
SUBNET_MAC = 0,
SUBNET_IPV4,
SUBNET_IPV6,
- SUBNET_TYPES /* Guardian */
+ SUBNET_TYPES /* Guardian */
} subnet_type_t;
typedef struct subnet_mac_t {
#include "node.h"
typedef struct subnet_t {
- struct node_t *owner; /* the owner of this subnet */
+ struct node_t *owner; /* the owner of this subnet */
- subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
- time_t expires; /* expiry time */
- int weight; /* weight (higher value is higher priority) */
+ subnet_type_t type; /* subnet type (IPv4? IPv6? MAC? something even weirder?) */
+ time_t expires; /* expiry time */
+ int weight; /* weight (higher value is higher priority) */
/* And now for the actual subnet: */
extern bool dump_subnets(struct connection_t *);
extern void subnet_cache_flush(void);
-#endif /* __TINC_SUBNET_H__ */
+#endif /* __TINC_SUBNET_H__ */
if(result)
return result;
-
+
result = a->weight - b->weight;
if(result || !a->owner || !b->owner)
if(result)
return result;
-
+
result = a->weight - b->weight;
if(result || !a->owner || !b->owner)
if(result)
return result;
-
+
result = memcmp(&a->net.ipv6.address, &b->net.ipv6.address, sizeof(ipv6_t));
if(result)
return result;
-
+
result = a->weight - b->weight;
if(result || !a->owner || !b->owner)
static bool show_version = false;
static char *name = NULL;
-static char *identname = NULL; /* program name for syslog */
-static char *pidfilename = NULL; /* pid file location */
+static char *identname = NULL; /* program name for syslog */
+static char *pidfilename = NULL; /* pid file location */
static char *confdir = NULL;
static char controlcookie[1024];
char *netname = NULL;
while((r = getopt_long(argc, argv, "c:n:Dd::Lo:RU:", long_options, &option_index)) != EOF) {
switch (r) {
- case 0: /* long option */
+ case 0: /* long option */
break;
- case 'c': /* config file */
+ case 'c': /* config file */
confbase = xstrdup(optarg);
break;
- case 'n': /* net name given */
+ case 'n': /* net name given */
netname = xstrdup(optarg);
break;
- case 1: /* show help */
+ case 1: /* show help */
show_help = true;
break;
- case 2: /* show version */
+ case 2: /* show version */
show_version = true;
break;
- case 5: /* open control socket here */
+ case 5: /* open control socket here */
pidfilename = xstrdup(optarg);
break;
- case 6:
+ case 6: /* force */
force = true;
break;
- case '?':
+ case '?': /* wrong options */
usage(true);
return false;
}
}
- if(!netname && (netname = getenv("NETNAME")))
- netname = xstrdup(netname);
+ if(!netname && (netname = getenv("NETNAME")))
+ netname = xstrdup(netname);
- /* netname "." is special: a "top-level name" */
+ /* netname "." is special: a "top-level name" */
- if(netname && (!*netname || !strcmp(netname, "."))) {
- free(netname);
- netname = NULL;
- }
+ if(netname && (!*netname || !strcmp(netname, "."))) {
+ free(netname);
+ netname = NULL;
+ }
if(netname && (strpbrk(netname, "\\/") || *netname == '.')) {
fprintf(stderr, "Invalid character in netname!\n");
filename = buf2;
}
- umask(0077); /* Disallow everything for group and other */
+ umask(0077); /* Disallow everything for group and other */
disable_old_keys(filename, what);
if(!f)
return false;
-
+
#ifdef HAVE_FCHMOD
/* Make it unreadable for others. */
fchmod(fileno(f), 0600);
#endif
-
+
ecdsa_write_pem_private_key(&key, f);
fclose(f);
if(!f)
return false;
-
+
#ifdef HAVE_FCHMOD
/* Make it unreadable for others. */
fchmod(fileno(f), 0600);
#endif
-
+
rsa_write_pem_private_key(&key, f);
fclose(f);
blen -= result;
}
- return true;
+ return true;
}
static void pcap(int fd, FILE *out, int snaplen) {
}
sendline(fd, "%d ^%s %d", ID, controlcookie, TINC_CTL_VERSION_CURRENT);
-
+
if(!recvline(fd, line, sizeof line) || sscanf(line, "%d %d %d", &code, &version, &pid) != 3 || code != 4 || version != TINC_CTL_VERSION_CURRENT) {
if(verbose)
fprintf(stderr, "Could not fully establish control socket connection\n");
if(!pid)
exit(execvp(c, nargv));
-
+
free(nargv);
int status = -1;
char *value;
int len;
- len = strcspn(line, "\t =");
- value = line + len;
- value += strspn(value, "\t ");
- if(*value == '=') {
- value++;
- value += strspn(value, "\t ");
- }
- line[len] = '\0';
+ len = strcspn(line, "\t =");
+ value = line + len;
+ value += strspn(value, "\t ");
+ if(*value == '=') {
+ value++;
+ value += strspn(value, "\t ");
+ }
+ line[len] = '\0';
variable = strchr(line, '.');
if(variable) {
node = line;
if(!parse_options(argc, argv))
return 1;
-
+
make_names();
if(show_version) {
/* If nonzero, write log entries to a separate file. */
bool use_logfile = false;
-char *identname = NULL; /* program name for syslog */
-char *logfilename = NULL; /* log file location */
+char *identname = NULL; /* program name for syslog */
+char *logfilename = NULL; /* log file location */
char *pidfilename = NULL;
-char **g_argv; /* a copy of the cmdline arguments */
+char **g_argv; /* a copy of the cmdline arguments */
static int status = 1;
program_name);
else {
printf("Usage: %s [option]...\n\n", program_name);
- printf( " -c, --config=DIR Read configuration options from DIR.\n"
+ 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"
" --bypass-security Disables meta protocol security, for debugging.\n"
" -o, --option[HOST.]KEY=VALUE Set global/host configuration value.\n"
" -R, --chroot chroot to NET dir at startup.\n"
- " -U, --user=USER setuid to given USER at startup.\n" " --help Display this help and exit.\n"
+ " -U, --user=USER setuid to given USER at startup.\n" " --help Display this help and exit.\n"
" --version Output version information and exit.\n\n");
printf("Report bugs to tinc@tinc-vpn.org.\n");
}
while((r = getopt_long(argc, argv, "c:DLd::n:o:RU:", long_options, &option_index)) != EOF) {
switch (r) {
- case 0: /* long option */
+ case 0: /* long option */
break;
- case 'c': /* config file */
+ case 'c': /* config file */
confbase = xstrdup(optarg);
break;
- case 'D': /* no detach */
+ case 'D': /* no detach */
do_detach = false;
break;
- case 'L': /* no detach */
+ case 'L': /* no detach */
#ifndef HAVE_MLOCKALL
logger(DEBUG_ALWAYS, LOG_ERR, "%s not supported on this platform", "mlockall()");
return false;
break;
#endif
- case 'd': /* inc debug level */
+ case 'd': /* inc debug level */
if(optarg)
debug_level = atoi(optarg);
else
debug_level++;
break;
- case 'n': /* net name given */
+ case 'n': /* net name given */
netname = xstrdup(optarg);
break;
- case 'o': /* option */
+ case 'o': /* option */
cfg = parse_config_line(optarg, NULL, ++lineno);
if (!cfg)
return false;
list_insert_tail(cmdline_conf, cfg);
break;
- case 'R': /* chroot to NETNAME dir */
+ case 'R': /* chroot to NETNAME dir */
do_chroot = true;
break;
- case 'U': /* setuid to USER */
+ case 'U': /* setuid to USER */
switchuser = optarg;
break;
- case 1: /* show help */
+ case 1: /* show help */
show_help = true;
break;
- case 2: /* show version */
+ case 2: /* show version */
show_version = true;
break;
- case 3: /* bypass security */
+ case 3: /* bypass security */
bypass_security = true;
break;
- case 4: /* write log entries to a file */
+ case 4: /* write log entries to a file */
use_logfile = true;
if(optarg)
logfilename = xstrdup(optarg);
break;
- case 5: /* open control socket here */
+ case 5: /* open control socket here */
pidfilename = xstrdup(optarg);
break;
- case '?':
+ case '?': /* wrong options */
usage(true);
return false;
#endif
}
if (do_chroot) {
- tzset(); /* for proper timestamps in logs */
+ tzset(); /* for proper timestamps in logs */
if (chroot(confbase) != 0 || chdir("/") != 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s",
"chroot", strerror(errno));
if(!parse_options(argc, argv))
return 1;
-
+
make_names();
if(show_version) {
InitializeCriticalSection(&mutex);
EnterCriticalSection(&mutex);
#endif
- char *priority = NULL;
+ char *priority = NULL;
if(!detach())
return 1;
/* Change process priority */
- if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) {
- if(!strcasecmp(priority, "Normal")) {
- if (setpriority(NORMAL_PRIORITY_CLASS) != 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s",
- "setpriority", strerror(errno));
- goto end;
- }
- } else if(!strcasecmp(priority, "Low")) {
- if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s",
- "setpriority", strerror(errno));
- goto end;
- }
- } else if(!strcasecmp(priority, "High")) {
- if (setpriority(HIGH_PRIORITY_CLASS) != 0) {
- logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s",
- "setpriority", strerror(errno));
- goto end;
- }
- } else {
- logger(DEBUG_ALWAYS, LOG_ERR, "Invalid priority `%s`!", priority);
- goto end;
- }
- }
+ if(get_config_string(lookup_config(config_tree, "ProcessPriority"), &priority)) {
+ if(!strcasecmp(priority, "Normal")) {
+ if (setpriority(NORMAL_PRIORITY_CLASS) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno));
+ goto end;
+ }
+ } else if(!strcasecmp(priority, "Low")) {
+ if (setpriority(BELOW_NORMAL_PRIORITY_CLASS) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno));
+ goto end;
+ }
+ } else if(!strcasecmp(priority, "High")) {
+ if (setpriority(HIGH_PRIORITY_CLASS) != 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setpriority", strerror(errno));
+ goto end;
+ }
+ } else {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Invalid priority `%s`!", priority);
+ goto end;
+ }
+ }
/* drop privileges */
if (!drop_privs())
for(int i = 0; i < n; i++)
sorted[i]->i = i;
-
+
int cmpfloat(float a, float b) {
if(a < b)
return -1;
name.usecs = tv.tv_usec;
data_sun.sun_family = AF_UNIX;
memcpy(&data_sun.sun_path, &name, sizeof name);
-
+
if(bind(data_fd, (struct sockaddr *)&data_sun, sizeof data_sun) < 0) {
logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind data %s: %s", device_info, strerror(errno));
running = false;
return c - 'a' + 26;
else if(c >= 'A')
return c - 'A';
- else if(c >= '0')
+ else if(c >= '0')
return c - '0' + 52;
else if(c == '+')
return 62;
int di = length / 3 * 4;
switch(length % 3) {
- case 2:
+ case 2:
triplet = usrc[si] | usrc[si + 1] << 8;
dst[di] = base64imals[triplet & 63]; triplet >>= 6;
dst[di + 1] = base64imals[triplet & 63]; triplet >>= 6;
ptr = buf + sprintf(buf, "(%d) ", err);
if (!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) {
+ NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) {
strncpy(buf, "(unable to format errormessage)", sizeof(buf));
};
extern unsigned int bitfield_to_int(const void *bitfield, size_t size);
-#endif /* __TINC_UTILS_H__ */
+#endif /* __TINC_UTILS_H__ */