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.

227 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. ipr9x.c
  5. Abstract:
  6. This file contains the implementation of IP Receive buffer
  7. list manager. On Windows ME this is done to avoid
  8. fragmenting the non-paged pool when receive buffers are not
  9. pre-posted by AFVXD.
  10. Author:
  11. Scott Holden (sholden) 30-Apr-2000
  12. --*/
  13. #include "precomp.h"
  14. #include "addr.h"
  15. #include "tcp.h"
  16. #include "tcb.h"
  17. #include "tcprcv.h"
  18. #include "tcpsend.h"
  19. #include "tcpconn.h"
  20. #include "tcpdeliv.h"
  21. #include "tlcommon.h"
  22. #include "tcpipbuf.h"
  23. #include "pplasl.h"
  24. #include "mdl2ndis.h"
  25. HANDLE TcpIprDataPoolSmall = NULL;
  26. HANDLE TcpIprDataPoolMedium = NULL;
  27. HANDLE TcpIprDataPoolLarge = NULL;
  28. #if DBG
  29. ULONG TcpIprAllocs = 0;
  30. ULONG TcpIprFrees = 0;
  31. ULONG TcpIprAllocMisses = 0;
  32. #endif // DBG
  33. //
  34. // The three buffer pool sizes are based on MTU. 576 for PPP, 1500 for ethernet,
  35. // and 8K+ for loopback and ATM. Since for 8K buffers we really need a little
  36. // more than 8K, we will allocate a full three pages
  37. //
  38. #define SMALL_TCP_IPR_BUFFER_SIZE (sizeof(IPRcvBuf) + sizeof(HANDLE) + 576)
  39. #define MEDIUM_TCP_IPR_BUFFER_SIZE (sizeof(IPRcvBuf) + sizeof(HANDLE) + 1500)
  40. #define LARGE_TCP_IPR_BUFFER_SIZE (3 * 4096)
  41. //* UnInitTcpIprPools - Destroys TCP IPRcvBuffer lookaside lists.
  42. //
  43. // Uninitializes the lookasides lists for TCP buffered data.
  44. //
  45. // Input: None.
  46. //
  47. // Returns: None.
  48. //
  49. VOID
  50. UnInitTcpIprPools(VOID)
  51. {
  52. PplDestroyPool(TcpIprDataPoolSmall);
  53. PplDestroyPool(TcpIprDataPoolMedium);
  54. PplDestroyPool(TcpIprDataPoolLarge);
  55. }
  56. //* InitTcpIprPools - Initializes TCP IPRcvBuffer lookaside lists.
  57. //
  58. // Initializes the lookaside lists for buffer data.
  59. //
  60. // Input: None.
  61. //
  62. // Returns: TRUE, if successful, else FALSE.
  63. //
  64. BOOLEAN
  65. InitTcpIprPools(VOID)
  66. {
  67. BOOLEAN Status = TRUE;
  68. TcpIprDataPoolSmall = PplCreatePool(NULL, NULL, 0,
  69. SMALL_TCP_IPR_BUFFER_SIZE, 'BPCT', 512);
  70. if (TcpIprDataPoolSmall == NULL) {
  71. Status = FALSE;
  72. goto done;
  73. }
  74. TcpIprDataPoolMedium = PplCreatePool(NULL, NULL, 0,
  75. MEDIUM_TCP_IPR_BUFFER_SIZE, 'BPCT', 256);
  76. if (TcpIprDataPoolMedium == NULL) {
  77. Status = FALSE;
  78. goto done;
  79. }
  80. TcpIprDataPoolLarge = PplCreatePool(NULL, NULL, 0,
  81. LARGE_TCP_IPR_BUFFER_SIZE, 'BPCT', 64);
  82. if (TcpIprDataPoolLarge == NULL) {
  83. Status = FALSE;
  84. }
  85. done:
  86. if (Status == FALSE) {
  87. UnInitTcpIprPools();
  88. }
  89. return (Status);
  90. }
  91. //* AllocTcpIpr - Allocates the IPRcvBuffer from lookaside lists.
  92. //
  93. // A utility routine to allocate a TCP owned IPRcvBuffer. This routine
  94. // attempts to allocate the RB from an appropriate lookaside list, el
  95. //
  96. // Input: BufferSize - Size of data to buffer.
  97. //
  98. // Returns: Pointer to allocated IPR.
  99. //
  100. IPRcvBuf *
  101. AllocTcpIpr(ULONG BufferSize, ULONG Tag)
  102. {
  103. PCHAR Buffer;
  104. IPRcvBuf *Ipr = NULL;
  105. LOGICAL FromList = FALSE;
  106. ULONG AllocateSize;
  107. HANDLE BufferPool = NULL;
  108. ULONG Depth;
  109. // Real size that we need.
  110. AllocateSize = BufferSize + sizeof(HANDLE) + sizeof(IPRcvBuf);
  111. if (AllocateSize <= LARGE_TCP_IPR_BUFFER_SIZE) {
  112. //
  113. // Pick the buffer pool to allocate from.
  114. //
  115. if (AllocateSize <= SMALL_TCP_IPR_BUFFER_SIZE) {
  116. BufferPool = TcpIprDataPoolSmall;
  117. } else if (AllocateSize <= MEDIUM_TCP_IPR_BUFFER_SIZE) {
  118. BufferPool = TcpIprDataPoolMedium;
  119. } else {
  120. BufferPool = TcpIprDataPoolLarge;
  121. }
  122. Buffer = PplAllocate(BufferPool, &FromList);
  123. } else {
  124. //
  125. // Allocate from NP pool.
  126. //
  127. Buffer = CTEAllocMemLow(AllocateSize, Tag);
  128. }
  129. if (Buffer == NULL) {
  130. goto done;
  131. }
  132. #if DBG
  133. if (FromList == FALSE) {
  134. InterlockedIncrement(&TcpIprAllocMisses);
  135. }
  136. #endif // DBG
  137. // Store buffer pool so we know how to free the buffer.
  138. *((HANDLE *)Buffer) = BufferPool;
  139. // Get IPR.
  140. Ipr = (IPRcvBuf *) (Buffer + sizeof(HANDLE));
  141. // Set up IPR fields appropriately.
  142. Ipr->ipr_owner = IPR_OWNER_TCP;
  143. Ipr->ipr_next = NULL;
  144. Ipr->ipr_buffer = (PCHAR) Ipr + sizeof(IPRcvBuf);
  145. Ipr->ipr_size = BufferSize;
  146. #if DBG
  147. InterlockedIncrement(&TcpIprAllocs);
  148. #endif // DBG
  149. done:
  150. return (Ipr);
  151. }
  152. //* FreeTcpIpr - Frees the IPRcvBuffer to the correct lookaside list.
  153. //
  154. // A utility routine to free a TCP owned IPRcvBuffer.
  155. //
  156. // Input: Ipr - Pointer the RB.
  157. //
  158. // Returns: None.
  159. //
  160. VOID
  161. FreeTcpIpr(IPRcvBuf *Ipr)
  162. {
  163. HANDLE BufferPool;
  164. PCHAR Buffer;
  165. // Get real start of buffer.
  166. Buffer = (PCHAR) Ipr - sizeof(HANDLE);
  167. // Get the pool handle.
  168. BufferPool = *((HANDLE *) Buffer);
  169. if (BufferPool) {
  170. PplFree(BufferPool, Buffer);
  171. } else {
  172. CTEFreeMem(Buffer);
  173. }
  174. #if DBG
  175. InterlockedIncrement(&TcpIprFrees);
  176. #endif // DBG
  177. return;
  178. }