From bcacfb06385ab4177ffabe4e3aa979d3540b6428 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 25 Oct 2019 18:33:23 -0500 Subject: [PATCH 1/2] 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) + } +} From 710815fed595af7abeac82ca088577e287d231d4 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Fri, 25 Oct 2019 19:32:53 -0500 Subject: [PATCH 2/2] add dummy functions for other platforms --- src/yggdrasil/tcp.go | 2 +- src/yggdrasil/tcp_darwin.go | 4 ++++ src/yggdrasil/tcp_linux.go | 2 +- src/yggdrasil/tcp_other.go | 4 ++++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index 0733b58..9cca419 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -299,7 +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) + dialer.Control = t.getControl(sintf) ief, err := net.InterfaceByName(sintf) if err != nil { return diff --git a/src/yggdrasil/tcp_darwin.go b/src/yggdrasil/tcp_darwin.go index 9d55a1d..3d0626c 100644 --- a/src/yggdrasil/tcp_darwin.go +++ b/src/yggdrasil/tcp_darwin.go @@ -26,3 +26,7 @@ func (t *tcp) tcpContext(network, address string, c syscall.RawConn) error { return control } } + +func (t *tcp) getControl(sintf string) func(string, string, syscall.RawConn) error { + return t.tcpContext +} diff --git a/src/yggdrasil/tcp_linux.go b/src/yggdrasil/tcp_linux.go index 8d36f04..9ec3c10 100644 --- a/src/yggdrasil/tcp_linux.go +++ b/src/yggdrasil/tcp_linux.go @@ -30,7 +30,7 @@ func (t *tcp) tcpContext(network, address string, c syscall.RawConn) error { return nil } -func (t *tcp) getContextWithBindToDevice(sintf string) func(string, string, syscall.RawConn) error { +func (t *tcp) getControl(sintf string) func(string, string, syscall.RawConn) error { return func(network, address string, c syscall.RawConn) error { var err error btd := func(fd uintptr) { diff --git a/src/yggdrasil/tcp_other.go b/src/yggdrasil/tcp_other.go index 44c3d76..7ee4197 100644 --- a/src/yggdrasil/tcp_other.go +++ b/src/yggdrasil/tcp_other.go @@ -11,3 +11,7 @@ import ( func (t *tcp) tcpContext(network, address string, c syscall.RawConn) error { return nil } + +func (t *tcp) getControl(sintf string) func(string, string, syscall.RawConn) error { + return t.tcpContext +}