summaryrefslogtreecommitdiffhomepage
path: root/tun_linux.go
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-04-27 02:23:48 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2018-04-27 02:47:31 +0200
commit92261b770fdf745b6437a4f24482d19a480a00eb (patch)
tree387a57926e8a4288162b0a7f3bba26d9e242a388 /tun_linux.go
parent0715bdf353dd670bf7c3af332a8dabbe30187a1d (diff)
Fix error handling and cleanup of netlink listener
Diffstat (limited to 'tun_linux.go')
-rw-r--r--tun_linux.go51
1 files changed, 29 insertions, 22 deletions
diff --git a/tun_linux.go b/tun_linux.go
index 1abc86f..0672b5e 100644
--- a/tun_linux.go
+++ b/tun_linux.go
@@ -36,31 +36,15 @@ type NativeTun struct {
closingWriter *os.File
}
-func toRTMGRP(sc uint) uint {
- return 1 << (sc - 1)
-}
-
-func (tun *NativeTun) bindRTMGRP() (int, error) {
- groups := toRTMGRP(unix.RTNLGRP_LINK)
- groups |= toRTMGRP(unix.RTNLGRP_IPV4_IFADDR)
- groups |= toRTMGRP(unix.RTNLGRP_IPV6_IFADDR)
- sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, unix.NETLINK_ROUTE)
- if err != nil {
- return 0, err
- }
- saddr := &unix.SockaddrNetlink{
- Family: unix.AF_NETLINK,
- Pid: uint32(os.Getpid()),
- Groups: uint32(groups),
- }
- return sock, unix.Bind(sock, saddr)
-}
-
func (tun *NativeTun) File() *os.File {
return tun.fd
}
func (tun *NativeTun) RoutineHackListener() {
+ // TODO: This function never actually exits in response to anything,
+ // a go routine that goes forever. We'll want to fix that if this is
+ // to ever be used as any sort of library.
+
/* This is needed for the detection to work across network namespaces
* If you are reading this and know a better method, please get in touch.
*/
@@ -78,12 +62,35 @@ func (tun *NativeTun) RoutineHackListener() {
}
}
+func toRTMGRP(sc uint) uint {
+ return 1 << (sc - 1)
+}
+
func (tun *NativeTun) RoutineNetlinkListener() {
- sock, err := tun.bindRTMGRP()
+
+ groups := toRTMGRP(unix.RTNLGRP_LINK)
+ groups |= toRTMGRP(unix.RTNLGRP_IPV4_IFADDR)
+ groups |= toRTMGRP(unix.RTNLGRP_IPV6_IFADDR)
+ sock, err := unix.Socket(unix.AF_NETLINK, unix.SOCK_RAW, unix.NETLINK_ROUTE)
if err != nil {
- tun.errors <- errors.New("Failed to create netlink event listener")
+ tun.errors <- errors.New("Failed to create netlink event listener socket")
return
}
+ defer unix.Close(sock)
+ saddr := &unix.SockaddrNetlink{
+ Family: unix.AF_NETLINK,
+ Pid: uint32(os.Getpid()),
+ Groups: uint32(groups),
+ }
+ err = unix.Bind(sock, saddr)
+ if err != nil {
+ tun.errors <- errors.New("Failed to bind netlink event listener socket")
+ return
+ }
+
+ // TODO: This function never actually exits in response to anything,
+ // a go routine that goes forever. We'll want to fix that if this is
+ // to ever be used as any sort of library.
for msg := make([]byte, 1<<16); ; {