Repository: cloudflare/boringtun (language: rust)

Issue:
Timer problem in virtualized environment
Hi there,
I'm trying to run boringtun on a vServer that uses virtuozzo as its hypervisor and it exits immediately with the following message:
```
~> sudo boringtun -f -v debug wg0 
Timer("Invalid argument")
~> 
```

The system:
```
~> uname -a
Linux **** 4.15.0 #1 SMP Thu Feb 21 17:35:43 MSK 2019 x86_64 x86_64 x86_64 GNU/Linux
~> cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.2 LTS"
~> rustup show
Default host: x86_64-unknown-linux-gnu

stable-x86_64-unknown-linux-gnu (default)
rustc 1.33.0 (2aa4c46cf 2019-02-28)
~> 
```

Have you got any clue what could be causing this?

Regards,
Markus


Discussion / hints:
My guess would be some problem using `timer_fd` with `CLOCK_BOOTTIME`
Indeed, that's the problem, thank you!
```
~> cat test.c
#include <errno.h>
#include <stdio.h>
#include <sys/timerfd.h>

int main() {
	errno = 0;
	int fd1 = timerfd_create(CLOCK_BOOTTIME, 0);

	perror(NULL);

	errno = 0;
	int fd2 = timerfd_create(CLOCK_MONOTONIC, 0);

	perror(NULL);
}
~> gcc -o test test.c
~> sudo ./test
Invalid argument
Success
~> 
```

https://github.com/cloudflare/boringtun/blob/e765e12613e8eb33e39e7fb0676ad5797c02c5f6/src/device/epoll.rs#L104

So I think I could change this to `CLOCK_MONOTONIC` when I can guarantee that the system won't be suspended as long as boringtun is running?
That is right 

Fix patch:
diff --git a/src/device/epoll.rs b/src/device/epoll.rs
index 52045117..db80c228 100644
--- a/src/device/epoll.rs
+++ b/src/device/epoll.rs
@@ -102,7 +102,11 @@ impl<H: Sync + Send> EventPoll<H> {
     pub fn new_periodic_event(&self, handler: H, period: Duration) -> Result<EventRef, Error> {
         // The periodic event on Linux uses the timerfd
         let tfd = match unsafe { timerfd_create(CLOCK_BOOTTIME, TFD_NONBLOCK) } {
-            -1 => return Err(Error::Timer(errno_str())),
+            -1 => match unsafe { timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK) } {
+                // A fallback for kernels < 3.15
+                -1 => return Err(Error::Timer(errno_str())),
+                efd => efd,
+            },
             efd => efd,
         };
 


Test patch: