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?


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.