⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.cpp

📁 本实例将通过ISAPI实现限制IP访问的功能
💻 CPP
字号:
/* 
DB.CPP 
    This module implements a simple ip address cache.  The cached addresses are kept
    in an LRU sorted list.  If there will be a large number of simultaneous
    addresses, then a sorted array would be more appropriate.
*/

#include "stdafx.h"
#include "IPAddressFilter.h"

/*
Routine Description:
    Initializes the cache module

Return Value:
    TRUE if initialized successfully, FALSE on error
*/
BOOL CIPAddressFilter::InitializeCache()
{
	if ( m_fCacheInitialized )
		return TRUE;

	InitializeCriticalSection( &m_csCacheLock );
	m_CacheListHead.Blink = m_CacheListHead.Flink = &m_CacheListHead;

	m_fCacheInitialized = TRUE;

	return TRUE;
}


/*
Routine Description:
    Checks to see if an address is in the cache

Arguments:
    pszIPAddress - IP address to find
		pfFound      - Set to TRUE if the specified address was found

Return Value:
    TRUE if no errors occurred.
*/
BOOL CIPAddressFilter::LookupIPAddressInCache(const CHAR* pszIPAddress, BOOL* pfFound)
{
	LIST_ENTRY* pEntry;
	IP_INFO*    pIPAddress;
	DWORD       cPosition = 0;

	//  Search the cache for the specified address
	EnterCriticalSection( &m_csCacheLock );
	for ( pEntry = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntry->Flink)
	{
		pIPAddress = CONTAINING_RECORD( pEntry, IP_INFO, ListEntry );
		if ( !stricmp( pszIPAddress, pIPAddress->achIPAddress ))
			goto Found;

		cPosition++;
	}

	LeaveCriticalSection( &m_csCacheLock );

	//  Not Found
	*pfFound = FALSE;
	return TRUE;

Found:
	//  Move this address entry to the front of the list as we're probably going
	//  to get subsequent requests for this address.  Note we only move it
	//  if it's not already near the front
	if ( cPosition > LIST_REORDER_THRESHOLD )
	{
		//  Remove from the old position...
		pEntry->Blink->Flink = pEntry->Flink;
		pEntry->Flink->Blink = pEntry->Blink;
		// ...and insert it at the beginning of the list
		pEntry->Blink = &m_CacheListHead;
		pEntry->Flink = m_CacheListHead.Flink;
		m_CacheListHead.Flink->Blink = pEntry;
		m_CacheListHead.Flink        = pEntry;
	}

	LeaveCriticalSection( &m_csCacheLock );

	*pfFound = TRUE;
	return TRUE;
}

/*
Routine Description:
    Adds the specified address to the cache

Arguments:
    pszIPAddress - IP address to add

Return Value:
    TRUE if no errors occurred.
*/
BOOL CIPAddressFilter::AddIPAddressToCache(const CHAR* pszIPAddress)
{
	LIST_ENTRY* pEntry;
	IP_INFO*    pIPAddress;

	//  Check our parameters before adding them to the cache
	if ( strlen( pszIPAddress ) > MAX_IP_ADDRESS )
	{
		SetLastError( ERROR_INVALID_PARAMETER );
		return FALSE;
	}

	//  Search the cache for the specified address to make sure there are no
	//  duplicates
	EnterCriticalSection( &m_csCacheLock );
	for ( pEntry  = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry = pEntry->Flink )
	{
		pIPAddress = CONTAINING_RECORD( pEntry, IP_INFO, ListEntry );
		if ( !stricmp( pszIPAddress, pIPAddress->achIPAddress ))
			goto Found;
	}

	//  Allocate a new cache item and put it at the head of the list
	pIPAddress = (IP_INFO *) LocalAlloc( LPTR, sizeof( IP_INFO ));
	if ( !pIPAddress )
	{
		LeaveCriticalSection( &m_csCacheLock );
		SetLastError( ERROR_NOT_ENOUGH_MEMORY );
		return FALSE;
	}
	pIPAddress->ListEntry.Flink = m_CacheListHead.Flink;
	pIPAddress->ListEntry.Blink = &m_CacheListHead;
	m_CacheListHead.Flink->Blink = &pIPAddress->ListEntry;
	m_CacheListHead.Flink = &pIPAddress->ListEntry;

Found:
	//  Set the various fields
	strcpy( pIPAddress->achIPAddress, pszIPAddress );

	m_cCacheItems++;

	//  If there are too many cached addresses, remove the least recently
	//  used one now
	if ( m_cCacheItems > MAX_CACHED_ADDRESSES )
	{
		pEntry = m_CacheListHead.Blink;
		pEntry->Blink->Flink = &m_CacheListHead;
		m_CacheListHead.Blink  = pEntry->Blink;
		LocalFree( CONTAINING_RECORD( pEntry, IP_INFO, ListEntry ));
		m_cCacheItems--;
	}

	LeaveCriticalSection( &m_csCacheLock );

	return TRUE;
}

/*
Routine Description:
    Terminates the cache module and frees any allocated memory
*/
VOID CIPAddressFilter::TerminateCache()
{
	LIST_ENTRY* pEntry;
	LIST_ENTRY* pEntryNext;
	IP_INFO*    pIPAddress;

	if ( !m_fCacheInitialized )
		return;

	EnterCriticalSection( &m_csCacheLock );

	// Free all of the cache entries
	for ( pEntry  = m_CacheListHead.Flink; pEntry != &m_CacheListHead; pEntry  = pEntryNext )
	{
		pIPAddress = CONTAINING_RECORD( pEntry, IP_INFO, ListEntry );
		pEntryNext = pEntry->Flink;

		//  Remove this entry from the list and free it
		pEntry->Blink->Flink = pEntry->Flink;
		pEntry->Flink->Blink = pEntry->Blink;

		LocalFree( pIPAddress );
	}

	m_cCacheItems = 0;
	LeaveCriticalSection( &m_csCacheLock );
	DeleteCriticalSection( &m_csCacheLock );
	m_fCacheInitialized = FALSE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -