}
bool get_config_subnet(const config_t *cfg, subnet_t **result) {
- subnet_t subnet = {NULL};
+ subnet_t subnet = {};
if(!cfg) {
return false;
#define OPTION_CLAMP_MSS 0x0008
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: 1; /* Set to 1 if you want this connection removed */
- unsigned int timeout: 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 proxy_passed: 1; /* 1 if we are connecting via a proxy and we have finished talking with it */
+ 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: 1; /* Set to 1 if you want this connection removed */
+ unsigned int timeout: 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 proxy_passed: 1; /* 1 if we are connecting via a proxy and we have finished talking with it */
unsigned int unused: 22;
} connection_status_t;
#include "node.h"
typedef struct connection_t {
- char *name; /* name he claims to have */
+ char *name; /* name he claims to have */
- union sockaddr_t address; /* his real (internet) ip */
- char *hostname; /* the hostname of its real ip */
+ union sockaddr_t address; /* his real (internet) ip */
+ char *hostname; /* the hostname of its real ip */
int protocol_version; /* used protocol */
- int socket; /* socket used for this connection */
- uint32_t options; /* options for this connection */
+ 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 node_t *node; /* node associated with the other end */
struct edge_t *edge; /* edge associated with this connection */
- RSA *rsa_key; /* his public/private key */
+ RSA *rsa_key; /* his public/private key */
const EVP_CIPHER *incipher; /* Cipher he will use to send data to us */
const EVP_CIPHER *outcipher; /* Cipher we will use to send data to him */
EVP_CIPHER_CTX *inctx; /* Context of encrypted meta data that will come from him to us */
EVP_CIPHER_CTX *outctx; /* Context of encrypted meta data that will be sent from us to him */
uint64_t inbudget; /* Encrypted bytes send budget */
uint64_t outbudget; /* Encrypted bytes receive budget */
- char *inkey; /* His symmetric meta key + iv */
- char *outkey; /* Our symmetric meta key + iv */
- int inkeylength; /* Length of his key + iv */
- int outkeylength; /* Length of our key + iv */
+ char *inkey; /* His symmetric meta key + iv */
+ char *outkey; /* Our symmetric meta key + iv */
+ int inkeylength; /* Length of his key + iv */
+ int outkeylength; /* Length of our key + iv */
const EVP_MD *indigest;
const EVP_MD *outdigest;
int inmaclength;
int outmaclength;
int incompression;
int outcompression;
- char *mychallenge; /* challenge we received from him */
- char *hischallenge; /* challenge we sent to him */
+ char *mychallenge; /* challenge we received from him */
+ char *hischallenge; /* challenge we sent to him */
char buffer[MAXBUFSIZE]; /* metadata input buffer */
- int buflen; /* bytes read into buffer */
- int reqlen; /* length of incoming request */
- int tcplen; /* length of incoming TCPpacket */
- int allow_request; /* defined if there's only one request possible */
-
- char *outbuf; /* metadata output buffer */
- int outbufstart; /* index of first meaningful byte in output buffer */
- int outbuflen; /* number of meaningful bytes in output buffer */
- int outbufsize; /* number of bytes allocated to output buffer */
+ int buflen; /* bytes read into buffer */
+ int reqlen; /* length of incoming request */
+ length_t tcplen; /* length of incoming TCPpacket */
+ int allow_request; /* defined if there's only one request possible */
+
+ char *outbuf; /* metadata output buffer */
+ int outbufstart; /* index of first meaningful byte in output buffer */
+ int outbuflen; /* number of meaningful bytes in output buffer */
+ int outbufsize; /* number of bytes allocated to output buffer */
time_t last_ping_time; /* last time we saw some activity from the other end or pinged them */
time_t last_flushed_time; /* last time buffer was empty. Only meaningful if outbuflen > 0 */
}
static bool read_packet(vpn_packet_t *packet) {
+ (void)packet;
return false;
}
/* Add our data to buffer */
if(c->status.encryptout) {
/* Check encryption limits */
- if(length > c->outbudget) {
+ if((uint64_t)length > c->outbudget) {
ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for encryption to %s (%s)", c->name, c->hostname);
return false;
} else {
/* Is it proxy metadata? */
if(c->allow_request == PROXY) {
- reqlen = receive_proxy_meta(c, oldlen, lenin);
+ reqlen = receive_proxy_meta(c);
if(reqlen < 0) {
return false;
if(c->status.decryptin && !decrypted) {
/* Check decryption limits */
- if(lenin > c->inbudget) {
+ if((uint64_t)lenin > c->inbudget) {
ifdebug(META) logger(LOG_ERR, "Byte limit exceeded for decryption from %s (%s)", c->name, c->hostname);
return false;
} else {
uint16_t x[8];
} ipv6_t;
-typedef short length_t;
+typedef uint16_t length_t;
#define AF_UNKNOWN 255
extern int setup_listen_socket(const sockaddr_t *);
extern int setup_vpn_in_socket(const sockaddr_t *);
extern void send_packet(const struct node_t *, vpn_packet_t *);
-extern void receive_tcppacket(struct connection_t *, const char *, int);
+extern void receive_tcppacket(struct connection_t *, const char *, length_t);
extern void broadcast_packet(const struct node_t *, vpn_packet_t *);
extern char *get_name(void);
extern bool setup_network(void);
lzo1x_1_compress(source, len, dest, &lzolen, lzo_wrkmem);
return lzolen;
#else
- return -1;
+ return 0;
#endif
} else if(level < 10) {
#ifdef HAVE_ZLIB
return destlen;
} else
#endif
- return -1;
+ return 0;
} else {
#ifdef HAVE_LZO
lzo_uint lzolen = MAXSIZE;
lzo1x_999_compress(source, len, dest, &lzolen, lzo_wrkmem);
return lzolen;
#else
- return -1;
+ return 0;
#endif
}
- return -1;
+ return 0;
}
static length_t uncompress_packet(uint8_t *dest, const uint8_t *source, length_t len, int level) {
return lzolen;
} else
#endif
- return -1;
+ return 0;
}
#ifdef HAVE_ZLIB
if(uncompress(dest, &destlen, source, len) == Z_OK) {
return destlen;
} else {
- return -1;
+ return 0;
}
}
vpn_packet_t *outpkt;
int outlen, outpad;
unsigned char hmac[EVP_MAX_MD_SIZE];
- int i;
if(!n->inkey) {
ifdebug(TRAFFIC) logger(LOG_DEBUG, "Got packet from %s (%s) but he hasn't got our key yet",
return;
}
} else {
- for(i = n->received_seqno + 1; i < inpkt->seqno; i++) {
+ for(uint32_t i = n->received_seqno + 1; i < inpkt->seqno; i++) {
n->late[(i / 8) % replaywin] |= 1 << i % 8;
}
}
if(n->incompression) {
outpkt = pkt[nextpkt++];
- if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) {
+ if(!(outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression))) {
ifdebug(TRAFFIC) logger(LOG_ERR, "Error while uncompressing packet from %s (%s)",
n->name, n->hostname);
return;
}
}
-void receive_tcppacket(connection_t *c, const char *buffer, int len) {
+void receive_tcppacket(connection_t *c, const char *buffer, length_t len) {
vpn_packet_t outpkt;
if(len > sizeof(outpkt.data)) {
if(n->outcompression) {
outpkt = pkt[nextpkt++];
- if((outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression)) < 0) {
+ if(!(outpkt->len = compress_packet(outpkt->data, inpkt->data, inpkt->len, n->outcompression))) {
ifdebug(TRAFFIC) logger(LOG_ERR, "Error while compressing packet to %s (%s)",
n->name, n->hostname);
return;
socklen_t fromlen = sizeof(from);
node_t *n;
- pkt.len = recvfrom(listen_socket[sock].udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
+ ssize_t len = recvfrom(listen_socket[sock].udp, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
- if(pkt.len < 0) {
- if(!sockwouldblock(sockerrno)) {
+ if(len <= 0 || len > UINT16_MAX) {
+ if(len >= 0) {
+ logger(LOG_ERR, "Receiving packet with invalid size");
+ } else if(!sockwouldblock(sockerrno)) {
logger(LOG_ERR, "Receiving packet failed: %s", sockstrerror(sockerrno));
}
return;
}
+ pkt.len = len;
sockaddrunmap(&from); /* Some braindead IPv6 implementations do stupid things. */
n = lookup_node_udp(&from);
/* First, check for simple PublicKey statement */
if(get_config_string(lookup_config(c->config_tree, "PublicKey"), &key)) {
- if(BN_hex2bn(&n, key) != strlen(key)) {
+ if((size_t)BN_hex2bn(&n, key) != strlen(key)) {
free(key);
logger(LOG_ERR, "Invalid PublicKey for %s!", c->name);
return false;
myself->connection->rsa_key = RSA_new();
// RSA_blinding_on(myself->connection->rsa_key, NULL);
- if(BN_hex2bn(&d, key) != strlen(key)) {
+ if((size_t)BN_hex2bn(&d, key) != strlen(key)) {
logger(LOG_ERR, "Invalid PrivateKey for myself!");
free(key);
return false;
return false;
}
- if(BN_hex2bn(&n, pubkey) != strlen(pubkey)) {
+ if((size_t)BN_hex2bn(&n, pubkey) != strlen(pubkey)) {
free(pubkey);
BN_free(d);
logger(LOG_ERR, "Invalid PublicKey for myself!");
char *address = NULL;
char *proxy = NULL;
char *space;
- char *envp[5] = {NULL};
- struct addrinfo *ai, *aip, hint = {0};
+ char *envp[5] = {};
+ struct addrinfo *ai, *aip, hint = {};
bool choice;
int i, err;
int replaywin_int;
void close_network_connections(void) {
avl_node_t *node, *next;
connection_t *c;
- char *envp[5] = {NULL};
+ char *envp[5] = {};
int i;
for(node = connection_tree->head; node; node = next) {
Return NULL on failure.
*/
struct addrinfo *str2addrinfo(const char *address, const char *service, int socktype) {
- struct addrinfo *ai = NULL, hint = {0};
+ struct addrinfo *ai = NULL, hint = {};
int err;
hint.ai_family = addressfamily;
}
sockaddr_t str2sockaddr(const char *address, const char *port) {
- struct addrinfo *ai = NULL, hint = {0};
+ struct addrinfo *ai = NULL, hint = {};
sockaddr_t result;
int err;
}
node_t *lookup_node(char *name) {
- node_t n = {NULL};
+ node_t n = {};
n.name = name;
}
node_t *lookup_node_udp(const sockaddr_t *sa) {
- node_t n = {NULL};
+ node_t n = {};
n.address = *sa;
n.name = NULL;
#ifndef HAVE_MINGW
static RETSIGTYPE sigterm_handler(int a) {
+ (void)a;
logger(LOG_NOTICE, "Got %s signal", "TERM");
if(running) {
}
static RETSIGTYPE sigquit_handler(int a) {
+ (void)a;
logger(LOG_NOTICE, "Got %s signal", "QUIT");
if(running) {
}
static RETSIGTYPE sighup_handler(int a) {
+ (void)a;
logger(LOG_NOTICE, "Got %s signal", "HUP");
sighup = true;
}
static RETSIGTYPE sigint_handler(int a) {
+ (void)a;
static int saved_debug_level = -1;
logger(LOG_NOTICE, "Got %s signal", "INT");
}
static RETSIGTYPE sigalrm_handler(int a) {
+ (void)a;
logger(LOG_NOTICE, "Got %s signal", "ALRM");
sigalrm = true;
}
static RETSIGTYPE sigusr1_handler(int a) {
+ (void)a;
dump_connections();
}
static RETSIGTYPE sigusr2_handler(int a) {
+ (void)a;
devops.dump_stats();
dump_nodes();
dump_edges();
}
static RETSIGTYPE sigwinch_handler(int a) {
+ (void)a;
do_purge = true;
}
static RETSIGTYPE unexpected_signal_handler(int a) {
+ (void)a;
logger(LOG_WARNING, "Got unexpected signal %d (%s)", a, strsignal(a));
}
static RETSIGTYPE ignore_signal_handler(int a) {
+ (void)a;
ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignored signal %d (%s)", a, strsignal(a));
}
buffer[sizeof(buffer) - 1] = 0;
va_end(args);
- if(len < 0 || len > sizeof(buffer) - 1) {
+ if(len < 0 || (size_t)len > sizeof(buffer) - 1) {
logger(LOG_ERR, "Output buffer overflow while sending request to %s (%s)",
c->name, c->hostname);
return false;
}
bool seen_request(char *request) {
- past_request_t *new, p = {NULL};
+ past_request_t *new, p = {};
p.request = request;
/* Check if the length of the meta key is all right */
- if(strlen(buffer) != len * 2) {
+ if(strlen(buffer) != (size_t)len * 2) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength");
return false;
}
/* Check if the length of the challenge is all right */
- if(strlen(buffer) != len * 2) {
+ if(strlen(buffer) != (size_t)len * 2) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name,
c->hostname, "wrong challenge length");
return false;
/* Check if the length of the hash is all right */
- if(strlen(hishash) != EVP_MD_size(c->outdigest) * 2) {
+ if(strlen(hishash) != (size_t)EVP_MD_size(c->outdigest) * 2) {
logger(LOG_ERR, "Possible intruder %s (%s): %s", c->name,
c->hostname, "wrong challenge reply length");
return false;
}
bool tcppacket_h(connection_t *c) {
- short int len;
+ length_t len;
- if(sscanf(c->buffer, "%*d %hd", &len) != 1) {
+ if(sscanf(c->buffer, "%*d %hu", &len) != 1) {
logger(LOG_ERR, "Got bad %s from %s (%s)", "PACKET", c->name,
c->hostname);
return false;
char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE];
node_t *owner;
- subnet_t s = {NULL}, *new, *old;
+ subnet_t s = {}, *new, *old;
if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
logger(LOG_ERR, "Got bad %s from %s (%s)", "ADD_SUBNET", c->name,
char subnetstr[MAX_STRING_SIZE];
char name[MAX_STRING_SIZE];
node_t *owner;
- subnet_t s = {NULL}, *find;
+ subnet_t s = {}, *find;
if(sscanf(c->buffer, "%*d %*x " MAX_STRING " " MAX_STRING, name, subnetstr) != 2) {
logger(LOG_ERR, "Got bad %s from %s (%s)", "DEL_SUBNET", c->name,
return false;
}
+ // fallthrough
case PROXY_SOCKS4A: {
if(c->address.sa.sa_family != AF_INET && c->address.sa.sa_family != AF_UNKNOWN) {
logger(LOG_ERR, "Can only connect to IPv4 addresses or hostnames through a SOCKS 4a proxy!");
}
}
-int receive_proxy_meta(connection_t *c, int start, int lenin) {
+int receive_proxy_meta(connection_t *c) {
switch(proxytype) {
case PROXY_SOCKS4:
case PROXY_SOCKS4A:
extern char *proxypass;
extern bool send_proxyrequest(struct connection_t *c);
-extern int receive_proxy_meta(struct connection_t *c, int start, int lenin);
+extern int receive_proxy_meta(struct connection_t *c);
#endif
/* RFC 792 */
static void route_ipv4_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
- struct ip ip = {0};
- struct icmp icmp = {0};
+ struct ip ip = {};
+ struct icmp icmp = {};
struct in_addr ip_src;
struct in_addr ip_dst;
static void route_ipv6_unreachable(node_t *source, vpn_packet_t *packet, length_t ether_size, uint8_t type, uint8_t code) {
struct ip6_hdr ip6;
- struct icmp6_hdr icmp6 = {0};
+ struct icmp6_hdr icmp6 = {};
uint16_t checksum;
struct {
/* This function prettyprints the key generation process */
static int indicator(int a, int b, BN_GENCB *cb) {
+ (void)cb;
+
switch(a) {
case 0:
fprintf(stderr, ".");