Windows Networking 1: 明明数据包已经到达网卡,为什么我的服务器不收包?

简介: Windows Networking 1: 明明数据包已经到达网卡,为什么我的服务器不收包? 前后端收发包的问题,往往排查起来颇为费劲。本系列以网络问题排查为基础,总结排查过程和分析结果,一步一步完善对 NDIS (Network Driver Interface Specification) Framework,以及对 Qemu Virtio netkvm 驱动的分析和研究。

作者:陈鸽

Windows Networking 1: 明明数据包已经到达网卡,为什么我的服务器不收包?

前后端收发包的问题,往往排查起来颇为费劲。本系列以网络问题排查为基础,总结排查过程和分析结果,一步一步完善对 NDIS (Network Driver Interface Specification) Framework,以及对 Qemu Virtio netkvm 驱动的分析和研究。

问题

Windows Server 通过FTP上传文件,在传输过程中触发网络异常问题导致传输失败。尽管服务器网络经过一段时间后自动恢复,但是每次上传都很容易重现问题。

基本信息收集

问题描述粗看起来挺明确的,但是我们还是要理清楚具体细节问题,例如,

1.网络异常触发的条件:其他客户端通过FTP上传文件。
2.网络异常的现象:

  1. )在这台机器上ping 127.0.0.1,显示正常。此处说明Windows的TCPIP协议栈工作正常,问题发生在更底层驱动设备上。如果此处异常,一般我们考虑通过netsh.exe来reset tcpip和winsock。
  2. )这是一台经典网络主机,在问题发生的时候,内网网卡工作正常。具体来说就是,其他同内网网段机器ping这台Windows服务器正常,通过内网网卡ping内网dns正常。
  3. )问题发生的时候,这台机器尝试ping外网网卡上配置的网关不通。此处第2和第3步说明网卡驱动本身应该工作正常,问题可能在网卡或者该外网网卡所对应的NDIS Miniport,包括对应的NDIS.sys维护的NDIS_MINIPORT_BLOCK结构和网卡驱动维护的_ADAPTER结构
  4. )在尝试ping网关的时候,运行ARP -a 显示网关MAC和IP映射关系是Incomplete。说明数据包的发送已经尝试触发ARP过程,但是无法收到响应。
  5. )基于第4步,检查网卡设备(devmgmt.msc)显示状态正常,但是网卡接口(Network Connection -> NIC Properties)显示发送计数有增加,但接收计数却没有增加。这也侧面说明ARP请求发送正常,但是没有收到响应。
  6. )最后,尝试禁用启用网卡,发现问题解决。

3.根据异常现象排查,我们初步定位ARP问题,但通过arp.exe -s 去添加静态ARP信息(arp.exe -s gw.ipv4.address ee:ff:ff:ff:ff:ff),发现还是无法ping通网关,说明arp并不是主要的原因。

定位问题

为了更准确的定位问题,我们在Windows主机上以及它的宿主机上同时抓包分析。可惜的是,这次的抓包是直接打印在屏幕上,没有保留具体抓包内容。下次如果遇到类似情况,截图补上。

口述一下抓包的分析结果,添加静态ARP之后,VIF口上的抓包我们可以看到ping的ICMP Echo Request报文由vif口发送出去,并收到ICMP Echo Reply报文。

由于之前的种种测试排查,我们认为问题发生在底层驱动,由于问题现场存在,直接从NC上抓取Windows的dump分析。

技巧分享

Windows操作系统自2008 R2开始就集成了抓包能力,功能实现在NDIS.sys上,与Windows的ETW机制协同工作,为我们排查带来便利。启用的方式很简单,运行命令,

netsh trace start capture=yes

复现问题后,运行命令,

netsh trace stop

抓到的日志文件会被写在当前用户的temp目录下。当然,在运行stop命令后,Windows会把日志文件的位置打印在cmd.exe窗口中。

使用这个命令抓到的文件可以使用Microsoft Network Monitor 3.4或者Microsoft Message Analyzer打开。Wireshark暂时无法识别。

另外,额外提一句,Windows的ETW是一个比较好的排查操作系统内部组件行为的工具,Windows提供了一些既有的Scenarios和Providers,可以使用netsh trace show scenarios和netsh trace show providers来查看。有机会另写一篇文章作为补充。对于网络来说,我这边简单组合了一下ndis,tcpip,afd,winsock相关的providers,适用一般情况下对系统网络行为做一些比较深入的研究,命令如下,


netsh trace start provider={2F07E2EE-15DB-40F1-90EF-9D7BA282188A} keywords=0xffffffffffffffff level=0xff provider={E53C6823-7BB8-44BB-90DC-3F86090D48A6} keywords=0xffffffffffffffff level=0xff provider={7D44233D-3055-4B9C-BA64-0D47CA40A232} keywords=0xffffffffffffffff level=0xff provider={50B3E73C-9370-461D-BB9F-26F32D68887D} keywords=0xffffffffffffffff level=0xff provider={43D1A55C-76D6-4F7E-995C-64C711E5CAFE} keywords=0xffffffffffffffff level=0xff maxSize=500MB fileMode=circular persistent=no overwrite=yes report=yes correlation=yes traceFile=c:\NetworkTrace.etl capture=yes packettruncatebytes=128 IPv4.Address=<ipv4.address.for.filtering>

具体命令含义可以参考netsh trace capture help

Memory Dump分析

首先查看网卡Miniport状态,并无异常状态。一般如果网卡异常我们可能会看到例如Pending OID,或者Reset等General信息,可以尝试升级网卡驱动。

image.png

接下来检查send path,也就是发送情况。在老版本Windows操作系统,我们可以看mopen上的reference,原理是tcpip.sys driver每在发送的请求的时候都会增加tcpip与miniport的mopen的reference,而在网卡会在报文发送完成后,调用tcpip.sys驱动的回调函数释放reference。

image.png

在Windows Server 2008 R2之后的版本,mopen的reference不再起作用,发送的计数被记录在tcpip.sys的Provider_Rundown_Protection中,以满足在不同的CPU上处理发送请求的能力。Rundown的计数针对每个CPU,通过加减法计算有没有pending NBL未发送。

参考资料:
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/content/wdm/nf-wdm-exinitializerundownprotection

通过其他状态计数来确认发送接收情况:通过code review,我们找到了Virtio netkvm的统计信息,进一步确认发送正常,接收异常。

image.png

进一步看数据结构, NetReceiveBuffer List里面是空的,NetNofReceiveBuffers 也是0,应该是网卡驱动发现没有可用的buffer,导致就不能继续收包。这里面netkvm驱动有很多做法,比如在buffer满的情况下disbale网卡中断,也就不会有收报的行为发生。

image.png

后续检查ParaNdis_ProcessRxPath函数和 virtqueue_get_buf 函数,确认ring buffer满,

image.png

根据Virtio netkvm的代码,NetReceiveBuffersWaiting这个LIST_ENTRY数据结构里面的buffer内容其实是Windows 操作系统的NDIS 框架驱动负责维护,并调用netkvm驱动注册好的 ReturnPacketHandler 也就是 netkvm!ParaNdis5_ReturnPacket 来释放buffer并放回NetReceiveBuffers中。

在这里,问题集中在为什么NDIS没有调用我们的回调函数。Windows对网卡相关的缓存回收主要依靠NET_BUFFER_LIST数据结构的Reference,也就是引用计数。如果buffer被使用,那么它的reference count就会+1,如果buffer操作完成,对应引用的驱动会调用Dereference来释放引用。只有当buffer的reference计数变为0,才会回调释放buffer函数。

问题的定位是通过枚举所有未释放的buffer,打印出网络包结构,例如,

!list "-t \_LIST\_ENTRY.Flink -e -x \"dt netkvm!IONetDescriptor @$extret; dt ndis!_NDIS_PACKET poi(@$extret+0x40) Private.; dt _MDL poi(poi(@$extret+0x40)+8); db poi(poi(poi(@$extret+0x40)+8)+0x18) L0x50\" 0xfffffadf`37fa26d0"

image.png

注:0x0bda = 3034 是FTP Pasv模式的data port。

本案例是Serv-U FTP服务器不处理收包导致buffer被用满,而通过使用Windows build-in的IIS FTP解决。

总结

综合前面的分析,一般情况下的下一步计划类似如下,

  1. Windows 本身NDIS驱动没有正确处理buffer的释放,对此,建议是安装好最新的 ndis.sys 补丁。
  2. 其他三方驱动对buffer有不正确的引用,导致引用计数一直无法为0,得到释放。建议是卸载三方,保持一个干净的操作系统。
  3. 报文没有被处理。
  • Possible Cause 1,数据包收到后需要通过消息通知机制indicate给上层Application,这里indication慢或者死锁会导致问题。
  • Possible Cause 2, 应用程序有Critical Section,导致没有recv操作发生等等。这中间就涉及了tcpip.sys, afd.sys, winsock, 以及应用程序本身,任何一环出问题都有可能引起网络问题。

对此,一般的建议是升级驱动tcpip.sys, afd.sys, 和 winsock组件,以及使用其他软件来替代当前使用的应用程序。

相关文章
|
4月前
|
SQL Apache Windows
Windows服务器80端口被占用的全面解决方案
在服务管理器中启动apache2服务,即可正常使用80端口。若系统中还安装了其他微软产品如sql等,也可尝试停止其服务进行测试,但请注意,SQL通常不会使用80端口,因此一般不会受到影响。以上就是关于80端口被system占用的详细解决方法,希望对你有所帮助。
|
4月前
|
Windows
Windows下版本控制器(SVN)-验证是否安装成功+配置版本库+启动服务器端程序
Windows下版本控制器(SVN)-验证是否安装成功+配置版本库+启动服务器端程序
130 2
|
4月前
|
监控 Linux 网络安全
FinalShell SSH工具下载,服务器管理,远程桌面加速软件,支持Windows,macOS,Linux
FinalShell是一款国人开发的多平台SSH客户端工具,支持Windows、Mac OS X和Linux系统。它提供一体化服务器管理功能,支持shell和sftp同屏显示,命令自动提示,操作便捷。软件还具备加速功能,提升访问服务器速度,适合普通用户和专业人士使用。
512 0
|
5月前
|
Windows
Windows下版本控制器(SVN)-启动服务器端程序
Windows下版本控制器(SVN)-启动服务器端程序
142 4
|
6月前
|
存储 安全 Ubuntu
从Linux到Windows:阿里云服务器系统镜像适配场景与选择参考
阿里云为用户提供了丰富多样的服务器操作系统选择,以满足不同场景下的应用需求。目前,云服务器的操作系统镜像主要分为公共镜像、自定义镜像、共享镜像、镜像市场和社区镜像五大类。以下是对这些镜像类型的详细介绍及选择云服务器系统时需要考虑的因素,以供参考。
|
6天前
|
运维 安全 Ubuntu
阿里云渠道商:服务器操作系统怎么选?
阿里云提供丰富操作系统镜像,涵盖Windows与主流Linux发行版。选型需综合技术兼容性、运维成本、安全稳定等因素。推荐Alibaba Cloud Linux、Ubuntu等用于Web与容器场景,Windows Server支撑.NET应用。建议优先选用LTS版本并进行测试验证,通过标准化镜像管理提升部署效率与一致性。
|
7天前
|
存储 监控 安全
阿里云渠道商:云服务器价格有什么变动?
阿里云带宽与存储费用呈基础资源降价、增值服务差异化趋势。企业应结合业务特点,通过阶梯计价、智能分层、弹性带宽等策略优化成本,借助云监控与预算预警机制,实现高效、可控的云资源管理。
|
9天前
|
弹性计算 运维 安全
区别及选择指南:阿里云轻量应用服务器与ECS云服务器有什么区别?
阿里云轻量应用服务器适合个人开发者、学生搭建博客、测试环境,易用且性价比高;ECS功能更强大,适合企业级应用如大数据、高流量网站。根据需求选择:轻量入门首选,ECS专业之选。
|
9天前
|
弹性计算 运维 安全
阿里云轻量应用服务器与云服务器ECS啥区别?新手帮助教程
阿里云轻量应用服务器适合个人开发者搭建博客、测试环境等低流量场景,操作简单、成本低;ECS适用于企业级高负载业务,功能强大、灵活可扩展。二者在性能、网络、镜像及运维管理上差异显著,用户应根据实际需求选择。
|
17天前
|
弹性计算 ice
阿里云4核8G云服务器配置价格:热门ECS实例及CPU处理器型号说明
阿里云2025年4核8G服务器配置价格汇总,涵盖经济型e实例、计算型c9i等热门ECS实例,CPU含Intel Xeon及AMD EPYC系列,月费159元起,年付低至1578元,按小时计费0.45元起,实际购买享折扣优惠。
202 1

热门文章

最新文章

下一篇
开通oss服务