Drop libevent and use our own event handling again.
authorGuus Sliepen <guus@tinc-vpn.org>
Thu, 29 Nov 2012 11:28:23 +0000 (12:28 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 29 Nov 2012 11:28:23 +0000 (12:28 +0100)
There are several reasons for this:

- MacOS/X doesn't support polling the tap device using kqueue, requiring a
  workaround to fall back to select().
- On Windows only sockets are properly handled, therefore tinc uses a second
  thread that does a blocking ReadFile() on the TAP-Win32/64 device. However,
  this does not mix well with libevent.
- Libevent, event just the core, is quite large, and although it is easy to get
  and install on many platforms, it can be a burden.
- Libev is more lightweight and seems technically superior, but it doesn't
  abstract away all the platform differences (for example, async events are not
  supported on Windows).

28 files changed:
README
README.git
configure.in
doc/tinc.texi
have.h
m4/libevent.m4 [deleted file]
src/Makefile.am
src/connection.c
src/connection.h
src/control.c
src/event.c [new file with mode: 0644]
src/event.h [new file with mode: 0644]
src/graph.c
src/logger.c
src/meta.c
src/net.c
src/net.h
src/net_packet.c
src/net_setup.c
src/net_socket.c
src/node.c
src/node.h
src/protocol.c
src/route.c
src/sptps_test.c
src/tincctl.c
src/tincd.c
src/top.c

diff --git a/README b/README
index 10cb0b5..1566af9 100644 (file)
--- a/README
+++ b/README
@@ -50,7 +50,6 @@ In order to compile tinc, you will need a GNU C compiler environment. Please
 ensure you have the latest stable versions of all the required libraries:
 
 - OpenSSL (http://www.openssl.org/) version 1.0.0 or later.
-- Libevent (http://monkey.org/~provos/libevent/)
 
 The following libraries are used by default, but can be disabled if necessary:
 
index 77595d6..92aa113 100644 (file)
@@ -8,7 +8,6 @@ to install the very latest versions of the following packages:
 - automake
 - autoconf
 - gettext
-- libevent
 
 Then you have to let the autotools create all the autogenerated files, using
 this command:
index c8a5341..1f0945f 100644 (file)
@@ -183,7 +183,6 @@ AC_ARG_WITH(libgcrypt, AC_HELP_STRING([--with-libgcrypt], [enable use of libgcry
 
 tinc_CURSES
 tinc_READLINE
-tinc_LIBEVENT
 tinc_ZLIB
 tinc_LZO
 
index 452f9f5..c0115f4 100644 (file)
@@ -339,7 +339,6 @@ having them installed, configure will give you an error message, and stop.
 * OpenSSL::
 * zlib::
 * lzo::
-* libevent::
 * libcurses::
 * libreadline::
 @end menu
@@ -458,27 +457,6 @@ make sure you build development and runtime libraries (which is the
 default).
 
 
-@c ==================================================================
-@node       libevent
-@subsection libevent
-
-@cindex libevent
-For the main event loop, tinc uses the libevent library.
-
-If this library is not installed, you wil get an error when configuring
-tinc for build.
-
-You can use your operating system's package manager to install this if
-available.  Make sure you install the development AND runtime versions
-of this package.
-
-If you have to install libevent manually, you can get the source code
-from @url{http://libevent.org/}. Instructions on how to configure,
-build and install this package are included within the package.  Please
-make sure you build development and runtime libraries (which is the
-default).
-
-
 @c ==================================================================
 @node       libcurses
 @subsection libcurses
diff --git a/have.h b/have.h
index d040717..6d65bcd 100644 (file)
--- a/have.h
+++ b/have.h
 #include <netinet/if_ether.h>
 #endif
 
-#ifdef HAVE_EVENT_H
-#include <event.h>
-#endif
-
 #ifdef HAVE_MINGW
 #define SLASH "\\"
 #else
diff --git a/m4/libevent.m4 b/m4/libevent.m4
deleted file mode 100644 (file)
index 34bdef7..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-dnl Check to find the libevent headers/libraries
-
-AC_DEFUN([tinc_LIBEVENT],
-[
-  AC_ARG_WITH(libevent,
-    AS_HELP_STRING([--with-libevent=DIR], [libevent base directory, or:]),
-    [libevent="$withval"
-     CPPFLAGS="$CPPFLAGS -I$withval/include"
-     LDFLAGS="$LDFLAGS -L$withval/lib"]
-  )
-
-  AC_ARG_WITH(libevent-include,
-    AS_HELP_STRING([--with-libevent-include=DIR], [libevent headers directory]),
-    [libevent_include="$withval"
-     CPPFLAGS="$CPPFLAGS -I$withval"]
-  )
-
-  AC_ARG_WITH(libevent-lib,
-    AS_HELP_STRING([--with-libevent-lib=DIR], [libevent library directory]),
-    [libevent_lib="$withval"
-     LDFLAGS="$LDFLAGS -L$withval"]
-  )
-
-  AC_CHECK_HEADERS(event.h,
-    [],
-    [AC_MSG_ERROR("libevent header files not found."); break]
-  )
-
-  AC_CHECK_LIB(event, event_init,
-    [LIBS="-levent $LIBS"],
-    [AC_MSG_ERROR("libevent libraries not found.")]
-  )
-])
index 3bd8646..6a8737b 100644 (file)
@@ -8,7 +8,7 @@ tincd_SOURCES = \
        utils.c getopt.c getopt1.c list.c splay_tree.c dropin.c fake-getaddrinfo.c fake-getnameinfo.c hash.c \
        buffer.c conf.c connection.c control.c edge.c graph.c logger.c meta.c net.c net_packet.c net_setup.c \
        net_socket.c netutl.c node.c process.c protocol.c protocol_auth.c protocol_edge.c protocol_misc.c \
-       protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c tincd.c \
+       protocol_key.c protocol_subnet.c route.c sptps.c subnet.c subnet_parse.c event.c tincd.c \
        dummy_device.c raw_socket_device.c multicast_device.c
        
 if UML
@@ -46,7 +46,7 @@ INCLUDES = @INCLUDES@ -I$(top_builddir)
 noinst_HEADERS = \
        xalloc.h utils.h getopt.h list.h splay_tree.h dropin.h fake-getaddrinfo.h fake-getnameinfo.h fake-gai-errnos.h ipv6.h ipv4.h ethernet.h \
        buffer.h conf.h connection.h control.h control_common.h device.h edge.h graph.h info.h logger.h meta.h net.h netutl.h node.h process.h \
-       protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h
+       protocol.h route.h subnet.h sptps.h tincctl.h top.h bsd/tunemu.h hash.h event.h
 
 nodist_noinst_HEADERS = \
        cipher.h crypto.h ecdh.h ecdsa.h digest.h prf.h rsa.h ecdsagen.h rsagen.h
index d39f43f..4798c5a 100644 (file)
@@ -68,11 +68,7 @@ void free_connection(connection_t *c) {
        buffer_clear(&c->inbuf);
        buffer_clear(&c->outbuf);
 
-       if(event_initialized(&c->inevent))
-               event_del(&c->inevent);
-
-       if(event_initialized(&c->outevent))
-               event_del(&c->outevent);
+       io_del(&c->io);
 
        if(c->socket > 0)
                closesocket(c->socket);
index 01c2bf4..10f4a76 100644 (file)
@@ -90,8 +90,7 @@ typedef struct connection_t {
 
        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 */
+       io_t io;                        /* input/output event on this metadata connection */
        int tcplen;                     /* length of incoming TCPpacket */
        int allow_request;              /* defined if there's only one request possible */
 
index c166943..83a9d79 100644 (file)
@@ -58,7 +58,7 @@ bool control_h(connection_t *c, const char *request) {
 
        switch (type) {
                case REQ_STOP:
-                       event_loopexit(NULL);
+                       event_exit();
                        return control_ok(c, REQ_STOP);
 
                case REQ_DUMP_NODES:
@@ -156,7 +156,7 @@ bool init_control(void) {
 
        // Make sure we have a valid address, and map 0.0.0.0 and :: to 127.0.0.1 and ::1.
 
-       if(getsockname(listen_socket[0].tcp, (struct sockaddr *)&sa, &len)) {
+       if(getsockname(listen_socket[0].tcp.fd, (struct sockaddr *)&sa, &len)) {
                xasprintf(&localhost, "127.0.0.1 port %d", myport);
        } else {
                if(sa.sa.sa_family == AF_INET) {
diff --git a/src/event.c b/src/event.c
new file mode 100644 (file)
index 0000000..6827dc0
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+    event.c -- I/O, timeout and signal event handling
+    Copyright (C) 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "system.h"
+
+#include "event.h"
+#include "net.h"
+#include "utils.h"
+
+struct timeval now;
+
+static fd_set readfds;
+static fd_set writefds;
+static volatile bool running;
+
+static int io_compare(const io_t *a, const io_t *b) {
+       return a->fd - b->fd;
+}
+
+static int timeout_compare(const timeout_t *a, const timeout_t *b) {
+       struct timeval diff;
+       timersub(&a->tv, &b->tv, &diff);
+       return diff.tv_sec ?: diff.tv_usec;
+}
+
+static int signal_compare(const signal_t *a, const signal_t *b) {
+       return a->signum - b->signum;
+}
+
+static splay_tree_t io_tree = {.compare = (splay_compare_t)io_compare};
+static splay_tree_t timeout_tree = {.compare = (splay_compare_t)timeout_compare};
+static splay_tree_t signal_tree = {.compare = (splay_compare_t)signal_compare};
+
+void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
+       if(io->cb)
+               return;
+
+       io->fd = fd;
+       io->cb = cb;
+       io->data = data;
+       io->node.data = io;
+
+       io_set(io, flags);
+
+       splay_insert_node(&io_tree, &io->node);
+}
+
+void io_set(io_t *io, int flags) {
+       io->flags = flags;
+
+       if(flags & IO_READ)
+               FD_SET(io->fd, &readfds);
+       else
+               FD_CLR(io->fd, &readfds);
+
+       if(flags & IO_WRITE)
+               FD_SET(io->fd, &writefds);
+       else
+               FD_CLR(io->fd, &writefds);
+}
+
+void io_del(io_t *io) {
+       if(!io->cb)
+               return;
+
+       io_set(io, 0);
+
+       splay_unlink_node(&io_tree, &io->node);
+       io->cb = NULL;
+}
+
+void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv) {
+       if(timeout->cb)
+               return;
+
+       timeout->cb = cb;
+       timeout->data = data;
+       timeout->node.data = timeout;
+
+       timeout_set(timeout, tv);
+}
+
+void timeout_set(timeout_t *timeout, struct timeval *tv) {
+       if(timeout->tv.tv_sec)
+               splay_unlink_node(&timeout_tree, &timeout->node);
+
+       if(!now.tv_sec)
+               gettimeofday(&now, NULL);
+
+       timeradd(&now, tv, &timeout->tv);
+
+       splay_insert_node(&timeout_tree, &timeout->node);
+}
+
+void timeout_del(timeout_t *timeout) {
+       if(!timeout->cb)
+               return;
+
+       splay_unlink_node(&timeout_tree, &timeout->node);
+       timeout->cb = NULL;
+}
+
+#ifndef HAVE_MINGW
+static io_t signalio;
+static int pipefd[2] = {-1, -1};
+
+static void signal_handler(int signum) {
+       unsigned char num = signum;
+       write(pipefd[1], &num, 1);
+}
+
+static void signalio_handler(void *data, int flags) {
+       unsigned char signum;
+       if(read(pipefd[0], &signum, 1) != 1)
+               return;
+
+       signal_t *sig = splay_search(&signal_tree, &((signal_t){.signum = signum}));
+       if(sig)
+               sig->cb(sig->data);
+}
+
+static void pipe_init(void) {
+       if(!pipe(pipefd))
+               io_add(&signalio, signalio_handler, NULL, pipefd[0], IO_READ);
+}
+
+void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum) {
+       if(sig->cb)
+               return;
+
+       sig->cb = cb;
+       sig->data = data;
+       sig->signum = signum;
+       sig->node.data = sig;
+
+       if(pipefd[0] == -1)
+               pipe_init();
+
+       signal(sig->signum, signal_handler);
+
+       splay_insert_node(&signal_tree, &sig->node);
+}
+
+void signal_del(signal_t *sig) {
+       if(!sig->cb)
+               return;
+
+       signal(sig->signum, SIG_DFL);
+
+       splay_unlink_node(&signal_tree, &sig->node);
+       sig->cb = NULL;
+}
+#endif
+
+bool event_loop(void) {
+       running = true;
+
+       fd_set readable;
+       fd_set writable;
+
+       while(running) {
+               gettimeofday(&now, NULL);
+               struct timeval diff, *tv = NULL;
+
+               while(timeout_tree.head) {
+                       timeout_t *timeout = timeout_tree.head->data;
+                       timersub(&timeout->tv, &now, &diff);
+
+                       if(diff.tv_sec <= 0) {
+                               timeout->cb(timeout->data);
+                               if(timercmp(&timeout->tv, &now, <))
+                                       timeout_del(timeout);
+                       } else {
+                               tv = &diff;
+                               break;
+                       }
+               }
+
+               memcpy(&readable, &readfds, sizeof readable);
+               memcpy(&writable, &writefds, sizeof writable);
+
+               int fds = 0;
+
+               if(io_tree.tail) {
+                       io_t *last = io_tree.tail->data;
+                       fds = last->fd + 1;
+               }
+
+#ifdef HAVE_MINGW
+               LeaveCriticalSection(&mutex);
+#endif
+               int n = select(fds, &readable, &writable, NULL, tv);
+#ifdef HAVE_MINGW
+               EnterCriticalSection(&mutex);
+#endif
+
+               if(n < 0) {
+                       if(sockwouldblock(errno))
+                               continue;
+                       else
+                               return false;
+               }
+
+               if(!n)
+                       continue;
+
+               for splay_each(io_t, io, &io_tree) {
+                       if(FD_ISSET(io->fd, &writable))
+                               io->cb(io->data, IO_WRITE);
+                       else if(FD_ISSET(io->fd, &readable))
+                               io->cb(io->data, IO_READ);
+               }
+       }
+
+       return true;
+}
+
+void event_exit(void) {
+       running = false;
+}
diff --git a/src/event.h b/src/event.h
new file mode 100644 (file)
index 0000000..d0129d0
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    event.h -- I/O, timeout and signal event handling
+    Copyright (C) 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
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef __TINC_EVENT_H__
+#define __TINC_EVENT_H__
+
+#include "splay_tree.h"
+
+#define IO_READ 1
+#define IO_WRITE 2
+
+typedef void (*io_cb_t)(void *data, int flags);
+typedef void (*timeout_cb_t)(void *data);
+typedef void (*signal_cb_t)(void *data);
+
+typedef struct io_t {
+       int fd;
+       int flags;
+       io_cb_t cb;
+       void *data;
+       splay_node_t node;
+} io_t;
+
+typedef struct timeout_t {
+       struct timeval tv;
+       timeout_cb_t cb;
+       void *data;
+       splay_node_t node;
+} timeout_t;
+
+typedef struct signal_t {
+       int signum;
+       signal_cb_t cb;
+       void *data;
+       splay_node_t node;
+} signal_t;
+
+extern struct timeval now;
+
+extern void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags);
+extern void io_del(io_t *io);
+extern void io_set(io_t *io, int flags);
+
+extern void timeout_add(timeout_t *timeout, timeout_cb_t cb, void *data, struct timeval *tv);
+extern void timeout_del(timeout_t *timeout);
+extern void timeout_set(timeout_t *timeout, struct timeval *tv);
+
+extern void signal_add(signal_t *sig, signal_cb_t cb, void *data, int signum);
+extern void signal_del(signal_t *sig);
+
+extern bool event_loop(void);
+extern void event_exit(void);
+
+#endif
index 9036c52..73db3b2 100644 (file)
@@ -213,8 +213,7 @@ static void check_reachability(void) {
                        n->minmtu = 0;
                        n->mtuprobes = 0;
 
-                       if(timeout_initialized(&n->mtuevent))
-                               event_del(&n->mtuevent);
+                       timeout_del(&n->mtutimeout);
 
                        char *name;
                        char *address;
index 4527a37..6e3d2c0 100644 (file)
@@ -41,7 +41,6 @@ bool logcontrol = false;
 
 static void real_logger(int level, int priority, const char *message) {
        char timestr[32] = "";
-       time_t now;
        static bool suppress = false;
 
        // Bail out early if there is nothing to do.
@@ -58,8 +57,9 @@ static void real_logger(int level, int priority, const char *message) {
                                fflush(stderr);
                                break;
                        case LOGMODE_FILE:
-                               now = time(NULL);
-                               strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now));
+                               if(!now.tv_sec)
+                                       gettimeofday(&now, NULL);
+                               strftime(timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S", localtime(&now.tv_sec));
                                fprintf(logfile, "%s %s[%ld]: %s\n", timestr, logident, (long)logpid, message);
                                fflush(logfile);
                                break;
index 84fb196..1244bfd 100644 (file)
@@ -39,7 +39,7 @@ bool send_meta_sptps(void *handle, uint8_t type, const char *buffer, size_t leng
        }
 
        buffer_add(&c->outbuf, buffer, length);
-       event_add(&c->outevent, NULL);
+       io_set(&c->io, IO_READ | IO_WRITE);
 
        return true;
 }
@@ -65,12 +65,11 @@ bool send_meta(connection_t *c, const char *buffer, int length) {
                                        c->name, c->hostname);
                        return false;
                }
-
        } else {
                buffer_add(&c->outbuf, buffer, length);
        }
 
-       event_add(&c->outevent, NULL);
+       io_set(&c->io, IO_READ | IO_WRITE);
 
        return true;
 }
index 77ff1c8..fe272db 100644 (file)
--- a/src/net.c
+++ b/src/net.c
@@ -137,18 +137,16 @@ void terminate_connection(connection_t *c, bool report) {
   end does not reply in time, we consider them dead
   and close the connection.
 */
-static void timeout_handler(int fd, short events, void *event) {
-       time_t now = time(NULL);
-
+static void timeout_handler(void *data) {
        for list_each(connection_t, c, connection_list) {
                if(c->status.control)
                        continue;
 
-               if(c->last_ping_time + pingtimeout <= now) {
+               if(c->last_ping_time + pingtimeout <= now.tv_sec) {
                        if(c->status.active) {
                                if(c->status.pinged) {
-                                       logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now - c->last_ping_time);
-                               } else if(c->last_ping_time + pinginterval <= now) {
+                                       logger(DEBUG_CONNECTIONS, LOG_INFO, "%s (%s) didn't respond to PING in %ld seconds", c->name, c->hostname, (long)now.tv_sec - c->last_ping_time);
+                               } else if(c->last_ping_time + pinginterval <= now.tv_sec) {
                                        send_ping(c);
                                        continue;
                                } else {
@@ -164,10 +162,10 @@ static void timeout_handler(int fd, short events, void *event) {
                }
        }
 
-       event_add(event, &(struct timeval){pingtimeout, rand() % 100000});
+       timeout_set(data, &(struct timeval){pingtimeout, rand() % 100000});
 }
 
-static void periodic_handler(int fd, short events, void *event) {
+static void periodic_handler(void *data) {
        /* Check if there are too many contradicting ADD_EDGE and DEL_EDGE messages.
           This usually only happens when another node has the same Name as this node.
           If so, sleep for a short while to prevent a storm of contradicting messages.
@@ -278,11 +276,10 @@ static void periodic_handler(int fd, short events, void *event) {
                }
        }
 
-       event_add(event, &(struct timeval){5, rand() % 100000});
+       timeout_set(data, &(struct timeval){5, rand() % 100000});
 }
 
-void handle_meta_connection_data(int fd, short events, void *data) {
-       connection_t *c = data;
+void handle_meta_connection_data(connection_t *c) {
        int result;
        socklen_t len = sizeof result;
 
@@ -306,19 +303,19 @@ void handle_meta_connection_data(int fd, short events, void *data) {
        }
 }
 
-static void sigterm_handler(int signal, short events, void *data) {
-       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
-       event_loopexit(NULL);
+static void sigterm_handler(void *data) {
+       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
+       event_exit();
 }
 
-static void sighup_handler(int signal, short events, void *data) {
-       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
+static void sighup_handler(void *data) {
+       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
        reopenlogger();
        reload_configuration();
 }
 
-static void sigalrm_handler(int signal, short events, void *data) {
-       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(signal));
+static void sigalrm_handler(void *data) {
+       logger(DEBUG_ALWAYS, LOG_NOTICE, "Got %s signal", strsignal(((signal_t *)data)->signum));
        retry();
 }
 
@@ -332,7 +329,7 @@ int reload_configuration(void) {
 
        if(!read_server_config()) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Unable to reread configuration file, exitting.");
-               event_loopexit(NULL);
+               event_exit();
                return EINVAL;
        }
 
@@ -431,8 +428,7 @@ int reload_configuration(void) {
 void retry(void) {
        for list_each(connection_t, c, connection_list) {
                if(c->outgoing && !c->node) {
-                       if(timeout_initialized(&c->outgoing->ev))
-                               event_del(&c->outgoing->ev);
+                       timeout_del(&c->outgoing->ev);
                        if(c->status.connecting)
                                close(c->socket);
                        c->outgoing->timeout = 0;
@@ -445,44 +441,38 @@ void retry(void) {
   this is where it all happens...
 */
 int main_loop(void) {
-       struct event timeout_event;
-       struct event periodic_event;
-
-       timeout_set(&timeout_event, timeout_handler, &timeout_event);
-       event_add(&timeout_event, &(struct timeval){pingtimeout, rand() % 100000});
+       timeout_t pingtimer = {{0}};
+       timeout_t periodictimer = {{0}};
 
-       timeout_set(&periodic_event, periodic_handler, &periodic_event);
-       event_add(&periodic_event, &(struct timeval){5, rand() % 100000});
+       timeout_add(&pingtimer, timeout_handler, &pingtimer, &(struct timeval){pingtimeout, rand() % 100000});
+       timeout_add(&periodictimer, periodic_handler, &periodictimer, &(struct timeval){pingtimeout, rand() % 100000});
 
 #ifndef HAVE_MINGW
-       struct event sighup_event;
-       struct event sigterm_event;
-       struct event sigquit_event;
-       struct event sigalrm_event;
-
-       signal_set(&sighup_event, SIGHUP, sighup_handler, NULL);
-       signal_add(&sighup_event, NULL);
-       signal_set(&sigterm_event, SIGTERM, sigterm_handler, NULL);
-       signal_add(&sigterm_event, NULL);
-       signal_set(&sigquit_event, SIGQUIT, sigterm_handler, NULL);
-       signal_add(&sigquit_event, NULL);
-       signal_set(&sigalrm_event, SIGALRM, sigalrm_handler, NULL);
-       signal_add(&sigalrm_event, NULL);
+       signal_t sighup = {0};
+       signal_t sigterm = {0};
+       signal_t sigquit = {0};
+       signal_t sigalrm = {0};
+
+       signal_add(&sighup, sighup_handler, &sighup, SIGHUP);
+       signal_add(&sigterm, sigterm_handler, &sigterm, SIGTERM);
+       signal_add(&sigquit, sigterm_handler, &sigquit, SIGQUIT);
+       signal_add(&sigalrm, sigalrm_handler, &sigalrm, SIGALRM);
 #endif
 
-       if(event_loop(0) < 0) {
+       if(!event_loop()) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Error while waiting for input: %s", strerror(errno));
                return 1;
        }
 
 #ifndef HAVE_MINGW
-       signal_del(&sighup_event);
-       signal_del(&sigterm_event);
-       signal_del(&sigquit_event);
-       signal_del(&sigalrm_event);
+       signal_del(&sighup);
+       signal_del(&sigalrm);
+       signal_del(&sigquit);
+       signal_del(&sigterm);
 #endif
 
-       event_del(&timeout_event);
+       timeout_del(&periodictimer);
+       timeout_del(&pingtimer);
 
        return 0;
 }
index 2cb7f94..4277279 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -24,6 +24,7 @@
 #include "ipv6.h"
 #include "cipher.h"
 #include "digest.h"
+#include "event.h"
 
 #ifdef ENABLE_JUMBOGRAMS
 #define MTU 9018        /* 9000 bytes payload + 14 bytes ethernet header + 4 bytes VLAN tag */
@@ -99,10 +100,8 @@ typedef enum packet_type_t {
 } packet_type_t;
 
 typedef struct listen_socket_t {
-       struct event ev_tcp;
-       struct event ev_udp;
-       int tcp;
-       int udp;
+       io_t tcp;
+       io_t udp;
        sockaddr_t sa;
 } listen_socket_t;
 
@@ -116,7 +115,7 @@ typedef struct outgoing_t {
        struct config_t *cfg;
        struct addrinfo *ai;
        struct addrinfo *aip;
-       struct event ev;
+       timeout_t ev;
 } outgoing_t;
 
 extern list_t *outgoing_list;
@@ -161,10 +160,10 @@ extern char *scriptextension;
 #include "node.h"
 
 extern void retry_outgoing(outgoing_t *);
-extern void handle_incoming_vpn_data(int, short, void *);
+extern void handle_incoming_vpn_data(void *, int);
 extern void finish_connecting(struct connection_t *);
 extern bool do_outgoing_connection(struct outgoing_t *);
-extern void handle_new_meta_connection(int, short, void *);
+extern void handle_new_meta_connection(void *, int);
 extern int setup_listen_socket(const sockaddr_t *);
 extern int setup_vpn_in_socket(const sockaddr_t *);
 extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len);
@@ -184,8 +183,8 @@ extern bool node_read_ecdsa_public_key(struct node_t *);
 extern bool read_ecdsa_public_key(struct connection_t *);
 extern bool read_rsa_public_key(struct connection_t *);
 extern void send_mtu_probe(struct node_t *);
-extern void handle_device_data(int, short, void *);
-extern void handle_meta_connection_data(int, short, void *);
+extern void handle_device_data(void *, int);
+extern void handle_meta_connection_data(struct connection_t *);
 extern void regenerate_key(void);
 extern void purge(void);
 extern void retry(void);
index e50135e..81ca70a 100644 (file)
@@ -77,7 +77,7 @@ bool localdiscovery = false;
    which will be broadcast to the local network.
 */
 
-static void send_mtu_probe_handler(int fd, short events, void *data) {
+static void send_mtu_probe_handler(void *data) {
        node_t *n = data;
        int timeout = 1;
 
@@ -151,13 +151,12 @@ static void send_mtu_probe_handler(int fd, short events, void *data) {
        }
 
 end:
-       event_add(&n->mtuevent, &(struct timeval){timeout, rand() % 100000});
+       timeout_set(&n->mtutimeout, &(struct timeval){timeout, rand() % 100000});
 }
 
 void send_mtu_probe(node_t *n) {
-       if(!timeout_initialized(&n->mtuevent))
-               timeout_set(&n->mtuevent, send_mtu_probe_handler, n);
-       send_mtu_probe_handler(0, 0, n);
+       timeout_add(&n->mtutimeout, send_mtu_probe_handler, n, &(struct timeval){1, 0});
+       send_mtu_probe_handler(n);
 }
 
 static void mtu_probe_h(node_t *n, vpn_packet_t *packet, length_t len) {
@@ -557,15 +556,13 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
        /* Make sure we have a valid key */
 
        if(!n->status.validkey) {
-               time_t now = time(NULL);
-
                logger(DEBUG_TRAFFIC, LOG_INFO,
                                   "No valid key known yet for %s (%s), forwarding via TCP",
                                   n->name, n->hostname);
 
-               if(n->last_req_key + 10 <= now) {
+               if(n->last_req_key + 10 <= now.tv_sec) {
                        send_req_key(n);
-                       n->last_req_key = now;
+                       n->last_req_key = now.tv_sec;
                }
 
                send_tcppacket(n->nexthop->connection, origpkt);
@@ -644,12 +641,12 @@ static void send_udppacket(node_t *n, vpn_packet_t *origpkt) {
           && 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.fd, 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
 
-       if(sendto(listen_socket[sock].udp, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
+       if(sendto(listen_socket[sock].udp.fd, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
                if(sockmsgsize(sockerrno)) {
                        if(n->maxmtu >= origlen)
                                n->maxmtu = origlen - 1;
@@ -686,7 +683,7 @@ bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len) {
 
        choose_udp_address(to, &sa, &sock);
 
-       if(sendto(listen_socket[sock].udp, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
+       if(sendto(listen_socket[sock].udp.fd, data, len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
                if(sockmsgsize(sockerrno)) {
                        if(to->maxmtu >= len)
                                to->maxmtu = len - 1;
@@ -869,14 +866,13 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
        node_t *n = NULL;
        bool hard = false;
        static time_t last_hard_try = 0;
-       time_t now = time(NULL);
 
        for splay_each(edge_t, e, edge_weight_tree) {
                if(!e->to->status.reachable || e->to == myself)
                        continue;
 
                if(sockaddrcmp_noport(from, &e->address)) {
-                       if(last_hard_try == now)
+                       if(last_hard_try == now.tv_sec)
                                continue;
                        hard = true;
                }
@@ -889,13 +885,14 @@ static node_t *try_harder(const sockaddr_t *from, const vpn_packet_t *pkt) {
        }
 
        if(hard)
-               last_hard_try = now;
+               last_hard_try = now.tv_sec;
 
-       last_hard_try = now;
+       last_hard_try = now.tv_sec;
        return n;
 }
 
-void handle_incoming_vpn_data(int sock, short events, void *data) {
+void handle_incoming_vpn_data(void *data, int flags) {
+       listen_socket_t *ls = data;
        vpn_packet_t pkt;
        char *hostname;
        sockaddr_t from = {{0}};
@@ -903,7 +900,7 @@ void handle_incoming_vpn_data(int sock, short events, void *data) {
        node_t *n;
        int len;
 
-       len = recvfrom(sock, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
+       len = recvfrom(ls->udp.fd, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
 
        if(len <= 0 || len > MAXSIZE) {
                if(!sockwouldblock(sockerrno))
@@ -931,12 +928,12 @@ void handle_incoming_vpn_data(int sock, short events, void *data) {
                        return;
        }
 
-       n->sock = (intptr_t)data;
+       n->sock = ls - listen_socket;
 
        receive_udppacket(n, &pkt);
 }
 
-void handle_device_data(int sock, short events, void *data) {
+void handle_device_data(void *data, int flags) {
        vpn_packet_t packet;
 
        packet.priority = 0;
index 7485d21..c5c83e7 100644 (file)
@@ -42,7 +42,7 @@
 #include "xalloc.h"
 
 char *myport;
-static struct event device_ev;
+static io_t device_io;
 devops_t devops;
 
 char *proxyhost;
@@ -270,22 +270,16 @@ static bool read_rsa_private_key(void) {
        return result;
 }
 
-static struct event keyexpire_event;
+static timeout_t keyexpire_timeout;
 
-static void keyexpire_handler(int fd, short events, void *data) {
+static void keyexpire_handler(void *data) {
        regenerate_key();
+       timeout_set(data, &(struct timeval){keylifetime, rand() % 100000});
 }
 
 void regenerate_key(void) {
-       if(timeout_initialized(&keyexpire_event)) {
-               logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
-               event_del(&keyexpire_event);
-               send_key_changed();
-       } else {
-               timeout_set(&keyexpire_event, keyexpire_handler, NULL);
-       }
-
-       event_add(&keyexpire_event, &(struct timeval){keylifetime, rand() % 100000});
+       logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
+       send_key_changed();
 }
 
 /*
@@ -716,7 +710,8 @@ static bool setup_myself(void) {
 
        free(cipher);
 
-       regenerate_key();
+       send_key_changed();
+       timeout_add(&keyexpire_timeout, keyexpire_handler, &keyexpire_timeout, &(struct timeval){keylifetime, rand() % 100000});
 
        /* Check if we want to use message authentication codes... */
 
@@ -790,15 +785,8 @@ static bool setup_myself(void) {
        if(!devops.setup())
                return false;
 
-       if(device_fd >= 0) {
-               event_set(&device_ev, device_fd, EV_READ|EV_PERSIST, handle_device_data, NULL);
-
-               if (event_add(&device_ev, NULL) < 0) {
-                       logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
-                       devops.close();
-                       return false;
-               }
-       }
+       if(device_fd >= 0)
+               io_add(&device_io, handle_device_data, NULL, device_fd, IO_READ);
 
        /* Run tinc-up script to further initialize the tap interface */
        char *envp[5];
@@ -840,27 +828,16 @@ static bool setup_myself(void) {
                                return false;
                        }
 
-                       listen_socket[i].tcp = i + 3;
-
 #ifdef FD_CLOEXEC
                        fcntl(i + 3, F_SETFD, FD_CLOEXEC);
 #endif
 
-                       listen_socket[i].udp = setup_vpn_in_socket(&sa);
-                       if(listen_socket[i].udp < 0)
+                       int udp_fd = setup_vpn_in_socket(&sa);
+                       if(udp_fd < 0)
                                return false;
 
-                       event_set(&listen_socket[i].ev_tcp, listen_socket[i].tcp, EV_READ|EV_PERSIST, handle_new_meta_connection, NULL);
-                       if(event_add(&listen_socket[i].ev_tcp, NULL) < 0) {
-                               logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
-                               abort();
-                       }
-
-                       event_set(&listen_socket[i].ev_udp, listen_socket[i].udp, EV_READ|EV_PERSIST, handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets);
-                       if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) {
-                               logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
-                               abort();
-                       }
+                       io_add(&listen_socket[i].tcp, (io_cb_t)handle_new_meta_connection, &listen_socket[i], i + 3, IO_READ);
+                       io_add(&listen_socket[i].udp, (io_cb_t)handle_incoming_vpn_data, &listen_socket[i], udp_fd, IO_READ);
 
                        if(debug_level >= DEBUG_CONNECTIONS) {
                                hostname = sockaddr2hostname(&sa);
@@ -913,37 +890,20 @@ static bool setup_myself(void) {
                                        return false;
                                }
 
-                               listen_socket[listen_sockets].tcp =
-                                       setup_listen_socket((sockaddr_t *) aip->ai_addr);
+                               int tcp_fd = setup_listen_socket((sockaddr_t *) aip->ai_addr);
 
-                               if(listen_socket[listen_sockets].tcp < 0)
+                               if(tcp_fd < 0)
                                        continue;
 
-                               listen_socket[listen_sockets].udp =
-                                       setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
+                               int udp_fd = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr);
 
-                               if(listen_socket[listen_sockets].udp < 0) {
-                                       close(listen_socket[listen_sockets].tcp);
+                               if(tcp_fd < 0) {
+                                       close(tcp_fd);
                                        continue;
                                }
 
-                               event_set(&listen_socket[listen_sockets].ev_tcp,
-                                                 listen_socket[listen_sockets].tcp,
-                                                 EV_READ|EV_PERSIST,
-                                                 handle_new_meta_connection, NULL);
-                               if(event_add(&listen_socket[listen_sockets].ev_tcp, NULL) < 0) {
-                                       logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
-                                       abort();
-                               }
-
-                               event_set(&listen_socket[listen_sockets].ev_udp,
-                                                 listen_socket[listen_sockets].udp,
-                                                 EV_READ|EV_PERSIST,
-                                                 handle_incoming_vpn_data, (void *)(intptr_t)listen_sockets);
-                               if(event_add(&listen_socket[listen_sockets].ev_udp, NULL) < 0) {
-                                       logger(DEBUG_ALWAYS, LOG_ERR, "event_add failed: %s", strerror(errno));
-                                       abort();
-                               }
+                               io_add(&listen_socket[listen_sockets].tcp, handle_new_meta_connection, &listen_socket[listen_sockets], tcp_fd, IO_READ);
+                               io_add(&listen_socket[listen_sockets].udp, handle_incoming_vpn_data, &listen_socket[listen_sockets], udp_fd, IO_READ);
 
                                if(debug_level >= DEBUG_CONNECTIONS) {
                                        hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr);
@@ -1025,10 +985,10 @@ void close_network_connections(void) {
        }
 
        for(int i = 0; i < listen_sockets; i++) {
-               event_del(&listen_socket[i].ev_tcp);
-               event_del(&listen_socket[i].ev_udp);
-               close(listen_socket[i].tcp);
-               close(listen_socket[i].udp);
+               io_del(&listen_socket[i].tcp);
+               io_del(&listen_socket[i].udp);
+               close(listen_socket[i].tcp.fd);
+               close(listen_socket[i].udp.fd);
        }
 
        char *envp[5];
index ce1e3aa..212649b 100644 (file)
@@ -271,7 +271,7 @@ int setup_vpn_in_socket(const sockaddr_t *sa) {
        return nfd;
 } /* int setup_vpn_in_socket */
 
-static void retry_outgoing_handler(int fd, short events, void *data) {
+static void retry_outgoing_handler(void *data) {
        setup_outgoing_connection(data);
 }
 
@@ -281,12 +281,9 @@ void retry_outgoing(outgoing_t *outgoing) {
        if(outgoing->timeout > maxtimeout)
                outgoing->timeout = maxtimeout;
 
-       timeout_set(&outgoing->ev, retry_outgoing_handler, outgoing);
-       event_add(&outgoing->ev, &(struct timeval){outgoing->timeout, rand() % 100000});
+       timeout_add(&outgoing->ev, retry_outgoing_handler, outgoing, &(struct timeval){outgoing->timeout, rand() % 100000});
 
-       logger(DEBUG_CONNECTIONS, LOG_NOTICE,
-                          "Trying to re-establish outgoing connection in %d seconds",
-                          outgoing->timeout);
+       logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Trying to re-establish outgoing connection in %d seconds", outgoing->timeout);
 }
 
 void finish_connecting(connection_t *c) {
@@ -349,9 +346,7 @@ static void do_outgoing_pipe(connection_t *c, char *command) {
 #endif
 }
 
-static void handle_meta_write(int sock, short events, void *data) {
-       connection_t *c = data;
-
+static void handle_meta_write(connection_t *c) {
        ssize_t outlen = send(c->socket, c->outbuf.data + c->outbuf.offset, c->outbuf.len - c->outbuf.offset, 0);
        if(outlen <= 0) {
                if(!errno || errno == EPIPE) {
@@ -368,10 +363,16 @@ static void handle_meta_write(int sock, short events, void *data) {
        }
 
        buffer_read(&c->outbuf, outlen);
-       if(!c->outbuf.len && event_initialized(&c->outevent))
-               event_del(&c->outevent);
+       if(!c->outbuf.len)
+               io_set(&c->io, IO_READ);
 }
 
+static void handle_meta_io(void *data, int flags) {
+       if(flags & IO_WRITE)
+               handle_meta_write(data);
+       else
+               handle_meta_connection_data(data);
+}
 
 bool do_outgoing_connection(outgoing_t *outgoing) {
        char *address, *port, *space;
@@ -487,16 +488,13 @@ begin:
 
        connection_add(c);
 
-       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);
+       io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
 
        return true;
 }
 
 void setup_outgoing_connection(outgoing_t *outgoing) {
-       if(event_initialized(&outgoing->ev))
-               event_del(&outgoing->ev);
+       timeout_del(&outgoing->ev);
 
        node_t *n = lookup_node(outgoing->name);
 
@@ -523,13 +521,14 @@ void setup_outgoing_connection(outgoing_t *outgoing) {
   accept a new tcp connect and create a
   new connection
 */
-void handle_new_meta_connection(int sock, short events, void *data) {
+void handle_new_meta_connection(void *data, int flags) {
+       listen_socket_t *l = data;
        connection_t *c;
        sockaddr_t sa;
        int fd;
        socklen_t len = sizeof sa;
 
-       fd = accept(sock, &sa.sa, &len);
+       fd = accept(l->tcp.fd, &sa.sa, &len);
 
        if(fd < 0) {
                logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
@@ -552,9 +551,7 @@ void handle_new_meta_connection(int sock, short events, void *data) {
 
        logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
 
-       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);
+       io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
 
        configure_tcp(c);
 
@@ -565,8 +562,7 @@ void handle_new_meta_connection(int sock, short events, void *data) {
 }
 
 static void free_outgoing(outgoing_t *outgoing) {
-       if(event_initialized(&outgoing->ev))
-               event_del(&outgoing->ev);
+       timeout_del(&outgoing->ev);
 
        if(outgoing->ai)
                freeaddrinfo(outgoing->ai);
index 5dc3119..465a48a 100644 (file)
@@ -78,8 +78,7 @@ void free_node(node_t *n) {
        ecdsa_free(&n->ecdsa);
        sptps_stop(&n->sptps);
 
-       if(timeout_initialized(&n->mtuevent))
-               event_del(&n->mtuevent);
+       timeout_del(&n->mtutimeout);
 
        if(n->hostname)
                free(n->hostname);
index 3327fca..c567ad9 100644 (file)
@@ -25,6 +25,7 @@
 #include "cipher.h"
 #include "connection.h"
 #include "digest.h"
+#include "event.h"
 #include "subnet.h"
 
 typedef struct node_status_t {
@@ -83,7 +84,7 @@ typedef struct node_t {
        length_t minmtu;                        /* Probed minimum MTU */
        length_t maxmtu;                        /* Probed maximum MTU */
        int mtuprobes;                          /* Number of probes */
-       struct event mtuevent;                  /* Probe event */
+       timeout_t mtutimeout;                   /* Probe event */
 
        uint64_t in_packets;
        uint64_t in_bytes;
index 34c3f3b..bdc0378 100644 (file)
@@ -165,7 +165,24 @@ static void free_past_request(past_request_t *r) {
        free(r);
 }
 
-static struct event past_request_event;
+static timeout_t past_request_timeout;
+
+static void age_past_requests(void *data) {
+       int left = 0, deleted = 0;
+
+       for splay_each(past_request_t, p, past_request_tree) {
+               if(p->firstseen + pinginterval <= now.tv_sec)
+                       splay_delete_node(past_request_tree, node), deleted++;
+               else
+                       left++;
+       }
+
+       if(left || deleted)
+               logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d", deleted, left);
+
+       if(left)
+               timeout_set(&past_request_timeout, &(struct timeval){10, rand() % 100000});
+}
 
 bool seen_request(const char *request) {
        past_request_t *new, p = {NULL};
@@ -180,39 +197,17 @@ bool seen_request(const char *request) {
                new->request = xstrdup(request);
                new->firstseen = time(NULL);
                splay_insert(past_request_tree, new);
-               event_add(&past_request_event, &(struct timeval){10, rand() % 100000});
+               timeout_add(&past_request_timeout, age_past_requests, NULL, &(struct timeval){10, rand() % 100000});
                return false;
        }
 }
 
-static void age_past_requests(int fd, short events, void *data) {
-       int left = 0, deleted = 0;
-       time_t now = time(NULL);
-
-       for splay_each(past_request_t, p, past_request_tree) {
-               if(p->firstseen + pinginterval <= now)
-                       splay_delete_node(past_request_tree, node), deleted++;
-               else
-                       left++;
-       }
-
-       if(left || deleted)
-               logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Aging past requests: deleted %d, left %d",
-                          deleted, left);
-
-       if(left)
-               event_add(&past_request_event, &(struct timeval){10, rand() % 100000});
-}
-
 void init_requests(void) {
        past_request_tree = splay_alloc_tree((splay_compare_t) past_request_compare, (splay_action_t) free_past_request);
-
-       timeout_set(&past_request_event, age_past_requests, NULL);
 }
 
 void exit_requests(void) {
        splay_delete_tree(past_request_tree);
 
-       if(timeout_initialized(&past_request_event))
-               event_del(&past_request_event);
+       timeout_del(&past_request_timeout);
 }
index 46867d9..7bb9996 100644 (file)
@@ -59,7 +59,7 @@ static const size_t opt_size = sizeof(struct nd_opt_hdr);
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
 #endif
 
-static struct event age_subnets_event;
+static timeout_t age_subnets_timeout;
 
 /* RFC 1071 */
 
@@ -84,13 +84,12 @@ static uint16_t inet_checksum(void *data, int len, uint16_t prevsum) {
 static bool ratelimit(int frequency) {
        static time_t lasttime = 0;
        static int count = 0;
-       time_t now = time(NULL);
 
-       if(lasttime == now) {
+       if(lasttime == now.tv_sec) {
                if(count >= frequency)
                        return true;
        } else {
-               lasttime = now;
+               lasttime = now.tv_sec;
                count = 0;
        }
 
@@ -192,12 +191,11 @@ static void swap_mac_addresses(vpn_packet_t *packet) {
        memcpy(&packet->data[6], &tmp, sizeof tmp);
 }
 
-static void age_subnets(int fd, short events, void *data) {
+static void age_subnets(void *data) {
        bool left = false;
-       time_t now = time(NULL);
 
        for splay_each(subnet_t, s, myself->subnet_tree) {
-               if(s->expires && s->expires < now) {
+               if(s->expires && s->expires < now.tv_sec) {
                        if(debug_level >= DEBUG_TRAFFIC) {
                                char netstr[MAXNETSTR];
                                if(net2str(netstr, sizeof netstr, s))
@@ -216,7 +214,7 @@ static void age_subnets(int fd, short events, void *data) {
        }
 
        if(left)
-               event_add(&age_subnets_event, &(struct timeval){10, rand() % 100000});
+               timeout_set(&age_subnets_timeout, &(struct timeval){10, rand() % 100000});
 }
 
 static void learn_mac(mac_t *address) {
@@ -243,9 +241,7 @@ static void learn_mac(mac_t *address) {
                        if(c->status.active)
                                send_add_subnet(c, subnet);
 
-               if(!timeout_initialized(&age_subnets_event))
-                       timeout_set(&age_subnets_event, age_subnets, NULL);
-               event_add(&age_subnets_event, &(struct timeval){10, rand() % 100000});
+               timeout_add(&age_subnets_timeout, age_subnets, NULL, &(struct timeval){10, rand() % 100000});
        } else {
                if(subnet->expires)
                        subnet->expires = time(NULL) + macexpire;
index 7aafbbe..9db63ff 100644 (file)
@@ -29,6 +29,7 @@ bool send_request(void *c, const char *msg, ...) { return false; }
 struct list_t *connection_list = NULL;
 bool send_meta(void *c, const char *msg , int len) { return false; }
 char *logfilename = NULL;
+struct timeval now;
 
 ecdsa_t mykey, hiskey;
 
index 344aa97..130ddde 100644 (file)
@@ -62,6 +62,7 @@ char *netname = NULL;
 char *confbase = NULL;
 static char *tinc_conf = NULL;
 static char *hosts_dir = NULL;
+struct timeval now;
 
 // Horrible global variables...
 static int pid = 0;
index be13164..3883ec2 100644 (file)
@@ -450,18 +450,6 @@ int main2(int argc, char **argv) {
        }
 #endif
 
-#ifdef HAVE_DARWIN
-       if(!getenv("EVENT_KQUEUE"))
-               setenv("EVENT_NOKQUEUE", "1", 0);
-       if(!getenv("EVENT_POLL"))
-               setenv("EVENT_NOPOLL", "1", 0);
-#endif
-
-       if(!event_init()) {
-               logger(DEBUG_ALWAYS, LOG_ERR, "Error initializing libevent!");
-               return 1;
-       }
-
        /* Setup sockets and open device. */
 
        if(!setup_network())
index 8232c7a..7504889 100644 (file)
--- a/src/top.c
+++ b/src/top.c
@@ -57,7 +57,7 @@ static int sortmode = 0;
 static bool cumulative = false;
 
 static list_t node_list;
-static struct timeval now, prev, diff;
+static struct timeval cur, prev, diff;
 static int delay = 1000;
 static bool changed = true;
 static const char *unit = "bytes";
@@ -69,10 +69,10 @@ static float scale = 1;
 
 static void update(int fd) {
        sendline(fd, "%d %d", CONTROL, REQ_DUMP_TRAFFIC);
-       gettimeofday(&now, NULL);
+       gettimeofday(&cur, NULL);
 
-       timersub(&now, &prev, &diff);
-       prev = now;
+       timersub(&cur, &prev, &diff);
+       prev = cur;
        float interval = diff.tv_sec + diff.tv_usec * 1e-6;
 
        char line[4096];