Why CPU overhead reach abnormal 100%???Strange!!!!!!!!!!!!!!

Home Forums Discussions Support Portal Why CPU overhead reach abnormal 100%???Strange!!!!!!!!!!!!!!

This topic contains 2 replies, has 2 voices, and was last updated by  speedvoipok 10 years, 10 months ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
    Posts
  • #5164

    speedvoipok
    Participant

    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 adapter

    g_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;
    }

    #6522

    Vadim Smirnov
    Moderator

    I 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:

    http://www.ntkernel.com/forum/viewtopic.php?t=281

    #6523

    speedvoipok
    Participant

    Hi 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.

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.