[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 wine-bugs at winehq.org
Mon Jun 14 08:35:45 CDT 2021


https://bugs.winehq.org/show_bug.cgi?id=8332

--- Comment #32 from Gabriel Ivăncescu <gabrielopcode at gmail.com> ---
(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.
> 
> 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:
> 
> ---snip---
>     int sid=socket(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=socket(AF_INET,SOCK_DGRAM,IPPROTO_ICMP);
>     }
> ---snip---
> 
> Documentation:
> Linux: https://lwn.net/Articles/420800/
> MacOS: http://www.manpagez.com/man/4/icmp/
> 
> 
> On MacOS, I think that work fine.
> 
> Linux however is currently completely broken, and pinging always fail,
> because:
> 
> 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.
> 
> 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" with
> its own value, ie. this value is later overwritten by the kernel:
> 
> ---snip---
>     icmp_header->icmp_id=id;
> ---snip---
> 
> causing this check in icmp_get_reply() to always fail:
> 
> ---snip---
>                 if ((icmp_header->icmp_id==id) &&
> (icmp_header->icmp_seq==seq))
> ---snip---
> 
> and the reply thus falsely never matches the request, so pinging still fails.
> 
> 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.
> 
> 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().
> 
> I don't know how Gabriel ever said that this works on Linux. Either he never
> tested, only tested pinging an invalid address, or Linux changed how
> unprivileged ICMP sockets work between then and now:
> 
> ---snip---
> commit e6d9aaeb67172dd0ba1e73f34c7f0cad36ed43ff
> Author: Gabriel Iv��ncescu <gabrielopcode at gmail.com>
> Date:   Mon Aug 3 16:15:52 2020 +0300
> 
>     iphlpapi: Update comment for SOCK_DGRAM since Linux also supports it
> from 3.0.
>     
>     Linux does require the user to be in the range specified by
>     /proc/sys/net/ipv4/ping_group_range though, but otherwise works fine.
>     
>     Signed-off-by: Gabriel Iv��ncescu <gabrielopcode at gmail.com>
>     Signed-off-by: Alexandre Julliard <julliard at winehq.org>
> ---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 sockets
with the aforementioned requirements specified. So the code was already broken.
The "broken" functionality you mention was already there.

-- 
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.


More information about the wine-bugs mailing list