WinAPI - Why does ICMPSendEcho2Ex report false timeouts when Timeout is set below 1000ms?
Edit: I started asking this as a PowerShell / .Net question and couldn't find a link to it online. With feedback, it looks like it's a WINAPI issue, so it's edit / rewrite / redo, but most of the tests and .Net reference link for this reason.
Summary
The WINAPI ping function IcmpSendEcho2
seems to have a sync error if the ping timeout parameter is set below 1000ms (1 second). This causes it to return intermittent false timeout errors. Instead of the proportional "lower timeout = more failures" behavior, this appears to be disabling expected behavior> = 1000ms +, <= 999ms causes spurious timeouts, often in an alternating success / failure / success / failure pattern.
I call them bogus timeouts because I have a WireShark packet capture showing a response packet bouncing back during the timeout, and in part because a 1ms change shouldn't be a significant time, where responses usually have 500-800ms headroom, and partly because I can run two parallel sets of pings with different timeouts and see different behavior between them.
In the comments of my original .Net question, @wOxxOm has:
- located open source .Net code where System.Net.NetworkInformation.Ping () wraps WinAPI and there seems to be no specific handling of timeouts there, it was passed down to the bottom layer directly - perhaps line 675 with the call
UnsafeNetInfoNativeMethods.IcmpSendEcho2()
and @Lieven Keersmaekers researched and found things beyond my skill level to interpret:
-
"I can repeat that this is a basic WINAPI problem. After successful execution and requesting a timeout in
IPHLPAPI!IcmpSendEcho2Ex
: the parameter000003e7
is on the stack, both set the event and return inIPHLPAPI!IcmpEchoRequestComplete
with a difference in the eax success register containing00000000
, and the eax timeout register containing00000102
( WAIT_TIMEOUT) -
"Compiling 64-bit version of C #, no more calls to
IPHLPAPI
. Sequential thing that is displayedclr.dll GetLastError()
returnsWSA_QOS_ADMISSION_FAILURE
for timeouts. Also in my example there is a sequential order of execution of threads between success and timeout, slightly different."- This StackOverflow question indicates what
WSA_QOS_ADMISSION_FAILURE
could be a bug and in factIP_REQ_TIMED_OUT
.
- This StackOverflow question indicates what
Testing steps:
Select a remote host and set continuous pings. (The IP address in my examples is from Baidu.cn (China) and has ping responses of around ~ 310ms for me). The expected behavior for all of them is almost entirely ping responses, with occasional drops due to network conditions.
PowerShell / .Net , with 999ms timeout, actual result is fancy response / drop / response / drop templates, much more than expected:
$Pinger = New-Object -TypeName System.Net.NetworkInformation.Ping
while($true) {
$Pinger.Send('111.13.101.208', 999)
start-sleep -Seconds 1
}
ping.exe command line with 999ms timeout, actual result is more reliable (edit: but later results also find this in the question):
ping 111.13.101.208 -t -w 999
PowerShell / .Net , with 1000ms timeout, the actual result will be as expected:
$Pinger = New-Object -TypeName System.Net.NetworkInformation.Ping
while($true) {
$Pinger.Send('111.13.101.208', 1000)
start-sleep -Seconds 1
}
It repeats from C # too, but now I edited this code, it looks like it is a WinAPI issue.
Example screenshot of them walking side by side
- Left, .Net with 999ms timeout and 50% failure.
- Center, command line, almost all answers.
- Right, .Net with 1000ms timeout, almost all answers.
Previous Research / Background
I started with a 500ms timeout and the number of fake responses seems to vary depending on the ping response time of the remote host:
- pinging something 30ms away TimedOut reports about 1 in 10 peaks
- pinging something 100ms timedOut reports around 1 to 4 ping
- pinging something 300ms from TimedOut reports about 1 to 2 ping
From the same computer, on the same internet connection, sends the same amount of data (32-byte buffer) with the same 500ms timeout, without using any other large bandwidth. I don't run antivirus network filter outside of Windows 10 by default, two other people I know have confirmed this frequent TimedOut actions on their computers (now two more in the comments), with more or less timeouts, so it shouldn't be my network card or drivers or ISP.
Capture WireShark packet for ping response that is falsely reported as timeout
I pinged manually four times up to 100ms of the host with a 500ms timeout while WireShark was capturing network traffic. PowerShell screenshot:
Screenshot of WireShark:
Note that WireShark logs 4 requests, 4 responses are returned, each with a time difference of about 0.11s (110ms) - all within a timeout, but PowerShell incorrectly reports the latter as a timeout.
Related questions
Googling shows me a bunch of problems with System.Net.NetworkInformation.Ping
but none of them looks the same, like
- System.Net.NetworkInformation.Ping crashes - it crashes if allocated / destroyed in a loop in .Net 3.5 because its internals are erroneously garbage collected. (.Net 4 here and not highlighting in a loop)
- Blue screen when using Ping - 6+ years of ping capable of Windows BSOD (not debugging asynchronous ping here)
- https://github.com/dotnet/corefx/issues/15989 is not a timeout, if you set the timeout to 1ms and the response comes back after 20ms, it still succeeds, False positive but not negative ...
The documentation for Ping () warns about success with a low timeout, but I don't see it warns that the timeout can erroneously report a failure if set below 1 second.
Edit: Now when I search for ICMPSendEcho2, I found exactly this problem described earlier in a blog post in May 2015 here: https://www.frameflow.com/ping-utility-flaw-in-windows-api-creating-false -timeouts / - search for the same behavior, but no more detailed explanation. They say it ping.exe
does, when I originally thought it wasn't. They also say:
- "In our tests, we were unable to reproduce it on Windows Server 2003 R2 or Windows Server 2008 R2, but it was consistently viewed on Windows Server 2012 R2 and the latest builds of Windows 10."
Why? What is wrong with the timeout handling that causes it to ignore ping reps entering the network stack entirely? Why is 1000ms a significant reduction?
source to share
No one has answered this question yet
See similar questions:
or similar: