From 83fe84d11a90d91b03d63d40afef77c18ee91df4 Mon Sep 17 00:00:00 2001 From: braginini Date: Mon, 14 Jun 2021 16:57:18 +0200 Subject: [PATCH 01/23] test: add basic signal IT tests --- cmd/signal.go | 4 +- go.mod | 4 +- go.sum | 52 ++++++++++++++++++-- signal/signal_suite_test.go | 13 +++++ signal/signal_test.go | 97 +++++++++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 signal/signal_suite_test.go create mode 100644 signal/signal_test.go 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/go.mod b/go.mod index 1b3a90f85..662e4dff3 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,10 @@ go 1.16 require ( github.com/cenkalti/backoff/v4 v4.1.0 - github.com/golang/protobuf v1.4.3 + 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 diff --git a/go.sum b/go.sum index 4e259b40e..5a45593db 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= @@ -114,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= @@ -137,8 +143,10 @@ github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d h1:MFX8DxRnKMY/2M3H61 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= @@ -175,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= @@ -239,6 +259,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= @@ -250,6 +271,7 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF 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= @@ -261,6 +283,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= @@ -285,8 +308,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= @@ -303,8 +328,10 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL 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= @@ -312,6 +339,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= @@ -323,9 +351,11 @@ 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= @@ -339,9 +369,12 @@ 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= @@ -351,6 +384,7 @@ golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7w 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= @@ -390,7 +424,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= @@ -433,18 +470,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/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..561c523ce --- /dev/null +++ b/signal/signal_test.go @@ -0,0 +1,97 @@ +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" + "net" +) + +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("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()) + + Expect(stream).To(BeNil()) + Expect(err).NotTo(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()) + if err != nil { + Fail("failed creating raw signal client") + } + defer conn.Close() + + 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 +} From 9b9c7ada7d7e56b45bcafb1811b42722323b017d Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 15 Jun 2021 16:08:46 +0200 Subject: [PATCH 02/23] test: add messages exchange between peers [SIGNAL] --- signal/signal_test.go | 81 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/signal/signal_test.go b/signal/signal_test.go index 561c523ce..ea7f3b61c 100644 --- a/signal/signal_test.go +++ b/signal/signal_test.go @@ -9,7 +9,11 @@ import ( 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() { @@ -31,6 +35,57 @@ var _ = Describe("Client", func() { 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() + clientB.Send(&sigProto.Message{ + Key: keyB.PublicKey().String(), + RemoteKey: keyA.PublicKey().String(), + Body: &sigProto.Body{Payload: "pong"}, + }) + msgReceived.Done() + return nil + }) + clientB.WaitConnected() + + // PeerA initiates ping-pong + clientA.Send(&sigProto.Message{ + Key: keyA.PublicKey().String(), + RemoteKey: keyB.PublicKey().String(), + Body: &sigProto.Body{Payload: "ping"}, + }) + + msgReceived.Wait() + + 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() { @@ -52,11 +107,27 @@ var _ = Describe("Client", func() { client := createRawSignalClient(addr) stream, err := client.ConnectStream(context.Background()) - Expect(stream).To(BeNil()) + _, 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()) + }) + }) + }) }) @@ -71,11 +142,15 @@ func createSignalClient(addr string, key wgtypes.Key) *signal.Client { func createRawSignalClient(addr string) sigProto.SignalExchangeClient { ctx := context.Background() - conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure()) + 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") } - defer conn.Close() return sigProto.NewSignalExchangeClient(conn) } From 5f8a489f9092d7cbf44b2e3b75f08b19218ca3be Mon Sep 17 00:00:00 2001 From: braginini Date: Mon, 14 Jun 2021 16:57:18 +0200 Subject: [PATCH 03/23] test: add basic signal IT tests --- cmd/signal.go | 4 +- go.mod | 4 +- go.sum | 52 ++++++++++++++++++-- signal/signal_suite_test.go | 13 +++++ signal/signal_test.go | 97 +++++++++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 signal/signal_suite_test.go create mode 100644 signal/signal_test.go 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/go.mod b/go.mod index 1b3a90f85..662e4dff3 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,10 @@ go 1.16 require ( github.com/cenkalti/backoff/v4 v4.1.0 - github.com/golang/protobuf v1.4.3 + 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 diff --git a/go.sum b/go.sum index 4e259b40e..5a45593db 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= @@ -114,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= @@ -137,8 +143,10 @@ github.com/koneu/natend v0.0.0-20150829182554-ec0926ea948d h1:MFX8DxRnKMY/2M3H61 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= @@ -175,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= @@ -239,6 +259,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= @@ -250,6 +271,7 @@ github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmF 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= @@ -261,6 +283,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= @@ -285,8 +308,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= @@ -303,8 +328,10 @@ golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLL 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= @@ -312,6 +339,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= @@ -323,9 +351,11 @@ 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= @@ -339,9 +369,12 @@ 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= @@ -351,6 +384,7 @@ golang.org/x/sys v0.0.0-20201118182958-a01c418693c7/go.mod h1:h1NjWce9XRLGQEsW7w 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= @@ -390,7 +424,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= @@ -433,18 +470,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/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..561c523ce --- /dev/null +++ b/signal/signal_test.go @@ -0,0 +1,97 @@ +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" + "net" +) + +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("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()) + + Expect(stream).To(BeNil()) + Expect(err).NotTo(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()) + if err != nil { + Fail("failed creating raw signal client") + } + defer conn.Close() + + 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 +} From dfcf9f9087bcc133760a6cd05c13fbda16038eac Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 15 Jun 2021 16:08:46 +0200 Subject: [PATCH 04/23] test: add messages exchange between peers [SIGNAL] --- signal/signal_test.go | 81 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/signal/signal_test.go b/signal/signal_test.go index 561c523ce..ea7f3b61c 100644 --- a/signal/signal_test.go +++ b/signal/signal_test.go @@ -9,7 +9,11 @@ import ( 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() { @@ -31,6 +35,57 @@ var _ = Describe("Client", func() { 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() + clientB.Send(&sigProto.Message{ + Key: keyB.PublicKey().String(), + RemoteKey: keyA.PublicKey().String(), + Body: &sigProto.Body{Payload: "pong"}, + }) + msgReceived.Done() + return nil + }) + clientB.WaitConnected() + + // PeerA initiates ping-pong + clientA.Send(&sigProto.Message{ + Key: keyA.PublicKey().String(), + RemoteKey: keyB.PublicKey().String(), + Body: &sigProto.Body{Payload: "ping"}, + }) + + msgReceived.Wait() + + 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() { @@ -52,11 +107,27 @@ var _ = Describe("Client", func() { client := createRawSignalClient(addr) stream, err := client.ConnectStream(context.Background()) - Expect(stream).To(BeNil()) + _, 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()) + }) + }) + }) }) @@ -71,11 +142,15 @@ func createSignalClient(addr string, key wgtypes.Key) *signal.Client { func createRawSignalClient(addr string) sigProto.SignalExchangeClient { ctx := context.Background() - conn, err := grpc.DialContext(ctx, addr, grpc.WithInsecure()) + 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") } - defer conn.Close() return sigProto.NewSignalExchangeClient(conn) } From c49bd23ac54705d82ffb5a66b07d2026a6428f43 Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 15 Jun 2021 16:20:39 +0200 Subject: [PATCH 05/23] chore: fix golint error --- signal/signal_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/signal/signal_test.go b/signal/signal_test.go index ea7f3b61c..0027c713a 100644 --- a/signal/signal_test.go +++ b/signal/signal_test.go @@ -60,22 +60,28 @@ var _ = Describe("Client", func() { clientB := createSignalClient(addr, keyB) clientB.Receive(func(msg *sigProto.Message) error { receivedOnB = msg.GetBody().GetPayload() - clientB.Send(&sigProto.Message{ + 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 - clientA.Send(&sigProto.Message{ + 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") + } msgReceived.Wait() From f247f9a2f8761dadc40e7ef7adf90703c41b86fd Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 15 Jun 2021 16:31:45 +0200 Subject: [PATCH 06/23] chore: fix golint error --- signal/signal_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/signal/signal_test.go b/signal/signal_test.go index 0027c713a..c9ffd5c0c 100644 --- a/signal/signal_test.go +++ b/signal/signal_test.go @@ -112,6 +112,9 @@ var _ = Describe("Client", func() { client := createRawSignalClient(addr) stream, err := client.ConnectStream(context.Background()) + if err != nil { + Fail("error connecting to stream") + } _, err = stream.Recv() From 94c0091a7bc719c11656062ba29cba30ba795400 Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 15 Jun 2021 18:58:47 +0200 Subject: [PATCH 07/23] test: add message exchange test timeout --- signal/client.go | 8 +++++--- signal/signal.go | 1 - signal/signal_test.go | 22 ++++++++++++++++++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/signal/client.go b/signal/client.go index 43f82b5c3..f0f3b95b2 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,8 @@ 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() + //ctx, cancel := context.WithCancel(ctx) + //defer cancel() stream, err := c.realClient.ConnectStream(ctx) diff --git a/signal/signal.go b/signal/signal.go index a75c2050e..2c3101e2e 100644 --- a/signal/signal.go +++ b/signal/signal.go @@ -53,7 +53,6 @@ func (s *SignalExchangeServer) ConnectStream(stream proto.SignalExchange_Connect } log.Infof("peer [%s] has successfully connected", p.Id) - for { msg, err := stream.Recv() if err == io.EOF { diff --git a/signal/signal_test.go b/signal/signal_test.go index c9ffd5c0c..b43bba129 100644 --- a/signal/signal_test.go +++ b/signal/signal_test.go @@ -66,7 +66,7 @@ var _ = Describe("Client", func() { Body: &sigProto.Body{Payload: "pong"}, }) if err != nil { - Fail("failed sending a message to {PeerA}") + Fail("failed sending a message to PeerA") } msgReceived.Done() return nil @@ -83,7 +83,9 @@ var _ = Describe("Client", func() { Fail("failed sending a message to PeerB") } - msgReceived.Wait() + 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")) @@ -179,3 +181,19 @@ func startSignal() (*grpc.Server, net.Listener) { 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 + } +} From 9308a51800b986a58c3b11ba43f63a337d35bccf Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 15 Jun 2021 19:02:46 +0200 Subject: [PATCH 08/23] refactor: rename SignalExchangeServer to Server to comply with good practices --- signal/signal.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/signal/signal.go b/signal/signal.go index 2c3101e2e..91aa9edd9 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,7 +46,7 @@ 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 @@ -82,7 +82,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) From db673ed34fd96537e6c5156f22b1a636d4d8c4ff Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 17 Jun 2021 11:12:35 +0200 Subject: [PATCH 09/23] fix: #35 peer Registration Race when client connects to the signal server --- go.sum | 3 +++ signal/client.go | 11 +++++++++-- signal/proto/constants.go | 1 + signal/signal.go | 7 +++++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/go.sum b/go.sum index 5a45593db..54f3a500e 100644 --- a/go.sum +++ b/go.sum @@ -220,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= @@ -360,6 +362,7 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h 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= diff --git a/signal/client.go b/signal/client.go index f0f3b95b2..bf4c2db8b 100644 --- a/signal/client.go +++ b/signal/client.go @@ -109,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) @@ -118,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 91aa9edd9..a94370f31 100644 --- a/signal/signal.go +++ b/signal/signal.go @@ -52,6 +52,13 @@ func (s *Server) ConnectStream(stream proto.SignalExchange_ConnectStreamServer) return err } + //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() From 923cabda9aecb0652ade5000ca03a45da57ad962 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 17 Jun 2021 14:27:33 +0200 Subject: [PATCH 10/23] feature: initial implementation of avoiding local proxy if peers are in the same net --- connection/connection.go | 14 ++++++++++++-- connection/wgproxy.go | 9 +++++++++ iface/iface.go | 3 +++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/connection/connection.go b/connection/connection.go index 67387571c..44161df54 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" @@ -144,10 +145,20 @@ 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)) + } 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 +309,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/iface/iface.go b/iface/iface.go index cb51e9ffd..5909aaeaf 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -14,6 +14,7 @@ import ( const ( defaultMTU = 1280 + WgPort = 51820 ) // Saves tun device object - is it required? @@ -85,10 +86,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 { From e41fdedd5bfd92c7d4663d488b230da52804ddb3 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 17 Jun 2021 21:31:53 +0200 Subject: [PATCH 11/23] feature: enable ice mDNS --- connection/connection.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/connection/connection.go b/connection/connection.go index 44161df54..69ff2a58a 100644 --- a/connection/connection.go +++ b/connection/connection.go @@ -94,8 +94,9 @@ 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{ - NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4}, - Urls: conn.Config.StunTurnURLS, + MulticastDNSMode: ice.MulticastDNSModeQueryAndGather, + NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4}, + Urls: conn.Config.StunTurnURLS, InterfaceFilter: func(s string) bool { if conn.Config.iFaceBlackList == nil { return true From aa854c58999be5b0d82bfb6b8112913ef174bc4a Mon Sep 17 00:00:00 2001 From: mlsmaycon Date: Fri, 18 Jun 2021 13:01:43 +0200 Subject: [PATCH 12/23] add linux native wg interface --- connection/connection.go | 6 +- iface/iface.go | 7 +- iface/iface_configuration.go | 207 +++++++++++++++++++++++++++++++++++ iface/iface_linux.go | 60 ++++++++-- 4 files changed, 262 insertions(+), 18 deletions(-) create mode 100644 iface/iface_configuration.go diff --git a/connection/connection.go b/connection/connection.go index 69ff2a58a..d64131384 100644 --- a/connection/connection.go +++ b/connection/connection.go @@ -94,9 +94,9 @@ 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, + // MulticastDNSMode: ice.MulticastDNSModeQueryAndGather, + NetworkTypes: []ice.NetworkType{ice.NetworkTypeUDP4}, + Urls: conn.Config.StunTurnURLS, InterfaceFilter: func(s string) bool { if conn.Config.iFaceBlackList == nil { return true diff --git a/iface/iface.go b/iface/iface.go index 5909aaeaf..d0d185f12 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -1,15 +1,12 @@ +// +build !linux + 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" ) const ( diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go new file mode 100644 index 000000000..8f56bd4ce --- /dev/null +++ b/iface/iface_configuration.go @@ -0,0 +1,207 @@ +package iface + +import ( + "net" + "time" + + log "github.com/sirupsen/logrus" + "golang.zx2c4.com/wireguard/wgctrl" + "golang.zx2c4.com/wireguard/wgctrl/wgtypes" +) + +const ( + defaultMTU = 1280 +) + +// ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key +func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { + key, err := wgtypes.GeneratePrivateKey() + if err != nil { + return nil, err + } + return &key, Configure(iface, key.String()) +} + +// Configure configures a Wireguard interface +// The interface must exist before calling this method (e.g. call interface.Create() before) +func Configure(iface string, privateKey string) error { + + log.Debugf("configuring Wireguard interface %s", iface) + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + log.Debugf("adding Wireguard private key") + key, err := wgtypes.ParseKey(privateKey) + if err != nil { + return err + } + fwmark := 0 + cfg := wgtypes.Config{ + PrivateKey: &key, + ReplacePeers: false, + FirewallMark: &fwmark, + } + err = wg.ConfigureDevice(iface, cfg) + if err != nil { + return err + } + + return nil +} + +// GetListenPort returns the listening port of the Wireguard endpoint +func GetListenPort(iface string) (*int, error) { + log.Debugf("getting Wireguard listen port of interface %s", iface) + + //discover Wireguard current configuration + wg, err := wgctrl.New() + if err != nil { + return nil, err + } + defer wg.Close() + + d, err := wg.Device(iface) + if err != nil { + return nil, err + } + log.Debugf("got Wireguard device listen port %s, %d", iface, &d.ListenPort) + + return &d.ListenPort, nil +} + +// UpdateListenPort updates a Wireguard interface listen port +func UpdateListenPort(iface string, newPort int) error { + log.Debugf("updating Wireguard listen port of interface %s, new port %d", iface, newPort) + + //discover Wireguard current configuration + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + _, err = wg.Device(iface) + if err != nil { + return err + } + log.Debugf("got Wireguard device %s", iface) + + config := wgtypes.Config{ + ListenPort: &newPort, + ReplacePeers: false, + } + err = wg.ConfigureDevice(iface, config) + if err != nil { + return err + } + + log.Debugf("updated Wireguard listen port of interface %s, new port %d", iface, newPort) + + return nil +} + +// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist +// Endpoint is optional +func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error { + + log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint) + + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + _, err = wg.Device(iface) + if err != nil { + return err + } + log.Debugf("got Wireguard device %s", iface) + + //parse allowed ips + _, ipNet, err := net.ParseCIDR(allowedIps) + if err != nil { + return err + } + + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + peers := make([]wgtypes.PeerConfig, 0) + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + ReplaceAllowedIPs: true, + AllowedIPs: []net.IPNet{*ipNet}, + PersistentKeepaliveInterval: &keepAlive, + } + peers = append(peers, peer) + + config := wgtypes.Config{ + ReplacePeers: false, + Peers: peers, + } + err = wg.ConfigureDevice(iface, config) + if err != nil { + return err + } + + if endpoint != "" { + return UpdatePeerEndpoint(iface, peerKey, endpoint) + } + + return nil +} + +// UpdatePeerEndpoint updates a Wireguard interface Peer with the new endpoint +// Used when NAT hole punching was successful and an update of the remote peer endpoint is required +func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error { + + log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint) + + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + _, err = wg.Device(iface) + if err != nil { + return err + } + log.Debugf("got Wireguard device %s", iface) + + peerAddr, err := net.ResolveUDPAddr("udp4", newEndpoint) + if err != nil { + return err + } + + log.Debugf("parsed peer endpoint [%s]", peerAddr.String()) + + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + peers := make([]wgtypes.PeerConfig, 0) + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + ReplaceAllowedIPs: false, + UpdateOnly: true, + Endpoint: peerAddr, + } + peers = append(peers, peer) + + config := wgtypes.Config{ + ReplacePeers: false, + Peers: peers, + } + err = wg.ConfigureDevice(iface, config) + if err != nil { + return err + } + + return nil +} diff --git a/iface/iface_linux.go b/iface/iface_linux.go index 346ac5a0a..120d67954 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -3,24 +3,64 @@ package iface import ( log "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" - "golang.zx2c4.com/wireguard/tun" - "os" ) -//const ( -// interfacePrefix = "wg" -//) - -// assignAddr Adds IP address to the tunnel interface -func assignAddr(address string, tunDevice tun.Device) error { - var err error +// 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 { 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, } From 021092800be628100336e7d8313f9408033d37cf Mon Sep 17 00:00:00 2001 From: braginini Date: Fri, 18 Jun 2021 13:10:32 +0200 Subject: [PATCH 13/23] fix: extract constants from iface to iface_configuration --- iface/iface.go | 5 ----- iface/iface_configuration.go | 1 + 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/iface/iface.go b/iface/iface.go index d0d185f12..b58f4629c 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -9,11 +9,6 @@ import ( "golang.zx2c4.com/wireguard/tun" ) -const ( - defaultMTU = 1280 - WgPort = 51820 -) - // Saves tun device object - is it required? var tunIface tun.Device diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go index 8f56bd4ce..c17d46629 100644 --- a/iface/iface_configuration.go +++ b/iface/iface_configuration.go @@ -11,6 +11,7 @@ import ( const ( defaultMTU = 1280 + WgPort = 51820 ) // ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key From 8dfccfc8006b4612747bc6017c16b7c191055d50 Mon Sep 17 00:00:00 2001 From: braginini Date: Fri, 18 Jun 2021 13:22:56 +0200 Subject: [PATCH 14/23] refactor: remove unused code --- iface/iface.go | 195 ----------------------------------- iface/iface_configuration.go | 2 + 2 files changed, 2 insertions(+), 195 deletions(-) diff --git a/iface/iface.go b/iface/iface.go index b58f4629c..d33a2a829 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -51,198 +51,3 @@ func Create(iface string, address string) error { } return nil } - -// ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key -func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { - key, err := wgtypes.GeneratePrivateKey() - if err != nil { - return nil, err - } - return &key, Configure(iface, key.String()) -} - -// Configure configures a Wireguard interface -// The interface must exist before calling this method (e.g. call interface.Create() before) -func Configure(iface string, privateKey string) error { - - log.Debugf("configuring Wireguard interface %s", iface) - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - log.Debugf("adding Wireguard private key") - key, err := wgtypes.ParseKey(privateKey) - if err != nil { - 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 { - return err - } - - return nil -} - -// GetListenPort returns the listening port of the Wireguard endpoint -func GetListenPort(iface string) (*int, error) { - log.Debugf("getting Wireguard listen port of interface %s", iface) - - //discover Wireguard current configuration - wg, err := wgctrl.New() - if err != nil { - return nil, err - } - defer wg.Close() - - d, err := wg.Device(iface) - if err != nil { - return nil, err - } - log.Debugf("got Wireguard device listen port %s, %d", iface, &d.ListenPort) - - return &d.ListenPort, nil -} - -// UpdateListenPort updates a Wireguard interface listen port -func UpdateListenPort(iface string, newPort int) error { - log.Debugf("updating Wireguard listen port of interface %s, new port %d", iface, newPort) - - //discover Wireguard current configuration - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - _, err = wg.Device(iface) - if err != nil { - return err - } - log.Debugf("got Wireguard device %s", iface) - - config := wgtypes.Config{ - ListenPort: &newPort, - ReplacePeers: false, - } - err = wg.ConfigureDevice(iface, config) - if err != nil { - return err - } - - log.Debugf("updated Wireguard listen port of interface %s, new port %d", iface, newPort) - - return nil -} - -// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist -// Endpoint is optional -func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error { - - log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint) - - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - _, err = wg.Device(iface) - if err != nil { - return err - } - log.Debugf("got Wireguard device %s", iface) - - //parse allowed ips - _, ipNet, err := net.ParseCIDR(allowedIps) - if err != nil { - return err - } - - peerKeyParsed, err := wgtypes.ParseKey(peerKey) - if err != nil { - return err - } - peers := make([]wgtypes.PeerConfig, 0) - peer := wgtypes.PeerConfig{ - PublicKey: peerKeyParsed, - ReplaceAllowedIPs: true, - AllowedIPs: []net.IPNet{*ipNet}, - PersistentKeepaliveInterval: &keepAlive, - } - peers = append(peers, peer) - - config := wgtypes.Config{ - ReplacePeers: false, - Peers: peers, - } - err = wg.ConfigureDevice(iface, config) - if err != nil { - return err - } - - if endpoint != "" { - return UpdatePeerEndpoint(iface, peerKey, endpoint) - } - - return nil -} - -// UpdatePeerEndpoint updates a Wireguard interface Peer with the new endpoint -// Used when NAT hole punching was successful and an update of the remote peer endpoint is required -func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error { - - log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint) - - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - _, err = wg.Device(iface) - if err != nil { - return err - } - log.Debugf("got Wireguard device %s", iface) - - peerAddr, err := net.ResolveUDPAddr("udp4", newEndpoint) - if err != nil { - return err - } - - log.Debugf("parsed peer endpoint [%s]", peerAddr.String()) - - peerKeyParsed, err := wgtypes.ParseKey(peerKey) - if err != nil { - return err - } - peers := make([]wgtypes.PeerConfig, 0) - peer := wgtypes.PeerConfig{ - PublicKey: peerKeyParsed, - ReplaceAllowedIPs: false, - UpdateOnly: true, - Endpoint: peerAddr, - } - peers = append(peers, peer) - - config := wgtypes.Config{ - ReplacePeers: false, - Peers: peers, - } - err = wg.ConfigureDevice(iface, config) - if err != nil { - return err - } - - return nil -} diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go index c17d46629..d83abb25b 100644 --- a/iface/iface_configuration.go +++ b/iface/iface_configuration.go @@ -40,10 +40,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 { From dd72a01ecfab62d94e108b4c1fc107c5a26e4373 Mon Sep 17 00:00:00 2001 From: braginini Date: Tue, 22 Jun 2021 14:38:28 +0200 Subject: [PATCH 15/23] feature: add check of Wireguard kernel module existence (Linux only) --- go.mod | 1 + iface/mod.go | 140 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 iface/mod.go diff --git a/go.mod b/go.mod index 1b3a90f85..50e4a32ca 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( 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/iface/mod.go b/iface/mod.go new file mode 100644 index 000000000..0b59f3d9a --- /dev/null +++ b/iface/mod.go @@ -0,0 +1,140 @@ +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]), + ) +} + +// Name 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 Name(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 !info.Mode().IsRegular() { + return nil + } + fd, err := os.Open(path) + if err != nil { + return err + } + defer fd.Close() + name, err := Name(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") + if err != nil { + return false + } + + return true +} + +// 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 +} From 4216cd2986b4cd88e1f9514ec83324af6e17df5f Mon Sep 17 00:00:00 2001 From: braginini Date: Wed, 23 Jun 2021 16:11:54 +0200 Subject: [PATCH 16/23] feature: add feature to determine when to run wireguard userspace implementation or native one (linux) --- iface/iface.go | 46 +------------------ iface/iface_configuration.go | 46 +++++++++++++++++++ iface/iface_darwin.go | 4 +- iface/iface_linux.go | 88 +++++++++++++++++++----------------- iface/iface_windows.go | 4 +- 5 files changed, 97 insertions(+), 91 deletions(-) diff --git a/iface/iface.go b/iface/iface.go index d33a2a829..38beba6fa 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -2,52 +2,8 @@ package iface -import ( - log "github.com/sirupsen/logrus" - "golang.zx2c4.com/wireguard/conn" - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/tun" -) - -// Saves tun device object - is it required? -var tunIface tun.Device - // 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 { - var err error - tunIface, err = tun.CreateTUN(iface, defaultMTU) - if err != nil { - return err - } - - // We need to create a wireguard-go device and listen to configuration requests - tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) - err = tunDevice.Up() - if err != nil { - return err - } - uapi, err := getUAPI(iface) - if err != nil { - return err - } - - go func() { - for { - uapiConn, err := uapi.Accept() - if err != nil { - log.Debugln(err) - return - } - go tunDevice.IpcHandle(uapiConn) - } - }() - - log.Debugln("UAPI listener started") - - err = assignAddr(address, tunIface) - if err != nil { - return err - } - return nil + return CreateInUserspace(iface, address) } diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go index d83abb25b..f611a8553 100644 --- a/iface/iface_configuration.go +++ b/iface/iface_configuration.go @@ -1,6 +1,9 @@ package iface import ( + "golang.zx2c4.com/wireguard/conn" + "golang.zx2c4.com/wireguard/device" + "golang.zx2c4.com/wireguard/tun" "net" "time" @@ -23,6 +26,49 @@ func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { return &key, Configure(iface, key.String()) } +// CreateInUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation +func CreateInUserspace(iface string, address string) error { + var err error + tunIface, err := tun.CreateTUN(iface, defaultMTU) + if err != nil { + return err + } + + // We need to create a wireguard-go device and listen to configuration requests + tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) + err = tunDevice.Up() + if err != nil { + return err + } + uapi, err := getUAPI(iface) + if err != nil { + return err + } + + go func() { + for { + uapiConn, err := uapi.Accept() + if err != nil { + log.Debugln(err) + return + } + go tunDevice.IpcHandle(uapiConn) + } + }() + + log.Debugln("UAPI listener started") + + ifaceName, err := tunIface.Name() + if err != nil { + return err + } + err = assignAddr(address, ifaceName) + if err != nil { + return err + } + return nil +} + // Configure configures a Wireguard interface // The interface must exist before calling this method (e.g. call interface.Create() before) func Configure(iface string, privateKey string) error { diff --git a/iface/iface_darwin.go b/iface/iface_darwin.go index aa963e25e..0d07bff89 100644 --- a/iface/iface_darwin.go +++ b/iface/iface_darwin.go @@ -2,7 +2,6 @@ package iface import ( log "github.com/sirupsen/logrus" - "golang.zx2c4.com/wireguard/tun" "net" "os/exec" "strings" @@ -13,8 +12,7 @@ import ( //) // 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 120d67954..283ec2505 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -9,50 +9,56 @@ import ( // 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 { - attrs := netlink.NewLinkAttrs() - attrs.Name = iface - link := wgLink{ - attrs: &attrs, + if WireguardModExists() { + attrs := netlink.NewLinkAttrs() + 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 + } else { + return CreateInUserspace(iface, address) } - 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 diff --git a/iface/iface_windows.go b/iface/iface_windows.go index 9ce7aeafe..601ecfa4a 100644 --- a/iface/iface_windows.go +++ b/iface/iface_windows.go @@ -9,8 +9,8 @@ import ( ) // 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 { + nativeTunDevice := tunDevice.(*tun.NativeTun) luid := winipcfg.LUID(nativeTunDevice.LUID()) From 0e313eec24b7124f4e6f7d4b97cb835977cf4f6a Mon Sep 17 00:00:00 2001 From: braginini Date: Wed, 23 Jun 2021 16:16:48 +0200 Subject: [PATCH 17/23] fix: mod.go build only for linux --- iface/mod.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/iface/mod.go b/iface/mod.go index 0b59f3d9a..f020c3e13 100644 --- a/iface/mod.go +++ b/iface/mod.go @@ -1,3 +1,5 @@ +// +build linux + package iface // Holds logic to check existence of Wireguard kernel module From 561bd681d922767e814bdf0624895f734a648071 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 24 Jun 2021 10:55:05 +0200 Subject: [PATCH 18/23] fix: golint errors --- connection/connection.go | 3 +++ iface/mod.go | 12 +++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/connection/connection.go b/connection/connection.go index d64131384..7a95c766d 100644 --- a/connection/connection.go +++ b/connection/connection.go @@ -154,6 +154,9 @@ func (conn *Connection) Open(timeout time.Duration) error { 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 { diff --git a/iface/mod.go b/iface/mod.go index f020c3e13..dd3239dae 100644 --- a/iface/mod.go +++ b/iface/mod.go @@ -83,6 +83,12 @@ func elfMap(root string) (map[string]string, error) { 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 } @@ -118,11 +124,7 @@ func generateMap() (map[string]string, error) { // WireguardModExists returns true if Wireguard kernel module exists. func WireguardModExists() bool { _, err := resolveModName("wireguard") - if err != nil { - return false - } - - return true + return err == nil } // resolveModName will, given a module name (such as `wireguard`) return an absolute From 729b16e599fbc500840588b0f32b8f0b63dd61e8 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 24 Jun 2021 10:59:41 +0200 Subject: [PATCH 19/23] fix: windows iface build --- iface/iface_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iface/iface_windows.go b/iface/iface_windows.go index 601ecfa4a..9c7ff25cd 100644 --- a/iface/iface_windows.go +++ b/iface/iface_windows.go @@ -17,7 +17,7 @@ func assignAddr(address string, ifaceName string) error { 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 } From f2ca2fc7c1a0ee39825e5a995a9a40a3f3029397 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 24 Jun 2021 11:02:40 +0200 Subject: [PATCH 20/23] refactort: extract method to create Wireguard interface using kernel module --- iface/iface.go | 2 +- iface/iface_configuration.go | 4 +- iface/iface_linux.go | 96 +++++++++++++++++++----------------- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/iface/iface.go b/iface/iface.go index 38beba6fa..830a2ae52 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -5,5 +5,5 @@ package iface // 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 { - return CreateInUserspace(iface, address) + return CreateWithUserspace(iface, address) } diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go index f611a8553..cb2a95ebf 100644 --- a/iface/iface_configuration.go +++ b/iface/iface_configuration.go @@ -26,8 +26,8 @@ func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { return &key, Configure(iface, key.String()) } -// CreateInUserspace Creates a new Wireguard interface, using wireguard-go userspace implementation -func CreateInUserspace(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 { diff --git a/iface/iface_linux.go b/iface/iface_linux.go index 283ec2505..5d63695fc 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -11,56 +11,62 @@ import ( func Create(iface string, address string) error { if WireguardModExists() { - attrs := netlink.NewLinkAttrs() - 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 + return CreateWithKernel(iface, address) } else { - return CreateInUserspace(iface, address) + 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 = 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 From a40669270a2f60add2fce1e3dc8c1967542467bd Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 24 Jun 2021 11:46:33 +0200 Subject: [PATCH 21/23] refactor: rearrange iface package --- iface/iface.go | 256 ++++++++++++++++++++++++++++++++++- iface/iface_configuration.go | 256 ----------------------------------- iface/iface_darwin.go | 7 +- iface/iface_linux.go | 1 - iface/iface_windows.go | 7 +- 5 files changed, 260 insertions(+), 267 deletions(-) delete mode 100644 iface/iface_configuration.go diff --git a/iface/iface.go b/iface/iface.go index 830a2ae52..5534cd6e4 100644 --- a/iface/iface.go +++ b/iface/iface.go @@ -1,9 +1,253 @@ -// +build !linux - package iface -// 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 { - return CreateWithUserspace(iface, address) +import ( + 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 +) + +var tunIface tun.Device + +// 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 { + return err + } + + // We need to create a wireguard-go device and listen to configuration requests + tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) + err = tunDevice.Up() + if err != nil { + return err + } + uapi, err := getUAPI(iface) + if err != nil { + return err + } + + go func() { + for { + uapiConn, err := uapi.Accept() + if err != nil { + log.Debugln(err) + return + } + go tunDevice.IpcHandle(uapiConn) + } + }() + + log.Debugln("UAPI listener started") + + err = assignAddr(address, iface) + if err != nil { + return err + } + return nil +} + +// ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key +func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { + key, err := wgtypes.GeneratePrivateKey() + if err != nil { + return nil, err + } + return &key, Configure(iface, key.String()) +} + +// Configure configures a Wireguard interface +// The interface must exist before calling this method (e.g. call interface.Create() before) +func Configure(iface string, privateKey string) error { + + log.Debugf("configuring Wireguard interface %s", iface) + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + log.Debugf("adding Wireguard private key") + key, err := wgtypes.ParseKey(privateKey) + if err != nil { + 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 { + return err + } + + return nil +} + +// GetListenPort returns the listening port of the Wireguard endpoint +func GetListenPort(iface string) (*int, error) { + log.Debugf("getting Wireguard listen port of interface %s", iface) + + //discover Wireguard current configuration + wg, err := wgctrl.New() + if err != nil { + return nil, err + } + defer wg.Close() + + d, err := wg.Device(iface) + if err != nil { + return nil, err + } + log.Debugf("got Wireguard device listen port %s, %d", iface, &d.ListenPort) + + return &d.ListenPort, nil +} + +// UpdateListenPort updates a Wireguard interface listen port +func UpdateListenPort(iface string, newPort int) error { + log.Debugf("updating Wireguard listen port of interface %s, new port %d", iface, newPort) + + //discover Wireguard current configuration + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + _, err = wg.Device(iface) + if err != nil { + return err + } + log.Debugf("got Wireguard device %s", iface) + + config := wgtypes.Config{ + ListenPort: &newPort, + ReplacePeers: false, + } + err = wg.ConfigureDevice(iface, config) + if err != nil { + return err + } + + log.Debugf("updated Wireguard listen port of interface %s, new port %d", iface, newPort) + + return nil +} + +// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist +// Endpoint is optional +func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error { + + log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint) + + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + _, err = wg.Device(iface) + if err != nil { + return err + } + log.Debugf("got Wireguard device %s", iface) + + //parse allowed ips + _, ipNet, err := net.ParseCIDR(allowedIps) + if err != nil { + return err + } + + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + peers := make([]wgtypes.PeerConfig, 0) + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + ReplaceAllowedIPs: true, + AllowedIPs: []net.IPNet{*ipNet}, + PersistentKeepaliveInterval: &keepAlive, + } + peers = append(peers, peer) + + config := wgtypes.Config{ + ReplacePeers: false, + Peers: peers, + } + err = wg.ConfigureDevice(iface, config) + if err != nil { + return err + } + + if endpoint != "" { + return UpdatePeerEndpoint(iface, peerKey, endpoint) + } + + return nil +} + +// UpdatePeerEndpoint updates a Wireguard interface Peer with the new endpoint +// Used when NAT hole punching was successful and an update of the remote peer endpoint is required +func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error { + + log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint) + + wg, err := wgctrl.New() + if err != nil { + return err + } + defer wg.Close() + + _, err = wg.Device(iface) + if err != nil { + return err + } + log.Debugf("got Wireguard device %s", iface) + + peerAddr, err := net.ResolveUDPAddr("udp4", newEndpoint) + if err != nil { + return err + } + + log.Debugf("parsed peer endpoint [%s]", peerAddr.String()) + + peerKeyParsed, err := wgtypes.ParseKey(peerKey) + if err != nil { + return err + } + peers := make([]wgtypes.PeerConfig, 0) + peer := wgtypes.PeerConfig{ + PublicKey: peerKeyParsed, + ReplaceAllowedIPs: false, + UpdateOnly: true, + Endpoint: peerAddr, + } + peers = append(peers, peer) + + config := wgtypes.Config{ + ReplacePeers: false, + Peers: peers, + } + err = wg.ConfigureDevice(iface, config) + if err != nil { + return err + } + + return nil } diff --git a/iface/iface_configuration.go b/iface/iface_configuration.go deleted file mode 100644 index cb2a95ebf..000000000 --- a/iface/iface_configuration.go +++ /dev/null @@ -1,256 +0,0 @@ -package iface - -import ( - "golang.zx2c4.com/wireguard/conn" - "golang.zx2c4.com/wireguard/device" - "golang.zx2c4.com/wireguard/tun" - "net" - "time" - - log "github.com/sirupsen/logrus" - "golang.zx2c4.com/wireguard/wgctrl" - "golang.zx2c4.com/wireguard/wgctrl/wgtypes" -) - -const ( - defaultMTU = 1280 - WgPort = 51820 -) - -// ConfigureWithKeyGen Extends the functionality of Configure(iface string, privateKey string) by generating a new Wireguard private key -func ConfigureWithKeyGen(iface string) (*wgtypes.Key, error) { - key, err := wgtypes.GeneratePrivateKey() - if err != nil { - return nil, err - } - return &key, Configure(iface, key.String()) -} - -// 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 { - return err - } - - // We need to create a wireguard-go device and listen to configuration requests - tunDevice := device.NewDevice(tunIface, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, "[wiretrustee] ")) - err = tunDevice.Up() - if err != nil { - return err - } - uapi, err := getUAPI(iface) - if err != nil { - return err - } - - go func() { - for { - uapiConn, err := uapi.Accept() - if err != nil { - log.Debugln(err) - return - } - go tunDevice.IpcHandle(uapiConn) - } - }() - - log.Debugln("UAPI listener started") - - ifaceName, err := tunIface.Name() - if err != nil { - return err - } - err = assignAddr(address, ifaceName) - if err != nil { - return err - } - return nil -} - -// Configure configures a Wireguard interface -// The interface must exist before calling this method (e.g. call interface.Create() before) -func Configure(iface string, privateKey string) error { - - log.Debugf("configuring Wireguard interface %s", iface) - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - log.Debugf("adding Wireguard private key") - key, err := wgtypes.ParseKey(privateKey) - if err != nil { - 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 { - return err - } - - return nil -} - -// GetListenPort returns the listening port of the Wireguard endpoint -func GetListenPort(iface string) (*int, error) { - log.Debugf("getting Wireguard listen port of interface %s", iface) - - //discover Wireguard current configuration - wg, err := wgctrl.New() - if err != nil { - return nil, err - } - defer wg.Close() - - d, err := wg.Device(iface) - if err != nil { - return nil, err - } - log.Debugf("got Wireguard device listen port %s, %d", iface, &d.ListenPort) - - return &d.ListenPort, nil -} - -// UpdateListenPort updates a Wireguard interface listen port -func UpdateListenPort(iface string, newPort int) error { - log.Debugf("updating Wireguard listen port of interface %s, new port %d", iface, newPort) - - //discover Wireguard current configuration - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - _, err = wg.Device(iface) - if err != nil { - return err - } - log.Debugf("got Wireguard device %s", iface) - - config := wgtypes.Config{ - ListenPort: &newPort, - ReplacePeers: false, - } - err = wg.ConfigureDevice(iface, config) - if err != nil { - return err - } - - log.Debugf("updated Wireguard listen port of interface %s, new port %d", iface, newPort) - - return nil -} - -// UpdatePeer updates existing Wireguard Peer or creates a new one if doesn't exist -// Endpoint is optional -func UpdatePeer(iface string, peerKey string, allowedIps string, keepAlive time.Duration, endpoint string) error { - - log.Debugf("updating interface %s peer %s: endpoint %s ", iface, peerKey, endpoint) - - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - _, err = wg.Device(iface) - if err != nil { - return err - } - log.Debugf("got Wireguard device %s", iface) - - //parse allowed ips - _, ipNet, err := net.ParseCIDR(allowedIps) - if err != nil { - return err - } - - peerKeyParsed, err := wgtypes.ParseKey(peerKey) - if err != nil { - return err - } - peers := make([]wgtypes.PeerConfig, 0) - peer := wgtypes.PeerConfig{ - PublicKey: peerKeyParsed, - ReplaceAllowedIPs: true, - AllowedIPs: []net.IPNet{*ipNet}, - PersistentKeepaliveInterval: &keepAlive, - } - peers = append(peers, peer) - - config := wgtypes.Config{ - ReplacePeers: false, - Peers: peers, - } - err = wg.ConfigureDevice(iface, config) - if err != nil { - return err - } - - if endpoint != "" { - return UpdatePeerEndpoint(iface, peerKey, endpoint) - } - - return nil -} - -// UpdatePeerEndpoint updates a Wireguard interface Peer with the new endpoint -// Used when NAT hole punching was successful and an update of the remote peer endpoint is required -func UpdatePeerEndpoint(iface string, peerKey string, newEndpoint string) error { - - log.Debugf("updating peer %s endpoint %s ", peerKey, newEndpoint) - - wg, err := wgctrl.New() - if err != nil { - return err - } - defer wg.Close() - - _, err = wg.Device(iface) - if err != nil { - return err - } - log.Debugf("got Wireguard device %s", iface) - - peerAddr, err := net.ResolveUDPAddr("udp4", newEndpoint) - if err != nil { - return err - } - - log.Debugf("parsed peer endpoint [%s]", peerAddr.String()) - - peerKeyParsed, err := wgtypes.ParseKey(peerKey) - if err != nil { - return err - } - peers := make([]wgtypes.PeerConfig, 0) - peer := wgtypes.PeerConfig{ - PublicKey: peerKeyParsed, - ReplaceAllowedIPs: false, - UpdateOnly: true, - Endpoint: peerAddr, - } - peers = append(peers, peer) - - config := wgtypes.Config{ - ReplacePeers: false, - Peers: peers, - } - err = wg.ConfigureDevice(iface, config) - if err != nil { - return err - } - - return nil -} diff --git a/iface/iface_darwin.go b/iface/iface_darwin.go index 0d07bff89..c3c86050b 100644 --- a/iface/iface_darwin.go +++ b/iface/iface_darwin.go @@ -7,9 +7,10 @@ import ( "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, ifaceName string) error { diff --git a/iface/iface_linux.go b/iface/iface_linux.go index 5d63695fc..fd39aee45 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -15,7 +15,6 @@ func Create(iface string, address string) error { } else { return CreateWithUserspace(iface, address) } - } // CreateWithKernel Creates a new Wireguard interface using kernel Wireguard module. diff --git a/iface/iface_windows.go b/iface/iface_windows.go index 9c7ff25cd..46966b23d 100644 --- a/iface/iface_windows.go +++ b/iface/iface_windows.go @@ -8,10 +8,15 @@ 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, ifaceName string) error { - nativeTunDevice := tunDevice.(*tun.NativeTun) + nativeTunDevice := tunIface.(*tun.NativeTun) luid := winipcfg.LUID(nativeTunDevice.LUID()) ip, ipnet, _ := net.ParseCIDR(address) From dac865c61fea274a8e7f5776238bc55093698f23 Mon Sep 17 00:00:00 2001 From: braginini Date: Thu, 24 Jun 2021 12:49:14 +0200 Subject: [PATCH 22/23] chore: add log to detect a usage of the Wireguard kernel module --- iface/iface_linux.go | 1 + 1 file changed, 1 insertion(+) diff --git a/iface/iface_linux.go b/iface/iface_linux.go index fd39aee45..86c670785 100644 --- a/iface/iface_linux.go +++ b/iface/iface_linux.go @@ -11,6 +11,7 @@ import ( func Create(iface string, address string) error { if WireguardModExists() { + log.Debug("using kernel Wireguard module") return CreateWithKernel(iface, address) } else { return CreateWithUserspace(iface, address) From 61a7f3013b21259c95af3ec7e4e9a9dce56965fb Mon Sep 17 00:00:00 2001 From: mlsmaycon Date: Thu, 24 Jun 2021 23:16:09 +0200 Subject: [PATCH 23/23] Rename Name function --- iface/mod.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/iface/mod.go b/iface/mod.go index dd3239dae..d3195b808 100644 --- a/iface/mod.go +++ b/iface/mod.go @@ -38,10 +38,10 @@ func getModuleRoot() string { ) } -// Name will, given a file descriptor to a Kernel Module (.ko file), parse the +// 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 Name(file *os.File) (string, error) { +func modName(file *os.File) (string, error) { f, err := elf.NewFile(file) if err != nil { return "", err @@ -97,7 +97,7 @@ func elfMap(root string) (map[string]string, error) { return err } defer fd.Close() - name, err := Name(fd) + name, err := modName(fd) if err != nil { /* For now, let's just ignore that and avoid adding to it */ return nil