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.
 
 
 
 
 
 

473 lines
10 KiB

/*++
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
//