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

  1. /*++
  2. Copyright (c) 1997-2002 Microsoft Corporation
  3. Module Name:
  4. remote.c
  5. Abstract:
  6. DNS Resolver Service.
  7. Remote APIs to resolver service.
  8. Author:
  9. Glenn Curtis (glennc) Feb 1997
  10. Revision History:
  11. Jim Gilroy (jamesg) March 2000 cleanup
  12. --*/
  13. #include "local.h"
  14. //
  15. // Private protos
  16. //
  17. PDNS_RPC_CACHE_TABLE
  18. CreateCacheTableEntry(
  19. IN LPWSTR Name
  20. );
  21. VOID
  22. FreeCacheTableEntryList(
  23. IN PDNS_RPC_CACHE_TABLE pCacheTableList
  24. );
  25. //
  26. // Operations
  27. //
  28. DNS_STATUS
  29. CRrReadCache(
  30. IN DNS_RPC_HANDLE Reserved,
  31. OUT PDNS_RPC_CACHE_TABLE * ppCacheTable
  32. )
  33. /*++
  34. Routine Description:
  35. Arguments:
  36. Return Value:
  37. --*/ // CRrReadCache
  38. {
  39. DNS_STATUS status = ERROR_SUCCESS;
  40. PDNS_RPC_CACHE_TABLE pprevRpcEntry = NULL;
  41. DWORD iter;
  42. DWORD countEntries = 0;
  43. #define MAX_RPC_CACHE_ENTRY_COUNT (300)
  44. UNREFERENCED_PARAMETER(Reserved);
  45. DNSDBG( RPC, ( "CRrReadCache\n" ));
  46. if ( !ppCacheTable )
  47. {
  48. return ERROR_INVALID_PARAMETER;
  49. }
  50. *ppCacheTable = NULL;
  51. DNSLOG_F1( "DNS Caching Resolver Service - CRrReadCache" );
  52. if ( ! Rpc_AccessCheck( RESOLVER_ACCESS_ENUM ) )
  53. {
  54. DNSLOG_F1( "CRrReadCache - ERROR_ACCESS_DENIED" );
  55. return ERROR_ACCESS_DENIED;
  56. }
  57. status = LOCK_CACHE();
  58. if ( status != NO_ERROR )
  59. {
  60. return status;
  61. }
  62. DNSLOG_F2( " Current number of entries in cache : %d",
  63. g_EntryCount );
  64. DNSLOG_F2( " Current number of RR sets in cache : %d",
  65. g_RecordSetCount );
  66. //
  67. // Loop through all hash table slots looking for cache entries
  68. // to return.
  69. //
  70. for ( iter = 0; iter < g_HashTableSize; iter++ )
  71. {
  72. PCACHE_ENTRY pentry = g_HashTable[iter];
  73. DWORD iter2;
  74. while ( pentry &&
  75. countEntries < MAX_RPC_CACHE_ENTRY_COUNT )
  76. {
  77. PDNS_RPC_CACHE_TABLE prpcEntry;
  78. prpcEntry = CreateCacheTableEntry( pentry->pName );
  79. if ( ! prpcEntry )
  80. {
  81. // only failure is memory alloc
  82. FreeCacheTableEntryList( *ppCacheTable );
  83. *ppCacheTable = NULL;
  84. status = ERROR_NOT_ENOUGH_MEMORY;
  85. goto ErrorExit;
  86. }
  87. //
  88. // insert new entry at end of current list
  89. //
  90. if ( pprevRpcEntry )
  91. pprevRpcEntry->pNext = prpcEntry;
  92. else
  93. *ppCacheTable = prpcEntry;
  94. pprevRpcEntry = prpcEntry;
  95. countEntries++;
  96. //
  97. // fill in entry with current cached types
  98. //
  99. for ( iter2 = 0; iter2 < pentry->MaxCount; iter2++ )
  100. {
  101. PDNS_RECORD prr = pentry->Records[iter2];
  102. WORD type;
  103. if ( !prr )
  104. {
  105. continue;
  106. }
  107. // DCR -- goofy, just make sure the same and index (or limit?)
  108. type = prr->wType;
  109. if ( ! prpcEntry->Type1 )
  110. prpcEntry->Type1 = type;
  111. else if ( ! prpcEntry->Type2 )
  112. prpcEntry->Type2 = type;
  113. else
  114. prpcEntry->Type3 = type;
  115. }
  116. pentry = pentry->pNext;
  117. }
  118. if ( countEntries > MAX_RPC_CACHE_ENTRY_COUNT )
  119. {
  120. break;
  121. }
  122. }
  123. ErrorExit:
  124. UNLOCK_CACHE();
  125. DNSLOG_F3( " CRrReadCache - Returning status : 0x%.8X\n\t%s",
  126. status,
  127. Dns_StatusString( status ) );
  128. DNSLOG_F1( "" );
  129. return status;
  130. }
  131. DNS_STATUS
  132. CRrReadCacheEntry(
  133. IN DNS_RPC_HANDLE Reserved,
  134. IN LPWSTR pwsName,
  135. IN WORD wType,
  136. OUT PDNS_RECORD * ppRRSet
  137. )
  138. /*++
  139. Routine Description:
  140. Arguments:
  141. Return Value:
  142. --*/ // CRrReadCacheEntry
  143. {
  144. DNS_STATUS status;
  145. PCACHE_ENTRY pentry;
  146. PDNS_RECORD prr;
  147. UNREFERENCED_PARAMETER(Reserved);
  148. DNSLOG_F1( "DNS Caching Resolver Service - CRrReadCacheEntry" );
  149. DNSLOG_F1( " Arguments:" );
  150. DNSLOG_F2( " Name : %S", pwsName );
  151. DNSLOG_F2( " Type : %d", wType );
  152. DNSLOG_F1( "" );
  153. DNSDBG( RPC, (
  154. "\nCRrReadCacheEntry( %S, %d )\n",
  155. pwsName,
  156. wType ));
  157. if ( !ppRRSet )
  158. return ERROR_INVALID_PARAMETER;
  159. if ( ! Rpc_AccessCheck( RESOLVER_ACCESS_READ ) )
  160. {
  161. DNSLOG_F1( "CRrReadCacheEntry - ERROR_ACCESS_DENIED" );
  162. return ERROR_ACCESS_DENIED;
  163. }
  164. //
  165. // find record in cache
  166. // - copy if not NAME_ERROR or EMPTY
  167. // - default to not-found error
  168. // (DOES_NOT_EXIST error)
  169. //
  170. *ppRRSet = NULL;
  171. status = DNS_ERROR_RECORD_DOES_NOT_EXIST;
  172. Cache_GetRecordsForRpc(
  173. ppRRSet,
  174. & status,
  175. pwsName,
  176. wType,
  177. 0 // no screening flags
  178. );
  179. DNSLOG_F3( " CRrReadCacheEntry - Returning status : 0x%.8X\n\t%s",
  180. status,
  181. Dns_StatusString( status ) );
  182. DNSLOG_F1( "" );
  183. DNSDBG( RPC, (
  184. "Leave CRrReadCacheEntry( %S, %d ) => %d\n\n",
  185. pwsName,
  186. wType,
  187. status ));
  188. return status;
  189. }
  190. DNS_STATUS
  191. CRrGetHashTableStats(
  192. IN DNS_RPC_HANDLE Reserved,
  193. OUT LPDWORD pdwCacheHashTableSize,
  194. OUT LPDWORD pdwCacheHashTableBucketSize,
  195. OUT LPDWORD pdwNumberOfCacheEntries,
  196. OUT LPDWORD pdwNumberOfRecords,
  197. OUT LPDWORD pdwNumberOfExpiredRecords,
  198. OUT PDNS_STATS_TABLE * ppStatsTable
  199. )
  200. /*++
  201. Routine Description:
  202. Arguments:
  203. Return Value:
  204. --*/
  205. {
  206. PDNS_STATS_TABLE pprevRow = NULL;
  207. PDWORD_LIST_ITEM pprevItem = NULL;
  208. DWORD rowIter;
  209. DWORD itemIter;
  210. DWORD countExpiredRecords = 0;
  211. DWORD status = ERROR_SUCCESS;
  212. UNREFERENCED_PARAMETER(Reserved);
  213. if ( !pdwCacheHashTableSize ||
  214. !pdwCacheHashTableBucketSize ||
  215. !pdwNumberOfCacheEntries ||
  216. !pdwNumberOfRecords ||
  217. !pdwNumberOfExpiredRecords ||
  218. !ppStatsTable )
  219. {
  220. return ERROR_INVALID_PARAMETER;
  221. }
  222. DNSLOG_F1( "CRrGetHashTableStats" );
  223. DNSDBG( RPC, ( "CRrGetHashTableStats\n" ));
  224. if ( ! Rpc_AccessCheck( RESOLVER_ACCESS_READ ) )
  225. {
  226. DNSLOG_F1( "CRrGetHashTableStats - ERROR_ACCESS_DENIED" );
  227. return ERROR_ACCESS_DENIED;
  228. }
  229. status = LOCK_CACHE();
  230. if ( status != NO_ERROR )
  231. {
  232. return status;
  233. }
  234. *pdwCacheHashTableSize = g_HashTableSize;
  235. //*pdwCacheHashTableBucketSize = g_CacheHashTableBucketSize;
  236. *pdwCacheHashTableBucketSize = 0;
  237. *pdwNumberOfCacheEntries = g_EntryCount;
  238. *pdwNumberOfRecords = g_RecordSetCount;
  239. *pdwNumberOfExpiredRecords = 0;
  240. //
  241. // read entire hash table
  242. //
  243. for ( rowIter = 0;
  244. rowIter < g_HashTableSize;
  245. rowIter++ )
  246. {
  247. PCACHE_ENTRY pentry = g_HashTable[rowIter];
  248. PDNS_STATS_TABLE pnewRow;
  249. //
  250. // create table for each new row
  251. //
  252. pnewRow = RPC_HEAP_ALLOC_ZERO( sizeof(DNS_STATS_TABLE) );
  253. if ( !pnewRow )
  254. {
  255. status = ERROR_NOT_ENOUGH_MEMORY;
  256. goto Done;
  257. }
  258. if ( pprevRow )
  259. {
  260. pprevRow->pNext = pnewRow;
  261. }
  262. else
  263. {
  264. *ppStatsTable = pnewRow;
  265. }
  266. pprevRow = pnewRow;
  267. //
  268. // fill in row data (if any)
  269. //
  270. while ( pentry )
  271. {
  272. PDWORD_LIST_ITEM pnewItem;
  273. pnewItem = RPC_HEAP_ALLOC_ZERO( sizeof( DWORD_LIST_ITEM ) );
  274. if ( !pnewItem )
  275. {
  276. status = ERROR_NOT_ENOUGH_MEMORY;
  277. goto Done;
  278. }
  279. for ( itemIter = 0;
  280. itemIter < pentry->MaxCount;
  281. itemIter++ )
  282. {
  283. PDNS_RECORD prr = pentry->Records[itemIter];
  284. if ( prr )
  285. {
  286. pnewItem->Value1++;
  287. if ( !Cache_IsRecordTtlValid( prr ) )
  288. {
  289. pnewItem->Value2++;
  290. countExpiredRecords++;
  291. }
  292. }
  293. }
  294. if ( !pnewRow->pListItem )
  295. {
  296. pnewRow->pListItem = pnewItem;
  297. }
  298. else
  299. {
  300. pprevItem->pNext = pnewItem;
  301. }
  302. pprevItem = pnewItem;
  303. pentry = pentry->pNext;
  304. }
  305. }
  306. Done:
  307. UNLOCK_CACHE();
  308. *pdwNumberOfExpiredRecords = countExpiredRecords;
  309. return status;
  310. }
  311. PDNS_RPC_CACHE_TABLE
  312. CreateCacheTableEntry(
  313. IN LPWSTR pwsName
  314. )
  315. {
  316. PDNS_RPC_CACHE_TABLE prpcEntry = NULL;
  317. if ( ! pwsName )
  318. return NULL;
  319. prpcEntry = (PDNS_RPC_CACHE_TABLE)
  320. RPC_HEAP_ALLOC_ZERO( sizeof(DNS_RPC_CACHE_TABLE) );
  321. if ( prpcEntry == NULL )
  322. return NULL;
  323. prpcEntry->Name = RPC_HEAP_ALLOC( sizeof(WCHAR) * (wcslen(pwsName) + 1) );
  324. if ( ! prpcEntry->Name )
  325. {
  326. RPC_HEAP_FREE( prpcEntry );
  327. return NULL;
  328. }
  329. wcscpy( prpcEntry->Name, pwsName );
  330. return prpcEntry;
  331. }
  332. VOID
  333. FreeCacheTableEntryList(
  334. IN PDNS_RPC_CACHE_TABLE pCacheTableList )
  335. {
  336. while ( pCacheTableList )
  337. {
  338. PDNS_RPC_CACHE_TABLE pNext = pCacheTableList->pNext;
  339. if ( pCacheTableList->Name )
  340. {
  341. RPC_HEAP_FREE( pCacheTableList->Name );
  342. pCacheTableList->Name = NULL;
  343. }
  344. RPC_HEAP_FREE( pCacheTableList );
  345. pCacheTableList = pNext;
  346. }
  347. }
  348. //
  349. // End remote.c
  350. //