From bcacfb06385ab4177ffabe4e3aa979d3540b6428 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 25 Oct 2019 18:33:23 -0500 Subject: [PATCH] test adding BindToDevice to linux. if it works then we'll want to rethink slightly how we get the tcpContext on every platform, to make this compile everywhere and look a little cleaner --- src/yggdrasil/tcp.go | 1 + src/yggdrasil/tcp_linux.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index 7d5b80b..0733b58 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -299,6 +299,7 @@ func (t *tcp) call(saddr string, options interface{}, sintf string, upgrade *Tcp Timeout: time.Second * 5, } if sintf != "" { + dialer.Control = t.getContextWithBindToDevice(sintf) ief, err := net.InterfaceByName(sintf) if err != nil { return diff --git a/src/yggdrasil/tcp_linux.go b/src/yggdrasil/tcp_linux.go index 7eda3b5..8d36f04 100644 --- a/src/yggdrasil/tcp_linux.go +++ b/src/yggdrasil/tcp_linux.go @@ -29,3 +29,17 @@ func (t *tcp) tcpContext(network, address string, c syscall.RawConn) error { // Return nil because errors here are not considered fatal for the connection, it just means congestion control is suboptimal return nil } + +func (t *tcp) getContextWithBindToDevice(sintf string) func(string, string, syscall.RawConn) error { + return func(network, address string, c syscall.RawConn) error { + var err error + btd := func(fd uintptr) { + err = unix.BindToDevice(int(fd), sintf) + } + c.Control(btd) + if err != nil { + t.link.core.log.Debugln("Failed to set SO_BINDTODEVICE:", sintf) + } + return t.tcpContext(network, address, c) + } +}