From 4b1aefc2b0425d3bb0ae2fdd72484ae21c2d1f48 Mon Sep 17 00:00:00 2001 From: Nikita Skrynnik Date: Wed, 11 May 2022 12:24:13 +0700 Subject: [PATCH 1/3] ping: send 4 packets Signed-off-by: Nikita Skrynnik --- pkg/kernel/tools/heal/liveness_check.go | 40 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/pkg/kernel/tools/heal/liveness_check.go b/pkg/kernel/tools/heal/liveness_check.go index 637fcddd..61bb3732 100644 --- a/pkg/kernel/tools/heal/liveness_check.go +++ b/pkg/kernel/tools/heal/liveness_check.go @@ -30,7 +30,8 @@ import ( ) const ( - defaultTimeout = 200 * time.Millisecond + defaultTimeout = 4 * time.Second + packetCount = 4 ) // KernelLivenessCheck is an implementation of heal.LivenessCheck. It sends ICMP @@ -47,7 +48,7 @@ func KernelLivenessCheck(deadlineCtx context.Context, conn *networkservice.Conne deadline = time.Now().Add(defaultTimeout) } - p.MaxRTT = time.Until(deadline) + p.MaxRTT = time.Until(deadline) / packetCount addrCount := len(conn.GetContext().GetIpContext().GetDstIpAddrs()) for _, cidr := range conn.GetContext().GetIpContext().GetDstIpAddrs() { @@ -68,20 +69,31 @@ func KernelLivenessCheck(deadlineCtx context.Context, conn *networkservice.Conne var aliveCh = make(chan bool) p.OnIdle = func() { aliveCh <- int(atomic.LoadInt32(&count)) == addrCount - close(aliveCh) + atomic.AddInt32(&count, -count) } - err := p.Run() - - if err != nil { - log.FromContext(deadlineCtx).Error("Ping failed: %s", err.Error()) - return false - } + go func() { + for i := 0; i < packetCount; i++ { + err := p.Run() + if err != nil { + log.FromContext(deadlineCtx).Error("Ping failed: %s", err.Error()) + } + } + }() - select { - case alive := <-aliveCh: - return alive - case <-deadlineCtx.Done(): - return false + packetsReceived := 0 + for { + select { + case value := <-aliveCh: + if value { + return true + } + packetsReceived++ + if packetsReceived == packetCount { + return false + } + case <-deadlineCtx.Done(): + return false + } } } From dfdf90c609ca93fdfa171f41c1b37c8103fbc23f Mon Sep 17 00:00:00 2001 From: Nikita Skrynnik Date: Wed, 11 May 2022 20:23:37 +0700 Subject: [PATCH 2/3] apply comments Signed-off-by: Nikita Skrynnik --- pkg/kernel/tools/heal/liveness_check.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/kernel/tools/heal/liveness_check.go b/pkg/kernel/tools/heal/liveness_check.go index 61bb3732..c741e509 100644 --- a/pkg/kernel/tools/heal/liveness_check.go +++ b/pkg/kernel/tools/heal/liveness_check.go @@ -30,7 +30,7 @@ import ( ) const ( - defaultTimeout = 4 * time.Second + defaultTimeout = time.Second packetCount = 4 ) From 8bf2978b1bb4d67567009d51e7b07ce778e7e4d1 Mon Sep 17 00:00:00 2001 From: Nikita Skrynnik Date: Thu, 12 May 2022 22:48:37 +0700 Subject: [PATCH 3/3] use another ping library Signed-off-by: Nikita Skrynnik --- go.mod | 5 +- go.sum | 12 +++-- pkg/kernel/tools/heal/liveness_check.go | 66 ++++++++++--------------- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/go.mod b/go.mod index 4fab88ca..a85cf750 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,12 @@ module github.com/networkservicemesh/sdk-kernel go 1.18 require ( + github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 github.com/golang/protobuf v1.5.2 github.com/networkservicemesh/api v1.3.0-rc.1.0.20220405210054-fbcde048efa5 github.com/networkservicemesh/sdk v0.5.1-0.20220505102418-8d6762737896 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.7.0 - github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e github.com/vishvananda/netlink v1.1.1-0.20220118170537-d6b03fdeb845 github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 go.uber.org/goleak v1.1.12 @@ -22,7 +22,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.2.1 // indirect github.com/go-logr/stdr v1.2.0 // indirect - github.com/google/uuid v1.1.2 // indirect + github.com/google/uuid v1.2.0 // indirect github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sirupsen/logrus v1.8.1 // indirect @@ -40,6 +40,7 @@ require ( go.opentelemetry.io/otel/trace v1.3.0 // indirect go.opentelemetry.io/proto/otlp v0.11.0 // indirect golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect + golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12 // indirect google.golang.org/protobuf v1.27.1 // indirect diff --git a/go.sum b/go.sum index ab6c483d..33c7f1c6 100644 --- a/go.sum +++ b/go.sum @@ -36,7 +36,11 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.1 h1:DX7uPQ4WgAWfoh+NGGlbJQswnYIVvz0SRlLS3rPZQDA= github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.0 h1:j4LrlVXgrbIWO83mmQUnK0Hi+YnbD+vzrE1z/EphbFE= +github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 h1:dhy9OQKGBh4zVXbjwbxxHjRxMJtLXj3zfgpBYQaR4Q4= +github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534 h1:dhy9OQKGBh4zVXbjwbxxHjRxMJtLXj3zfgpBYQaR4Q4= +github.com/go-ping/ping v0.0.0-20211130115550-779d1e919534/go.mod h1:xIFjORFzTxqIV/tDVGO4eDy/bLuSyawEeojSm3GfRGk= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -61,8 +65,9 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= @@ -88,8 +93,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e h1:nt2877sKfojlHCTOBXbpWjBkuWKritFaGIfgQwbQUls= -github.com/tatsushid/go-fastping v0.0.0-20160109021039-d7bb493dee3e/go.mod h1:B4+Kq1u5FlULTjFSM707Q6e/cOHFv0z/6QRoxubDIQ8= github.com/vishvananda/netlink v1.1.1-0.20220118170537-d6b03fdeb845 h1:bIVwDExax2ZzN6mYF8Az0ms0wg+v/LYA4VI8x1TSQcs= github.com/vishvananda/netlink v1.1.1-0.20220118170537-d6b03fdeb845/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= @@ -143,6 +146,7 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -152,6 +156,7 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -161,6 +166,7 @@ golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/pkg/kernel/tools/heal/liveness_check.go b/pkg/kernel/tools/heal/liveness_check.go index c741e509..eb43e89f 100644 --- a/pkg/kernel/tools/heal/liveness_check.go +++ b/pkg/kernel/tools/heal/liveness_check.go @@ -20,13 +20,12 @@ package heal import ( "context" "net" - "sync/atomic" "time" + "github.com/go-ping/ping" "github.com/networkservicemesh/api/pkg/api/networkservice" "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel" "github.com/networkservicemesh/sdk/pkg/tools/log" - "github.com/tatsushid/go-fastping" ) const ( @@ -42,58 +41,47 @@ func KernelLivenessCheck(deadlineCtx context.Context, conn *networkservice.Conne return true } - p := fastping.NewPinger() deadline, ok := deadlineCtx.Deadline() if !ok { deadline = time.Now().Add(defaultTimeout) } - p.MaxRTT = time.Until(deadline) / packetCount - addrCount := len(conn.GetContext().GetIpContext().GetDstIpAddrs()) + timeout := time.Until(deadline) / time.Duration(addrCount+1) + + // This function requires string argument. Works fine with empty string. + pinger, err := ping.NewPinger("") + if err != nil { + log.FromContext(deadlineCtx).Errorf("Failed to create pinger: %s", err.Error()) + } + pinger.SetPrivileged(true) + pinger.Timeout = timeout + pinger.Count = packetCount + for _, cidr := range conn.GetContext().GetIpContext().GetDstIpAddrs() { addr, _, err := net.ParseCIDR(cidr) if err != nil { + log.FromContext(deadlineCtx).Errorf("ParseCIDR failed: %s", err.Error()) return false } - ipAddr := &net.IPAddr{IP: addr} - p.AddIPAddr(ipAddr) - } - - var count int32 - - p.OnRecv = func(ipAddr *net.IPAddr, d time.Duration) { - atomic.AddInt32(&count, 1) - } - var aliveCh = make(chan bool) - p.OnIdle = func() { - aliveCh <- int(atomic.LoadInt32(&count)) == addrCount - atomic.AddInt32(&count, -count) - } - - go func() { - for i := 0; i < packetCount; i++ { - err := p.Run() - if err != nil { - log.FromContext(deadlineCtx).Error("Ping failed: %s", err.Error()) - } + ipAddr := &net.IPAddr{IP: addr} + pinger.SetIPAddr(ipAddr) + err = pinger.Run() + if err != nil { + log.FromContext(deadlineCtx).Errorf("Ping failed: %s", err.Error()) + return false } - }() - packetsReceived := 0 - for { - select { - case value := <-aliveCh: - if value { - return true - } - packetsReceived++ - if packetsReceived == packetCount { - return false - } - case <-deadlineCtx.Done(): + if pinger.Statistics().PacketsRecv == 0 { return false } } + + select { + case <-deadlineCtx.Done(): + return false + default: + return true + } }