1

I want to send Pings at a high interval at some sites, so I've created a simple C# Console App to do so:

while (true)
{
    var start = DateTimeOffset.Now.ToUnixTimeMilliseconds();

    var pingTask = Task.Run(async () =>
    {
        try
        {
            var pinger = new System.Net.NetworkInformation.Ping();
            var pingReply = await pinger.SendPingAsync("google.com", 250);
            Console.WriteLine(pingReply.Status);
        } catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    });
    await Task.WhenAny(Task.Delay(50), pingTask);
    Console.WriteLine($"total wait: {DateTimeOffset.Now.ToUnixTimeMilliseconds() - start}");
}

While running this directly on Windows, nearly all pingTasks result in Success. However, running this on WSL or Docker (using the default auto-generated Dockerfile from Visual Studio) results something like the following:

total wait: 69
Success
Success
total wait: 23
Success
total wait: 22
Success
total wait: 24
Success
total wait: 14
Success
total wait: 20
Success
total wait: 20
Success
total wait: 19
Success
total wait: 23
Success
total wait: 18
total wait: 53
total wait: 44
total wait: 53
total wait: 50
total wait: 50
TimedOut
total wait: 53
TimedOut
total wait: 42
TimedOut
total wait: 51
TimedOut
total wait: 52
TimedOut
total wait: 50
TimedOut
total wait: 51
TimedOut

and all subsequent tasks are TimedOut. This applies to both WSL1 and WSL2. This does not occur when running on Docker in an actual Linux machine. I haven't tried running this directly on a Linux box without Docker.

Note also that the ping google.com -i 0.05 command works fine in WSL1 and WSL2 (when running as root of course) so sending pings on WSL can work.

It looks like there is some queue build up of sockets and it prevents all subsequent ping requests from occurring, but I was wondering if anyone knows why this might be. Is there some setting I can tweak to fix this?

Ringil
  • 6,277
  • 2
  • 23
  • 37
  • Are you _sure_ you are not being just "flood-banned"? – Fildor Jan 17 '22 at 12:41
  • 1
    If I was being flood-banned, I would expect similar results to occur when directly in Windows or from my Linux VM, but that's not the case as I wrote in my post. Note I also tested running the `ping` command directly in WSL1/2 with an interval of 50ms and that was fine as well. – Ringil Jan 17 '22 at 12:47
  • So, you _are_ sure. I just wanted to get that off the list. Ok, then. I am thrilled to read other ideas... – Fildor Jan 17 '22 at 12:52
  • Have you tried pinging an `IPAddress` instead of a host name, to rule out DNS resolver / cache issues? – Richard Deeming Jan 18 '22 at 14:37
  • @RichardDeeming I did that as well (the case in which I discovered this was actually directly using an `IPAddress`). Unfortunately, the same result occurs. – Ringil Jan 19 '22 at 00:09

1 Answers1

1

It turns out this was in fact being flood banned, but not by the server. My own router was detecting my pings as a PING OF DEATH ATTACK and blocking them. After messing with wireshark a bit, it looks like the specific thing that is causing my router to detect .NET's SendPingAsync in Linux as an attack, but not rapid pings from either a Windows setup or the ping cli tool in Linux is due to differences in using the Identifier and Sequence Number parts of the ICMP header.

Identifier Sequence Number
Linux ping CLI Constant Incrementing
Windows ICMP system call Constant Incrementing
.NET SendPingAsync in Linux Incrementing Constant

In particular, the autoincrementing of the Identifier specifically is what my router thinks is problematic.

The reasons behind why .NET's SendPingAsync implementations are like this way is that it seems to replicate Mono's implementation (See discussion here and the relevant source code parts.) I'm not sure why Mono was implemented in this manner.

According to the spec both are valid uses so I suppose my router is just being weird:

Identifier

      If code = 0, an identifier to aid in matching echos and replies,
      may be zero.

Sequence Number

      If code = 0, a sequence number to aid in matching echos and
      replies, may be zero.
Ringil
  • 6,277
  • 2
  • 23
  • 37