📄 messagemgr.c
字号:
//
// 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 + -