228 lines
4.8 KiB
C
228 lines
4.8 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1999-2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
ipr9x.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains the implementation of IP Receive buffer
|
||
|
list manager. On Windows ME this is done to avoid
|
||
|
fragmenting the non-paged pool when receive buffers are not
|
||
|
pre-posted by AFVXD.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Scott Holden (sholden) 30-Apr-2000
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#include "addr.h"
|
||
|
#include "tcp.h"
|
||
|
#include "tcb.h"
|
||
|
#include "tcprcv.h"
|
||
|
#include "tcpsend.h"
|
||
|
#include "tcpconn.h"
|
||
|
#include "tcpdeliv.h"
|
||
|
#include "tlcommon.h"
|
||
|
#include "tcpipbuf.h"
|
||
|
#include "pplasl.h"
|
||
|
#include "mdl2ndis.h"
|
||
|
|
||
|
HANDLE TcpIprDataPoolSmall = NULL;
|
||
|
HANDLE TcpIprDataPoolMedium = NULL;
|
||
|
HANDLE TcpIprDataPoolLarge = NULL;
|
||
|
|
||
|
#if DBG
|
||
|
ULONG TcpIprAllocs = 0;
|
||
|
ULONG TcpIprFrees = 0;
|
||
|
ULONG TcpIprAllocMisses = 0;
|
||
|
#endif // DBG
|
||
|
|
||
|
//
|
||
|
// The three buffer pool sizes are based on MTU. 576 for PPP, 1500 for ethernet,
|
||
|
// and 8K+ for loopback and ATM. Since for 8K buffers we really need a little
|
||
|
// more than 8K, we will allocate a full three pages
|
||
|
//
|
||
|
|
||
|
#define SMALL_TCP_IPR_BUFFER_SIZE (sizeof(IPRcvBuf) + sizeof(HANDLE) + 576)
|
||
|
#define MEDIUM_TCP_IPR_BUFFER_SIZE (sizeof(IPRcvBuf) + sizeof(HANDLE) + 1500)
|
||
|
#define LARGE_TCP_IPR_BUFFER_SIZE (3 * 4096)
|
||
|
|
||
|
//* UnInitTcpIprPools - Destroys TCP IPRcvBuffer lookaside lists.
|
||
|
//
|
||
|
// Uninitializes the lookasides lists for TCP buffered data.
|
||
|
//
|
||
|
// Input: None.
|
||
|
//
|
||
|
// Returns: None.
|
||
|
//
|
||
|
VOID
|
||
|
UnInitTcpIprPools(VOID)
|
||
|
{
|
||
|
PplDestroyPool(TcpIprDataPoolSmall);
|
||
|
PplDestroyPool(TcpIprDataPoolMedium);
|
||
|
PplDestroyPool(TcpIprDataPoolLarge);
|
||
|
}
|
||
|
|
||
|
//* InitTcpIprPools - Initializes TCP IPRcvBuffer lookaside lists.
|
||
|
//
|
||
|
// Initializes the lookaside lists for buffer data.
|
||
|
//
|
||
|
// Input: None.
|
||
|
//
|
||
|
// Returns: TRUE, if successful, else FALSE.
|
||
|
//
|
||
|
BOOLEAN
|
||
|
InitTcpIprPools(VOID)
|
||
|
{
|
||
|
BOOLEAN Status = TRUE;
|
||
|
|
||
|
TcpIprDataPoolSmall = PplCreatePool(NULL, NULL, 0,
|
||
|
SMALL_TCP_IPR_BUFFER_SIZE, 'BPCT', 512);
|
||
|
|
||
|
if (TcpIprDataPoolSmall == NULL) {
|
||
|
Status = FALSE;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
TcpIprDataPoolMedium = PplCreatePool(NULL, NULL, 0,
|
||
|
MEDIUM_TCP_IPR_BUFFER_SIZE, 'BPCT', 256);
|
||
|
|
||
|
if (TcpIprDataPoolMedium == NULL) {
|
||
|
Status = FALSE;
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
TcpIprDataPoolLarge = PplCreatePool(NULL, NULL, 0,
|
||
|
LARGE_TCP_IPR_BUFFER_SIZE, 'BPCT', 64);
|
||
|
|
||
|
if (TcpIprDataPoolLarge == NULL) {
|
||
|
Status = FALSE;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
|
||
|
if (Status == FALSE) {
|
||
|
UnInitTcpIprPools();
|
||
|
}
|
||
|
|
||
|
return (Status);
|
||
|
}
|
||
|
|
||
|
//* AllocTcpIpr - Allocates the IPRcvBuffer from lookaside lists.
|
||
|
//
|
||
|
// A utility routine to allocate a TCP owned IPRcvBuffer. This routine
|
||
|
// attempts to allocate the RB from an appropriate lookaside list, el
|
||
|
//
|
||
|
// Input: BufferSize - Size of data to buffer.
|
||
|
//
|
||
|
// Returns: Pointer to allocated IPR.
|
||
|
//
|
||
|
IPRcvBuf *
|
||
|
AllocTcpIpr(ULONG BufferSize, ULONG Tag)
|
||
|
{
|
||
|
PCHAR Buffer;
|
||
|
IPRcvBuf *Ipr = NULL;
|
||
|
LOGICAL FromList = FALSE;
|
||
|
ULONG AllocateSize;
|
||
|
HANDLE BufferPool = NULL;
|
||
|
ULONG Depth;
|
||
|
|
||
|
// Real size that we need.
|
||
|
AllocateSize = BufferSize + sizeof(HANDLE) + sizeof(IPRcvBuf);
|
||
|
|
||
|
if (AllocateSize <= LARGE_TCP_IPR_BUFFER_SIZE) {
|
||
|
|
||
|
//
|
||
|
// Pick the buffer pool to allocate from.
|
||
|
//
|
||
|
|
||
|
if (AllocateSize <= SMALL_TCP_IPR_BUFFER_SIZE) {
|
||
|
BufferPool = TcpIprDataPoolSmall;
|
||
|
} else if (AllocateSize <= MEDIUM_TCP_IPR_BUFFER_SIZE) {
|
||
|
BufferPool = TcpIprDataPoolMedium;
|
||
|
} else {
|
||
|
BufferPool = TcpIprDataPoolLarge;
|
||
|
}
|
||
|
|
||
|
Buffer = PplAllocate(BufferPool, &FromList);
|
||
|
|
||
|
} else {
|
||
|
|
||
|
//
|
||
|
// Allocate from NP pool.
|
||
|
//
|
||
|
|
||
|
Buffer = CTEAllocMemLow(AllocateSize, Tag);
|
||
|
}
|
||
|
|
||
|
if (Buffer == NULL) {
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
#if DBG
|
||
|
if (FromList == FALSE) {
|
||
|
InterlockedIncrement(&TcpIprAllocMisses);
|
||
|
}
|
||
|
#endif // DBG
|
||
|
|
||
|
// Store buffer pool so we know how to free the buffer.
|
||
|
*((HANDLE *)Buffer) = BufferPool;
|
||
|
|
||
|
// Get IPR.
|
||
|
Ipr = (IPRcvBuf *) (Buffer + sizeof(HANDLE));
|
||
|
|
||
|
// Set up IPR fields appropriately.
|
||
|
Ipr->ipr_owner = IPR_OWNER_TCP;
|
||
|
Ipr->ipr_next = NULL;
|
||
|
Ipr->ipr_buffer = (PCHAR) Ipr + sizeof(IPRcvBuf);
|
||
|
Ipr->ipr_size = BufferSize;
|
||
|
|
||
|
#if DBG
|
||
|
InterlockedIncrement(&TcpIprAllocs);
|
||
|
#endif // DBG
|
||
|
|
||
|
done:
|
||
|
|
||
|
return (Ipr);
|
||
|
}
|
||
|
|
||
|
//* FreeTcpIpr - Frees the IPRcvBuffer to the correct lookaside list.
|
||
|
//
|
||
|
// A utility routine to free a TCP owned IPRcvBuffer.
|
||
|
//
|
||
|
// Input: Ipr - Pointer the RB.
|
||
|
//
|
||
|
// Returns: None.
|
||
|
//
|
||
|
VOID
|
||
|
FreeTcpIpr(IPRcvBuf *Ipr)
|
||
|
{
|
||
|
HANDLE BufferPool;
|
||
|
PCHAR Buffer;
|
||
|
|
||
|
// Get real start of buffer.
|
||
|
Buffer = (PCHAR) Ipr - sizeof(HANDLE);
|
||
|
|
||
|
// Get the pool handle.
|
||
|
BufferPool = *((HANDLE *) Buffer);
|
||
|
|
||
|
if (BufferPool) {
|
||
|
PplFree(BufferPool, Buffer);
|
||
|
} else {
|
||
|
CTEFreeMem(Buffer);
|
||
|
}
|
||
|
|
||
|
#if DBG
|
||
|
InterlockedIncrement(&TcpIprFrees);
|
||
|
#endif // DBG
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|