From: Jason A. Donenfeld Date: Fri, 27 Apr 2018 00:23:48 +0000 (+0200) Subject: Fix error handling and cleanup of netlink listener X-Git-Tag: 0.0.20180514~49 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92261b770fdf745b6437a4f24482d19a480a00eb;p=thirdparty%2Fwireguard-go.git Fix error handling and cleanup of netlink listener --- 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); ; {