diagd: remove ping4/ping6 to external targets in favor of tcp4/tcp6

External ICMP does not necessarily work.
It typically does, but not always.
Last week, for a day or two, ICMP traffic was dropped by Google.

So now we use ICMP only for network equipment targets (default gateway),
and instead use TCP for external connectivity checks.

fixes #77
This commit is contained in:
Michael Stapelberg 2022-09-28 22:39:20 +02:00
parent c97c321740
commit a8a12cafc9
2 changed files with 42 additions and 8 deletions

View File

@ -94,14 +94,12 @@ func logic() error {
m := diag.NewMonitor(diag.Link(uplink).
Then(diag.DHCPv4().
Then(diag.Ping4Gateway().
Then(diag.Ping4("google.ch").
Then(diag.TCP4("www.google.ch:80"))))).
Then(diag.TCP4("www.google.ch:80")))).
Then(diag.DHCPv6().
Then(diag.Ping6("lan0", "google.ch"))).
Then(diag.TCP6("lan0", "www.google.ch:80"))).
Then(diag.RouterAdvertisments(uplink).
Then(diag.Ping6Gateway().
Then(diag.Ping6(uplink, "google.ch").
Then(diag.TCP6("www.google.ch:80"))))).
Then(diag.TCP6(uplink, "www.google.ch:80")))).
Then(diag.Ping6("", ip6allrouters+"%"+uplink)))
var mu sync.Mutex
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {

View File

@ -53,6 +53,7 @@ func TCP4(addr string) Node {
type tcp6 struct {
children []Node
ifname string
addr string
}
@ -70,7 +71,39 @@ func (d *tcp6) Children() []Node {
}
func (d *tcp6) Evaluate() (string, error) {
conn, err := net.Dial("tcp6", d.addr)
var dialer net.Dialer
if d.ifname != "" {
iface, err := net.InterfaceByName(d.ifname)
if err != nil {
return "", err
}
addrs, err := iface.Addrs()
if err != nil {
return "", err
}
for _, addr := range addrs {
ipnet, ok := addr.(*net.IPNet)
if !ok {
continue
}
if ipnet.IP.To4() != nil {
continue // skip IPv4 addresses
}
if !global.Contains(ipnet.IP) {
continue // skip local IPv6 addresses
}
dialer.LocalAddr = &net.TCPAddr{
IP: ipnet.IP,
}
break
}
}
conn, err := dialer.Dial("tcp6", d.addr)
if err != nil {
return "", err
}
@ -80,6 +113,9 @@ func (d *tcp6) Evaluate() (string, error) {
// TCP6 returns a Node which succeeds when the specified address accepts a TCPv6
// connection.
func TCP6(addr string) Node {
return &tcp6{addr: addr}
func TCP6(ifname, addr string) Node {
return &tcp6{
ifname: ifname,
addr: addr,
}
}