[Bug 8332] Applications and games using ICMP ping request report 'no connection to internet' (Wine 32-bit/64-bit preloader requires CAP_NET_RAW to create raw sockets)

"WineHQ Bugzilla" <[email protected]> Mon, 14 Jun 2021 13:35:45 +0000
Newsgroups gmane.comp.emulators.wine.bugs
Message-ID <[email protected]/>
https://bugs.winehq.org/show_bug.cgi?id=3D8332

--- Comment #32 from Gabriel Iv=C4=83ncescu <[email protected]> ---
(In reply to Damjan Jovanovic from comment #31)
> Falling back to calling the "ping" command line tool shouldn't ever be
> necessary on MacOS and Linux.
>=20
> When creating a raw socket fails, Wine tries to fall back to using an
> unprivileged ICMP socket, which is a non-standard socket type present on
> MacOS and Linux:
>=20
> ---snip---
>     int sid=3Dsocket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
>     if (sid < 0)
>     {
>         /* Some systems (e.g. Linux 3.0+ and Mac OS X) support
>            non-privileged ICMP via SOCK_DGRAM type. */
>         sid=3Dsocket(AF_INET,SOCK_DGRAM,IPPROTO_ICMP);
>     }
> ---snip---
>=20
> Documentation:
> Linux: https://lwn.net/Articles/420800/
> MacOS: http://www.manpagez.com/man/4/icmp/
>=20
>=20
> On MacOS, I think that work fine.
>=20
> Linux however is currently completely broken, and pinging always fail,
> because:
>=20
> 1. This socket type does not return the IP header as expected from the
> recvfrom() system call in the icmp_get_reply() function, causing the reply
> to be parsed incorrectly in that function. On Linux, the reply immediately
> begins with the ICMP header instead.
>=20
> 2. Even when that is somewhat fixed (it's long and painful to fix fully),=
 it
> still breaks, because Linux overwrites the ICMP header field "icmp_id" wi=
th
> its own value, ie. this value is later overwritten by the kernel:
>=20
> ---snip---
>     icmp_header->icmp_id=3Did;
> ---snip---
>=20
> causing this check in icmp_get_reply() to always fail:
>=20
> ---snip---
>                 if ((icmp_header->icmp_id=3D=3Did) &&
> (icmp_header->icmp_seq=3D=3Dseq))
> ---snip---
>=20
> and the reply thus falsely never matches the request, so pinging still fa=
ils.
>=20
> The "icmp_id" is overwritten by the socket's port number, which can be set
> through bind(). It cannot be queried by getsockname() which always returns
> port 0, even after bind(). However it seems best not to set it, let the
> kernel pick a free port, and then skip the icmp_id check above instead, as
> the kernel already filters replies by their icmp_id.
>=20
> Fixing (2) is easy, but (1) really needs to use recvmsg() instead, with
> IP_RECVTTL, IP_RECVTOS, IP_RETOPTS, IP_RECVERR and other ancillary data,
> only on Linux and only for these unprivileged ICMP sockets. Then this
> alternative source of IP header data needs to be integrated into
> icmp_get_reply().
>=20
> I don't know how Gabriel ever said that this works on Linux. Either he ne=
ver
> tested, only tested pinging an invalid address, or Linux changed how
> unprivileged ICMP sockets work between then and now:
>=20
> ---snip---
> commit e6d9aaeb67172dd0ba1e73f34c7f0cad36ed43ff
> Author: Gabriel Iv=EF=BF=BD=EF=BF=BDncescu <[email protected]>
> Date:   Mon Aug 3 16:15:52 2020 +0300
>=20
>     iphlpapi: Update comment for SOCK_DGRAM since Linux also supports it
> from 3.0.
>=20=20=20=20=20
>     Linux does require the user to be in the range specified by
>     /proc/sys/net/ipv4/ping_group_range though, but otherwise works fine.
>=20=20=20=20=20
>     Signed-off-by: Gabriel Iv=EF=BF=BD=EF=BF=BDncescu <gabrielopcode@gmai=
l.com>
>     Signed-off-by: Alexandre Julliard <[email protected]>
> ---snip---

I don't remember the exact details, there was a game pinging multiple time
every 5 seconds and it had a nasty stutter when that happened with the
wine-staging patch, since it invoked external commands and was very slow.

I'm not that familiar with it, so I admit I haven't tested it at all other =
than
creating the raw socket itself, but it did fix the slowdown; now that you
mention it, though, it probably failed to ping.

Note that the commit you referenced doesn't actually do anything, it just
changes a comment, which is true, because Linux does allow creating raw soc=
kets
with the aforementioned requirements specified. So the code was already bro=
ken.
The "broken" functionality you mention was already there.

--=20
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.=