📄 messagemgr.c
字号:
ASSERT(! dwError);
}
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
BAIL_ON_WIN32_ERROR(dwError);
break;
// don't call the add event function below.
}
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
dwError = DhcpV6EventAddEvent(
gpDhcpV6EventModule,
pDhcpV6Adapt->dwIPv6IfIndex,
DHCPV6MessageMgrTCallback,
pDhcpV6Adapt,
NULL
);
BAIL_ON_WIN32_ERROR(dwError);
break;
case dhcpv6_state_deinit:
DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_WARN, ("Timer Callback: DeInitializing on Adapt: %d with RefCount: %d", pDhcpV6Adapt->dwIPv6IfIndex, pDhcpV6Adapt->uRefCount));
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
break;
default:
ASSERT(0);
}
success:
DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_TRACE, ("End Timer Callback"));
return;
error:
DhcpV6Trace(DHCPV6_MISC, DHCPV6_LOG_LEVEL_ERROR, ("ERROR Timer Callback Fired for Adapt: %d with Error: %!status!", pDhcpV6Adapt->dwIPv6IfIndex, dwError));
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
return;
}
#ifdef UNDER_CE
void SetInitialTimeout(PDHCPV6_ADAPT pDhcpV6Adapt, ULONG Time, ULONG MaxTime,
ULONG MaxReXmits) {
DOUBLE dbRand;
dbRand = DhcpV6UniformRandom();
pDhcpV6Adapt->uRetransmissionTimeout = (Time * SEC_TO_MS) +
(ULONG)(Time * SEC_TO_MS * dbRand);
pDhcpV6Adapt->uMaxRetransmissionTimeout = MaxTime * SEC_TO_MS;
pDhcpV6Adapt->uMaxReXmits = MaxReXmits;
pDhcpV6Adapt->uReXmits = 0;
} // CalculateRexmitTimeout()
void CalculateRexmitTimeout(PDHCPV6_ADAPT pDhcpV6Adapt) {
DOUBLE dbRand;
dbRand = DhcpV6UniformRandom();
pDhcpV6Adapt->uRetransmissionTimeout =
2 * pDhcpV6Adapt->uRetransmissionTimeout +
(ULONG)(dbRand * pDhcpV6Adapt->uRetransmissionTimeout);
if (pDhcpV6Adapt->uRetransmissionTimeout >
pDhcpV6Adapt->uMaxRetransmissionTimeout) {
pDhcpV6Adapt->uRetransmissionTimeout =
pDhcpV6Adapt->uMaxRetransmissionTimeout +
(ULONG)(dbRand * pDhcpV6Adapt->uMaxRetransmissionTimeout);
}
} // CalculateRexmitTimeout()
// takes MaxTime & Time in MS and returns appropriate max time to wait in MS
DWORD FindMaxTimeout(PDHCPV6_ADAPT pDhcpV6Adapt, DWORD MaxTime,
DWORD Time) {
DWORD Ret;
// for expired times we return 1 instead of 0.
if (pDhcpV6Adapt->pPdOption) {
FILETIME CurTime, ElapsedTime;
GetCurrentFT (&CurTime);
#if 1
if (0 > CompareFileTime(&CurTime,
&pDhcpV6Adapt->pPdOption->IAPrefix.IALeaseObtained)) {
// something is wrong!
DEBUGMSG(ZONE_WARN,
(TEXT("DhcpV6: FindMaxTimeout: CurTime < LeaseObtained Time!\r\n")));
return 1;
}
#endif
sub64_64_64(&CurTime,
&pDhcpV6Adapt->pPdOption->IAPrefix.IALeaseObtained, &ElapsedTime);
div64_32_64(&ElapsedTime, NANO100_TO_MS, &ElapsedTime);
ASSERT(0 == ElapsedTime.dwHighDateTime);
if (ElapsedTime.dwHighDateTime)
Ret = 1;
else if (ElapsedTime.dwLowDateTime >= MaxTime)
Ret = 1;
else if (ElapsedTime.dwLowDateTime + Time > MaxTime) {
Ret = MaxTime - ElapsedTime.dwLowDateTime;
} else
Ret = Time;
} else {
Ret = Time;
}
return Ret;
}
//
// Lock: None
//
DWORD
DHCPV6MessageMgrSolicitMessage(
PDHCPV6_ADAPT pDhcpV6Adapt
)
{
DWORD dwError = 0;
ULONG uInfoRequestLength = 0;
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule = &pDhcpV6Adapt->DhcpV6OptionModule;
PDHCPV6_MESSAGE_HEADER pDhcpV6MessageHeader = NULL;
PUCHAR pucOptionHeader = NULL;
USHORT usOptionLength = 0;
WSABUF WSABuf = { 0 };
ULONG uByteSent = 0;
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_TRACE, ("Begin Information Request on Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));
AcquireExclusiveLock(&pDhcpV6Adapt->RWLock);
if (pDhcpV6Adapt->DhcpV6State == dhcpv6_state_deinit) {
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
return 0;
}
if (DHCPV6_MEDIA_DISC_FL & pDhcpV6Adapt->Flags) {
goto UpdateTime;
}
// options: ClientID, ORO (Option-Request-Option), IA_PD, elapsed time
// ORO options: DNS_SERVERS, IA_PD
usOptionLength = (USHORT)(2 * sizeof(USHORT));
//usOptionLength = (USHORT)(pDhcpV6OptionModule->uNumOfOptionsEnabled * sizeof(USHORT));
uInfoRequestLength = sizeof(DHCPV6_MESSAGE_HEADER) + // Fixed size header
(sizeof(DHCPV6_OPTION_HEADER) * 4) + // ClientID, ORO, IA_PD, elapsed t
(4 + pDhcpV6Adapt->cPhysicalAddr) + // DUID (ClientID) length
usOptionLength + IA_PD_OPTION_LEN + 2; // ORO + IA_PD + elapsed time
pDhcpV6MessageHeader = AllocDHCPV6Mem(uInfoRequestLength);
if (!pDhcpV6MessageHeader) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_LOCK_ERROR(dwError);
}
memset(pDhcpV6MessageHeader, 0, uInfoRequestLength);
pDhcpV6MessageHeader->MessageType = DHCPV6_MESSAGE_TYPE_SOLICIT;
dwError = DhcpV6GenerateRandom(pDhcpV6Adapt->ucTransactionID, sizeof(pDhcpV6Adapt->ucTransactionID));
BAIL_ON_LOCK_ERROR(dwError);
memcpy(
pDhcpV6MessageHeader->TransactionID,
pDhcpV6Adapt->ucTransactionID,
sizeof(pDhcpV6MessageHeader->TransactionID)
);
pucOptionHeader = (PUCHAR)(&pDhcpV6MessageHeader[1]);
pDhcpV6Adapt->DhcpV6State = dhcpv6_state_solicit;
dwError = DhcpV6OptionMgrCreateOptionRequestPD(
pDhcpV6Adapt,
pDhcpV6OptionModule,
pucOptionHeader,
sizeof(DHCPV6_OPTION_HEADER) + usOptionLength
);
BAIL_ON_LOCK_ERROR(dwError);
DEBUGMSG(1, (TEXT("DhcpV6: Sending Solicit message\r\n")));
WSABuf.len = uInfoRequestLength;
WSABuf.buf = (PUCHAR)pDhcpV6MessageHeader;
dwError = WSASendTo(
pDhcpV6Adapt->Socket,
&WSABuf,
1,
&uByteSent,
0,
(LPSOCKADDR)&MCastSockAddr,
sizeof(MCastSockAddr),
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
UpdateTime:
dwError = DhcpV6TimerSetTimer(
gpDhcpV6TimerModule,
pDhcpV6Adapt,
DHCPV6MessageMgrTimerCallbackRoutine,
pDhcpV6Adapt,
pDhcpV6Adapt->uRetransmissionTimeout
);
BAIL_ON_LOCK_ERROR(dwError);
CalculateRexmitTimeout(pDhcpV6Adapt);
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
success:
if (pDhcpV6MessageHeader) {
FreeDHCPV6Mem(pDhcpV6MessageHeader);
}
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_TRACE, ("End Information Request"));
return dwError;
lock:
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_ERROR, ("FAILED Information Request with Error: %!status!", dwError));
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
goto success;
}
//
// Lock: None
//
DWORD
DHCPV6MessageMgrRequestMessage(
PDHCPV6_ADAPT pDhcpV6Adapt
)
{
DWORD dwError = 0;
ULONG uInfoRequestLength = 0;
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule = &pDhcpV6Adapt->DhcpV6OptionModule;
PDHCPV6_MESSAGE_HEADER pDhcpV6MessageHeader = NULL;
PUCHAR pucOptionHeader = NULL;
USHORT usOptionLength = 0;
WSABUF WSABuf = { 0 };
ULONG uByteSent = 0;
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_TRACE, ("Begin Information Request on Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));
AcquireExclusiveLock(&pDhcpV6Adapt->RWLock);
if (pDhcpV6Adapt->DhcpV6State == dhcpv6_state_deinit) {
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
return 0;
}
if (DHCPV6_MEDIA_DISC_FL & pDhcpV6Adapt->Flags) {
goto UpdateTime;
}
// options: ClientID, ORO (Option-Request-Option), IA_PD, elapsed time
// ORO options: DNS_SERVERS, IA_PD
usOptionLength = (USHORT)(2 * sizeof(USHORT));
//usOptionLength = (USHORT)(pDhcpV6OptionModule->uNumOfOptionsEnabled * sizeof(USHORT));
uInfoRequestLength = sizeof(DHCPV6_MESSAGE_HEADER) + // Fixed size header
(sizeof(DHCPV6_OPTION_HEADER) * 4) + // ClientID, ORO, IA_PD, elapsed t
(4 + pDhcpV6Adapt->cPhysicalAddr) + // DUID (ClientID) length
usOptionLength + IA_PD_OPTION_LEN + 2; // ORO + IA_PD + elapsed time
uInfoRequestLength += sizeof(DHCPV6_OPTION_HEADER) + IA_PREFIX_OPTION_LEN;
if (pDhcpV6Adapt->pServerID) {
uInfoRequestLength += sizeof(DHCPV6_OPTION_HEADER) +
pDhcpV6Adapt->cServerID;
}
pDhcpV6MessageHeader = AllocDHCPV6Mem(uInfoRequestLength);
if (!pDhcpV6MessageHeader) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_LOCK_ERROR(dwError);
}
memset(pDhcpV6MessageHeader, 0, uInfoRequestLength);
pDhcpV6MessageHeader->MessageType = DHCPV6_MESSAGE_TYPE_REQUEST;
dwError = DhcpV6GenerateRandom(pDhcpV6Adapt->ucTransactionID, sizeof(pDhcpV6Adapt->ucTransactionID));
BAIL_ON_LOCK_ERROR(dwError);
memcpy(
pDhcpV6MessageHeader->TransactionID,
pDhcpV6Adapt->ucTransactionID,
sizeof(pDhcpV6MessageHeader->TransactionID)
);
pucOptionHeader = (PUCHAR)(&pDhcpV6MessageHeader[1]);
pDhcpV6Adapt->DhcpV6State = dhcpv6_state_srequest;
dwError = DhcpV6OptionMgrCreateOptionRequestPD(
pDhcpV6Adapt,
pDhcpV6OptionModule,
pucOptionHeader,
sizeof(DHCPV6_OPTION_HEADER) + usOptionLength
);
BAIL_ON_LOCK_ERROR(dwError);
DEBUGMSG(1, (TEXT("DhcpV6: Sending Request message\r\n")));
WSABuf.len = uInfoRequestLength;
WSABuf.buf = (PUCHAR)pDhcpV6MessageHeader;
dwError = WSASendTo(
pDhcpV6Adapt->Socket,
&WSABuf,
1,
&uByteSent,
0,
(LPSOCKADDR)&MCastSockAddr,
sizeof(MCastSockAddr),
NULL,
NULL
);
BAIL_ON_LOCK_ERROR(dwError);
UpdateTime:
pDhcpV6Adapt->uReXmits++;
dwError = DhcpV6TimerSetTimer(
gpDhcpV6TimerModule,
pDhcpV6Adapt,
DHCPV6MessageMgrTimerCallbackRoutine,
pDhcpV6Adapt,
pDhcpV6Adapt->uRetransmissionTimeout
);
BAIL_ON_LOCK_ERROR(dwError);
CalculateRexmitTimeout(pDhcpV6Adapt);
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
success:
if (pDhcpV6MessageHeader) {
FreeDHCPV6Mem(pDhcpV6MessageHeader);
}
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_TRACE, ("End Information Request"));
return dwError;
lock:
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_ERROR, ("FAILED Information Request with Error: %!status!", dwError));
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
goto success;
}
//
// Lock: None
//
DWORD
DHCPV6MessageMgrRenewMessage(
PDHCPV6_ADAPT pDhcpV6Adapt
)
{
DWORD dwError = 0;
ULONG uInfoRequestLength = 0;
PDHCPV6_OPTION_MODULE pDhcpV6OptionModule = &pDhcpV6Adapt->DhcpV6OptionModule;
PDHCPV6_MESSAGE_HEADER pDhcpV6MessageHeader = NULL;
PUCHAR pucOptionHeader = NULL;
USHORT usOptionLength = 0;
WSABUF WSABuf = { 0 };
ULONG uByteSent = 0;
ULONG ReXmitTime;
DhcpV6Trace(DHCPV6_SEND, DHCPV6_LOG_LEVEL_TRACE, ("Begin Information Request on Adapt: %d", pDhcpV6Adapt->dwIPv6IfIndex));
AcquireExclusiveLock(&pDhcpV6Adapt->RWLock);
if (pDhcpV6Adapt->DhcpV6State == dhcpv6_state_deinit) {
ReleaseExclusiveLock(&pDhcpV6Adapt->RWLock);
DereferenceDHCPV6Adapt(pDhcpV6Adapt);
return 0;
}
if (DHCPV6_MEDIA_DISC_FL & pDhcpV6Adapt->Flags) {
goto UpdateTime;
}
// options: ClientID, ORO (Option-Request-Option), IA_PD, elapsed time
// ORO options: DNS_SERVERS, IA_PD
usOptionLength = (USHORT)(2 * sizeof(USHORT));
//usOptionLength = (USHORT)(pDhcpV6OptionModule->uNumOfOptionsEnabled * sizeof(USHORT));
uInfoRequestLength = sizeof(DHCPV6_MESSAGE_HEADER) + // Fixed size header
(sizeof(DHCPV6_OPTION_HEADER) * 4) + // ClientID, ORO, IA_PD, elapsed t
(4 + pDhcpV6Adapt->cPhysicalAddr) + // DUID (ClientID) length
usOptionLength + IA_PD_OPTION_LEN + 2; // ORO + IA_PD + elapsed time
uInfoRequestLength += sizeof(DHCPV6_OPTION_HEADER) + IA_PREFIX_OPTION_LEN;
if (pDhcpV6Adapt->pServerID) {
uInfoRequestLength += sizeof(DHCPV6_OPTION_HEADER) +
pDhcpV6Adapt->cServerID;
}
pDhcpV6MessageHeader = AllocDHCPV6Mem(uInfoRequestLength);
if (!pDhcpV6MessageHeader) {
dwError = ERROR_OUTOFMEMORY;
BAIL_ON_LOCK_ERROR(dwError);
}
memset(pDhcpV6MessageHeader, 0, uInfoRequestLength);
pDhcpV6MessageHeader->MessageType = DHCPV6_MESSAGE_TYPE_RENEW;
dwError = DhcpV6GenerateRandom(pDhcpV6Adapt->ucTransactionID, sizeof(pDhcpV6Adapt->ucTransactionID));
BAIL_ON_LOCK_ERROR(dwError);
memcpy(
pDhcpV6MessageHeader->TransactionID,
pDhcpV6Adapt->ucTransactionID,
sizeof(pDhcpV6MessageHeader->TransactionID)
);
pucOptionHeader = (PUCHAR)(&pDhcpV6MessageHeader[1]);
pDhcpV6Adapt->DhcpV6State = dhcpv6_state_T1;
dwError = DhcpV6OptionMgrCreateOptionRequestPD(
pDhcpV6Adapt,
pDhcpV6OptionModule,
pucOptionHeader,
sizeof(DHCPV6_OPTION_HEADER) + usOptionLength
);
BAIL_ON_LOCK_ERROR(dwError);
DEBUGMSG(1, (TEXT("DhcpV6: Sending Renew message\r\n")));
WSABuf.len = uInfoRequestLength;
WSABuf.buf = (PUCHAR)pDhcpV6MessageHeader;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -