diff --git a/cmd/signal.go b/cmd/signal.go index 7c8ee4752..f39ace519 100644 --- a/cmd/signal.go +++ b/cmd/signal.go @@ -6,7 +6,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/cobra" sig "github.com/wiretrustee/wiretrustee/signal" - sProto "github.com/wiretrustee/wiretrustee/signal/proto" + sigProto "github.com/wiretrustee/wiretrustee/signal/proto" "google.golang.org/grpc" "net" ) @@ -30,7 +30,7 @@ var ( } var opts []grpc.ServerOption grpcServer := grpc.NewServer(opts...) - sProto.RegisterSignalExchangeServer(grpcServer, sig.NewServer()) + sigProto.RegisterSignalExchangeServer(grpcServer, sig.NewServer()) log.Printf("started server: localhost:%v", port) if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/connection/connection.go b/connection/connection.go index 67387571c..7a95c766d 100644 --- a/connection/connection.go +++ b/connection/connection.go @@ -5,6 +5,7 @@ import ( "fmt" ice "github.com/pion/ice/v2" log "github.com/sirupsen/logrus" + "github.com/wiretrustee/wiretrustee/iface" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "sync" "time" @@ -93,6 +94,7 @@ func (conn *Connection) Open(timeout time.Duration) error { // create an ice.Agent that will be responsible for negotiating and establishing actual peer-to-peer connection a, err := ice.NewAgent(&ice.AgentConfig{ + // MulticastDNSMode: ice.MulticastDNSModeQueryAndGather, NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4}, Urls: conn.Config.StunTurnURLS, InterfaceFilter: func(s string) bool { @@ -144,10 +146,23 @@ func (conn *Connection) Open(timeout time.Duration) error { return err } - err = conn.wgProxy.Start(remoteConn) + pair, err := conn.agent.GetSelectedCandidatePair() if err != nil { return err } + // in case the remote peer is in the local network we don't need a Wireguard proxy, direct communication is possible. + if pair.Local.Type() == ice.CandidateTypeHost && pair.Remote.Type() == ice.CandidateTypeHost { + log.Debugf("remote peer %s is in the local network with an address %s", conn.Config.RemoteWgKey.String(), pair.Remote.Address()) + err = conn.wgProxy.StartLocal(fmt.Sprintf("%s:%d", pair.Remote.Address(), iface.WgPort)) + if err != nil { + return err + } + } else { + err = conn.wgProxy.Start(remoteConn) + if err != nil { + return err + } + } log.Infof("opened connection to peer %s", conn.Config.RemoteWgKey.String()) case <-time.After(timeout): @@ -298,7 +313,6 @@ func (conn *Connection) listenOnConnectionStateChanges() error { } log.Infof("will connect to peer %s via a selected connnection candidate pair %s", conn.Config.RemoteWgKey.String(), pair) } else if state == ice.ConnectionStateDisconnected || state == ice.ConnectionStateFailed { - // todo do we really wanna have a connection restart within connection itself? Think of moving it outside err := conn.Close() if err != nil { log.Warnf("error while closing connection to peer %s -> %s", conn.Config.RemoteWgKey.String(), err.Error()) diff --git a/connection/wgproxy.go b/connection/wgproxy.go index 8eae1d111..489b421cb 100644 --- a/connection/wgproxy.go +++ b/connection/wgproxy.go @@ -42,6 +42,15 @@ func (p *WgProxy) Close() error { return nil } +func (p *WgProxy) StartLocal(host string) error { + err := iface.UpdatePeer(p.iface, p.remoteKey, p.allowedIps, DefaultWgKeepAlive, host) + if err != nil { + log.Errorf("error while configuring Wireguard peer [%s] %s", p.remoteKey, err.Error()) + return err + } + return nil +} + // Start starts a new proxy using the ICE connection func (p *WgProxy) Start(remoteConn *ice.Conn) error { diff --git a/go.mod b/go.mod index 0bf432b05..1c7bece58 100644 --- a/go.mod +++ b/go.mod @@ -4,13 +4,17 @@ go 1.16 require ( github.com/cenkalti/backoff/v4 v4.1.0 - github.com/golang/protobuf v1.4.3 - github.com/kardianos/service v1.2.0 + github.com/golang/protobuf v1.5.2 + github.com/google/nftables v0.0.0-20201230142148-715e31cb3c31 + github.com/onsi/ginkgo v1.16.4 + github.com/onsi/gomega v1.13.0 github.com/pion/ice/v2 v2.1.7 github.com/sirupsen/logrus v1.7.0 github.com/spf13/cobra v1.1.3 github.com/vishvananda/netlink v1.1.0 + github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf + golang.org/x/sys v0.0.0-20210510120138-977fb7262007 golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 golang.zx2c4.com/wireguard/wgctrl v0.0.0-20210506160403-92e472f520a5 golang.zx2c4.com/wireguard/windows v0.3.14 diff --git a/go.sum b/go.sum index b23c3b1cc..54f3a500e 100644 --- a/go.sum +++ b/go.sum @@ -45,12 +45,15 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -67,8 +70,10 @@ github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:x github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -80,6 +85,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/nftables v0.0.0-20201230142148-715e31cb3c31 h1:kyEB9geFhgDyawmvavtNu9iGW9ri/iq54XTSNIEeHxI= +github.com/google/nftables v0.0.0-20201230142148-715e31cb3c31/go.mod h1:cfspEyr/Ap+JDIITA+N9a0ernqG0qZ4W1aqMRgDZa1g= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= @@ -112,6 +119,7 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -129,14 +137,16 @@ github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/kardianos/service v1.2.0 h1:bGuZ/epo3vrt8IPC7mnKQolqFeYJb7Cs8Rk4PSOBB/g= -github.com/kardianos/service v1.2.0/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d h1:MFX8DxRnKMY/2M3H61iSsVbo/n3h0MWGmWNN1UViOU0= +github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d/go.mod h1:QHb4k4cr1fQikUahfcRVPcEXiUgFsdIstGqlurL0XL4= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= @@ -149,6 +159,7 @@ github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lk github.com/mdlayher/genetlink v1.0.0 h1:OoHN1OdyEIkScEmRgxLEe2M9U8ClMytqA5niynLtfj0= github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= +github.com/mdlayher/netlink v0.0.0-20191009155606-de872b0d824b/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= github.com/mdlayher/netlink v1.1.1/go.mod h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o= @@ -172,7 +183,19 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pion/dtls/v2 v2.0.9 h1:7Ow+V++YSZQMYzggI0P9vLJz/hUFcffsfGMfT/Qy+u8= @@ -197,6 +220,8 @@ github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o= github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= @@ -236,6 +261,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -243,9 +269,11 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -257,6 +285,7 @@ golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -281,8 +310,10 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -297,9 +328,12 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191028085509-fe3aa8a45271/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201201195509-5d6afe98e0b7/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -307,6 +341,7 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210504132125-bbd867fde50d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210510120150-4163338589ed h1:p9UgmWI9wKpfYmgaV/IZKGdXc5qEK45tDwwwDyjS26I= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -318,13 +353,16 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190411185658-b44545bcd369/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -334,18 +372,22 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191029155521-f43be2a4598c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210110051926-789bb1bd4061/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210123111255-9b0068b26619/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210216163648-f7da38b97c65/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -385,7 +427,10 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -428,18 +473,27 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/iface/iface.go b/iface/iface.go index e254a5cd5..5534cd6e4 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -1,32 +1,25 @@ package iface import ( - "net" - "time" - log "github.com/sirupsen/logrus" "golang.zx2c4.com/wireguard/conn" "golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/tun" "golang.zx2c4.com/wireguard/wgctrl" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "net" + "time" ) const ( defaultMTU = 1280 + WgPort = 51820 ) -// Saves tun device object - is it required? var tunIface tun.Device -// Delete deletes an existing Wireguard interface -func Delete() error { - return tunIface.Close() -} - -// Create Creates a new Wireguard interface, sets a given IP and brings it up. -// Will reuse an existing one. -func Create(iface string, address string) error { +// CreateWithUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation +func CreateWithUserspace(iface string, address string) error { var err error tunIface, err = tun.CreateTUN(iface, defaultMTU) if err != nil { @@ -57,7 +50,7 @@ func Create(iface string, address string) error { log.Debugln("UAPI listener started") - err = assignAddr(address, tunIface) + err = assignAddr(address, iface) if err != nil { return err } @@ -90,10 +83,12 @@ func Configure(iface string, privateKey string) error { return err } fwmark := 0 + p := WgPort cfg := wgtypes.Config{ PrivateKey: &key, ReplacePeers: false, FirewallMark: &fwmark, + ListenPort: &p, } err = wg.ConfigureDevice(iface, cfg) if err != nil { diff --git a/iface/iface_darwin.go b/iface/iface_darwin.go index aa963e25e..c3c86050b 100644 --- a/iface/iface_darwin.go +++ b/iface/iface_darwin.go @@ -2,19 +2,18 @@ package iface import ( log "github.com/sirupsen/logrus" - "golang.zx2c4.com/wireguard/tun" "net" "os/exec" "strings" ) -//const ( -// interfacePrefix = "utun" -//) +// Create Creates a new Wireguard interface, sets a given IP and brings it up. +func Create(iface string, address string) error { + return CreateWithUserspace(iface, address) +} // assignAddr Adds IP address to the tunnel interface and network route based on the range provided -func assignAddr(address string, tunDevice tun.Device) error { - ifaceName, err := tunDevice.Name() +func assignAddr(address string, ifaceName string) error { ip := strings.Split(address, "/") cmd := exec.Command("ifconfig", ifaceName, "inet", address, ip[0]) if out, err := cmd.CombinedOutput(); err != nil { diff --git a/iface/iface_linux.go b/iface/iface_linux.go index 346ac5a0a..86c670785 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -3,24 +3,76 @@ package iface import ( log "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" - "golang.zx2c4.com/wireguard/tun" - "os" ) -//const ( -// interfacePrefix = "wg" -//) +// Create Creates a new Wireguard interface, sets a given IP and brings it up. +// Will reuse an existing one. +func Create(iface string, address string) error { -// assignAddr Adds IP address to the tunnel interface -func assignAddr(address string, tunDevice tun.Device) error { - var err error + if WireguardModExists() { + log.Debug("using kernel Wireguard module") + return CreateWithKernel(iface, address) + } else { + return CreateWithUserspace(iface, address) + } +} + +// CreateWithKernel Creates a new Wireguard interface using kernel Wireguard module. +// Works for Linux and offers much better network performance +func CreateWithKernel(iface string, address string) error { attrs := netlink.NewLinkAttrs() - attrs.Name, err = tunDevice.Name() + attrs.Name = iface + + link := wgLink{ + attrs: &attrs, + } + + log.Debugf("adding device: %s", iface) + err := netlink.LinkAdd(&link) + if os.IsExist(err) { + log.Infof("interface %s already exists. Will reuse.", iface) + } else if err != nil { + return err + } + + log.Debugf("adding address %s to interface: %s", address, iface) + addr, _ := netlink.ParseAddr(address) + err = netlink.AddrAdd(&link, addr) + if os.IsExist(err) { + log.Infof("interface %s already has the address: %s", iface, address) + } else if err != nil { + return err + } + err = assignAddr(address, iface) if err != nil { return err } + // todo do a discovery + log.Debugf("setting MTU: %s", iface) + err = netlink.LinkSetMTU(&link, defaultMTU) + if err != nil { + log.Errorf("error setting MTU on interface: %s", iface) + return err + } + + log.Debugf("bringing up interface: %s", iface) + err = netlink.LinkSetUp(&link) + if err != nil { + log.Errorf("error bringing up interface: %s", iface) + return err + } + + return nil +} + +// assignAddr Adds IP address to the tunnel interface +func assignAddr(address, name string) error { + var err error + attrs := netlink.NewLinkAttrs() + attrs.Name = name + link := wgLink{ attrs: &attrs, } diff --git a/iface/iface_windows.go b/iface/iface_windows.go index 9ce7aeafe..46966b23d 100644 --- a/iface/iface_windows.go +++ b/iface/iface_windows.go @@ -8,16 +8,21 @@ import ( "net" ) +// Create Creates a new Wireguard interface, sets a given IP and brings it up. +func Create(iface string, address string) error { + return CreateWithUserspace(iface, address) +} + // assignAddr Adds IP address to the tunnel interface and network route based on the range provided -func assignAddr(address string, tunDevice tun.Device) error { - ifaceName, err := tunDevice.Name() - nativeTunDevice := tunDevice.(*tun.NativeTun) +func assignAddr(address string, ifaceName string) error { + + nativeTunDevice := tunIface.(*tun.NativeTun) luid := winipcfg.LUID(nativeTunDevice.LUID()) ip, ipnet, _ := net.ParseCIDR(address) log.Debugf("adding address %s to interface: %s", address, ifaceName) - err = luid.SetIPAddresses([]net.IPNet{{ip, ipnet.Mask}}) + err := luid.SetIPAddresses([]net.IPNet{{ip, ipnet.Mask}}) if err != nil { return err } diff --git a/iface/mod.go b/iface/mod.go new file mode 100644 index 000000000..d3195b808 --- /dev/null +++ b/iface/mod.go @@ -0,0 +1,144 @@ +// +build linux + +package iface + +// Holds logic to check existence of Wireguard kernel module +// Copied from https://github.com/paultag/go-modprobe + +import ( + "debug/elf" + "fmt" + "golang.org/x/sys/unix" + "os" + "path/filepath" + "strings" +) + +var ( + // get the root directory for the kernel modules. If this line panics, + // it's because getModuleRoot has failed to get the uname of the running + // kernel (likely a non-POSIX system, but maybe a broken kernel?) + moduleRoot = getModuleRoot() +) + +// Get the module root (/lib/modules/$(uname -r)/) +func getModuleRoot() string { + uname := unix.Utsname{} + if err := unix.Uname(&uname); err != nil { + panic(err) + } + + i := 0 + for ; uname.Release[i] != 0; i++ { + } + + return filepath.Join( + "/lib/modules", + string(uname.Release[:i]), + ) +} + +// modName will, given a file descriptor to a Kernel Module (.ko file), parse the +// binary to get the module name. For instance, given a handle to the file at +// `kernel/drivers/usb/gadget/legacy/g_ether.ko`, return `g_ether`. +func modName(file *os.File) (string, error) { + f, err := elf.NewFile(file) + if err != nil { + return "", err + } + + syms, err := f.Symbols() + if err != nil { + return "", err + } + + for _, sym := range syms { + if strings.Compare(sym.Name, "__this_module") == 0 { + section := f.Sections[sym.Section] + data, err := section.Data() + if err != nil { + return "", err + } + + if len(data) < 25 { + return "", fmt.Errorf("modprobe: data is short, __this_module is '%s'", data) + } + + data = data[24:] + i := 0 + for ; data[i] != 0x00; i++ { + } + return string(data[:i]), nil + } + } + + return "", fmt.Errorf("No name found. Is this a .ko or just an ELF?") +} + +// Open every single kernel module under the root, and parse the ELF headers to +// extract the module name. +func elfMap(root string) (map[string]string, error) { + ret := map[string]string{} + + err := filepath.Walk( + root, + func(path string, info os.FileInfo, err error) error { + + if err != nil { + // skip broken files + return nil + } + + if !info.Mode().IsRegular() { + return nil + } + fd, err := os.Open(path) + if err != nil { + return err + } + defer fd.Close() + name, err := modName(fd) + if err != nil { + /* For now, let's just ignore that and avoid adding to it */ + return nil + } + + ret[name] = path + return nil + }) + + if err != nil { + return nil, err + } + + return ret, nil +} + +// Open every single kernel module under the kernel module directory +// (/lib/modules/$(uname -r)/), and parse the ELF headers to extract the +// module name. +func generateMap() (map[string]string, error) { + return elfMap(moduleRoot) +} + +// WireguardModExists returns true if Wireguard kernel module exists. +func WireguardModExists() bool { + _, err := resolveModName("wireguard") + return err == nil +} + +// resolveModName will, given a module name (such as `wireguard`) return an absolute +// path to the .ko that provides that module. +func resolveModName(name string) (string, error) { + paths, err := generateMap() + if err != nil { + return "", err + } + + fsPath := paths[name] + if !strings.HasPrefix(fsPath, moduleRoot) { + return "", fmt.Errorf("module isn't in the module directory") + } + + return fsPath, nil +} diff --git a/signal/client.go b/signal/client.go index 43f82b5c3..bf4c2db8b 100644 --- a/signal/client.go +++ b/signal/client.go @@ -29,7 +29,7 @@ type Client struct { ctx context.Context stream proto.SignalExchange_ConnectStreamClient //waiting group to notify once stream is connected - connWg sync.WaitGroup //todo use a channel instead?? + connWg *sync.WaitGroup //todo use a channel instead?? } // Close Closes underlying connections to the Signal Exchange @@ -55,11 +55,13 @@ func NewClient(ctx context.Context, addr string, key wgtypes.Key) (*Client, erro return nil, err } + var wg sync.WaitGroup return &Client{ realClient: proto.NewSignalExchangeClient(conn), ctx: ctx, signalConn: conn, key: key, + connWg: &wg, }, nil } @@ -107,8 +109,6 @@ func (c *Client) connect(key string, msgHandler func(msg *proto.Message) error) // add key fingerprint to the request header to be identified on the server side md := metadata.New(map[string]string{proto.HeaderId: key}) ctx := metadata.NewOutgoingContext(c.ctx, md) - ctx, cancel := context.WithCancel(ctx) - defer cancel() stream, err := c.realClient.ConnectStream(ctx) @@ -116,6 +116,15 @@ func (c *Client) connect(key string, msgHandler func(msg *proto.Message) error) if err != nil { return err } + // blocks + header, err := c.stream.Header() + if err != nil { + return err + } + registered := header.Get(proto.HeaderRegistered) + if len(registered) == 0 { + return fmt.Errorf("didn't receive a registration header from the Signal server whille connecting to the streams") + } //connection established we are good to use the stream c.connWg.Done() diff --git a/signal/proto/constants.go b/signal/proto/constants.go index d12fff2ab..dfe293c62 100644 --- a/signal/proto/constants.go +++ b/signal/proto/constants.go @@ -2,3 +2,4 @@ package proto // protocol constants, field names that can be used by both client and server const HeaderId = "x-wiretrustee-peer-id" +const HeaderRegistered = "x-wiretrustee-peer-registered" diff --git a/signal/signal.go b/signal/signal.go index a75c2050e..a94370f31 100644 --- a/signal/signal.go +++ b/signal/signal.go @@ -12,20 +12,20 @@ import ( "io" ) -// SignalExchangeServer an instance of a Signal server -type SignalExchangeServer struct { +// Server an instance of a Signal server +type Server struct { registry *peer.Registry } // NewServer creates a new Signal server -func NewServer() *SignalExchangeServer { - return &SignalExchangeServer{ +func NewServer() *Server { + return &Server{ registry: peer.NewRegistry(), } } // Send forwards a message to the signal peer -func (s *SignalExchangeServer) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) { +func (s *Server) Send(ctx context.Context, msg *proto.EncryptedMessage) (*proto.EncryptedMessage, error) { if !s.registry.IsPeerRegistered(msg.Key) { return nil, fmt.Errorf("unknown peer %s", msg.Key) @@ -46,14 +46,20 @@ func (s *SignalExchangeServer) Send(ctx context.Context, msg *proto.EncryptedMes } // ConnectStream connects to the exchange stream -func (s *SignalExchangeServer) ConnectStream(stream proto.SignalExchange_ConnectStreamServer) error { +func (s *Server) ConnectStream(stream proto.SignalExchange_ConnectStreamServer) error { p, err := s.connectPeer(stream) if err != nil { return err } - log.Infof("peer [%s] has successfully connected", p.Id) + //needed to confirm that the peer has been registered so that the client can proceed + header := metadata.Pairs(proto.HeaderRegistered, "1") + err = stream.SendHeader(header) + if err != nil { + return err + } + log.Infof("peer [%s] has successfully connected", p.Id) for { msg, err := stream.Recv() if err == io.EOF { @@ -83,7 +89,7 @@ func (s *SignalExchangeServer) ConnectStream(stream proto.SignalExchange_Connect // Handles initial Peer connection. // Each connection must provide an ID header. // At this moment the connecting Peer will be registered in the peer.Registry -func (s SignalExchangeServer) connectPeer(stream proto.SignalExchange_ConnectStreamServer) (*peer.Peer, error) { +func (s Server) connectPeer(stream proto.SignalExchange_ConnectStreamServer) (*peer.Peer, error) { if meta, hasMeta := metadata.FromIncomingContext(stream.Context()); hasMeta { if id, found := meta[proto.HeaderId]; found { p := peer.NewPeer(id[0], stream) diff --git a/signal/signal_suite_test.go b/signal/signal_suite_test.go new file mode 100644 index 000000000..2df74e9c0 --- /dev/null +++ b/signal/signal_suite_test.go @@ -0,0 +1,13 @@ +package signal_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestSignal(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Signal Suite") +} diff --git a/signal/signal_test.go b/signal/signal_test.go new file mode 100644 index 000000000..b43bba129 --- /dev/null +++ b/signal/signal_test.go @@ -0,0 +1,199 @@ +package signal_test + +import ( + "context" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + log "github.com/sirupsen/logrus" + "github.com/wiretrustee/wiretrustee/signal" + sigProto "github.com/wiretrustee/wiretrustee/signal/proto" + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" + "google.golang.org/grpc" + "google.golang.org/grpc/keepalive" + "google.golang.org/grpc/metadata" + "net" + "sync" + "time" +) + +var _ = Describe("Client", func() { + + var ( + addr string + listener net.Listener + server *grpc.Server + ) + + BeforeEach(func() { + server, listener = startSignal() + addr = listener.Addr().String() + + }) + + AfterEach(func() { + server.Stop() + listener.Close() + }) + + Describe("Exchanging messages", func() { + Context("between connected peers", func() { + It("should be successful", func() { + + var msgReceived sync.WaitGroup + msgReceived.Add(2) + + var receivedOnA string + var receivedOnB string + + // connect PeerA to Signal + keyA, _ := wgtypes.GenerateKey() + clientA := createSignalClient(addr, keyA) + clientA.Receive(func(msg *sigProto.Message) error { + receivedOnA = msg.GetBody().GetPayload() + msgReceived.Done() + return nil + }) + clientA.WaitConnected() + + // connect PeerB to Signal + keyB, _ := wgtypes.GenerateKey() + clientB := createSignalClient(addr, keyB) + clientB.Receive(func(msg *sigProto.Message) error { + receivedOnB = msg.GetBody().GetPayload() + err := clientB.Send(&sigProto.Message{ + Key: keyB.PublicKey().String(), + RemoteKey: keyA.PublicKey().String(), + Body: &sigProto.Body{Payload: "pong"}, + }) + if err != nil { + Fail("failed sending a message to PeerA") + } + msgReceived.Done() + return nil + }) + clientB.WaitConnected() + + // PeerA initiates ping-pong + err := clientA.Send(&sigProto.Message{ + Key: keyA.PublicKey().String(), + RemoteKey: keyB.PublicKey().String(), + Body: &sigProto.Body{Payload: "ping"}, + }) + if err != nil { + Fail("failed sending a message to PeerB") + } + + if waitTimeout(&msgReceived, 3*time.Second) { + Fail("test timed out on waiting for peers to exchange messages") + } + + Expect(receivedOnA).To(BeEquivalentTo("pong")) + Expect(receivedOnB).To(BeEquivalentTo("ping")) + + }) + }) + }) + + Describe("Connecting to the Signal stream channel", func() { + Context("with a signal client", func() { + It("should be successful", func() { + + key, _ := wgtypes.GenerateKey() + client := createSignalClient(addr, key) + client.Receive(func(msg *sigProto.Message) error { + return nil + }) + client.WaitConnected() + + Expect(client).NotTo(BeNil()) + }) + }) + + Context("with a raw client and no ID header", func() { + It("should fail", func() { + + client := createRawSignalClient(addr) + stream, err := client.ConnectStream(context.Background()) + if err != nil { + Fail("error connecting to stream") + } + + _, err = stream.Recv() + + Expect(stream).NotTo(BeNil()) + Expect(err).NotTo(BeNil()) + }) + }) + + Context("with a raw client and with an ID header", func() { + It("should be successful", func() { + + md := metadata.New(map[string]string{sigProto.HeaderId: "peer"}) + ctx := metadata.NewOutgoingContext(context.Background(), md) + + client := createRawSignalClient(addr) + stream, err := client.ConnectStream(ctx) + + Expect(stream).NotTo(BeNil()) + Expect(err).To(BeNil()) + }) + }) + + }) + +}) + +func createSignalClient(addr string, key wgtypes.Key) *signal.Client { + client, err := signal.NewClient(context.Background(), addr, key) + if err != nil { + Fail("failed creating signal client") + } + return client +} + +func createRawSignalClient(addr string) sigProto.SignalExchangeClient { + ctx := context.Background() + conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure(), + grpc.WithBlock(), + grpc.WithKeepaliveParams(keepalive.ClientParameters{ + Time: 3 * time.Second, + Timeout: 2 * time.Second, + })) + if err != nil { + Fail("failed creating raw signal client") + } + + return sigProto.NewSignalExchangeClient(conn) +} + +func startSignal() (*grpc.Server, net.Listener) { + lis, err := net.Listen("tcp", ":0") + if err != nil { + panic(err) + } + s := grpc.NewServer() + sigProto.RegisterSignalExchangeServer(s, signal.NewServer()) + go func() { + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } + }() + + return s, lis +} + +// waitTimeout waits for the waitgroup for the specified max timeout. +// Returns true if waiting timed out. +func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool { + c := make(chan struct{}) + go func() { + defer close(c) + wg.Wait() + }() + select { + case <-c: + return false // completed normally + case <-time.After(timeout): + return true // timed out + } +}