//TODO: use a strict random source once to seed a PRNG?
+#ifndef HAVE_MINGW
+
static int random_fd = -1;
void crypto_init(void) {
}
void crypto_exit(void) {
+ close(random_fd);
+}
+
+#else
+
+#include <wincrypt.h>
+HCRYPTPROV prov;
+
+void crypto_init(void) {
+ if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
+ fprintf(stderr, "CryptAcquireContext() failed!\n");
+ abort();
+ }
+}
+
+void crypto_exit(void) {
+ CryptReleaseContext(prov, 0);
}
void randomize(void *out, size_t outlen) {
- if(read(random_fd, out, outlen) != outlen) {
- fprintf(stderr, "Error reading random numbers: %s\n", strerror(errno));
+ if(!CryptGenRandom(prov, outlen, out)) {
+ fprintf(stderr, "CryptGenRandom() failed\n");
abort();
}
}
+
+#endif
#ifndef ED25519_NO_SEED
#ifdef _WIN32
-#include <Windows.h>
-#include <Wincrypt.h>
+#include <windows.h>
+#include <wincrypt.h>
#else
#include <stdio.h>
#endif
return 0;
}
-#endif
\ No newline at end of file
+#endif
/*
- event.c -- I/O, timeout and signal event handling
+ event.c -- I/O and timeout event handling
Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
This program is free software; you can redistribute it and/or modify
timeout->tv = (struct timeval){0, 0};
}
-static int signal_compare(const signal_t *a, const signal_t *b) {
- return (int)a->signum - (int)b->signum;
-}
-
-static void signalio_handler(event_loop_t *loop, void *data, int flags) {
- unsigned char signum;
- if(read(loop->pipefd[0], &signum, 1) != 1)
- return;
-
- signal_t *sig = splay_search(&loop->signals, &((signal_t){.signum = signum}));
- if(sig)
- sig->cb(loop, sig->data);
-}
-
-static void pipe_init(event_loop_t *loop) {
- if(!pipe(loop->pipefd))
- io_add(loop, &loop->signalio, signalio_handler, NULL, loop->pipefd[0], IO_READ);
-}
-
-void signal_add(event_loop_t *loop, signal_t *sig, signal_cb_t cb, void *data, uint8_t signum) {
- if(sig->cb)
- return;
-
- sig->cb = cb;
- sig->data = data;
- sig->signum = signum;
- sig->node.data = sig;
-
- if(loop->pipefd[0] == -1)
- pipe_init(loop);
-
- if(!splay_insert_node(&loop->signals, &sig->node))
- abort();
-}
-
-void signal_del(event_loop_t *loop, signal_t *sig) {
- if(!sig->cb)
- return;
-
- splay_unlink_node(&loop->signals, &sig->node);
- sig->cb = NULL;
-}
-
bool event_loop_run(event_loop_t *loop) {
loop->running = true;
void event_loop_init(event_loop_t *loop) {
loop->ios.compare = (splay_compare_t)io_compare;
loop->timeouts.compare = (splay_compare_t)timeout_compare;
- loop->signals.compare = (splay_compare_t)signal_compare;
- loop->pipefd[0] = -1;
- loop->pipefd[1] = -1;
gettimeofday(&loop->now, NULL);
}
splay_free_node(&loop->ios, node);
for splay_each(timeout_t, timeout, &loop->timeouts)
splay_free_node(&loop->timeouts, node);
- for splay_each(signal_t, signal, &loop->signals)
- splay_free_node(&loop->signals, node);
}
/*
- event.h -- I/O, timeout and signal event handling
+ event.h -- I/O and timeout event handling
Copyright (C) 2014 Guus Sliepen <guus@meshlink.io>
This program is free software; you can redistribute it and/or modify
typedef void (*io_cb_t)(event_loop_t *loop, void *data, int flags);
typedef void (*timeout_cb_t)(event_loop_t *loop, void *data);
-typedef void (*signal_cb_t)(event_loop_t *loop, void *data);
typedef struct io_t {
int fd;
struct splay_node_t node;
} timeout_t;
-typedef struct signal_t {
- int signum;
- signal_cb_t cb;
- void *data;
- struct splay_node_t node;
-} signal_t;
-
struct event_loop_t {
fd_set readfds;
fd_set writefds;
splay_tree_t ios;
splay_tree_t timeouts;
- splay_tree_t signals;
-
- io_t signalio;
- int pipefd[2];
void *data;
};
extern void timeout_del(event_loop_t *loop, timeout_t *timeout);
extern void timeout_set(event_loop_t *loop, timeout_t *timeout, struct timeval *tv);
-extern void signal_add(event_loop_t *loop, signal_t *sig, signal_cb_t cb, void *data, uint8_t signum);
-extern void signal_trigger(event_loop_t *loop, signal_t *sig);
-extern void signal_del(event_loop_t *loop, signal_t *sig);
-
extern void event_loop_init(event_loop_t *loop);
extern void event_loop_exit(event_loop_t *loop);
extern bool event_loop_run(event_loop_t *loop);
#include "xalloc.h"
#include "ed25519/sha512.h"
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
//TODO: this can go away completely
const var_t variables[] = {
if(!read_server_config(mesh))
return meshlink_close(mesh), NULL;
+#ifdef HAVE_MINGW
+ struct WSAData wsa_state;
+ WSAStartup(MAKEWORD(2, 2), &wsa_state);
+#endif
+
// Setup up everything
// TODO: we should not open listening sockets yet
exit_configuration(&mesh->config);
event_loop_exit(&mesh->loop);
+
+#ifdef HAVE_MINGW
+ WSACleanup();
+#endif
}
void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) {
#include <stdbool.h>
#include <stddef.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/// A handle for an instance of MeshLink.
typedef struct meshlink_handle meshlink_handle_t;
*/
extern void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node);
+#ifdef __cplusplus
+}
+#endif
+
#endif // MESHLINK_H
#include "sockaddr.h"
#include "sptps.h"
+#include <pthread.h>
+
#define MAXSOCKETS 8 /* Probably overkill... */
typedef struct listen_socket_t {
#endif
#if defined(SOL_TCP) && defined(TCP_NODELAY)
- option = 1;
- setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&option, sizeof option);
+ int nodelay = 1;
+ setsockopt(c->socket, SOL_TCP, TCP_NODELAY, (void *)&nodelay, sizeof nodelay);
#endif
#if defined(SOL_IP) && defined(IP_TOS) && defined(IPTOS_LOWDELAY)
- option = IPTOS_LOWDELAY;
- setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&option, sizeof option);
+ int lowdelay = IPTOS_LOWDELAY;
+ setsockopt(c->socket, SOL_IP, IP_TOS, (void *)&lowdelay, sizeof lowdelay);
#endif
}