⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 packet.cpp

📁 pppoe client
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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 + -