generated from sendnrw/template_golang
init
Some checks failed
build-binaries / build (, amd64, linux) (push) Has been skipped
build-binaries / build (, arm, 7, linux) (push) Has been skipped
build-binaries / build (, arm64, linux) (push) Has been skipped
build-binaries / build (.exe, amd64, windows) (push) Has been skipped
build-binaries / release (push) Has been skipped
build-binaries / publish-agent (push) Has been skipped
release-tag / release-image (push) Has been cancelled
Some checks failed
build-binaries / build (, amd64, linux) (push) Has been skipped
build-binaries / build (, arm, 7, linux) (push) Has been skipped
build-binaries / build (, arm64, linux) (push) Has been skipped
build-binaries / build (.exe, amd64, windows) (push) Has been skipped
build-binaries / release (push) Has been skipped
build-binaries / publish-agent (push) Has been skipped
release-tag / release-image (push) Has been cancelled
This commit is contained in:
116
pinger.go
Normal file
116
pinger.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
probing "github.com/prometheus-community/pro-bing"
|
||||
)
|
||||
|
||||
type PingResult struct {
|
||||
RTT time.Duration
|
||||
Alive bool
|
||||
Err error
|
||||
IP string
|
||||
}
|
||||
|
||||
type PingOptions struct {
|
||||
Timeout time.Duration
|
||||
Size int
|
||||
DisableIPv6 bool
|
||||
DNSServer string
|
||||
}
|
||||
|
||||
func resolveWithCustomDNS(server, host string) (string, error) {
|
||||
c := new(dns.Client)
|
||||
m := new(dns.Msg)
|
||||
m.SetQuestion(dns.Fqdn(host), dns.TypeA)
|
||||
|
||||
resp, _, err := c.Exchange(m, server)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, ans := range resp.Answer {
|
||||
if a, ok := ans.(*dns.A); ok {
|
||||
return a.A.String(), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", errors.New("no A record found")
|
||||
}
|
||||
|
||||
func resolveHost(host, dnsServer string, disableIPv6 bool) (string, error) {
|
||||
if ip := net.ParseIP(host); ip != nil {
|
||||
return host, nil
|
||||
}
|
||||
|
||||
if dnsServer != "" {
|
||||
if _, _, err := net.SplitHostPort(dnsServer); err != nil {
|
||||
dnsServer = net.JoinHostPort(dnsServer, "53")
|
||||
}
|
||||
return resolveWithCustomDNS(dnsServer, host)
|
||||
}
|
||||
|
||||
if disableIPv6 {
|
||||
ips, err := net.LookupIP(host)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
for _, ip := range ips {
|
||||
if ip.To4() != nil {
|
||||
return ip.String(), nil
|
||||
}
|
||||
}
|
||||
return "", errors.New("no IPv4 address found")
|
||||
}
|
||||
|
||||
ip, err := net.ResolveIPAddr("ip", host)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return ip.IP.String(), nil
|
||||
}
|
||||
|
||||
func doPing(host string, opts PingOptions) PingResult {
|
||||
ip, err := resolveHost(host, opts.DNSServer, opts.DisableIPv6)
|
||||
if err != nil {
|
||||
return PingResult{Alive: false, Err: err}
|
||||
}
|
||||
|
||||
pinger, err := probing.NewPinger(ip)
|
||||
if err != nil {
|
||||
return PingResult{Alive: false, Err: err, IP: ip}
|
||||
}
|
||||
|
||||
if opts.DisableIPv6 {
|
||||
pinger.SetNetwork("ip4")
|
||||
}
|
||||
|
||||
pinger.Count = 1
|
||||
pinger.Timeout = opts.Timeout
|
||||
pinger.Size = opts.Size
|
||||
|
||||
// falls du im Container kein CAP_NET_RAW gibst:
|
||||
pinger.SetPrivileged(false) // oder aus Config
|
||||
// wenn du CAP_NET_RAW vergibst:
|
||||
// pinger.SetPrivileged(true)
|
||||
|
||||
if err := pinger.Run(); err != nil {
|
||||
return PingResult{Alive: false, Err: err, IP: ip}
|
||||
}
|
||||
|
||||
stats := pinger.Statistics()
|
||||
if stats.PacketsRecv < 1 {
|
||||
return PingResult{Alive: false, Err: errors.New("no reply"), IP: ip}
|
||||
}
|
||||
|
||||
return PingResult{
|
||||
RTT: stats.AvgRtt,
|
||||
Alive: true,
|
||||
IP: ip,
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user