From 5ab8f9d2e62237eb3b9a26c6ee1e8c39a866487d Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Thu, 16 Nov 2023 15:47:32 +0400 Subject: [PATCH] feat: allow persistent keepalive to be set for the peer This allows persisten keepalive configuration on the SideroLink server side. Signed-off-by: Andrey Smirnov --- .codecov.yml | 2 +- .github/workflows/ci.yaml | 13 +------------ .github/workflows/slack-notify.yaml | 28 ++++------------------------ .kres.yaml | 5 +++++ Makefile | 8 ++++---- go.mod | 3 ++- go.sum | 2 ++ internal/server/server.go | 6 ++++-- pkg/wireguard/peer.go | 3 +++ pkg/wireguard/wireguard.go | 8 +++++++- 10 files changed, 33 insertions(+), 45 deletions(-) diff --git a/.codecov.yml b/.codecov.yml index 52c4f26..f63bb33 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2021-11-18T14:01:40Z by kres 8d6311a-dirty. +# Generated on 2023-11-16T11:52:03Z by kres latest. codecov: require_ci_to_pass: false diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6b4b407..41606b5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2023-11-07T12:21:22Z by kres latest. +# Generated on 2023-11-16T11:35:00Z by kres latest. name: default concurrency: @@ -49,17 +49,6 @@ jobs: with: driver: remote endpoint: tcp://localhost:1234 - - name: Save PR number - if: github.event_name == 'pull_request' && always() - run: | - echo ${{ github.event.number }} > pr-number.txt - - name: Upload PR number - if: github.event_name == 'pull_request' && always() - uses: actions/upload-artifact@v3 - with: - name: pr-number - path: pr-number.txt - retention-days: "1" - name: base run: | make base diff --git a/.github/workflows/slack-notify.yaml b/.github/workflows/slack-notify.yaml index ef10180..5b832b0 100644 --- a/.github/workflows/slack-notify.yaml +++ b/.github/workflows/slack-notify.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2023-11-07T12:21:22Z by kres latest. +# Generated on 2023-11-16T11:35:00Z by kres latest. name: slack-notify "on": @@ -16,33 +16,13 @@ jobs: - generic if: github.event.workflow_run.conclusion != 'skipped' steps: - - name: Download PR artifact - if: github.event.workflow_run.event == 'pull_request' - uses: actions/github-script@v6 - with: - script: |- - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - let matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { - return artifact.name == "pr-number" - })[0]; - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - let fs = require('fs'); - fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/pr-number.zip`, Buffer.from(download.data)); - name: Get PR number id: get-pr-number if: github.event.workflow_run.event == 'pull_request' + env: + GH_TOKEN: ${{ github.token }} run: | - unzip pr-number.zip - echo pull_request_number=$(cat pr-number.txt) >> $GITHUB_OUTPUT + echo pull_request_number=$(gh pr view -R ${{ github.repository }} ${{ github.event.workflow_run.head_repository.owner.login }}:${{ github.event.workflow_run.head_branch }} --json number --jq .number) >> $GITHUB_OUTPUT - name: Slack Notify uses: slackapi/slack-github-action@v1 with: diff --git a/.kres.yaml b/.kres.yaml index 0071b69..f8e8b58 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -35,3 +35,8 @@ spec: windows-amd64.exe: GOOS: windows GOARCH: amd64 +--- +kind: service.CodeCov +spec: + targetThreshold: 10 + diff --git a/Makefile b/Makefile index f369d5d..5e6e9e3 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2023-11-07T12:12:47Z by kres latest. +# Generated on 2023-11-16T11:35:00Z by kres latest. # common variables @@ -16,13 +16,13 @@ USERNAME ?= siderolabs REGISTRY_AND_USERNAME ?= $(REGISTRY)/$(USERNAME) PROTOBUF_GO_VERSION ?= 1.31.0 GRPC_GO_VERSION ?= 1.3.0 -GRPC_GATEWAY_VERSION ?= 2.18.0 +GRPC_GATEWAY_VERSION ?= 2.18.1 VTPROTOBUF_VERSION ?= 0.5.0 DEEPCOPY_VERSION ?= v0.5.5 GOLANGCILINT_VERSION ?= v1.55.2 GOFUMPT_VERSION ?= v0.5.0 -GO_VERSION ?= 1.21.3 -GOIMPORTS_VERSION ?= v0.14.0 +GO_VERSION ?= 1.21.4 +GOIMPORTS_VERSION ?= v0.15.0 GO_BUILDFLAGS ?= GO_LDFLAGS ?= CGO_ENABLED ?= 0 diff --git a/go.mod b/go.mod index 9597292..3610637 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module github.com/siderolabs/siderolink -go 1.21.0 +go 1.21.4 require ( github.com/jsimonetti/rtnetlink v1.3.5 + github.com/siderolabs/go-pointer v1.0.0 github.com/stretchr/testify v1.8.4 go.uber.org/zap v1.26.0 go4.org/netipx v0.0.0-20230824141953-6213f710f925 diff --git a/go.sum b/go.sum index 62e9c2f..3bbfefa 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,8 @@ github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721 h1:RlZweED6sbSArvlE9 github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= 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/siderolabs/go-pointer v1.0.0 h1:6TshPKep2doDQJAAtHUuHWXbca8ZfyRySjSBT/4GsMU= +github.com/siderolabs/go-pointer v1.0.0/go.mod h1:HTRFUNYa3R+k0FFKNv11zgkaCLzEkWVzoYZ433P3kHc= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= diff --git a/internal/server/server.go b/internal/server/server.go index 75bacc4..86a2790 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -12,6 +12,7 @@ import ( "io" "net/netip" + "github.com/siderolabs/go-pointer" "go.uber.org/zap" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" "google.golang.org/grpc/codes" @@ -79,8 +80,9 @@ func (srv *Server) Provision(_ context.Context, req *pb.ProvisionRequest) (*pb.P } srv.eventCh <- wireguard.PeerEvent{ - PubKey: pubKey, - Address: nodeAddress.Addr(), + PubKey: pubKey, + Address: nodeAddress.Addr(), + PersistentKeepAliveInterval: pointer.To(wireguard.RecommendedPersistentKeepAliveInterval), } srv.cfg.Logger.Debug( diff --git a/pkg/wireguard/peer.go b/pkg/wireguard/peer.go index d7540cc..fc90dfa 100644 --- a/pkg/wireguard/peer.go +++ b/pkg/wireguard/peer.go @@ -6,6 +6,7 @@ package wireguard import ( "net/netip" + "time" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) @@ -25,4 +26,6 @@ type PeerEvent struct { Endpoint string Address netip.Addr + + PersistentKeepAliveInterval *time.Duration } diff --git a/pkg/wireguard/wireguard.go b/pkg/wireguard/wireguard.go index da1eb18..eb9f8f7 100644 --- a/pkg/wireguard/wireguard.go +++ b/pkg/wireguard/wireguard.go @@ -15,6 +15,7 @@ import ( "sync" "time" + "github.com/siderolabs/go-pointer" "go.uber.org/zap" "go4.org/netipx" "golang.zx2c4.com/wireguard/conn" @@ -43,6 +44,9 @@ const ( // for IPv6. LinkMTU = 1280 + // RecommendedPersistentKeepAliveInterval is the recommended interval for persistent keepalive. + RecommendedPersistentKeepAliveInterval = 25 * time.Second + linkKindWireguard = "wireguard" ) @@ -245,7 +249,8 @@ func (dev *Device) checkDuplicateUpdate(client *wgctrl.Client, logger *zap.Logge } if prefix, ok := netipx.FromStdIPNet(&oldPeer.AllowedIPs[0]); ok { - if prefix.Addr() == peerEvent.Address { + if prefix.Addr() == peerEvent.Address && // check address match & keepalive settings match + (peerEvent.PersistentKeepAliveInterval == nil || pointer.SafeDeref(peerEvent.PersistentKeepAliveInterval) == oldPeer.PersistentKeepaliveInterval) { // skip the update logger.Info("skipping peer update", zap.String("public_key", pubKey)) @@ -289,6 +294,7 @@ func (dev *Device) handlePeerEvent(logger *zap.Logger, peerEvent PeerEvent) erro cfg.Peers[0].AllowedIPs = []net.IPNet{ *netipx.PrefixIPNet(netip.PrefixFrom(peerEvent.Address, peerEvent.Address.BitLen())), } + cfg.Peers[0].PersistentKeepaliveInterval = peerEvent.PersistentKeepAliveInterval if peerEvent.Endpoint != "" { ip, err := netip.ParseAddrPort(peerEvent.Endpoint)