📄 packet.cpp
字号:
if(pPool->m_ulFreeBuffers > pPool->m_ulMaxFreeGuard)
FreeUnusedBufferBlock(pPool);
PBUFFER_ITEM pItem = CONTAINING_RECORD(pRealBuffer,BUFFER_ITEM,m_pStorage);
InsertHeadList(&pPool->m_ltFreeBuffersHead,&pItem->m_ltBufferItemAnchor);
pPool->m_ulFreeBuffers ++;
pItem->m_pBufferBlock->m_ulFreeBufferItems ++;
NdisReleaseSpinLock(&pPool->m_lockSelf);
}
// free packet to pool
VOID FreeNdisPacketToPool(PPACKET_POOL pPool,PPACKET_ITEM pItem)
{
ASSERT(pPool && pItem && pPool->m_ulSig == PACKET_POOL_SIG);
NdisAcquireSpinLock(&pPool->m_lockSelf);
if(pPool->m_ulFreePackets > pPool->m_ulMaxFreeGuard)
FreeUnusedPacketBlock(pPool);
InsertHeadList(&pPool->m_ltFreePacketsHead,&pItem->m_ltPacketItemAnchor);
pPool->m_ulFreePackets ++;
pItem->m_pPacketBlock->m_ulFreePacketItems ++;
NdisReleaseSpinLock(&pPool->m_lockSelf);
}
// free packet
VOID FreePacket(PPACKET pPacket)
{
ASSERT(pPacket && pPacket->m_lRefCount == 0 && pPacket->m_ulSig == PACKET_SIG);
NdisFreeToNPagedLookasideList(&g_lookasidePacket,pPacket);
}
// add packet block to pool
PNDIS_PACKET AddPacketBlockToPool(PPACKET_POOL pPacketPool,PPACKET_ITEM *ppItem)
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(pPacketPool && pPacketPool->m_ulSig == PACKET_POOL_SIG && ppItem);
PNDIS_PACKET pRetPacket = NULL;
ULONG ulSize = pPacketPool->m_ulPacketsPerBlock * sizeof(PACKET_ITEM) + sizeof(PACKET_BLOCK);
PPACKET_BLOCK pBlock;
// allocate block memory
NDIS_STATUS status = AllocateMemory((PVOID*)&pBlock,ulSize,PACKET_BLOCK_SIG);
if(status != NDIS_STATUS_SUCCESS)
return NULL;
pBlock->m_ulSig = PACKET_BLOCK_SIG;
// allocate packet pool
NdisAllocatePacketPool(&status,&pBlock->m_hPacketPool,pPacketPool->m_ulPacketsPerBlock,pPacketPool->m_ulProtocolReservedLen);
if(status != NDIS_STATUS_SUCCESS)
{
FreeMemory(pBlock,ulSize);
return NULL;
}
// set value
pBlock->m_ulTotalPacketItems = pPacketPool->m_ulPacketsPerBlock;
pBlock->m_ulFreePacketItems = pPacketPool->m_ulPacketsPerBlock - 1;
pBlock->m_pPacketPool = pPacketPool;
ULONG i;
for(i = 0; i < pBlock->m_ulTotalPacketItems; i ++)
{
// prepare item
PPACKET_ITEM pItem = pBlock->m_arrayItems + i;
pItem->m_pPacketBlock = pBlock;
pItem->m_ulSig = PACKET_ITEM_SIG;
NdisAllocatePacket(&status,&pItem->m_pNdisPacket,pBlock->m_hPacketPool);
if(status != NDIS_STATUS_SUCCESS)
{
break;
}
}
// unsuccessful
if(status != NDIS_STATUS_SUCCESS)
{
for(ULONG j = 0; j < i ; j ++)
{
// free it
PPACKET_ITEM pItem = pBlock->m_arrayItems + j;
NdisFreePacket(pItem->m_pNdisPacket);
}
// free block
FreeMemory(pBlock,ulSize);
}
else
{
// update pool value
pPacketPool->m_ulFreePackets += pBlock->m_ulFreePacketItems;
pPacketPool->m_ulTotalPackets += pPacketPool->m_ulPacketsPerBlock;
// link block
InsertHeadList(&pPacketPool->m_ltPacketBlocksHead,&pBlock->m_ltPacketBlockAnchor);
// link free packet
PPACKET_ITEM pItem;
for(i = 1; i < pBlock->m_ulTotalPacketItems; i ++)
{
pItem = pBlock->m_arrayItems + i;
InsertHeadList(&pPacketPool->m_ltFreePacketsHead,&pItem->m_ltPacketItemAnchor);
}
// return the first one
pItem = pBlock->m_arrayItems;
InitializeListHead(&pItem->m_ltPacketItemAnchor);
pRetPacket = pItem->m_pNdisPacket;
*ppItem = pItem;
}
return pRetPacket;
}
// add buffer block to pool
PPPPOE_FRAME AddBufferBlockToPool(PBUFFER_POOL pBufferPool,PNDIS_BUFFER *ppHeadBuffer,PNDIS_BUFFER *ppDataBuffer)
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
ASSERT(pBufferPool && pBufferPool->m_ulSig == BUFFER_POOL_SIG && ppHeadBuffer && ppDataBuffer);
PPPPOE_FRAME pRetFrame = NULL;
ULONG ulSize = pBufferPool->m_ulBuffersPerBlock *(pBufferPool->m_ulBufferSize + sizeof(BUFFER_ITEM)) + sizeof(BUFFER_BLOCK);
// round it
ulSize = (ulSize + 7) & 0xfffffff8;
PBUFFER_BLOCK pBlock;
// allocate block memory
NDIS_STATUS status = AllocateMemory((PVOID*)&pBlock,ulSize,BUFFER_POOL_SIG);
if(status != NDIS_STATUS_SUCCESS)
return NULL;
pBlock->m_ulSig = BUFFER_BLOCK_SIG;
// allocate buffer pool
NdisAllocateBufferPool(&status,&pBlock->m_hBufferPool,pBufferPool->m_ulBuffersPerBlock * 2);
if(status != NDIS_STATUS_SUCCESS)
{
FreeMemory(pBlock,ulSize);
return NULL;
}
// set value
pBlock->m_ulTotalBufferItems = pBufferPool->m_ulBuffersPerBlock;
pBlock->m_ulFreeBufferItems = pBufferPool->m_ulBuffersPerBlock - 1;
pBlock->m_pBufferPool = pBufferPool;
ULONG i;
for(i = 0; i < pBlock->m_ulTotalBufferItems; i ++)
{
// prepare item
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,i,pBufferPool->m_ulBufferSize);
pItem->m_pBufferBlock = pBlock;
pItem->m_ulSig = BUFFER_ITEM_SIG;
NdisAllocateBuffer(&status,&pItem->m_pNdisHeadBuffer,pBlock->m_hBufferPool,pItem->m_pStorage,PPPOE_HEADER_LEN);
if(status != NDIS_STATUS_SUCCESS)
{
break;
}
NdisAllocateBuffer(&status,&pItem->m_pNdisDataBuffer,pBlock->m_hBufferPool,pItem->m_pStorage + PPPOE_HEADER_LEN,
pBufferPool->m_ulBufferSize - PPPOE_HEADER_LEN);
if(status != NDIS_STATUS_SUCCESS)
{
NdisFreeBuffer(pItem->m_pNdisHeadBuffer);
break;
}
}
// unsuccessful
if(status != NDIS_STATUS_SUCCESS)
{
for(ULONG j = 0; j < i ; j ++)
{
// free it
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,i,pBufferPool->m_ulBufferSize);
NdisFreeBuffer(pItem->m_pNdisHeadBuffer);
NdisFreeBuffer(pItem->m_pNdisDataBuffer);
}
// free block
FreeMemory(pBlock,ulSize);
}
else
{
// update pool value
pBufferPool->m_ulFreeBuffers += pBlock->m_ulFreeBufferItems;
pBufferPool->m_ulTotalBuffers += pBufferPool->m_ulBuffersPerBlock;
// link block
InsertHeadList(&pBufferPool->m_ltBufferBlocksHead,&pBlock->m_ltBufferBlockAnchor);
// link free packet
PBUFFER_ITEM pItem;
for(i = 1; i < pBlock->m_ulTotalBufferItems; i ++)
{
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,i,pBufferPool->m_ulBufferSize);
InsertHeadList(&pBufferPool->m_ltFreeBuffersHead,&pItem->m_ltBufferItemAnchor);
}
// return the first one
pItem = pBlock->m_arrayItem;
InitializeListHead(&pItem->m_ltBufferItemAnchor);
*ppHeadBuffer = pItem->m_pNdisHeadBuffer;
*ppDataBuffer = pItem->m_pNdisDataBuffer;
pRetFrame = reinterpret_cast<PPPPOE_FRAME>(pItem->m_pStorage);
}
return pRetFrame;
}
// free unused packet block
VOID FreeUnusedPacketBlock(PPACKET_POOL pPacketPool)
{
ASSERT(pPacketPool && pPacketPool->m_ulSig == PACKET_POOL_SIG);
ULONG ulSize = pPacketPool->m_ulPacketsPerBlock * sizeof(PACKET_ITEM) + sizeof(PACKET_BLOCK);
PLIST_ENTRY pEntry = pPacketPool->m_ltPacketBlocksHead.Flink;
while(pEntry != &pPacketPool->m_ltPacketBlocksHead)
{
PPACKET_BLOCK pBlock = CONTAINING_RECORD(pEntry,PACKET_BLOCK,m_ltPacketBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == PACKET_BLOCK_SIG);
pEntry = pEntry->Flink;
if(pBlock->m_ulFreePacketItems == pBlock->m_ulTotalPacketItems)
{
for(ULONG j = 0; j < pBlock->m_ulTotalPacketItems ; j ++)
{
// free it
PPACKET_ITEM pItem = pBlock->m_arrayItems + j;
ASSERT(pItem && pItem->m_ulSig == PACKET_ITEM_SIG);
NdisFreePacket(pItem->m_pNdisPacket);
RemoveEntryList(&pItem->m_ltPacketItemAnchor);
}
pPacketPool->m_ulTotalPackets -= pBlock->m_ulTotalPacketItems;
pPacketPool->m_ulFreePackets -= pBlock->m_ulFreePacketItems;
RemoveEntryList(&pBlock->m_ltPacketBlockAnchor);
NdisFreePacketPool(pBlock->m_hPacketPool);
// free block
FreeMemory(pBlock,ulSize);
}
}
}
// free unused packet block
VOID FreeUnusedBufferBlock(PBUFFER_POOL pBufferPool)
{
ASSERT(pBufferPool && pBufferPool->m_ulSig == BUFFER_POOL_SIG);
ULONG ulSize = pBufferPool->m_ulBuffersPerBlock *(pBufferPool->m_ulBufferSize + sizeof(BUFFER_ITEM)) + sizeof(BUFFER_BLOCK);
ulSize = (ulSize + 7) & 0xfffffff8;
PLIST_ENTRY pEntry = pBufferPool->m_ltBufferBlocksHead.Flink;
while(pEntry != &pBufferPool->m_ltBufferBlocksHead)
{
PBUFFER_BLOCK pBlock = CONTAINING_RECORD(pEntry,BUFFER_BLOCK,m_ltBufferBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == BUFFER_BLOCK_SIG);
pEntry = pEntry->Flink;
if(pBlock->m_ulFreeBufferItems == pBlock->m_ulTotalBufferItems)
{
for(ULONG j = 0; j < pBlock->m_ulTotalBufferItems ; j ++)
{
// free it
PBUFFER_ITEM pItem = GET_ITEM_FROM_BLOCK_BY_INDEX(pBlock,j,pBufferPool->m_ulBufferSize);
ASSERT(pItem && pItem->m_ulSig == BUFFER_ITEM_SIG && pItem->m_pNdisDataBuffer && pItem->m_pNdisHeadBuffer);
NdisFreeBuffer(pItem->m_pNdisHeadBuffer);
NdisFreeBuffer(pItem->m_pNdisDataBuffer);
RemoveEntryList(&pItem->m_ltBufferItemAnchor);
}
pBufferPool->m_ulTotalBuffers -= pBlock->m_ulTotalBufferItems;
pBufferPool->m_ulFreeBuffers -= pBlock->m_ulFreeBufferItems;
RemoveEntryList(&pBlock->m_ltBufferBlockAnchor);
NdisFreeBufferPool(pBlock->m_hBufferPool);
// free block
FreeMemory(pBlock,ulSize);
}
}
}
// dump packet leak
VOID DumpPoolLeak()
{
NdisAcquireSpinLock(&g_poolBuffer.m_lockSelf);
PLIST_ENTRY pEntry = g_poolBuffer.m_ltBufferBlocksHead.Flink;
while(pEntry != &g_poolBuffer.m_ltBufferBlocksHead)
{
PBUFFER_BLOCK pBlock = CONTAINING_RECORD(pEntry,BUFFER_BLOCK,m_ltBufferBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == BUFFER_BLOCK_SIG);
pEntry = pEntry->Flink;
DebugError(("buffer block = 0x%x,unfree buffer items count = %d\n",
pBlock,pBlock->m_ulTotalBufferItems - pBlock->m_ulFreeBufferItems));
}
NdisReleaseSpinLock(&g_poolBuffer.m_lockSelf);
NdisAcquireSpinLock(&g_poolPacket.m_lockSelf);
pEntry = g_poolPacket.m_ltPacketBlocksHead.Flink;
while(pEntry != &g_poolPacket.m_ltPacketBlocksHead)
{
PPACKET_BLOCK pBlock = CONTAINING_RECORD(pEntry,PACKET_BLOCK,m_ltPacketBlockAnchor);
ASSERT(pBlock && pBlock->m_ulSig == PACKET_BLOCK_SIG);
pEntry = pEntry->Flink;
DebugError(("packet block = 0x%x,unfree packet items count = %d\n",
pBlock,pBlock->m_ulTotalPacketItems - pBlock->m_ulFreePacketItems));
}
NdisReleaseSpinLock(&g_poolPacket.m_lockSelf);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -