github.com/grafana/synthetic-monitoring-agent@v0.64.2/internal/prober/icmp/icmp.go (about) 1 package icmp 2 3 import ( 4 "context" 5 "errors" 6 "sync" 7 "time" 8 9 "github.com/go-kit/log" 10 "github.com/grafana/synthetic-monitoring-agent/internal/model" 11 "github.com/grafana/synthetic-monitoring-agent/internal/prober/logger" 12 sm "github.com/grafana/synthetic-monitoring-agent/pkg/pb/synthetic_monitoring" 13 "github.com/prometheus/blackbox_exporter/config" 14 "github.com/prometheus/client_golang/prometheus" 15 ) 16 17 var errUnsupportedCheck = errors.New("unsupported check") 18 19 type Module struct { 20 Prober string 21 Timeout time.Duration 22 PacketCount int64 23 ReqSuccessCount int64 24 MaxResolveRetries int64 25 ICMP config.ICMPProbe 26 Privileged bool 27 } 28 29 type Prober struct { 30 config Module 31 } 32 33 func NewProber(check model.Check) (Prober, error) { 34 var p Prober 35 36 if check.Settings.Ping == nil { 37 return p, errUnsupportedCheck 38 } 39 40 p.config = settingsToModule(check.Settings.Ping) 41 p.config.Timeout = time.Duration(check.Timeout) * time.Millisecond 42 p.config.Privileged = isPrivilegedRequired() 43 44 return p, nil 45 } 46 47 func (p Prober) Name() string { 48 return "ping" 49 } 50 51 func (p Prober) Probe(ctx context.Context, target string, registry *prometheus.Registry, l logger.Logger, _ string) (bool, float64) { 52 return probeICMP(ctx, target, p.config, registry, l) 53 } 54 55 func settingsToModule(settings *sm.PingSettings) Module { 56 var m Module 57 58 m.Prober = sm.CheckTypePing.String() 59 60 m.ICMP.IPProtocol, m.ICMP.IPProtocolFallback = settings.IpVersion.ToIpProtocol() 61 62 m.ICMP.SourceIPAddress = settings.SourceIpAddress 63 64 m.ICMP.PayloadSize = int(settings.PayloadSize) 65 66 m.ICMP.DontFragment = settings.DontFragment 67 68 if settings.PacketCount == 0 { 69 m.PacketCount = 3 70 m.ReqSuccessCount = 1 71 } else { 72 m.PacketCount = settings.PacketCount 73 m.ReqSuccessCount = settings.PacketCount // TODO(mem): expose this setting 74 } 75 76 // TODO(mem): add a setting for this 77 m.MaxResolveRetries = 3 78 79 return m 80 } 81 82 var ( 83 privilegedRequired bool 84 privilegedCheckDone bool 85 privilegedCheckMutex sync.Mutex 86 ) 87 88 func isPrivilegedRequired() bool { 89 privilegedCheckMutex.Lock() 90 defer privilegedCheckMutex.Unlock() 91 92 if privilegedCheckDone { 93 return privilegedRequired 94 } 95 96 var ( 97 ctx = context.Background() 98 target = "127.0.0.1" 99 registry = prometheus.NewRegistry() 100 logger = log.NewNopLogger() 101 config = Module{ 102 Prober: "test-unprivileged", 103 Timeout: 1 * time.Second, 104 PacketCount: 1, 105 Privileged: false, 106 ICMP: config.ICMPProbe{ 107 IPProtocol: "ip4", 108 }, 109 } 110 ) 111 112 success, _ := probeICMP(ctx, target, config, registry, logger) 113 114 privilegedRequired = !success 115 privilegedCheckDone = true 116 117 return privilegedRequired 118 }