Home › Forums › Discussions › Support › Why CPU overhead reach abnormal 100%???Strange!!!!!!!!!!!!!!
- This topic has 2 replies, 2 voices, and was last updated 16 years, 11 months ago by speedvoipok.
-
AuthorPosts
-
January 6, 2008 at 7:30 pm #5164
I have designed and implemented a simple packet dispatch engine(PDE) which is based upon passthrough sample of Winpkfilter. Our PDE is also build as .dll and only a thin wrapper to passthru. But after running PDE for small while, CPU overhead abnormally reach 100%, Why to behavior so? I try my best to look through my program for several days, but pity to get no result, Help me! Ndis-Guru..
Source code is list as follows:Pde.cpp
======
#include “stdafx.h”
#include “iphlp.h”
#include “..VgLogVgLog.h”
#include “Pde.h”//
Global declaration
VG_PDE_CONTEXT g_VgPdeContext; // Pde control context
CNdisApi g_CNdisApi; // CNdisApi class interface instance//
Macros
//
DLL Main Entry
// BOOL APIENTRY DllMain( HANDLE hModule,
// DWORD ul_reason_for_call,
// LPVOID lpReserved
// )
// {
// switch (ul_reason_for_call)
// {
// case DLL_PROCESS_ATTACH:
// case DLL_THREAD_ATTACH:
// case DLL_THREAD_DETACH:
// case DLL_PROCESS_DETACH:
// break;
// }
// return TRUE;
// }//
Function implementation
static USHORT _ntohs(USHORT netshort)
{
PUCHAR pBuffer;
USHORT nResult;nResult = 0;
pBuffer = (PUCHAR )&netshort;nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
| ( pBuffer[ 1 ] & 0x00FF );return( nResult );
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeStartup
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
VGPDE_STATUS VGPDEAPI VgPdeStartup(unsigned char *pAdapterMac)
{
HANDLE currentHandle;VgPdeSetActiveAdapterHandle(pAdapterMac);
currentHandle = VgPdeGetActiveAdapterHandle();if(!g_CNdisApi.IsDriverLoaded())
{
VGPDELOG(“Driver not installed on this system, failed to load.n”);
return VGPDEERRDRVNOTFOUND;
}if(!g_CNdisApi.GetTcpipBoundAdaptersInfo(&g_VgPdeContext.adList))
{
VGPDELOG(“Error in getting adapters on this system.n”);
return VGPDEERRNOTGETADAPTERS;
}// g_VgPdeContext.activeAdIndex = 0; /* default adapter index */
g_VgPdeContext.mode.dwFlags = MSTCP_FLAG_SENT_TUNNEL|MSTCP_FLAG_RECV_TUNNEL;
g_VgPdeContext.mode.hAdapterHandle = currentHandle;
// Create notification event
g_VgPdeContext.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if((!g_VgPdeContext.hEvent) || (!g_CNdisApi.SetPacketEvent(currentHandle, g_VgPdeContext.hEvent)))
{
VGPDELOG(“Failed to set notification event for driver.n”);
return (0x1); // abnormal exit
}// Initialize reception Request
ZeroMemory(&g_VgPdeContext.rxReq, sizeof(ETH_REQUEST));
ZeroMemory(&g_VgPdeContext.rxpktBuf, sizeof(INTERMEDIATE_BUFFER));
g_VgPdeContext.rxReq.EthPacket.Buffer = &g_VgPdeContext.rxpktBuf;
g_VgPdeContext.rxReq.hAdapterHandle = currentHandle;// // Initialize transmission Request
// ZeroMemory(&g_VgPdeContext.txReq, sizeof(ETH_REQUEST));
// ZeroMemory(&g_VgPdeContext.txpktBuf, sizeof(INTERMEDIATE_BUFFER));
// g_VgPdeContext.txReq.EthPacket.Buffer = &g_VgPdeContext.txpktBuf;// Initialize event handler sets for callback
ZeroMemory(&g_VgPdeContext.pktEvSets, sizeof(VG_PACKET_EVENT_HANDLER_SET));g_CNdisApi.SetAdapterMode(&g_VgPdeContext.mode);
g_VgPdeContext.hThread = CreateThread(NULL, 0, PacketDispatchEngine, 0,
0, NULL);return VGPDE_OK;
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeCleanup
//
// Purpose
// This function releases packets in the adapter queue and stops listening
// the interface
//
// Parameters
//
// Return Value
//
// Remarks
//
void VGPDEAPI VgPdeCleanup()
{
g_VgPdeContext.mode.dwFlags = 0;
g_VgPdeContext.mode.hAdapterHandle = VgPdeGetActiveAdapterHandle();// Set NULL event to release previously set event object
g_CNdisApi.SetPacketEvent(VgPdeGetActiveAdapterHandle(), NULL);// Close Event
if (g_VgPdeContext.hEvent)
CloseHandle (g_VgPdeContext.hEvent);// Set default adapter mode
g_CNdisApi.SetAdapterMode(&g_VgPdeContext.mode);// Empty adapter packets queue
g_CNdisApi.FlushAdapterPacketQueue (VgPdeGetActiveAdapterHandle());
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeRegister
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
BOOL VGPDEAPI VgPdeRegister(PVG_PACKET_EVENT_HANDLER_SET pPktEvSet)
{
if (NULL == pPktEvSet)
return FALSE;g_VgPdeContext.pktEvSets.pfnEvArpHandler = pPktEvSet->pfnEvArpHandler;
g_VgPdeContext.pktEvSets.pfnEvIpHandler = pPktEvSet->pfnEvIpHandler;return TRUE;
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeUnRegister
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
void VGPDEAPI VgPdeUnRegister()
{
g_VgPdeContext.pktEvSets.pfnEvArpHandler = NULL;
g_VgPdeContext.pktEvSets.pfnEvIpHandler = NULL;
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeGetActiveAdapterHandle
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
HANDLE VGPDEAPI VgPdeGetActiveAdapterHandle()
{
return g_VgPdeContext.adList.m_nAdapterHandle[g_VgPdeContext.activeAdIndex];
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeGetAdapterHandleByIndex
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
HANDLE VGPDEAPI VgPdeGetAdapterHandleByIndex(DWORD adIdx)
{
return g_VgPdeContext.adList.m_nAdapterHandle[adIdx];
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeSetActiveAdapterHandle
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
VGPDE_STATUS VGPDEAPI VgPdeSetActiveAdapterHandle(unsigned char *pAdapterMac)
{
unsigned long i;
int j;
BOOL bFindAdapter = FALSE;if(NULL == pAdapterMac)
return VGPDE_FAILURE;// search possible adapter mac address
for(i = 0; i < g_VgPdeContext.adList.m_nAdapterCount; i++)
{
for(j = 0; j < ETHER_ADDR_LENGTH; j++)
if(g_VgPdeContext.adList.m_czCurrentAddress[j] != pAdapterMac[j])
break;
if(j == ETHER_ADDR_LENGTH) // adapter found
{
bFindAdapter = TRUE;
g_VgPdeContext.activeAdIndex = i;
break;
}
}if(bFindAdapter)
return VGPDE_OK;
else
{
VGPDELOG(“Adapter not Found on this system!n”);
return VGPDEERRADAPTERNOTFOUND;
}
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeInvoke
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
VGPDE_STATUS VGPDEAPI VgPdeInvoke()
{
g_VgPdeContext.hThread = CreateThread(NULL, 0, PacketDispatchEngine, 0,
0, NULL);
if(!g_VgPdeContext.hThread)
return VGPDE_FAILURE;
return VGPDE_OK;
}/////////////////////////////////////////////////////////////////////////////
//// PacketDispatchEngine
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//DWORD WINAPI PacketDispatchEngine(LPVOID pParam)
{
DWORD currentAdIdx = g_VgPdeContext.activeAdIndex;
HANDLE currentHandle = VgPdeGetAdapterHandleByIndex(currentAdIdx);
HANDLE activeHandle;
ether_header_ptr pEthHeader = NULL;
arphdr_ptr pArpHeader = NULL;
VG_PACKET_DESCRIPTOR pktDescriptor;while(TRUE)
{
activeHandle = VgPdeGetActiveAdapterHandle();
if(currentHandle != activeHandle) // active adapter changed!!!
{
currentHandle = activeHandle; // point to current adapterg_VgPdeContext.mode.hAdapterHandle = currentHandle;
g_VgPdeContext.rxReq.hAdapterHandle = currentHandle; // Hook rxReq with adapter
g_CNdisApi.SetPacketEvent(currentHandle, g_VgPdeContext.hEvent); // hook event with adapter
g_CNdisApi.SetAdapterMode(&g_VgPdeContext.mode); // set adapter mode
}//
// Wait before active interface is ready to indicate the packet
//
WaitForSingleObject (g_VgPdeContext.hEvent, INFINITE);
ResetEvent(g_VgPdeContext.hEvent);//
// Read packet from the interface until there are any
//
while(g_CNdisApi.ReadPacket(&g_VgPdeContext.rxReq))
{
//
// Get Ethernet header
//
pEthHeader = (ether_header_ptr)g_VgPdeContext.rxpktBuf.m_IBuffer;// packet descriptor manipulation
pktDescriptor.nPktLen = g_VgPdeContext.rxpktBuf.m_Length; // frame length
pktDescriptor.pPktBuf = g_VgPdeContext.rxpktBuf.m_IBuffer; // full frame including ether header
if (g_VgPdeContext.rxpktBuf.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
pktDescriptor.ePktDirection = VG_PACKET_FROM_MSTCP;
else
pktDescriptor.ePktDirection = VG_PACKET_FROM_NIC;//
// Check if Ethernet frame contains ARP packet
//
if(_ntohs(pEthHeader->h_proto) == ETH_P_ARP)
{
// packet type specified
pktDescriptor.ePktType = VG_PACKET_ARP;
//
// ARP packet handler callback
//
if(g_VgPdeContext.pktEvSets.pfnEvArpHandler != NULL)
g_VgPdeContext.pktEvSets.pfnEvArpHandler(&pktDescriptor);
}
else if(_ntohs(pEthHeader->h_proto) == ETH_P_IP)
{
// packet type specified
pktDescriptor.ePktType = VG_PACKET_IP;
//
// IP packet handler callback
//
if(g_VgPdeContext.pktEvSets.pfnEvIpHandler != NULL)
g_VgPdeContext.pktEvSets.pfnEvIpHandler(&pktDescriptor);
}
}
}return 0;
}/////////////////////////////////////////////////////////////////////////////
//// VgPdeTransmit
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
BOOL VGPDEAPI VgPdeTransmit(char *pPktBuf, int pktLength, VG_PACKET_DIRECTION eDirection)
{
if(NULL == pPktBuf)
return FALSE;// Copy packet contents including ether header
memcpy(g_VgPdeContext.rxpktBuf.m_IBuffer, pPktBuf, pktLength);
// set packet length
g_VgPdeContext.rxpktBuf.m_Length = pktLength;if(eDirection == VG_PACKET_TO_NIC)
return (g_CNdisApi.SendPacketToAdapter(&g_VgPdeContext.rxReq));
else
return (g_CNdisApi.SendPacketToMstcp(&g_VgPdeContext.rxReq));}
/////////////////////////////////////////////////////////////////////////////
//// VgPdeForward
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//
BOOL VGPDEAPI VgPdeForward(char *pPktBuf, int pktLength, unsigned char *pDestMac)
{
ether_header_ptr pEtherHdr = NULL;return TRUE;
}static void _PdeLog(PDE_LOG_LEVEL level,char *module,const char *fmt, …)
{char buf[16];
const char *s;
int d;
va_list ap;
FILE * pLogFile = NULL;
char filename[MAX_PATH];strcpy(filename,PDE_LOG_FILE);
pLogFile = fopen(filename,”a+”);
if(pLogFile == NULL)
return;SYSTEMTIME sysTime;
GetSystemTime(&sysTime);switch(level)
{
case PDE_LOG_LEVEL_INFO:
fprintf(pLogFile, “%d-%d-%d %d:%d:%d:%d : Information: %s:”, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds,module);
break;case PDE_LOG_LEVEL_ERROR:
fprintf(pLogFile, “%d-%d-%d %d:%d:%d:%d : Error: %s:”, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds,module);
break;
case PDE_LOG_LEVEL_FATAL:
fprintf(pLogFile, “%d-%d-%d %d:%d:%d:%d : Fatal: %s:”, sysTime.wYear, sysTime.wMonth, sysTime.wDay,
sysTime.wHour, sysTime.wMinute, sysTime.wSecond, sysTime.wMilliseconds,module);
break;
default: break;
}va_start(ap, fmt);
while (*fmt)
{
if (*fmt != ‘%’)
{
fputc(*fmt++,pLogFile);
continue;
}
switch (*++fmt)
{
case ‘s’:
case ‘S’:
s = va_arg(ap, const char *);
for ( ; *s; s++)
{
fputc(*s,pLogFile);
}
break;
case ‘d’:
case ‘D’:
d = va_arg(ap, int);
itoa(d, buf, 10);
for (s = buf; *s; s++)
{
fputc(*s,pLogFile);
}
break;
/* Add other specifiers here… */
case ‘x’:
case ‘X’:
d = va_arg(ap, int);
itoa(d, buf, 16);
for (s = buf; *s; s++)
{
fputc(*s,pLogFile);
}
break;default:
fputc(*fmt,pLogFile);
break;
}
fmt++;
}
va_end(ap);
fprintf(pLogFile,”n”);
fclose(pLogFile);
}Pde.h
====
#ifndef _PDE_H
#define _PDE_H#include
#include
#include
#include#define VG_PDE_NDIS_HOOKING // Upon NDIS-Hooking NdisRD driver
#ifdef VG_PDE_NDIS_HOOKING
#include “..NdisRdincludecommon.h”
#include “..NdisRdincludendisapi.h”
#endif// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the PDE_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// PDE_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef PDE_EXPORTS
#define PDE_API __declspec(dllexport)
#else
#define PDE_API __declspec(dllimport)
#endif#define VGPDEAPI WINAPI
#define VGPDE_DEBUG
#ifdef VGPDE_DEBUG
#define VGPDELOG(_x)
_PdeLog(PDE_LOG_LEVEL_ERROR, “Pde”, (_x))
#else
#define VGPDELOG(_x)
#endif//#define ReleaseInterface VgPdeCleanup
#define _htons _ntohs/*
* All PDE error constants are biased by VGPDEERRBASE from
* the “normal”
*/
#define VGPDEERRBASE 1000
#define VGPDEERRDRVNOTFOUND (VGPDEERRBASE + 1)
#define VGPDEERRNOTGETADAPTERS (VGPDEERRBASE + 2)
#define VGPDEERRADAPTERNOTFOUND (VGPDEERRBASE + 3)
#define VGPDEERRCREATEEVENT (VGPDEERRBASE + 4)#define VGPDE_OK 0
#define VGPDE_FAILURE -1#define PDE_LOG_FILE “..\bin\PdeLog.txt”
#pragma pack(1)
typedef enum _PDE_LOG_LEVEL
{
PDE_LOG_LEVEL_INFO = 0,
PDE_LOG_LEVEL_ERROR,
PDE_LOG_LEVEL_FATAL
}PDE_LOG_LEVEL;typedef int VGPDE_STATUS;
typedef enum _VG_PACKET_TYPE // type of packet
{
VG_PACKET_ARP = 0,
VG_PACKET_IP
}VG_PACKET_TYPE;typedef enum _VG_PACKET_DIRECTION // flow direction of packet
{
VG_PACKET_FROM_MSTCP,
VG_PACKET_FROM_NIC,
VG_PACKET_TO_MSTCP,
VG_PACKET_TO_NIC
}VG_PACKET_DIRECTION;typedef UCHAR VG_PACKET_BUF, *PVG_PACKET_BUF;
typedef struct _VG_PACKET_DESCRIPTOR
{
VG_PACKET_TYPE ePktType;
VG_PACKET_DIRECTION ePktDirection;
PVG_PACKET_BUF pPktBuf;
UINT nPktLen;
}VG_PACKET_DESCRIPTOR, *PVG_PACKET_DESCRIPTOR;typedef BOOL (*VG_PACKET_EVENT_HANDLER)(IN PVG_PACKET_DESCRIPTOR pPktDes);
typedef struct _VG_PACKET_EVENT_HANDLER_SET
{
VG_PACKET_EVENT_HANDLER pfnEvArpHandler; // for ARP packet
VG_PACKET_EVENT_HANDLER pfnEvIpHandler; // for IP packet
}VG_PACKET_EVENT_HANDLER_SET, *PVG_PACKET_EVENT_HANDLER_SET;/* Core control data structure */
typedef struct _VG_PDE_CONTEXT
{
HANDLE hThread; // worker thread for packet event indication
TCP_AdapterList adList; // array of all adapters within system
DWORD activeAdIndex; // current active adapter
ADAPTER_MODE mode; // adapter working mode
ETH_REQUEST rxReq; // for packet reception
INTERMEDIATE_BUFFER rxpktBuf; // holding real packet contents for reception
ETH_REQUEST txReq; // for packet transmission
INTERMEDIATE_BUFFER txpktBuf; // holding real packet contents for transmission
HANDLE hEvent; // for event notification between pde and ndisrd driver
VG_PACKET_EVENT_HANDLER_SET pktEvSets;
}VG_PDE_CONTEXT, *PVG_PDE_CONTEXT;// This class is exported from the Pde.dll
class PDE_API CPde
{
public:
CPde(void);
// TODO: add your methods here.
};static USHORT _ntohs(USHORT netshort);
DWORD WINAPI PacketDispatchEngine(LPVOID pParam);
static void _PdeLog(PDE_LOG_LEVEL level,char *module,const char *fmt, …);extern “C”
{
VGPDE_STATUS VGPDEAPI VgPdeStartup(unsigned char *pAdapterMac);
void VGPDEAPI VgPdeCleanup();
BOOL VGPDEAPI VgPdeRegister(PVG_PACKET_EVENT_HANDLER_SET pPktEvSet);
void VGPDEAPI VgPdeUnRegister();
HANDLE VGPDEAPI VgPdeGetActiveAdapterHandle();
HANDLE VGPDEAPI VgPdeGetAdapterHandleByIndex(DWORD adIdx);
VGPDE_STATUS VGPDEAPI VgPdeSetActiveAdapterHandle(unsigned char *pAdapterMac);
BOOL VGPDEAPI VgPdeTransmit(char *pPktBuf, int pktLength, VG_PACKET_DIRECTION eDirection);
BOOL VGPDEAPI VgPdeForward(char *pPktBuf, int pktLength, unsigned char *pDestMac);
};#endif
Also here is PdeDemo.cpp which calls Pde.dll export routine.
=============================================
#include “stdafx.h”
#include “..Pde.h”
#include “..iphlp.h”#define PdeDemoShow printf
unsigned char srcMac[] = {0x00, 0xC0, 0x9F, 0xF3, 0x45, 0x7A};
unsigned char dstMac[] = {0x00, 0x1C, 0xF0, 0x47, 0xBA, 0x38};BOOL ArpHandler(IN PVG_PACKET_DESCRIPTOR pPktDes)
{
return TRUE;
}BOOL IpHandler(IN PVG_PACKET_DESCRIPTOR pPktDes)
{
ether_header *pEthHdr = NULL;
iphdr *pIpHdr = NULL;if (NULL == pPktDes)
return FALSE;pEthHdr =(ether_header *)(pPktDes->pPktBuf);
pIpHdr = (iphdr *)(pPktDes->pPktBuf + sizeof(ether_header));if(pPktDes->ePktDirection == VG_PACKET_FROM_NIC)
{
memcpy(pEthHdr->h_dest, dstMac, ETH_ALEN);
memcpy(pEthHdr->h_source, srcMac, ETH_ALEN);
if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
{
PdeDemoShow(“IpHandler@VgPdeTransmit errorn”);
return FALSE;
}
}
else /* from MSTCP */
{
if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
{
PdeDemoShow(“IpHandler@VgPdeTransmit errorn”);
return FALSE;
}
}return TRUE;
}int main(int argc, char* argv[])
{
VG_PACKET_EVENT_HANDLER_SET evHandlerSet;PdeDemoShow(“nPde Demo Apploication v1.0.0(Build 20080107) is running ….n”);
PdeDemoShow(“Copyright(c)by SpeedVoIP Communication Technology Co., Ltd.n”);memset(&evHandlerSet, 0, sizeof(evHandlerSet));
evHandlerSet.pfnEvArpHandler = ArpHandler;
evHandlerSet.pfnEvIpHandler = IpHandler;VgPdeStartup(srcMac);
VgPdeRegister(&evHandlerSet);while(1);
return 0;
}January 7, 2008 at 4:02 pm #6522I suppose the problem is not in the engine but in what you do with packets:
if(pPktDes->ePktDirection == VG_PACKET_FROM_NIC)
{
memcpy(pEthHdr->h_dest, dstMac, ETH_ALEN);
memcpy(pEthHdr->h_source, srcMac, ETH_ALEN);
if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
{
PdeDemoShow("IpHandler@VgPdeTransmit errorn");
return FALSE;
}
}
else /* from MSTCP */
{
if(!VgPdeTransmit((char *)pPktDes->pPktBuf,pPktDes->nPktLen,VG_PACKET_TO_NIC))
{
PdeDemoShow("IpHandler@VgPdeTransmit errorn");
return FALSE;
}
}I don’t know what are the MAC addresses you have used are taken from. But if the address you set as source MAC does not match the NIC address you send the packet from then you may meet problems. In Windows all packets sent on the network are normally indicated back to protocol (so called hardware loopback). It is posssible to use NDIS_FLAGS_DONT_LOOPBACK or/and NDIS_FLAGS_SKIP_LOOPBACK flags (set for the packet in INTERMEDIATE_BUFFER.m_Flags) to prevent the loopback but these packets are system specific and not guarantee to work properly on every Windows, though I used them just fine for the Ethernet Bridge. WinpkFilter normally filters out the loopback packet by checking the source MAC address (packet is skipped if source MAC = NIC MAC), but in your case it may fail to do so (if source MAC does not match the NIC address) and even single packet starts going in the endless loop (from application to WinkFilter, then From WinpkFilter to NIC, from NIC to WinpkFilter, from WinpkFilter to application and so on) -> 100% CPU load.
You can read this topic on forum regarding the loopback packets:
January 7, 2008 at 5:05 pm #6523Hi Vadim:
I can make sure that in pdedemo.cpp src mac must match that of NIC over which packets send. I think loopback cause maybe be excluded from our consideration.
Today I have taken another experiment on PDE, when adding extra code into pdedemo.cpp, all things are ok, CPU overhead revert to normal level, about 2~7%.
===============================================================================================
/* yield control to windows to avoid high
CPU overhead */
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
===============================================================================================
I feel that it has something to with Windows thread or process schedule. -
AuthorPosts
- You must be logged in to reply to this topic.