WinAPI - 当Timeout设置为低于1000毫秒时,为什么ICMPSendEcho2Ex报告错误超时?

时间:2017-08-06 03:42:54

标签: winapi networking kernel windbg ping

编辑:我开始将此问作为PowerShell / .Net问题,并且无法在互联网上找到它的任何参考。有了反馈,它似乎是一个WINAPI问题所以这是一个编辑/重写/重拍,但很多测试和背景参考.Net就是出于这个原因。

摘要

如果ping超时参数设置为低于1000毫秒(1秒),则WINAPI ping函数IcmpSendEcho2似乎有时间错误。这会导致它返回间歇性的错误超时错误。而不是比例"更低的超时=更多失败"行为,它似乎是> = 1000ms +的预期行为的截止值,< = 999ms触发错误超时,通常是交替的成功/失败/成功/失败模式。

我称之为虚假超时,因为我有WireShark数据包捕获显示回复数据包在超时内恢复正常,部分原因是1ms更改不应该是回复通常有500-800ms的大量时间的余量,部分是因为我可以运行两个具有不同超时的并发集,并看到两者之间的不同行为。

在我原来的.Net问题的评论中,@ wOxxOm有:

和@Lieven Keersmaekers调查并发现超出我的技能水平的事情来解释:

  • "我可以说这是一个潜在的WINAPI问题。成功和timedout调用成IPHLPAPI!IcmpSendEcho2Ex后:000003e7参数在堆栈上,两者都设置了一个事件,并且两者都返回IPHLPAPI!IcmpEchoRequestComplete,但成功调用的差异为{s}包含00000000的eax寄存器和包含00000102的超时调用eax寄存器(WAIT_TIMEOUT)

  • "编译64位C#版本时,不再需要调用IPHLPAPI。显示的一致性是clr.dll GetLastError()返回WSA_QOS_ADMISSION_FAILURE超时。在我的示例中也一致的是成功和超时调用之间的线程执行顺序略有不同。"

测试步骤:

选择一个远程主机并设置一些连续的ping运行。 (我的例子中的知识产权属于Baidu.cn(中国),对我来说有大约310毫秒的ping回复)。所有这些行为的预期行为:几乎完全是ping回复,偶尔因网络状况而下降。

PowerShell / .Net ,超时999毫秒,实际结果是奇怪的回复/丢弃/回复/丢弃模式,远远超出预期:

$Pinger = New-Object -TypeName System.Net.NetworkInformation.Ping
while($true) { 
    $Pinger.Send('111.13.101.208', 999)
    start-sleep -Seconds 1
}

命令提示符ping.exe ,超时999ms,实际结果更可靠(编辑:但后来的调查结果也引起了质疑):

ping 111.13.101.208 -t -w 999

PowerShell / .Net ,超时1000毫秒,实际结果符合预期:

$Pinger = New-Object -TypeName System.Net.NetworkInformation.Ping
while($true) { 
    $Pinger.Send('111.13.101.208', 1000)
    start-sleep -Seconds 1
}

它也可以与C#重复,但我现在已经编辑了这段代码似乎是一个WinAPI问题。

这些并排运行的屏幕截图

  • 在左边,.Net有999ms超时和50%失败。
  • 中心,命令提示符,几乎所有回复。
  • 在右边,.Net有1000毫秒超时,几乎所有回复。

Comparing command prompt ping and two powershell pings

早期调查/背景

我从一个500毫秒的超时开始,假回复的数量似乎因远程主机的ping回复时间而异:

  • ping 30ms之外的东西报告TimedOut大约1/10 ping
  • ping 100ms之外的东西报告TimedOut大约四分之一
  • ping 300ms之外的东西报告TimedOut大约每两个ping中

在同一台计算机上,在同一个互联网连接上,使用相同的500ms超时设置发送相同数量的数据(32字节缓冲区),而不使用其他大量带宽。我在Windows 10默认设置之外没有运行防病毒网络过滤器,我认识的另外两个人已经在他们的计算机上确认了这种频繁的TimedOut行为(现在评论中有两个以上),有更多或更少的超时,所以它不应该是我的网卡或司机或ISP。

ping回复的WireShark数据包捕获,错误地报告为超时

我手动ping了四次到一个~100ms的主机,500ms超时,WireShark捕获网络流量。 PowerShell截图:

Pings from PowerShell - 4 sent, 3 replies

WireShark截图:

WireShark log of the pings showing 4 sent, 4 replies

请注意,WireShark日志会记录4个请求,4个回复,每个回复的时间差大约为0.11秒(110毫秒) - 所有这些都在超时内,但PowerShell错误地将最后一个报告为超时。< / p>

相关问题

谷歌搜索向我展示了System.Net.NetworkInformation.Ping的大量问题,但没有一个看起来相同,例如。

documentation for Ping()警告低延迟 - 可能仍然说成功,但我不能看到它警告超时可能会错误报告失败,如果设置低于1秒。

编辑:现在我正在搜索ICMPSendEcho2,我在2015年5月的博客文章中发现了此问题:https://www.frameflow.com/ping-utility-flaw-in-windows-api-creating-false-timeouts/ - 找到相同的行为,但没有进一步的解释。他们说ping.exe受到了影响,当我原本以为它不是。他们还说:

  • &#34; 在我们的测试中,我们无法在Windows Server 2003 R2和Windows Server 2008 R2上重现它。但是,它在Windows Server 2012 R2和Windows 10的最新版本中始终如一。&#34;

为什么?超时处理有什么问题让它忽略ping repsonses完全进入网络堆栈?为什么1000ms是一个重要的截止点?

0 个答案:

没有答案