return true;
}
-static const char *__itoa(int value) {
- static char buffer[sizeof(int) * 8 + 1]; // not thread safe
-
- if(snprintf(buffer, sizeof(buffer), "%d", value) == -1) {
- return "";
- }
-
- return buffer;
-}
-
bool devtool_export_json_all_edges_state(meshlink_handle_t *mesh, FILE *stream) {
bool result = true;
goto fail;
}
+ char buf[16];
+
for(size_t i = 0; i < node_count; ++i) {
if(!fstrwrite("\t\t\"", stream) || !fstrwrite(((node_t *)nodes[i])->name, stream) || !fstrwrite("\": {\n", stream)) {
goto fail;
goto fail;
}
- if(!fstrwrite("\t\t\t\"devclass\": ", stream) || !fstrwrite(__itoa(((node_t *)nodes[i])->devclass), stream) || !fstrwrite("\n", stream)) {
+ snprintf(buf, sizeof(buf), "%d", ((node_t *)nodes[i])->devclass);
+
+ if(!fstrwrite("\t\t\t\"devclass\": ", stream) || !fstrwrite(buf, stream) || !fstrwrite("\n", stream)) {
goto fail;
}
free(address);
- if(!fstrwrite("\t\t\t\"weight\": ", stream) || !fstrwrite(__itoa(edges[i].weight), stream) || !fstrwrite("\n", stream)) {
+ snprintf(buf, sizeof(buf), "%d", edges[i].weight);
+
+ if(!fstrwrite("\t\t\t\"weight\": ", stream) || !fstrwrite(buf, stream) || !fstrwrite("\n", stream)) {
goto fail;
}
return true;
}
+
static bool sendline(int fd, char *format, ...) {
- static char buffer[4096];
+ char buffer[4096];
char *p = buffer;
int blen = 0;
va_list ap;
}
/// Device class traits
-dev_class_traits_t dev_class_traits[_DEV_CLASS_MAX + 1] = {
+const dev_class_traits_t dev_class_traits[_DEV_CLASS_MAX + 1] = {
{ .min_connects = 3, .max_connects = 10000, .edge_weight = 1 }, // DEV_CLASS_BACKBONE
{ .min_connects = 3, .max_connects = 100, .edge_weight = 3 }, // DEV_CLASS_STATIONARY
{ .min_connects = 3, .max_connects = 3, .edge_weight = 6 }, // DEV_CLASS_PORTABLE
struct splay_tree_t *past_request_tree;
timeout_t past_request_timeout;
+ int connection_burst;
int contradicting_add_edge;
int contradicting_del_edge;
int sleeptime;
+ time_t connection_burst_time;
time_t last_config_check;
+ time_t last_hard_try;
timeout_t pingtimer;
timeout_t periodictimer;
struct connection_t *everyone;
+ int next_pit;
+ int pits[10];
+
// Infrequently used callbacks
meshlink_node_status_cb_t node_status_cb;
meshlink_channel_accept_cb_t channel_accept_cb;
int pinginterval; /* seconds between pings */
int pingtimeout; /* seconds to wait for response */
int maxtimeout;
+ int udp_choice;
int netns;
int edge_weight;
} dev_class_traits_t;
-extern dev_class_traits_t dev_class_traits[];
+extern const dev_class_traits_t dev_class_traits[];
#endif
struct addrinfo *aip;
} outgoing_t;
-extern int maxoutbufsize;
-extern int addressfamily;
-
-extern int keylifetime;
-extern int max_connection_burst;
-extern bool do_prune;
-
/* Yes, very strange placement indeed, but otherwise the typedefs get all tangled up */
#include "connection.h"
#include "node.h"
to the node's reflexive UDP address discovered during key
exchange. */
- static int x = 0;
-
- if(++x >= 3) {
- x = 0;
+ if(++mesh->udp_choice >= 3) {
+ mesh->udp_choice = 0;
return;
}
static node_t *try_harder(meshlink_handle_t *mesh, const sockaddr_t *from, const vpn_packet_t *pkt) {
node_t *n = NULL;
bool hard = false;
- static time_t last_hard_try = 0;
for splay_each(edge_t, e, mesh->edges) {
if(!e->to->status.reachable || e->to == mesh->self) {
}
if(sockaddrcmp_noport(from, &e->address)) {
- if(last_hard_try == mesh->loop.now.tv_sec) {
+ if(mesh->last_hard_try == mesh->loop.now.tv_sec) {
continue;
}
}
if(hard) {
- last_hard_try = mesh->loop.now.tv_sec;
+ mesh->last_hard_try = mesh->loop.now.tv_sec;
}
- last_hard_try = mesh->loop.now.tv_sec;
return n;
}
struct addrinfo *ai;
struct addrinfo hint = {
- .ai_family = addressfamily,
+ .ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
.ai_flags = AI_PASSIVE,
bool setup_myself(meshlink_handle_t *mesh) {
/* Set some defaults */
- keylifetime = 3600; // TODO: check if this can be removed as well
mesh->maxtimeout = 900;
/* Done */
mesh->pinginterval = 60;
mesh->pingtimeout = 5;
- maxoutbufsize = 10 * MTU;
if(!setup_myself(mesh)) {
return false;
#define MSG_NOSIGNAL 0
#endif
-int addressfamily = AF_UNSPEC;
-int seconds_till_retry = 5;
-int max_connection_burst = 100;
+static const int max_connection_burst = 100;
/* Setup sockets */
}
/// Delayed close of a filedescriptor.
-static void tarpit(int fd) {
- static int pits[10] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
- static int next_pit = 0;
+static void tarpit(meshlink_handle_t *mesh, int fd) {
+ if(!fd) {
+ return;
+ }
- if(pits[next_pit] != -1) {
- closesocket(pits[next_pit]);
+ if(mesh->pits[mesh->next_pit]) {
+ closesocket(mesh->pits[mesh->next_pit]);
}
- pits[next_pit++] = fd;
+ mesh->pits[mesh->next_pit++] = fd;
- if(next_pit >= (int)(sizeof pits / sizeof pits[0])) {
- next_pit = 0;
+ if(mesh->next_pit >= (int)(sizeof mesh->pits / sizeof mesh->pits[0])) {
+ mesh->next_pit = 0;
}
}
/* Rate limit incoming connections to max_connection_burst/second. */
- static int connection_burst;
- static int connection_burst_time;
-
- if(mesh->loop.now.tv_sec != connection_burst_time) {
- connection_burst_time = mesh->loop.now.tv_sec;
- connection_burst = 0;
+ if(mesh->loop.now.tv_sec != mesh->connection_burst_time) {
+ mesh->connection_burst_time = mesh->loop.now.tv_sec;
+ mesh->connection_burst = 0;
}
- if(connection_burst >= max_connection_burst) {
- tarpit(fd);
+ if(mesh->connection_burst >= max_connection_burst) {
+ tarpit(mesh, fd);
return;
}
- connection_burst++;
+ mesh->connection_burst++;
// Accept the new connection
#include "utils.h"
#include "xalloc.h"
-bool hostnames = false;
-
/*
Turn a string into a struct addrinfo.
Return NULL on failure.
int err;
struct addrinfo hint = {
- .ai_family = addressfamily,
+ .ai_family = AF_UNSPEC,
.ai_socktype = socktype,
};
return str;
}
- err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port),
- hostnames ? 0 : (NI_NUMERICHOST | NI_NUMERICSERV));
+ err = getnameinfo(&sa->sa, SALEN(sa->sa), address, sizeof(address), port, sizeof(port), NI_NUMERICHOST | NI_NUMERICSERV);
if(err) {
logger(NULL, MESHLINK_ERROR, "Error while looking up hostname: %s", err == EAI_SYSTEM ? strerror(errno) : gai_strerror(err));
#include "net.h"
#include "packmsg.h"
-extern bool hostnames;
-
extern struct addrinfo *str2addrinfo(const char *, const char *, int) __attribute__((__malloc__));
extern sockaddr_t str2sockaddr(const char *, const char *);
extern void sockaddr2str(const sockaddr_t *, char **, char **);
#include "route.h"
#include "utils.h"
-bool decrement_ttl = false;
-
static bool checklength(node_t *source, vpn_packet_t *packet, uint16_t length) {
if(packet->len < length) {
logger(source->mesh, MESHLINK_WARNING, "Got too short packet from %s", source->name);
#include "net.h"
#include "node.h"
-extern bool decrement_ttl;
-
extern void route(struct meshlink_handle *mesh, struct node_t *, struct vpn_packet_t *);
#endif
#include "prf.h"
#include "sptps.h"
-unsigned int sptps_replaywin = 32;
-
/*
Nonce MUST be exchanged first (done)
Signatures MUST be done over both nonces, to guarantee the signature is fresh
s->datagram = datagram;
s->mykey = mykey;
s->hiskey = hiskey;
- s->replaywin = sptps_replaywin;
+ s->replaywin = 32;
if(s->replaywin) {
s->late = malloc(s->replaywin);
} sptps_t;
-extern unsigned int sptps_replaywin;
extern void sptps_log_quiet(sptps_t *s, int s_errno, const char *format, va_list ap);
extern void sptps_log_stderr(sptps_t *s, int s_errno, const char *format, va_list ap);
extern void (*sptps_log)(sptps_t *s, int s_errno, const char *format, va_list ap);
#endif
const char *winerror(int err) {
- static char buf[1024], *ptr;
+ char buf[1024], *ptr;
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)) {
+ if(!FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), ptr, sizeof(buf) - (ptr - buf), NULL)) {
strncpy(buf, "(unable to format errormessage)", sizeof(buf));
}
- ;
-
if((ptr = strchr(buf, '\r'))) {
- * ptr = '\0';
+ *ptr = '\0';
}
return buf;