|
|
/*++
Copyright (c) 1997-2002 Microsoft Corporation
Module Name:
remote.c
Abstract:
DNS Resolver Service.
Remote APIs to resolver service.
Author:
Glenn Curtis (glennc) Feb 1997
Revision History:
Jim Gilroy (jamesg) March 2000 cleanup
--*/
#include "local.h"
//
// Private protos
//
PDNS_RPC_CACHE_TABLE CreateCacheTableEntry( IN LPWSTR Name );
VOID FreeCacheTableEntryList( IN PDNS_RPC_CACHE_TABLE pCacheTableList );
//
// Operations
//
DNS_STATUS CRrReadCache( IN DNS_RPC_HANDLE Reserved, OUT PDNS_RPC_CACHE_TABLE * ppCacheTable ) /*++
Routine Description:
Arguments:
Return Value:
--*/ // CRrReadCache
{ DNS_STATUS status = ERROR_SUCCESS; PDNS_RPC_CACHE_TABLE pprevRpcEntry = NULL; DWORD iter; DWORD countEntries = 0;
#define MAX_RPC_CACHE_ENTRY_COUNT (300)
UNREFERENCED_PARAMETER(Reserved);
DNSDBG( RPC, ( "CRrReadCache\n" ));
if ( !ppCacheTable ) { return ERROR_INVALID_PARAMETER; }
*ppCacheTable = NULL;
DNSLOG_F1( "DNS Caching Resolver Service - CRrReadCache" );
if ( ! Rpc_AccessCheck( RESOLVER_ACCESS_ENUM ) ) { DNSLOG_F1( "CRrReadCache - ERROR_ACCESS_DENIED" ); return ERROR_ACCESS_DENIED; }
status = LOCK_CACHE(); if ( status != NO_ERROR ) { return status; }
DNSLOG_F2( " Current number of entries in cache : %d", g_EntryCount ); DNSLOG_F2( " Current number of RR sets in cache : %d", g_RecordSetCount );
//
// Loop through all hash table slots looking for cache entries
// to return.
//
for ( iter = 0; iter < g_HashTableSize; iter++ ) { PCACHE_ENTRY pentry = g_HashTable[iter]; DWORD iter2;
while ( pentry && countEntries < MAX_RPC_CACHE_ENTRY_COUNT ) { PDNS_RPC_CACHE_TABLE prpcEntry;
prpcEntry = CreateCacheTableEntry( pentry->pName ); if ( ! prpcEntry ) { // only failure is memory alloc
FreeCacheTableEntryList( *ppCacheTable ); *ppCacheTable = NULL; status = ERROR_NOT_ENOUGH_MEMORY; goto ErrorExit; }
//
// insert new entry at end of current list
//
if ( pprevRpcEntry ) pprevRpcEntry->pNext = prpcEntry; else *ppCacheTable = prpcEntry;
pprevRpcEntry = prpcEntry;
countEntries++;
//
// fill in entry with current cached types
//
for ( iter2 = 0; iter2 < pentry->MaxCount; iter2++ ) { PDNS_RECORD prr = pentry->Records[iter2]; WORD type;
if ( !prr ) { continue; }
// DCR -- goofy, just make sure the same and index (or limit?)
type = prr->wType;
if ( ! prpcEntry->Type1 ) prpcEntry->Type1 = type; else if ( ! prpcEntry->Type2 ) prpcEntry->Type2 = type; else prpcEntry->Type3 = type; } pentry = pentry->pNext; }
if ( countEntries > MAX_RPC_CACHE_ENTRY_COUNT ) { break; } }
ErrorExit:
UNLOCK_CACHE();
DNSLOG_F3( " CRrReadCache - Returning status : 0x%.8X\n\t%s", status, Dns_StatusString( status ) ); DNSLOG_F1( "" );
return status; }
DNS_STATUS CRrReadCacheEntry( IN DNS_RPC_HANDLE Reserved, IN LPWSTR pwsName, IN WORD wType, OUT PDNS_RECORD * ppRRSet ) /*++
Routine Description:
Arguments:
Return Value:
--*/ // CRrReadCacheEntry
{ DNS_STATUS status; PCACHE_ENTRY pentry; PDNS_RECORD prr;
UNREFERENCED_PARAMETER(Reserved);
DNSLOG_F1( "DNS Caching Resolver Service - CRrReadCacheEntry" ); DNSLOG_F1( " Arguments:" ); DNSLOG_F2( " Name : %S", pwsName ); DNSLOG_F2( " Type : %d", wType ); DNSLOG_F1( "" );
DNSDBG( RPC, ( "\nCRrReadCacheEntry( %S, %d )\n", pwsName, wType ));
if ( !ppRRSet ) return ERROR_INVALID_PARAMETER;
if ( ! Rpc_AccessCheck( RESOLVER_ACCESS_READ ) ) { DNSLOG_F1( "CRrReadCacheEntry - ERROR_ACCESS_DENIED" ); return ERROR_ACCESS_DENIED; }
//
// find record in cache
// - copy if not NAME_ERROR or EMPTY
// - default to not-found error
// (DOES_NOT_EXIST error)
//
*ppRRSet = NULL; status = DNS_ERROR_RECORD_DOES_NOT_EXIST;
Cache_GetRecordsForRpc( ppRRSet, & status, pwsName, wType, 0 // no screening flags
);
DNSLOG_F3( " CRrReadCacheEntry - Returning status : 0x%.8X\n\t%s", status, Dns_StatusString( status ) ); DNSLOG_F1( "" );
DNSDBG( RPC, ( "Leave CRrReadCacheEntry( %S, %d ) => %d\n\n", pwsName, wType, status ));
return status; }
DNS_STATUS CRrGetHashTableStats( IN DNS_RPC_HANDLE Reserved, OUT LPDWORD pdwCacheHashTableSize, OUT LPDWORD pdwCacheHashTableBucketSize, OUT LPDWORD pdwNumberOfCacheEntries, OUT LPDWORD pdwNumberOfRecords, OUT LPDWORD pdwNumberOfExpiredRecords, OUT PDNS_STATS_TABLE * ppStatsTable ) /*++
Routine Description:
Arguments:
Return Value:
--*/ { PDNS_STATS_TABLE pprevRow = NULL; PDWORD_LIST_ITEM pprevItem = NULL; DWORD rowIter; DWORD itemIter; DWORD countExpiredRecords = 0; DWORD status = ERROR_SUCCESS;
UNREFERENCED_PARAMETER(Reserved);
if ( !pdwCacheHashTableSize || !pdwCacheHashTableBucketSize || !pdwNumberOfCacheEntries || !pdwNumberOfRecords || !pdwNumberOfExpiredRecords || !ppStatsTable ) { return ERROR_INVALID_PARAMETER; }
DNSLOG_F1( "CRrGetHashTableStats" ); DNSDBG( RPC, ( "CRrGetHashTableStats\n" ));
if ( ! Rpc_AccessCheck( RESOLVER_ACCESS_READ ) ) { DNSLOG_F1( "CRrGetHashTableStats - ERROR_ACCESS_DENIED" ); return ERROR_ACCESS_DENIED; }
status = LOCK_CACHE(); if ( status != NO_ERROR ) { return status; }
*pdwCacheHashTableSize = g_HashTableSize; //*pdwCacheHashTableBucketSize = g_CacheHashTableBucketSize;
*pdwCacheHashTableBucketSize = 0; *pdwNumberOfCacheEntries = g_EntryCount; *pdwNumberOfRecords = g_RecordSetCount; *pdwNumberOfExpiredRecords = 0;
//
// read entire hash table
//
for ( rowIter = 0; rowIter < g_HashTableSize; rowIter++ ) { PCACHE_ENTRY pentry = g_HashTable[rowIter]; PDNS_STATS_TABLE pnewRow;
//
// create table for each new row
//
pnewRow = RPC_HEAP_ALLOC_ZERO( sizeof(DNS_STATS_TABLE) ); if ( !pnewRow ) { status = ERROR_NOT_ENOUGH_MEMORY; goto Done; }
if ( pprevRow ) { pprevRow->pNext = pnewRow; } else { *ppStatsTable = pnewRow; } pprevRow = pnewRow;
//
// fill in row data (if any)
//
while ( pentry ) { PDWORD_LIST_ITEM pnewItem;
pnewItem = RPC_HEAP_ALLOC_ZERO( sizeof( DWORD_LIST_ITEM ) ); if ( !pnewItem ) { status = ERROR_NOT_ENOUGH_MEMORY; goto Done; }
for ( itemIter = 0; itemIter < pentry->MaxCount; itemIter++ ) { PDNS_RECORD prr = pentry->Records[itemIter]; if ( prr ) { pnewItem->Value1++;
if ( !Cache_IsRecordTtlValid( prr ) ) { pnewItem->Value2++; countExpiredRecords++; } } }
if ( !pnewRow->pListItem ) { pnewRow->pListItem = pnewItem; } else { pprevItem->pNext = pnewItem; }
pprevItem = pnewItem; pentry = pentry->pNext; } }
Done:
UNLOCK_CACHE(); *pdwNumberOfExpiredRecords = countExpiredRecords; return status; }
PDNS_RPC_CACHE_TABLE CreateCacheTableEntry( IN LPWSTR pwsName ) { PDNS_RPC_CACHE_TABLE prpcEntry = NULL;
if ( ! pwsName ) return NULL;
prpcEntry = (PDNS_RPC_CACHE_TABLE) RPC_HEAP_ALLOC_ZERO( sizeof(DNS_RPC_CACHE_TABLE) );
if ( prpcEntry == NULL ) return NULL;
prpcEntry->Name = RPC_HEAP_ALLOC( sizeof(WCHAR) * (wcslen(pwsName) + 1) ); if ( ! prpcEntry->Name ) { RPC_HEAP_FREE( prpcEntry ); return NULL; }
wcscpy( prpcEntry->Name, pwsName );
return prpcEntry; }
VOID FreeCacheTableEntryList( IN PDNS_RPC_CACHE_TABLE pCacheTableList ) { while ( pCacheTableList ) { PDNS_RPC_CACHE_TABLE pNext = pCacheTableList->pNext;
if ( pCacheTableList->Name ) { RPC_HEAP_FREE( pCacheTableList->Name ); pCacheTableList->Name = NULL; }
RPC_HEAP_FREE( pCacheTableList );
pCacheTableList = pNext; } }
//
// End remote.c
//
|