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

📄 messagemgr.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/*++



Module Name:

    messagemgr.c

Abstract:

    Message Manager for DhcpV6 client.



    FrancisD

Environment:

    User Level: Windows

Revision History:


--*/

#include "dhcpv6p.h"
//#include "precomp.h"
//#include "messagemgr.tmh"


void mul64_32_64(const FILETIME *lpnum1, DWORD num2, LPFILETIME lpres) {
    __int64 num1;
    num1 = (__int64)lpnum1->dwLowDateTime * (__int64)num2;
    num1 += ((__int64)lpnum1->dwHighDateTime * (__int64)num2)<<32;
    lpres->dwHighDateTime = (DWORD)(num1>>32);
    lpres->dwLowDateTime = (DWORD)(num1&0xffffffff);
}

void add64_32_64(const FILETIME *lpnum1, DWORD num2, LPFILETIME lpres) {
    DWORD bottom = lpnum1->dwLowDateTime + num2;
    lpres->dwHighDateTime = lpnum1->dwHighDateTime + (bottom < lpnum1->dwLowDateTime ? 1 : 0);
    lpres->dwLowDateTime = bottom;
}

#ifdef THUMB
#pragma optimize("",off)
#endif
void add64_64_64(const FILETIME *lpnum1, LPFILETIME lpnum2, LPFILETIME lpres) {
    __int64 num1, num2;
    num1 = (((__int64)lpnum1->dwHighDateTime)<<32)+(__int64)lpnum1->dwLowDateTime;
    num2 = (((__int64)lpnum2->dwHighDateTime)<<32)+(__int64)lpnum2->dwLowDateTime;
    num1 += num2;
    lpres->dwHighDateTime = (DWORD)(num1>>32);
    lpres->dwLowDateTime = (DWORD)(num1&0xffffffff);
}

void sub64_64_64(const FILETIME *lpnum1, LPFILETIME lpnum2, LPFILETIME lpres) {
    __int64 num1, num2;
    num1 = (((__int64)lpnum1->dwHighDateTime)<<32)+(__int64)lpnum1->dwLowDateTime;
    num2 = (((__int64)lpnum2->dwHighDateTime)<<32)+(__int64)lpnum2->dwLowDateTime;
    num1 -= num2;
    lpres->dwHighDateTime = (DWORD)(num1>>32);
    lpres->dwLowDateTime = (DWORD)(num1&0xffffffff);
}
// Unsigned divide
// Divides a 64 bit number by a *31* bit number.  Doesn't work for 32 bit divisors!

void div64_32_64(const FILETIME *lpdividend, DWORD divisor, LPFILETIME lpresult) {
    DWORD bitmask;
    DWORD top;
    FILETIME wholetop = *lpdividend;
    top = 0;
    lpresult->dwHighDateTime = 0;
    for (bitmask = 0x80000000; bitmask; bitmask >>= 1) {
        top = (top<<1) + ((wholetop.dwHighDateTime&bitmask) ? 1 : 0);
        if (top >= divisor) {
            top -= divisor;
            lpresult->dwHighDateTime |= bitmask;
        }
    }
    lpresult->dwLowDateTime = 0;
    for (bitmask = 0x80000000; bitmask; bitmask >>= 1) {
        top = (top<<1) + ((wholetop.dwLowDateTime&bitmask) ? 1 : 0);
        if (top >= divisor) {
            top -= divisor;
            lpresult->dwLowDateTime |= bitmask;
        }
    }
}

#ifdef THUMB
#pragma optimize("",on)
#endif

extern DWORD FindMaxTimeout(PDHCPV6_ADAPT pDhcpV6Adapt, DWORD MaxTime, 
    DWORD Time);


VOID
DHCPV6MessageMgrSolicitCallback(
    PVOID pvContext1,
    PVOID pvContext2
    )
{
    DWORD dwError = 0;
    PDHCPV6_ADAPT pDhcpV6Adapt = (PDHCPV6_ADAPT)pvContext1;


    dwError = DHCPV6MessageMgrSolicitMessage(pDhcpV6Adapt);

    return;
}

VOID
DHCPV6MessageMgrRequestCallback(
    PVOID pvContext1,
    PVOID pvContext2
    )
{
    DWORD dwError = 0;
    PDHCPV6_ADAPT pDhcpV6Adapt = (PDHCPV6_ADAPT)pvContext1;


    dwError = DHCPV6MessageMgrRequestMessage(pDhcpV6Adapt);

    return;
}

VOID
DHCPV6MessageMgrTCallback(
    PVOID pvContext1,
    PVOID pvContext2
    )
{
    DWORD dwError = 0;
    PDHCPV6_ADAPT pDhcpV6Adapt = (PDHCPV6_ADAPT)pvContext1;

    DEBUGMSG(1, (TEXT("+DHCPV6MessageMgrTCallback\r\n")));

    if (dhcpv6_state_T1 == pDhcpV6Adapt->DhcpV6State)
        dwError = DHCPV6MessageMgrRenewMessage(pDhcpV6Adapt);
    else if (dhcpv6_state_T2 == pDhcpV6Adapt->DhcpV6State  ||
        dhcpv6_state_rebindconfirm == pDhcpV6Adapt->DhcpV6State)
        dwError = DHCPV6MessageMgrRebindMessage(pDhcpV6Adapt);

    return;
}



VOID
DHCPV6MessageMgrInfoReqCallback(
    PVOID pvContext1,
    PVOID pvContext2
    )
{
    DWORD dwError = 0;
    PDHCPV6_ADAPT pDhcpV6Adapt = (PDHCPV6_ADAPT)pvContext1;


    dwError = DHCPV6MessageMgrInfoRequest(pDhcpV6Adapt);

    return;
}

LONG TimerExpired(PDHCPV6_ADAPT pDhcpV6Adapt, DWORD Time) {
    FILETIME    CurTime, ExpireTime;

    ExpireTime.dwLowDateTime = Time;
    ExpireTime.dwHighDateTime = 0;
    mul64_32_64(&ExpireTime, NANO100_TO_SEC, &ExpireTime);
    add64_64_64(&pDhcpV6Adapt->pPdOption->IAPrefix.IALeaseObtained, 
        &ExpireTime, &ExpireTime);

    GetCurrentFT (&CurTime);
    return CompareFileTime(&CurTime, &ExpireTime);

}   // TimerExpired()


VOID
CALLBACK
DHCPV6MessageMgrTimerCallbackRoutine(
    PVOID pvContext,
    BOOLEAN bWaitTimeout
    )
{
    DWORD dwError = 0;
    PDHCPV6_ADAPT pDhcpV6Adapt = (PDHCPV6_ADAPT)pvContext;
    DWORD   fTimerExpired;


    DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_TRACE, ("Begin Timer Callback Fired for Adapt: %d with RefCount: %d", pDhcpV6Adapt->dwIPv6IfIndex, pDhcpV6Adapt->uRefCount));

    AcquireExclusiveLock(&pDhcpV6Adapt->RWLock);
    DEBUGMSG(1, (TEXT("+DHCPV6MessageMgrTimerCallbackRoutine\r\n")));

    if (pDhcpV6Adapt->bEventTimerQueued == FALSE) {
        DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("Timer Callback Fired Ignored: has been processed already"));
        ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
        BAIL_ON_WIN32_SUCCESS(dwError);
    }
    pDhcpV6Adapt->bEventTimerQueued = FALSE;

    if(pDhcpV6Adapt->bEventTimerCancelled) {
        DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("Timer Callback Cancelled on Adapt: %d with RefCount: %d", pDhcpV6Adapt->dwIPv6IfIndex, pDhcpV6Adapt->uRefCount));
        ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
        DereferenceDHCPV6Adapt(pDhcpV6Adapt);
        BAIL_ON_WIN32_SUCCESS(dwError);
    }

    switch (pDhcpV6Adapt->DhcpV6State) {
    case dhcpv6_state_solicit:
        ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
        DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("WARN: Timer Callback: Request - No reply for InfoRequest on Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));
        dwError = DhcpV6EventAddEvent(
                        gpDhcpV6EventModule,
                        pDhcpV6Adapt->dwIPv6IfIndex,
                        DHCPV6MessageMgrSolicitCallback,
                        pDhcpV6Adapt,
                        NULL
                        );
        BAIL_ON_WIN32_ERROR(dwError);
        break;

    case dhcpv6_state_srequest:

        if (pDhcpV6Adapt->uMaxReXmits && 
            (pDhcpV6Adapt->uReXmits >= pDhcpV6Adapt->uMaxReXmits)) {
            SetInitialTimeout(pDhcpV6Adapt, DHCPV6_SOL_TIMEOUT, 
                DHCPV6_SOL_MAX_RT, 0);
            dwError = DhcpV6EventAddEvent(gpDhcpV6EventModule,
                pDhcpV6Adapt->dwIPv6IfIndex, DHCPV6MessageMgrSolicitCallback,
                pDhcpV6Adapt, NULL);

            ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);

            ASSERT(! dwError);
            BAIL_ON_WIN32_ERROR(dwError);
            break;
        }
        
        ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
        DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("WARN: Timer Callback: Request - No reply for InfoRequest on Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));
        dwError = DhcpV6EventAddEvent(
                        gpDhcpV6EventModule,
                        pDhcpV6Adapt->dwIPv6IfIndex,
                        DHCPV6MessageMgrRequestCallback,
                        pDhcpV6Adapt,
                        NULL
                        );
        BAIL_ON_WIN32_ERROR(dwError);
        break;

    case dhcpv6_state_request:
        ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
        DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("WARN: Timer Callback: Request - No reply for InfoRequest on Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));
        dwError = DhcpV6EventAddEvent(
                        gpDhcpV6EventModule,
                        pDhcpV6Adapt->dwIPv6IfIndex,
                        DHCPV6MessageMgrInfoReqCallback,
                        pDhcpV6Adapt,
                        NULL
                        );
        BAIL_ON_WIN32_ERROR(dwError);
        break;

    case dhcpv6_state_rebindconfirm:

        // 3 reasons to go to solicit mode
        // 1. no prefix option, 2. prefix ValidLifetime has expired
        // 3. DHCPV6_CNF_MAX_RD has expired

        if (pDhcpV6Adapt->pPdOption)
            fTimerExpired = (TimerExpired(pDhcpV6Adapt, 
                pDhcpV6Adapt->pPdOption->IAPrefix.ValidLifetime) >= 0);
        
        if ((! pDhcpV6Adapt->pPdOption) || fTimerExpired ||
            (pDhcpV6Adapt->StartRebindConfirm + (DHCPV6_CNF_MAX_RD * SEC_TO_MS)
            <= GetTickCount())) {

            // prefix has expired go back to solicit mode
            // should we delete the existing pd?

            if (pDhcpV6Adapt->pPdOption) {

                if (fTimerExpired) {
                    // delete existing prefix
                    DHCPV6_IA_PREFIX *pPrefix = &pDhcpV6Adapt->pPdOption->IAPrefix;

                    DHCPv6ManagePrefix(
                        pDhcpV6Adapt->dwIPv6IfIndex,
                        pPrefix->PrefixAddr,
                        pPrefix->cPrefix,
                        0, 0);

                    FreeDHCPV6Mem(pDhcpV6Adapt->pPdOption);
                    pDhcpV6Adapt->pPdOption = NULL;

                }
                DHCPv6ManagePrefixPeriodicCleanup();
                
            }
            DeleteRegistrySettings(pDhcpV6Adapt, DEL_REG_ALL);

            SetInitialTimeout(pDhcpV6Adapt, DHCPV6_SOL_TIMEOUT, 
                DHCPV6_SOL_MAX_RT, 0);
            ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);

            dwError = DhcpV6EventAddEvent(gpDhcpV6EventModule,
                pDhcpV6Adapt->dwIPv6IfIndex, DHCPV6MessageMgrSolicitCallback,
                pDhcpV6Adapt, NULL);


            ASSERT(! dwError);
            BAIL_ON_WIN32_ERROR(dwError);
            break;
        }
        ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
        dwError = DhcpV6EventAddEvent(
                        gpDhcpV6EventModule,
                        pDhcpV6Adapt->dwIPv6IfIndex,
                        DHCPV6MessageMgrTCallback,
                        pDhcpV6Adapt,
                        NULL
                        );
        
        BAIL_ON_WIN32_ERROR(dwError);
        break;

    case dhcpv6_state_configured:
    case dhcpv6_state_T1:
    case dhcpv6_state_T2:
        DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("Timer Callback: Already Configured on Adapt: %d with RefCount: %d", pDhcpV6Adapt->dwIPv6IfIndex, pDhcpV6Adapt->uRefCount));

        if ((! gbDHCPV6PDEnabled) || (! pDhcpV6Adapt->pPdOption)) {
            ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
            DereferenceDHCPV6Adapt(pDhcpV6Adapt);
            break;
        }

        if (TimerExpired(pDhcpV6Adapt, 
            pDhcpV6Adapt->pPdOption->IAPrefix.ValidLifetime) >= 0) {

            // prefix has expired go back to solicit mode
            
            // delete existing prefix
            DHCPV6_IA_PREFIX *pPrefix = &pDhcpV6Adapt->pPdOption->IAPrefix;

            DHCPv6ManagePrefix(
                pDhcpV6Adapt->dwIPv6IfIndex,
                pPrefix->PrefixAddr,
                pPrefix->cPrefix,
                0, 0);
            DHCPv6ManagePrefixPeriodicCleanup();

            FreeDHCPV6Mem(pDhcpV6Adapt->pPdOption);
            pDhcpV6Adapt->pPdOption = NULL;


            DeleteRegistrySettings(pDhcpV6Adapt, DEL_REG_ALL);

            SetInitialTimeout(pDhcpV6Adapt, DHCPV6_SOL_TIMEOUT, 
                DHCPV6_SOL_MAX_RT, 0);

            dwError = DhcpV6EventAddEvent(gpDhcpV6EventModule,
                pDhcpV6Adapt->dwIPv6IfIndex, DHCPV6MessageMgrSolicitCallback,
                pDhcpV6Adapt, NULL);

            ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);

            ASSERT(! dwError);
            BAIL_ON_WIN32_ERROR(dwError);
            break;
        }

        // check T2 time first--it shouldn't normally expire before T1
        if (TimerExpired(pDhcpV6Adapt, pDhcpV6Adapt->pPdOption->T2) >= 0) {
            if (dhcpv6_state_T2 != pDhcpV6Adapt->DhcpV6State) {
                SetInitialTimeout(pDhcpV6Adapt, DHCPV6_REB_TIMEOUT, 
                    DHCPV6_REB_MAX_RT, 0);
            }
            pDhcpV6Adapt->DhcpV6State = dhcpv6_state_T2;
        } else if (TimerExpired(pDhcpV6Adapt, pDhcpV6Adapt->pPdOption->T1) 
            >= 0) {
            if (dhcpv6_state_T1 != pDhcpV6Adapt->DhcpV6State) {
                SetInitialTimeout(pDhcpV6Adapt, DHCPV6_REN_TIMEOUT, 
                    DHCPV6_REN_MAX_RT, 0);
            }
            pDhcpV6Adapt->DhcpV6State = dhcpv6_state_T1;
        } else {
            ULONG       ReXmitTime, MaxTime;
            FILETIME    CurTime, ElapsedTime;
            // strange why did we go off before T1 or T2 expired?

            MaxTime = pDhcpV6Adapt->pPdOption->T1 * SEC_TO_MS;

            // find new time to fire!
            GetCurrentFT (&CurTime);
            if (0 > CompareFileTime(&CurTime, 
                &pDhcpV6Adapt->pPdOption->IAPrefix.IALeaseObtained)) {

                DEBUGMSG(ZONE_WARN, 
                    (TEXT("!DhcpV6: CurTime < LeaseObtained Time!\r\n")));
                ReXmitTime = MaxTime;

            } else {
                sub64_64_64(&CurTime,
                    &pDhcpV6Adapt->pPdOption->IAPrefix.IALeaseObtained, 
                    &ElapsedTime);
                div64_32_64(&ElapsedTime, NANO100_TO_MS, &ElapsedTime);

                if (ElapsedTime.dwHighDateTime)
                    ReXmitTime = 1;
                else if (ElapsedTime.dwLowDateTime >= MaxTime)
                    ReXmitTime = 1;
                else
                    ReXmitTime = MaxTime - ElapsedTime.dwLowDateTime;
            }

            // if time left is still greater than half T1 time, assume that 
            // someone changed the system time & go back to solicit mode
            if (ReXmitTime >= (MaxTime / 2)) {
                DHCPV6_IA_PREFIX *pPrefix = &pDhcpV6Adapt->pPdOption->IAPrefix;

                DEBUGMSG(ZONE_WARN, 
                    (TEXT("!DhcpV6: Timer went off and ReXmitTime > T1 / 2\r\n")));

                // delete existing prefix
                DHCPv6ManagePrefix(
                    pDhcpV6Adapt->dwIPv6IfIndex,
                    pPrefix->PrefixAddr,
                    pPrefix->cPrefix,
                    0, 0);
                DHCPv6ManagePrefixPeriodicCleanup();

                DeleteRegistrySettings(pDhcpV6Adapt, DEL_REG_ALL);

                FreeDHCPV6Mem(pDhcpV6Adapt->pPdOption);
                pDhcpV6Adapt->pPdOption = NULL;

                // go back to solicit mode
                SetInitialTimeout(pDhcpV6Adapt, DHCPV6_SOL_TIMEOUT, 
                    DHCPV6_SOL_MAX_RT, 0);

                dwError = DhcpV6EventAddEvent(gpDhcpV6EventModule,
                    pDhcpV6Adapt->dwIPv6IfIndex,
                    DHCPV6MessageMgrSolicitCallback, pDhcpV6Adapt, NULL);

                ASSERT(! dwError);

            } else {
                dwError = DhcpV6TimerSetTimer(gpDhcpV6TimerModule, 
                    pDhcpV6Adapt, DHCPV6MessageMgrTimerCallbackRoutine,
                    pDhcpV6Adapt, ReXmitTime);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -