Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

377 lines
8.6 KiB

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
loopmgr.c
Abstract:
This module contains all of the code to drive the
Loop Manager of IPSecSPD Service.
Author:
abhisheV 30-September-1999
Environment
User Level: Win32
Revision History:
--*/
#include "precomp.h"
enum {
SERVICE_STOP_EVENT = 0,
INTERFACE_CHANGE_EVENT,
NEW_LOCAL_POLICY_EVENT,
NEW_DS_POLICY_EVENT,
FORCED_POLICY_RELOAD_EVENT,
WAIT_EVENT_COUNT,
};
DWORD
ServiceWait(
)
{
DWORD dwError = 0;
HANDLE hWaitForEvents[WAIT_EVENT_COUNT];
BOOL bDoneWaiting = FALSE;
DWORD dwWaitMilliseconds = 0;
DWORD dwStatus = 0;
time_t LastTimeOutTime = 0;
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
IPSECSVC_SUCCESSFUL_START,
NULL,
TRUE,
TRUE
);
hWaitForEvents[SERVICE_STOP_EVENT] = ghServiceStopEvent;
hWaitForEvents[INTERFACE_CHANGE_EVENT] = GetInterfaceChangeEvent();
hWaitForEvents[NEW_LOCAL_POLICY_EVENT] = ghNewLocalPolicyEvent;
hWaitForEvents[NEW_DS_POLICY_EVENT] = ghNewDSPolicyEvent;
hWaitForEvents[FORCED_POLICY_RELOAD_EVENT] = ghForcedPolicyReloadEvent;
//
// First load the default main mode policy.
//
(VOID) LoadDefaultISAKMPInformation(
gpszDefaultISAKMPPolicyDN
);
//
// Initialize Policy State Block.
//
InitializePolicyStateBlock(
gpIpsecPolicyState
);
//
// Call the Polling Manager for the first time.
//
(VOID) StartStatePollingManager(
gpIpsecPolicyState
);
NotifyIpsecPolicyChange();
ComputeRelativePollingTime(
LastTimeOutTime,
TRUE,
&dwWaitMilliseconds
);
time(&LastTimeOutTime);
while (!bDoneWaiting) {
dwStatus = WaitForMultipleObjects(
WAIT_EVENT_COUNT,
hWaitForEvents,
FALSE,
dwWaitMilliseconds
);
PADeleteInUsePolicies();
switch (dwStatus) {
case SERVICE_STOP_EVENT:
dwError = ERROR_SUCCESS;
bDoneWaiting = TRUE;
break;
case INTERFACE_CHANGE_EVENT:
(VOID) OnInterfaceChangeEvent(
);
(VOID) IKEInterfaceChange();
break;
case NEW_LOCAL_POLICY_EVENT:
ResetEvent(ghNewLocalPolicyEvent);
if ((gpIpsecPolicyState->dwCurrentState != POLL_STATE_DS_DOWNLOADED) &&
(gpIpsecPolicyState->dwCurrentState != POLL_STATE_CACHE_DOWNLOADED)) {
(VOID) ProcessLocalPolicyPollState(
gpIpsecPolicyState
);
NotifyIpsecPolicyChange();
}
break;
case NEW_DS_POLICY_EVENT:
ResetEvent(ghNewDSPolicyEvent);
(VOID) OnPolicyChanged(
gpIpsecPolicyState
);
NotifyIpsecPolicyChange();
break;
case FORCED_POLICY_RELOAD_EVENT:
ResetEvent(ghForcedPolicyReloadEvent);
(VOID) OnPolicyChanged(
gpIpsecPolicyState
);
NotifyIpsecPolicyChange();
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
PASTORE_FORCED_POLICY_RELOAD,
NULL,
TRUE,
TRUE
);
break;
case WAIT_TIMEOUT:
time(&LastTimeOutTime);
(VOID) OnPolicyPoll(
gpIpsecPolicyState
);
break;
case WAIT_FAILED:
dwError = GetLastError();
bDoneWaiting = TRUE;
break;
default:
dwError = ERROR_INVALID_EVENT_COUNT;
bDoneWaiting = TRUE;
break;
}
ComputeRelativePollingTime(
LastTimeOutTime,
FALSE,
&dwWaitMilliseconds
);
}
if (!dwError) {
AuditEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
IPSECSVC_SUCCESSFUL_SHUTDOWN,
NULL,
TRUE,
TRUE
);
}
else {
AuditOneArgErrorEvent(
SE_CATEGID_POLICY_CHANGE,
SE_AUDITID_IPSEC_POLICY_CHANGED,
IPSECSVC_ERROR_SHUTDOWN,
dwError,
FALSE,
TRUE
);
}
return (dwError);
}
VOID
ComputeRelativePollingTime(
time_t LastTimeOutTime,
BOOL bInitialLoad,
PDWORD pWaitMilliseconds
)
{
DWORD WaitMilliseconds = 0;
DWORD DSReconnectMilliseconds = 0;
time_t NextTimeOutTime = 0;
time_t PresentTime = 0;
long WaitSeconds = gDefaultPollingInterval;
WaitMilliseconds = gCurrentPollingInterval * 1000;
if (!WaitMilliseconds) {
WaitMilliseconds = INFINITE;
}
DSReconnectMilliseconds = gdwDSConnectivityCheck*60*1000;
if ((gpIpsecPolicyState->dwCurrentState != POLL_STATE_DS_DOWNLOADED) &&
(gpIpsecPolicyState->dwCurrentState != POLL_STATE_LOCAL_DOWNLOADED)) {
if (WaitMilliseconds > DSReconnectMilliseconds) {
WaitMilliseconds = DSReconnectMilliseconds;
}
}
if (!bInitialLoad && WaitMilliseconds != INFINITE) {
//
// LastTimeOutTime is the snapshot time value in the past when
// we timed out waiting for multiple events.
// Ideally, the time for the next time out, NextTimeOutTime, is
// the time value in future which is sum of the last time when
// we timed out + the current waiting time value.
//
NextTimeOutTime = LastTimeOutTime + (WaitMilliseconds/1000);
//
// However, the last time we may not have timed out waiting
// for multiple events but rather came out because one of the
// events other than WAIT_TIMEOUT happened.
// However, on that event we may not have done a policy
// poll to figure out whether there was a policy change or
// not. If we again wait for WaitMilliseconds, then we are
// un-knowingly making our net time for policy poll greater
// than the alloted time interval value = WaitMilliseconds.
// So, we need to adjust the WaitMilliseconds to such a value
// that no matter what happens, we always do a policy poll
// atmost every WaitMilliseconds time interval value.
// The current time is PresentTime.
//
time(&PresentTime);
WaitSeconds = (long) (NextTimeOutTime - PresentTime);
if (WaitSeconds < 0) {
WaitMilliseconds = 0;
}
else {
WaitMilliseconds = WaitSeconds * 1000;
}
}
*pWaitMilliseconds = WaitMilliseconds;
}
VOID
NotifyIpsecPolicyChange(
)
{
PulseEvent(ghPolicyChangeNotifyEvent);
SendPschedIoctl();
ResetEvent(ghPolicyChangeNotifyEvent);
return;
}
VOID
SendPschedIoctl(
)
{
HANDLE hPschedDriverHandle = NULL;
ULONG uBytesReturned = 0;
BOOL bIOStatus = FALSE;
#define DriverName TEXT("\\\\.\\PSCHED")
#define IOCTL_PSCHED_ZAW_EVENT CTL_CODE( \
FILE_DEVICE_NETWORK, \
20, \
METHOD_BUFFERED, \
FILE_ANY_ACCESS \
)
hPschedDriverHandle = CreateFile(
DriverName,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL
);
if (hPschedDriverHandle != INVALID_HANDLE_VALUE) {
bIOStatus = DeviceIoControl(
hPschedDriverHandle,
IOCTL_PSCHED_ZAW_EVENT,
NULL,
0,
NULL,
0,
&uBytesReturned,
NULL
);
CloseHandle(hPschedDriverHandle);
}
}
VOID
PADeleteInUsePolicies(
)
{
DWORD dwError = 0;
dwError = PADeleteInUseMMPolicies();
dwError = PADeleteInUseMMAuthMethods();
dwError = PADeleteInUseQMPolicies();
return;
}