Add stricter checks for netnames.
[tinc] / src / event.c
index 5e6908f..59b96e3 100644 (file)
@@ -35,7 +35,7 @@ static const long READ_EVENTS = FD_READ | FD_ACCEPT | FD_CLOSE;
 static const long WRITE_EVENTS = FD_WRITE | FD_CONNECT;
 static DWORD event_count = 0;
 #endif
-static volatile bool running;
+static bool running;
 
 static int io_compare(const io_t *a, const io_t *b) {
 #ifndef HAVE_MINGW
@@ -91,8 +91,8 @@ void io_add(io_t *io, io_cb_t cb, void *data, int fd, int flags) {
 
 #ifdef HAVE_MINGW
 void io_add_event(io_t *io, io_cb_t cb, void *data, WSAEVENT event) {
-       io_add(io, cb, data, -1, 0);
        io->event = event;
+       io_add(io, cb, data, -1, 0);
 }
 #endif
 
@@ -256,10 +256,10 @@ bool event_loop(void) {
        fd_set writable;
 
        while(running) {
-               memcpy(&readable, &readfds, sizeof readable);
-               memcpy(&writable, &writefds, sizeof writable);
                struct timeval diff;
                struct timeval *tv = get_time_remaining(&diff);
+               memcpy(&readable, &readfds, sizeof readable);
+               memcpy(&writable, &writefds, sizeof writable);
 
                int fds = 0;
 
@@ -285,6 +285,16 @@ bool event_loop(void) {
                                io->cb(io->data, IO_WRITE);
                        else if(FD_ISSET(io->fd, &readable))
                                io->cb(io->data, IO_READ);
+                       else
+                               continue;
+
+                       /*
+                          There are scenarios in which the callback will remove another io_t from the tree
+                          (e.g. closing a double connection). Since splay_each does not support that, we
+                          need to exit the loop now. That's okay, since any remaining events will get picked
+                          up by the next select() call.
+                        */
+                       break;
                }
        }
 #else
@@ -294,9 +304,7 @@ bool event_loop(void) {
                DWORD timeout_ms = tv ? (tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1) : WSA_INFINITE;
 
                if (!event_count) {
-                       LeaveCriticalSection(&mutex);
                        Sleep(timeout_ms);
-                       EnterCriticalSection(&mutex);
                        continue;
                }
 
@@ -328,9 +336,7 @@ bool event_loop(void) {
                        event_index++;
                }
 
-               LeaveCriticalSection(&mutex);
                DWORD result = WSAWaitForMultipleEvents(event_count, events, FALSE, timeout_ms, FALSE);
-               EnterCriticalSection(&mutex);
 
                WSAEVENT event;
                if (result >= WSA_WAIT_EVENT_0 && result < WSA_WAIT_EVENT_0 + event_count)
@@ -362,12 +368,6 @@ bool event_loop(void) {
        return true;
 }
 
-void event_flush_output(void) {
-       for splay_each(io_t, io, &io_tree)
-               if(io->flags & IO_WRITE)
-                       io->cb(io->data, IO_WRITE);
-}
-
 void event_exit(void) {
        running = false;
 }