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.

294 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. NsPacketRoutines.h
  5. Abstract:
  6. This file contains the code for the packet-routines used for
  7. connection routines.
  8. The inbound routines have the exact same logic as the outbound routines.
  9. However, for reasons of efficiency the two are separate routines,
  10. to avoid the cost of indexing on 'NsDirection' for every packet
  11. processed.
  12. To avoid duplicating the code, then, this header file consolidates the code
  13. in one location. This file is included twice in NsPacket.c, and before each
  14. inclusion, either 'NS_INBOUND' or 'NS_OUTBOUND' is defined.
  15. This causes the compiler to generate the code for separate functions,
  16. as desired, while avoiding the unpleasantness of code-duplication.
  17. Each routine is invoked from 'NsProcess*Packet' at dispatch level
  18. with no locks held and with a reference acquired for the connection
  19. entry.
  20. Author:
  21. Jonathan Burstein (jonburs) 20-July-2001
  22. Environment:
  23. Kernel mode
  24. Revision History:
  25. --*/
  26. #ifdef NS_INBOUND
  27. #define NS_POSITIVE NsInboundDirection
  28. #define NS_NEGATIVE NsOutboundDirection
  29. #define NS_TCP_ROUTINE NsInboundTcpPacketRoutine
  30. #define NS_UDP_ROUTINE NsInboundUdpPacketRoutine
  31. #define NS_TCP_TRANSLATE_PORT_ROUTINE NsInboundTcpTranslatePortPacketRoutine
  32. #define NS_UDP_TRANSLATE_PORT_ROUTINE NsInboundUdpTranslatePortPacketRoutine
  33. #define NS_PACKET_FIN NS_CONNECTION_FLAG_IB_FIN
  34. #define NS_TRANSLATE_PORTS_TCP() \
  35. pContext->pTcpHeader->SourcePort = \
  36. CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsOutboundDirection])
  37. #define NS_TRANSLATE_PORTS_UDP() \
  38. pContext->pUdpHeader->SourcePort = \
  39. CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsOutboundDirection])
  40. #else
  41. #define NS_POSITIVE NsOutboundDirection
  42. #define NS_NEGATIVE NsInboundDirection
  43. #define NS_TCP_ROUTINE NsOutboundTcpPacketRoutine
  44. #define NS_UDP_ROUTINE NsOutboundUdpPacketRoutine
  45. #define NS_TCP_TRANSLATE_PORT_ROUTINE NsOutboundTcpTranslatePortPacketRoutine
  46. #define NS_UDP_TRANSLATE_PORT_ROUTINE NsOutboundUdpTranslatePortPacketRoutine
  47. #define NS_PACKET_FIN NS_CONNECTION_FLAG_OB_FIN
  48. #define NS_TRANSLATE_PORTS_TCP() \
  49. pContext->pTcpHeader->DestinationPort = \
  50. CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsInboundDirection])
  51. #define NS_TRANSLATE_PORTS_UDP() \
  52. pContext->pUdpHeader->DestinationPort = \
  53. CONNECTION_REMOTE_PORT(pConnection->ulPortKey[NsInboundDirection])
  54. #endif
  55. NTSTATUS
  56. FASTCALL
  57. NS_TCP_ROUTINE(
  58. PNS_CONNECTION_ENTRY pConnection,
  59. PNS_PACKET_CONTEXT pContext
  60. )
  61. {
  62. KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
  63. //
  64. // Update the connection state based on the flags in the packet:
  65. //
  66. // When a RST is seen, mark the connection for deletion
  67. // When a FIN is seen, mark the connection appropriately
  68. // When both FINs have been seen, mark the connection for deletion
  69. //
  70. if (TCP_FLAG(pContext->pTcpHeader, RST))
  71. {
  72. pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
  73. }
  74. else if (TCP_FLAG(pContext->pTcpHeader, FIN))
  75. {
  76. pConnection->ulFlags |= NS_PACKET_FIN;
  77. if (NS_CONNECTION_FIN(pConnection))
  78. {
  79. pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
  80. //
  81. // Perform a final update of the timestamp for the connection.
  82. // From this point on the timestamp is used to determine when
  83. // this connection has left the time-wait state.
  84. //
  85. KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
  86. }
  87. }
  88. //
  89. // Update the timestamp for the connection (if this connection is not in
  90. // a timer-wait state -- i.e., both FINs have not been seen).
  91. //
  92. if (!NS_CONNECTION_FIN(pConnection))
  93. {
  94. KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
  95. }
  96. KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
  97. //
  98. // Periodically resplay the connection entry
  99. //
  100. NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
  101. return STATUS_SUCCESS;
  102. } // NS_TCP_ROUTINE
  103. NTSTATUS
  104. FASTCALL
  105. NS_UDP_ROUTINE(
  106. PNS_CONNECTION_ENTRY pConnection,
  107. PNS_PACKET_CONTEXT pContext
  108. )
  109. {
  110. KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
  111. //
  112. // Update the timestamp for the connection
  113. //
  114. KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
  115. KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
  116. //
  117. // Periodically resplay the connection entry
  118. //
  119. NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
  120. return STATUS_SUCCESS;
  121. } // NS_UDP_ROUTINE
  122. NTSTATUS
  123. FASTCALL
  124. NS_TCP_TRANSLATE_PORT_ROUTINE(
  125. PNS_CONNECTION_ENTRY pConnection,
  126. PNS_PACKET_CONTEXT pContext
  127. )
  128. {
  129. ULONG ulChecksumDelta;
  130. //
  131. // Translate the port information in the packet
  132. //
  133. NS_TRANSLATE_PORTS_TCP();
  134. //
  135. // Update the protocol checksum
  136. //
  137. CHECKSUM_XFER(ulChecksumDelta, pContext->pTcpHeader->Checksum);
  138. ulChecksumDelta += pConnection->ulProtocolChecksumDelta[NS_POSITIVE];
  139. CHECKSUM_FOLD(ulChecksumDelta);
  140. CHECKSUM_XFER(pContext->pTcpHeader->Checksum, ulChecksumDelta);
  141. KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
  142. //
  143. // Update the connection state based on the flags in the packet:
  144. //
  145. // When a RST is seen, mark the connection for deletion
  146. // When a FIN is seen, mark the connection appropriately
  147. // When both FINs have been seen, mark the connection for deletion
  148. //
  149. if (TCP_FLAG(pContext->pTcpHeader, RST))
  150. {
  151. pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
  152. }
  153. else if (TCP_FLAG(pContext->pTcpHeader, FIN))
  154. {
  155. pConnection->ulFlags |= NS_PACKET_FIN;
  156. if (NS_CONNECTION_FIN(pConnection))
  157. {
  158. pConnection->ulFlags |= NS_CONNECTION_FLAG_EXPIRED;
  159. //
  160. // Perform a final update of the timestamp for the connection.
  161. // From this point on the timestamp is used to determine when
  162. // this connection has left the time-wait state.
  163. //
  164. KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
  165. }
  166. }
  167. //
  168. // Update the timestamp for the connection (if this connection is not in
  169. // a timer-wait state -- i.e., both FINs have not been seen).
  170. //
  171. if (!NS_CONNECTION_FIN(pConnection))
  172. {
  173. KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
  174. }
  175. KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
  176. //
  177. // Periodically resplay the connection entry
  178. //
  179. NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
  180. return STATUS_SUCCESS;
  181. } // NS_TCP_TRANSLATE_PORT_ROUTINE
  182. NTSTATUS
  183. FASTCALL
  184. NS_UDP_TRANSLATE_PORT_ROUTINE(
  185. PNS_CONNECTION_ENTRY pConnection,
  186. PNS_PACKET_CONTEXT pContext
  187. )
  188. {
  189. ULONG ulChecksumDelta;
  190. //
  191. // Translate the port information in the packet
  192. //
  193. NS_TRANSLATE_PORTS_UDP();
  194. //
  195. // Update the protocol checksum if the original packet contained
  196. // a checksum (UDP checksum is optional)
  197. //
  198. if (0 != pContext->pUdpHeader->Checksum)
  199. {
  200. CHECKSUM_XFER(ulChecksumDelta, pContext->pUdpHeader->Checksum);
  201. ulChecksumDelta += pConnection->ulProtocolChecksumDelta[NS_POSITIVE];
  202. CHECKSUM_FOLD(ulChecksumDelta);
  203. CHECKSUM_XFER(pContext->pUdpHeader->Checksum, ulChecksumDelta);
  204. }
  205. KeAcquireSpinLockAtDpcLevel(&pConnection->Lock);
  206. //
  207. // Update the timestamp for the connection
  208. //
  209. KeQueryTickCount((PLARGE_INTEGER)&pConnection->l64AccessOrExpiryTime);
  210. KeReleaseSpinLockFromDpcLevel(&pConnection->Lock);
  211. //
  212. // Periodically resplay the connection entry
  213. //
  214. NsTryToResplayConnectionEntry(pConnection, NS_POSITIVE);
  215. return STATUS_SUCCESS;
  216. } // NS_UDP_TRANSLATE_PORT_ROUTINE
  217. #undef NS_POSITIVE
  218. #undef NS_NEGATIVE
  219. #undef NS_TCP_ROUTINE
  220. #undef NS_UDP_ROUTINE
  221. #undef NS_TCP_TRANSLATE_PORT_ROUTINE
  222. #undef NS_UDP_TRANSLATE_PORT_ROUTINE
  223. #undef NS_PACKET_FIN
  224. #undef NS_TRANSLATE_PORTS_TCP
  225. #undef NS_TRANSLATE_PORTS_UDP