阅读:1634回复:2
再说PtSendComplete的释放问题。请大家指教
这几日在忙Ndis下的包转发,也就是拿到系统包之后复制到缓冲区,然后把NDIS_BUFFER连接到新的PACKET发送出去。
总是面临着资源回收得不够干净的问题。 我在PtSendComplete中是对自己申请的资源进行了自己的回收。查看网上大家用的处理自发包的回收都没有调用过NdisMSendComplete通知上层。确实是不需要在自发包情况下再通知了。因为上层并不知道。 但是包转发的情况下,我认为还是有必要调用NdisMSendComplete通知上层释放。但并不是释放我们自己的包。而是释放原来系统的PACKET。 我观察了原来的MPSendPackets. 在这个函数里,总共有2个包结构,一个Packet(系统提供的)一个MyPacket自己申请的。 M$的做法是,将Packet设置到OriginalPkt。然后在PtSendComplete中释放掉MyPacket。接着调用NdisMSendComplete通知上层释放Pkt也就是OriginalPkt中的Packet(原系统提供的包)。不知道我的观察对不对。 若是正确的。那我们在释放自己发送的包(转发的情况下) 也应该将原来系统的Packet再次NdisMSendComplete到上层。 我觉得处理的顺序应该是这样 NdisUnchainBufferAtFront(Packet,&pNdisBuffer); DBGPRINT(("<!> NdisUnchainBufferAtFront :%08X----------\n",pNdisBuffer)); NdisQueryBufferSafe(pNdisBuffer,(PVOID *)&pPacketContent8,&BufferLen,32); DBGPRINT(("<!> NdisQueryBufferSafe :%08X,%d----------\n",pPacketContent8,BufferLen)); NdisFreeBuffer(pNdisBuffer); NdisFreeMemory(pPacketContent8,BufferLen,0); NdisMSendComplete(pAdapt->MiniportHandle, Pkt, Status); NdisDprFreePacket(Packet); 注意,这里的Packet只指自己申请的包并非系统提供的包。Pkt才是系统提供的。 而我们不能再调用NdisIMCopySendCompletePerPacketInfo(Pkt,Packet) 因为这样的话就将自发包的数据覆盖掉了原来系统的包数据(Pkt)。 若以上结论是正确的话。那我们不应该将OriginalPkt设置为NULL来标志自己申请的包。 而必须扩展PSEND_RSVD结构。新建一个变量来标志这个包是自己的。 综上所述: 转发情况下,我们应该通知上层释放系统原来的Packet 我们应该新建立一个标志来区别自己申请的包结构 存在的疑问: 转发情况下,我们自己申请的包,是否应该设置NDIS_FLAGS_DONT_LOOPBACK呢? 还想请教各位大大一个问题,我的IMD转发驱动在某些机器上。运行几分钟或者一段时间后就出现断网等不稳定现象。这个问题可能是什么原因引起的呢? 若驱动只注册了MPSendPackets那么在8139等老网卡下。MPSend函数会调用吗? 在转发的函数里该怎么注意老网卡的兼容呢? 谢谢。!! 祝大家新年愉快!! |
|
沙发#
发布于:2008-02-07 15:21
我觉得用PacketPool来判断自己生成的Packet比较好。
转发包时,要把orinigalPkg的flag拷贝到新的packet里 MPSend和MPSendPackets只需要注册一个就可以了,Ndis应该是推荐注册MPSendPackets的 祝新年快乐!! |
|
板凳#
发布于:2008-02-22 11:08
转发包时,要把orinigalPkg的flag拷贝到新的packet里
如果在PSEND_RSVD结构中加入新的flag 这样的话 系统上面发下来的包 这个位置由谁来填写? 我感觉还是 用OriginalPacket 为NULL来判断比较好 自己的包发出去直接就 SendComplete系统的包 我这么做 系统没问题 运行很久了 不过就是发包有的网卡 没反应 发不出去 发现是包内容的问题 因为如果用 系统自己的 NDIS_BUFFER能发,我自己建立的 BUFFER一部分卡发不出去 |
|