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.

285 lines
6.0 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. NsTimer.c
  5. Abstract:
  6. IpSec NAT shim timer management
  7. Author:
  8. Jonathan Burstein (jonburs) 11-July-2001
  9. Environment:
  10. Kernel mode
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. //
  16. // Defines the interval at which the timer fires, in 100-nanosecond intervals
  17. //
  18. #define NS_TIMER_INTERVAL (60 * 1000 * 1000 * 10)
  19. //
  20. // Return-value of KeQueryTimeIncrement, used for normalizing tick-counts
  21. //
  22. ULONG NsTimeIncrement;
  23. //
  24. // DPC object for NsTimerRoutine
  25. //
  26. KDPC NsTimerDpcObject;
  27. //
  28. // Timer object for NsTimerRoutine
  29. //
  30. KTIMER NsTimerObject;
  31. //
  32. // Protocol timeouts
  33. //
  34. ULONG NsTcpTimeoutSeconds;
  35. ULONG NsTcpTimeWaitSeconds;
  36. ULONG NsUdpTimeoutSeconds;
  37. //
  38. // Function Prototypes
  39. //
  40. VOID
  41. NsTimerRoutine(
  42. PKDPC Dpc,
  43. PVOID DeferredContext,
  44. PVOID SystemArgument1,
  45. PVOID SystemArgument2
  46. );
  47. NTSTATUS
  48. NsInitializeTimerManagement(
  49. VOID
  50. )
  51. /*++
  52. Routine Description:
  53. This routine is invoked to initialize the timer management module.
  54. Arguments:
  55. none.
  56. Return Value:
  57. NTSTATUS.
  58. --*/
  59. {
  60. LARGE_INTEGER DueTime;
  61. CALLTRACE(("NsInitializeTimerManagement\n"));
  62. NsTimeIncrement = KeQueryTimeIncrement();
  63. KeInitializeDpc(&NsTimerDpcObject, NsTimerRoutine, NULL);
  64. KeInitializeTimer(&NsTimerObject);
  65. DueTime.LowPart = NS_TIMER_INTERVAL;
  66. DueTime.HighPart = 0;
  67. DueTime = RtlLargeIntegerNegate(DueTime);
  68. KeSetTimerEx(
  69. &NsTimerObject,
  70. DueTime,
  71. NS_TIMER_INTERVAL / 10000,
  72. &NsTimerDpcObject
  73. );
  74. NsTcpTimeoutSeconds = 60 * 60 * 24;
  75. NsTcpTimeWaitSeconds = 60 * 4;
  76. NsUdpTimeoutSeconds = 60;
  77. return STATUS_SUCCESS;
  78. } // NsInitializeTimerManagement
  79. VOID
  80. NsShutdownTimerManagement(
  81. VOID
  82. )
  83. /*++
  84. Routine Description:
  85. This routine is invoked to cleanup the timer management module.
  86. Arguments:
  87. none.
  88. Return Value:
  89. none.
  90. --*/
  91. {
  92. CALLTRACE(("NsShutdownTimerManagement\n"));
  93. KeCancelTimer(&NsTimerObject);
  94. } // NsShutdownTimerManagement
  95. VOID
  96. NsTimerRoutine(
  97. PKDPC Dpc,
  98. PVOID DeferredContext,
  99. PVOID SystemArgument1,
  100. PVOID SystemArgument2
  101. )
  102. /*++
  103. Routine Description:
  104. This routine is invoked periodically to garbage-collect expired mappings.
  105. Arguments:
  106. Dpc - associated DPC object
  107. DeferredContext - unused.
  108. SystemArgument1 - unused.
  109. SystemArgument2 - unused.
  110. Return Value:
  111. none.
  112. --*/
  113. {
  114. LONG64 CurrentTime;
  115. KIRQL Irql;
  116. PLIST_ENTRY Link;
  117. PNS_CONNECTION_ENTRY pConnectionEntry;
  118. PNS_ICMP_ENTRY pIcmpEntry;
  119. LONG64 Timeout;
  120. LONG64 TcpMinAccessTime;
  121. LONG64 TcpMinTimeWaitExpiryTime;
  122. LONG64 UdpMinAccessTime;
  123. TRACE(TIMER, ("NsTimerRoutine\n"));
  124. //
  125. // Compute the minimum values allowed in TCP/UDP 'LastAccessTime' fields;
  126. // any mappings last accessed before these thresholds will be eliminated.
  127. //
  128. KeQueryTickCount((PLARGE_INTEGER)&CurrentTime);
  129. TcpMinAccessTime = CurrentTime - SECONDS_TO_TICKS(NsTcpTimeoutSeconds);
  130. TcpMinTimeWaitExpiryTime =
  131. CurrentTime - SECONDS_TO_TICKS(NsTcpTimeWaitSeconds);
  132. UdpMinAccessTime = CurrentTime - SECONDS_TO_TICKS(NsUdpTimeoutSeconds);
  133. //
  134. // Clean out expired connection entries,
  135. // using the above precomputed minimum access times
  136. //
  137. KeAcquireSpinLock(&NsConnectionLock, &Irql);
  138. for (Link = NsConnectionList.Flink;
  139. Link != &NsConnectionList;
  140. Link = Link->Flink)
  141. {
  142. pConnectionEntry = CONTAINING_RECORD(Link, NS_CONNECTION_ENTRY, Link);
  143. //
  144. // See if the connection has expired
  145. //
  146. KeAcquireSpinLockAtDpcLevel(&pConnectionEntry->Lock);
  147. if (!NS_CONNECTION_EXPIRED(pConnectionEntry))
  148. {
  149. //
  150. // The entry is not explicitly marked for expiration;
  151. // see if its last access time is too long ago
  152. //
  153. if (NS_PROTOCOL_TCP == pConnectionEntry->ucProtocol)
  154. {
  155. if (pConnectionEntry->l64AccessOrExpiryTime >= TcpMinAccessTime)
  156. {
  157. KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock);
  158. continue;
  159. }
  160. }
  161. else if (pConnectionEntry->l64AccessOrExpiryTime >= UdpMinAccessTime)
  162. {
  163. KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock);
  164. continue;
  165. }
  166. }
  167. else if (NS_CONNECTION_FIN(pConnectionEntry)
  168. && pConnectionEntry->l64AccessOrExpiryTime >= TcpMinTimeWaitExpiryTime)
  169. {
  170. //
  171. // This connection was marked as expired because FINs were
  172. // seen in both directions, but has not yet left the time-wait
  173. // period.
  174. //
  175. KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock);
  176. continue;
  177. }
  178. KeReleaseSpinLockFromDpcLevel(&pConnectionEntry->Lock);
  179. //
  180. // The entry has expired; remove it
  181. //
  182. Link = Link->Blink;
  183. NsDeleteConnectionEntry(pConnectionEntry);
  184. }
  185. KeReleaseSpinLockFromDpcLevel(&NsConnectionLock);
  186. //
  187. // Traverse the ICMP list and remove each expired entry.
  188. //
  189. KeAcquireSpinLockAtDpcLevel(&NsIcmpLock);
  190. for (Link = NsIcmpList.Flink;
  191. Link != &NsIcmpList;
  192. Link = Link->Flink)
  193. {
  194. pIcmpEntry = CONTAINING_RECORD(Link, NS_ICMP_ENTRY, Link);
  195. if (pIcmpEntry->l64LastAccessTime>= UdpMinAccessTime) { continue; }
  196. Link = Link->Blink;
  197. RemoveEntryList(&pIcmpEntry->Link);
  198. FREE_ICMP_BLOCK(pIcmpEntry);
  199. }
  200. KeReleaseSpinLock(&NsIcmpLock, Irql);
  201. } // NsTimerRoutine