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.

229 lines
6.5 KiB

  1. /*************************************************************************
  2. *
  3. * ignore.c
  4. *
  5. * Ignore duplicate (retry) connections for IPX
  6. *
  7. * Copyright 1998, Microsoft
  8. *
  9. *************************************************************************/
  10. #include <ntddk.h>
  11. #include <tdi.h>
  12. /*
  13. * The following defines are necessary since they are referenced in
  14. * afd.h but defined in sdk/inc/winsock2.h, which we can't include here.
  15. */
  16. #define SG_UNCONSTRAINED_GROUP 0x01
  17. #define SG_CONSTRAINED_GROUP 0x02
  18. #include <afd.h>
  19. #include <isnkrnl.h>
  20. #include <ndis.h>
  21. #include <wsnwlink.h>
  22. #include <winstaw.h>
  23. #define _DEFCHARINFO_
  24. #include <icadd.h>
  25. #include <ctxdd.h>
  26. #include <icaipx.h>
  27. //#include <cxstatus.h>
  28. #include <sdapi.h>
  29. #include <td.h>
  30. #include "tdipx.h"
  31. /*=============================================================================
  32. == External Functions Defined
  33. =============================================================================*/
  34. BOOLEAN IsOnIgnoreList( PTD, PLIST_ENTRY, PTRANSPORT_ADDRESS, ULONG );
  35. VOID AddToIgnoreList( PTD, PLIST_ENTRY, PTRANSPORT_ADDRESS, ULONG );
  36. VOID CleanupIgnoreList( PTD, PLIST_ENTRY );
  37. /*=============================================================================
  38. == Functions Used
  39. =============================================================================*/
  40. NTSTATUS MemoryAllocate( ULONG, PVOID * );
  41. VOID MemoryFree( PVOID );
  42. #define IGNORE_TIMEOUT 15 // 15 seconds
  43. /*
  44. * List of addresses
  45. */
  46. typedef struct _IGNOREADDRESS {
  47. LIST_ENTRY Links;
  48. LARGE_INTEGER TimeOut;
  49. PTRANSPORT_ADDRESS pRemoteAddress;
  50. ULONG RemoteAddressLength;
  51. } IGNOREADDRESS, *PIGNOREADDRESS;
  52. /*******************************************************************************
  53. *
  54. * IsOnIgnoreList
  55. *
  56. * Is this address on the list of recently received addresses?
  57. * This occurs when a client retries a connection packet.
  58. *
  59. * ENTRY:
  60. * pTd (input)
  61. * pointer to TD data structure
  62. * pIgnoreList (input)
  63. * Pointer to address ignore list
  64. * pRemoteAddress (input)
  65. * Pointer to IPX address received
  66. * RemoteAddressLength (input)
  67. * Length in bytes of pRemoteAddress
  68. *
  69. * EXIT:
  70. * STATUS_SUCCESS - no error
  71. *
  72. ******************************************************************************/
  73. BOOLEAN
  74. IsOnIgnoreList(
  75. PTD pTd,
  76. PLIST_ENTRY pIgnoreList,
  77. PTRANSPORT_ADDRESS pRemoteAddress,
  78. ULONG RemoteAddressLength
  79. )
  80. {
  81. PLIST_ENTRY Next;
  82. PLIST_ENTRY Head;
  83. PIGNOREADDRESS pIgnoreAddress;
  84. LARGE_INTEGER CurrentTime;
  85. KeQuerySystemTime( &CurrentTime ); // 100 nanoseconds
  86. TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: searching for %02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x\n",
  87. pRemoteAddress->Address[0].Address[0],
  88. pRemoteAddress->Address[0].Address[1],
  89. pRemoteAddress->Address[0].Address[2],
  90. pRemoteAddress->Address[0].Address[3],
  91. pRemoteAddress->Address[0].Address[4],
  92. pRemoteAddress->Address[0].Address[5],
  93. pRemoteAddress->Address[0].Address[6],
  94. pRemoteAddress->Address[0].Address[7],
  95. pRemoteAddress->Address[0].Address[8],
  96. pRemoteAddress->Address[0].Address[9] ));
  97. /*
  98. * Scan the list of addresses for this one, pruning old addresses.
  99. */
  100. Head = pIgnoreList;
  101. Next = Head->Flink;
  102. while ( Next != Head ) {
  103. pIgnoreAddress = CONTAINING_RECORD( Next, IGNOREADDRESS, Links );
  104. if ( RtlLargeIntegerLessThan( CurrentTime, pIgnoreAddress->TimeOut ) ) {
  105. if ( RemoteAddressLength == pIgnoreAddress->RemoteAddressLength &&
  106. !memcmp( pRemoteAddress, pIgnoreAddress->pRemoteAddress,
  107. RemoteAddressLength ) ) {
  108. TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: matched %x\n", Next ));
  109. return TRUE;
  110. }
  111. Next = Next->Flink;
  112. } else {
  113. TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: removing %x\n", Next ));
  114. RemoveEntryList( Next );
  115. Next = Next->Flink;
  116. InitializeListHead( &pIgnoreAddress->Links );
  117. MemoryFree( pIgnoreAddress );
  118. }
  119. }
  120. TRACE(( pTd->pContext, TC_TD, TT_API3, "TDIPX: no matches\n" ));
  121. return FALSE;
  122. }
  123. /*******************************************************************************
  124. *
  125. * AddToIgnoreList
  126. *
  127. * Add this address to the list of recently received connection packets.
  128. * This list should be cleared frequently.
  129. *
  130. * ENTRY:
  131. * pTd (input)
  132. * pointer to TD data structure
  133. * pIgnoreList (input)
  134. * Pointer to address ignore list
  135. * pRemoteAddress (input)
  136. * Pointer to IPX address
  137. * RemoteAddressLength (input)
  138. * Length in bytes of pRemoteAddress
  139. *
  140. * EXIT:
  141. * none
  142. *
  143. ******************************************************************************/
  144. VOID
  145. AddToIgnoreList(
  146. PTD pTd,
  147. PLIST_ENTRY pIgnoreList,
  148. PTRANSPORT_ADDRESS pRemoteAddress,
  149. ULONG RemoteAddressLength )
  150. {
  151. NTSTATUS Status;
  152. PIGNOREADDRESS pIgnoreAddress;
  153. LARGE_INTEGER CurrentTime;
  154. LARGE_INTEGER TimeOut;
  155. Status = MemoryAllocate( sizeof( IGNOREADDRESS ) + RemoteAddressLength,
  156. &pIgnoreAddress );
  157. if ( !NT_SUCCESS( Status ) ) {
  158. return;
  159. }
  160. pIgnoreAddress->pRemoteAddress = (PTRANSPORT_ADDRESS)(pIgnoreAddress + 1);
  161. pIgnoreAddress->RemoteAddressLength = RemoteAddressLength;
  162. KeQuerySystemTime( &CurrentTime ); // 100 nanoseconds
  163. TimeOut = RtlEnlargedIntegerMultiply( 10000, IGNORE_TIMEOUT * 1000 );
  164. pIgnoreAddress->TimeOut = RtlLargeIntegerAdd( CurrentTime, TimeOut );
  165. memcpy( pIgnoreAddress->pRemoteAddress, pRemoteAddress, RemoteAddressLength );
  166. InsertHeadList( pIgnoreList, &pIgnoreAddress->Links );
  167. TRACE(( pTd->pContext, TC_PD, TT_API3, "TDIPX: adding %x\n", &pIgnoreAddress->Links ));
  168. }
  169. /*******************************************************************************
  170. *
  171. * CleanupIgnoreList
  172. *
  173. * Delete all entries on the list
  174. *
  175. * ENTRY:
  176. * pTd (input)
  177. * pointer to TD data structure
  178. * pIgnoreList (input)
  179. * Pointer to address ignore list
  180. *
  181. * EXIT:
  182. * none
  183. *
  184. ******************************************************************************/
  185. VOID
  186. CleanupIgnoreList( PTD pTd, PLIST_ENTRY pIgnoreList )
  187. {
  188. PIGNOREADDRESS pIgnoreAddress;
  189. while ( !IsListEmpty( pIgnoreList ) ) {
  190. pIgnoreAddress = CONTAINING_RECORD( pIgnoreList->Flink,
  191. IGNOREADDRESS, Links );
  192. RemoveEntryList( &pIgnoreAddress->Links );
  193. InitializeListHead( &pIgnoreAddress->Links );
  194. MemoryFree( pIgnoreAddress );
  195. }
  196. }