From 471f7ff08e897a6b4f2779e10d28aeb0a5b9e0e4 Mon Sep 17 00:00:00 2001 From: Mathias Hall-Andersen Date: Wed, 29 Nov 2017 18:46:31 +0100 Subject: Added cross namespace TUN status detection --- src/tun_linux.go | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'src/tun_linux.go') diff --git a/src/tun_linux.go b/src/tun_linux.go index a728a48..81f1bbb 100644 --- a/src/tun_linux.go +++ b/src/tun_linux.go @@ -11,6 +11,7 @@ import ( "net" "os" "strings" + "time" "unsafe" ) @@ -60,15 +61,32 @@ func (tun *NativeTun) File() *os.File { return tun.fd } +func (tun *NativeTun) RoutineHackListener() { + /* This is needed for the detection to work accross network namespaces + * If you are reading this and know a better method, please get in touch. + */ + fd := int(tun.fd.Fd()) + for { + _, err := unix.Write(fd, nil) + switch err { + case unix.EINVAL: + tun.events <- TUNEventUp + case unix.EIO: + tun.events <- TUNEventDown + default: + } + time.Sleep(time.Second / 10) + } +} + func (tun *NativeTun) RoutineNetlinkListener() { + sock := int(C.bind_rtmgrp()) if sock < 0 { tun.errors <- errors.New("Failed to create netlink event listener") return } - tun.events <- TUNEventUp // TODO: Fix network namespace problem - for msg := make([]byte, 1<<16); ; { msgn, _, _, _, err := unix.Recvmsg(sock, msg[:], nil, 0) @@ -269,6 +287,7 @@ func CreateTUNFromFile(name string, fd *os.File) (TUNDevice, error) { } go device.RoutineNetlinkListener() + go device.RoutineHackListener() // cross namespace // set default MTU @@ -324,6 +343,7 @@ func CreateTUN(name string) (TUNDevice, error) { } go device.RoutineNetlinkListener() + go device.RoutineHackListener() // cross namespace // set default MTU -- cgit v1.2.3-59-g8ed1b