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