schweikert / fping

High performance ping tool
https://fping.org
Other
1.01k stars 250 forks source link

Prefer SOCK_DGRAM #317

Closed Yenya closed 1 month ago

Yenya commented 4 months ago

ping(8) from iputils-20240117 prefers SOCK_DGRAM instead of SOCK_RAW, which has a bonus of using kernel-assigned Identification. Apart from unprivileged operations, this also avoids collisions caused by user-assigned Identification on busy monitoring hosts (see also: birthday paradox).

So let's try SOCK_DGRAM first, and only if that fails, fall back to SOCK_RAW.

auerswal commented 4 months ago

It seems as if SOCK_DGRAM does not work as well as SOCK_RAW for fping when using the kernel Linux, according to the test failures.

auerswal commented 2 months ago

Since this would introduce a regression (i.e., losing the functionality to ping IPv6 multicast groups), without introducing a clear improvement, I plan to close this pull request (no idea when, yet).

auerswal commented 2 months ago

At least in my tests on GNU/Linux, when fping 224.0.0.1 works, it does so for both privileged SOCK_RAW and unprivileged SOCK_DGRAM. The reply to an Echo request to a multicast IP address uses a unicast IP address as source, i.e., it comes from a different IP address. This also holds for the iputils ping program. Thus using SOCK_DGRAM does not necessarily solve the identification problem on busy monitoring hosts.

The iputils ping program shows the same problem as fping with your pull request, i.e., it cannot ping IPv6 multicast addresses, even with privileges (cap_net_raw+ep).

The ping program from GNU Inetutils prefers SOCK_RAW similar to fping. For IPv4 multicast, the observable results are comparable to those of fping and iputils ping. The ping6 program from GNU Inetutils does not fall back to SOCK_DGRAM and therefore does not show the multicast problem (but it does not work without privileges).

auerswal commented 1 month ago

According to a StackExchange answer, Apple's ping program uses a raw socket when started with root privileges, otherwise a datagram socket. This is supposedly done to allow extra functionality with root privileges.

I'd say that fping should prefer using a raw socket if possible (e.g., started by root, binary with set SUID bit, or binary with NET_CAP_RAW), and only fall back to a datagram socket if it cannot open a raw socket.