go-ping / ping

ICMP Ping library for Go
MIT License
1.31k stars 344 forks source link

ping endlessly running in case the network interface is lost while the pinger is not yet finished #195

Closed turtletramp closed 1 year ago

turtletramp commented 2 years ago

My System:

Steps to reproduce:

In the console the following can be seen endlessly

...
2021/12/27 10:35:42 FATAL: sending packet: write udp 0.0.0.0:77->8.8.8.8:0: sendto: network is unreachable
2021/12/27 10:35:43 FATAL: sending packet: write udp 0.0.0.0:77->8.8.8.8:0: sendto: network is unreachable
2021/12/27 10:35:44 FATAL: sending packet: write udp 0.0.0.0:77->8.8.8.8:0: sendto: network is unreachable
2021/12/27 10:35:45 FATAL: sending packet: write udp 0.0.0.0:77->8.8.8.8:0: sendto: network is unreachable
...

In the code I saw a "FIXME" where it hangs (line 485)

        case r := <-recvCh:
            err := p.processPacket(r)
            if err != nil {
                // FIXME: this logs as FATAL but continues
                logger.Fatalf("processing received packet: %s", err)
            }
turtletramp commented 2 years ago

I compared the behavior to the standard ping on Ubuntu which treats these packets as lost packets:

~$ ping -c 20 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=116 time=15.0 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=116 time=14.8 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=116 time=14.9 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=116 time=14.8 ms

--- 8.8.8.8 ping statistics ---
20 packets transmitted, 4 received, 80% packet loss, time 19369ms
rtt min/avg/max/mdev = 14.835/14.884/15.004/0.069 ms

Based on that I think the PacketsSent counter should still be increased even if the write fails.

turtletramp commented 2 years ago

I now had a very similar issue at a customer setup that I think has the same root cause. There the Network interface is nicely up and running but the system is directly connected to an LTE modem and the ping packets are sent but not a single response is received. Pinger in this case never reaches the .OnFinish callback. For debugging I added the .OnSend callback in addition to the .OnRecv callback and the log output looks something like this:

264 bytes sent 8.8.8.8: icmp_seq=0
264 bytes sent 8.8.8.8: icmp_seq=1
264 bytes sent 8.8.8.8: icmp_seq=2

And that's it. --> so I think when the interface is up but not a single response is received the pinger also hangs as with a network interface that is going down during pings.

Note: I will now try at this customer my patch from the pull request to see if it also helps for this issue. Note2: Of course I could set a general timeout to avoid this as well but when providing a count it would be great if it imply only tries count-times and then finishes without a timeout.