Leaked source code of windows server 2003
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.
|
|
/*++
Copyright (c) 1997-2001 Microsoft Corporation
Module Name:
NsTimer.c Abstract:
IpSec NAT shim timer management
Author:
Jonathan Burstein (jonburs) 11-July-2001 Environment:
Kernel mode
Revision History:
--*/
#include "precomp.h"
#pragma hdrstop
//
// Defines the interval at which the timer fires, in 100-nanosecond intervals
//
#define NS_TIMER_INTERVAL (60 * 1000 * 1000 * 10)
//
// Return-value of KeQueryTimeIncrement, used for normalizing tick-counts
//
ULONG NsTimeIncrement;
//
// DPC object for NsTimerRoutine
//
KDPC NsTimerDpcObject;
//
// Timer object for NsTimerRoutine
//
KTIMER NsTimerObject;
//
// Protocol timeouts
//
ULONG NsTcpTimeoutSeconds; ULONG NsTcpTimeWaitSeconds; ULONG NsUdpTimeoutSeconds;
//
// Function Prototypes
//
VOID NsTimerRoutine( PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2 );
NTSTATUS NsInitializeTimerManagement( VOID )
/*++
Routine Description:
This routine is invoked to initialize the timer management module.
Arguments:
none.
Return Value:
NTSTATUS.
--*/
{ LARGE_INTEGER DueTime;
CALLTRACE(("NsInitializeTimerManagement\n")); NsTimeIncrement = KeQueryTimeIncrement(); KeInitializeDpc(&NsTimerDpcObject, NsTimerRoutine, NULL); KeInitializeTimer(&NsTimerObject);
DueTime.LowPart = NS_TIMER_INTERVAL; DueTime.HighPart = 0; DueTime = RtlLargeIntegerNegate(DueTime); KeSetTimerEx( &NsTimerObject, DueTime, NS_TIMER_INTERVAL / 10000, &NsTimerDpcObject );
NsTcpTimeoutSeconds = 60 * 60 * 24; NsTcpTimeWaitSeconds = 60 * 4; NsUdpTimeoutSeconds = 60; return STATUS_SUCCESS; } // NsInitializeTimerManagement
VOID NsShutdownTimerManagement( VOID )
/*++
Routine Description:
This routine is invoked to cleanup the timer management module.
Arguments:
none.
Return Value:
none.
--*/
{ CALLTRACE(("NsShutdownTimerManagement\n")); KeCancelTimer(&NsTimerObject); } // NsShutdownTimerManagement
VOID NsTimerRoutine( PKDPC Dpc, PVOID DeferredContext, PVOID SystemArgument1, PVOID SystemArgument2 )
/*++
Routine Description:
This routine is invoked periodically to garbage-collect expired mappings.
Arguments:
Dpc - associated DPC object
DeferredContext - unused.
SystemArgument1 - unused.
SystemArgument2 - unused.
Return Value:
none.
--*/
{ LONG64 CurrentTime; KIRQL Irql; PLIST_ENTRY Link; PNS_CONNECTION_ENTRY pConnectionEntry; PNS_ICMP_ENTRY pIcmpEntry; LONG64 Timeout; LONG64 TcpMinAccessTime; LONG64 TcpMinTimeWaitExpiryTime; LONG64 UdpMinAccessTime;
TRACE(TIMER, ("NsTimerRoutine\n"));
//
// Compute the minimum values allowed in TCP/UDP 'LastAccessTime' fields;
// any mappings last accessed before these thresholds will be eliminated.
//
KeQueryTickCount((PLARGE_INTEGER)&CurrentTime); TcpMinAccessTime = CurrentTime - SECONDS_TO_TICKS(NsTcpTimeoutSeconds); TcpMinTimeWaitExpiryTime = CurrentTime - SECONDS_TO_TICKS(NsTcpTimeWaitSeconds); UdpMinAccessTime = CurrentTime - SECONDS_TO_TICKS(NsUdpTimeoutSeconds);
//
// Clean out expired connection entries,
// using the above precomputed minimum access times
//
KeAcquireSpinLock(&NsConnectionLock, &Irql); for (Link = NsConnectionList.Flink; Link != &NsConnectionList; Link = Link->Flink) {
pConnectionEntry = CONTAINING_RECORD(Link, NS_CONNECTION_ENTRY, Link); //
// See if the connection has expired
//
KeAcquireSpinLockAtDpcLevel(&pConnectionEntry->Lock); if (!NS_CONNECTION_EXPIRED(pConnectionEntry)) { //
// The entry is not explicitly marked for expiration;
// see if its last access time is too long ago
//
if (NS_PROTOCOL_TCP == pConnectionEntry->ucProtocol) { if (pConnectionEntry->l64AccessOrExpiryTime >= TcpMinAccessTime) { KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock); continue; } } else if (pConnectionEntry->l64AccessOrExpiryTime >= UdpMinAccessTime) { KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock); continue; } } else if (NS_CONNECTION_FIN(pConnectionEntry) && pConnectionEntry->l64AccessOrExpiryTime >= TcpMinTimeWaitExpiryTime) { //
// This connection was marked as expired because FINs were
// seen in both directions, but has not yet left the time-wait
// period.
//
KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock); continue; } KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock);
//
// The entry has expired; remove it
//
Link = Link->Blink; NsDeleteConnectionEntry(pConnectionEntry); } KeReleaseSpinLockFromDpcLevel(&NsConnectionLock);
//
// Traverse the ICMP list and remove each expired entry.
//
KeAcquireSpinLockAtDpcLevel(&NsIcmpLock); for (Link = NsIcmpList.Flink; Link != &NsIcmpList; Link = Link->Flink) { pIcmpEntry = CONTAINING_RECORD(Link, NS_ICMP_ENTRY, Link); if (pIcmpEntry->l64LastAccessTime>= UdpMinAccessTime) { continue; } Link = Link->Blink; RemoveEntryList(&pIcmpEntry->Link); FREE_ICMP_BLOCK(pIcmpEntry); } KeReleaseSpinLock(&NsIcmpLock, Irql);
} // NsTimerRoutine
|