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.

248 lines
6.6 KiB

  1. #include "convlog.h"
  2. /*
  3. This File implements caching of the mappings between ip addresses and machine names.
  4. pHashTable: An array of linked list headers which map directly to hash values, eg. the mapping for
  5. an ipaddr is stored in the list with header pHashTable[GetHashVal(ipaddr)]
  6. pHashEntries: An array of HashEntry strucures. Each structure contains a mapping of ip address to machine name.
  7. Algorithm: A HashEntry structure is allocated each time an
  8. entry is added to the cache. These are reused in circular fashion, eg. pHashEntries[0] is used first,
  9. then pHashEntries[1], etc. When the ulNumHashEntries+1 entry is added to the cache, the entry currently
  10. in pHashEntries[0] is discarded and pHashEntries[0] is reused. Hence the discard mechanism is
  11. Least Recently Allocated. This is probably not as efficient as Least Recently Used in terms of keeping
  12. the most relevant entries in the cache. But it is more effiecient in terms of code speed, as there is no overhead
  13. for keeping usage statistics or finding the least recently used entry.
  14. All linked lists are kept in the reverse order of their allocation, that is, the most recently allocated is at the start
  15. of the list. This allows for the most efficient allocation. It "should" also be efficient for lookup, but that could vary
  16. on a per logfile basis.
  17. All addressing of the pHashEntries array is currently done via array indices. At some point this should probably be
  18. converted to use structure pointers, as that generates slightly more efficient code.
  19. */
  20. #define HASHTABLELEN 2048
  21. #define NOCACHEENTRY 0xFFFFFFFF
  22. #define GetHashVal(p) ((p) % HASHTABLELEN)
  23. //This gets rid of the byte ordering dependency
  24. #define BINARYIPTONUMERICIP(p1) (ULONG) (((ULONG)p1[0] << 24) + ((ULONG)p1[1] << 16) + ((ULONG)p1[2] << 8) + ((ULONG)p1[3]))
  25. ULONG HashTable[HASHTABLELEN] = {0};
  26. PHASHENTRY pHashEntries;
  27. ULONG ulFreeListIndex = 0;
  28. BOOL bFreeElements = TRUE;
  29. BOOL bCachingEnabled = FALSE;
  30. ULONG ulCacheHits = 0;
  31. ULONG ulCacheMisses = 0;
  32. ULONG ulNumHashEntries;
  33. VOID
  34. InitHashTable(
  35. DWORD ulCacheSize
  36. )
  37. {
  38. DWORD i;
  39. for (i = 0; i < HASHTABLELEN; i++) {
  40. HashTable[i] = NOCACHEENTRY;
  41. }
  42. ulNumHashEntries = ulCacheSize;
  43. while ((!bCachingEnabled) && (ulNumHashEntries >= 1000)) {
  44. pHashEntries = (PHASHENTRY)
  45. GlobalAlloc(GPTR, (sizeof(HASHENTRY) * ulNumHashEntries));
  46. if (NULL != pHashEntries) {
  47. bCachingEnabled = TRUE;
  48. } else {
  49. ulNumHashEntries /= 2;
  50. }
  51. }
  52. if (!bCachingEnabled) {
  53. printfids(IDS_CACHE_ERR);
  54. }
  55. } // InitHashTable
  56. ULONG
  57. AllocHashEntry(
  58. VOID
  59. )
  60. {
  61. ULONG i, ulCurHashVal;
  62. if (ulFreeListIndex == ulNumHashEntries) {
  63. ulFreeListIndex = 0;
  64. bFreeElements = FALSE;
  65. }
  66. if (!bFreeElements) { // Use this entry anyway, but free it first
  67. ulCurHashVal = GetHashVal(pHashEntries[ulFreeListIndex].uIPAddr); //find hashtable entry
  68. if (HashTable[ulCurHashVal] == ulFreeListIndex) {
  69. HashTable[ulCurHashVal] = pHashEntries[ulFreeListIndex].NextPtr; //Remove the entry from the table
  70. }
  71. else {
  72. for (i = HashTable[ulCurHashVal]; pHashEntries[i].NextPtr != ulFreeListIndex; i = pHashEntries[i].NextPtr)
  73. ;
  74. pHashEntries[i].NextPtr = pHashEntries[ulFreeListIndex].NextPtr; //Remove the entry from the table
  75. }
  76. }
  77. return(ulFreeListIndex++);
  78. }
  79. ULONG GetElementFromCache(ULONG uIPAddr) {
  80. ULONG i = GetHashVal(uIPAddr);
  81. for (i =HashTable[i];(i != NOCACHEENTRY)&&(pHashEntries[i].uIPAddr != uIPAddr);i = pHashEntries[i].NextPtr)
  82. ;
  83. return(i);
  84. }
  85. VOID
  86. AddEntryToCache(
  87. IN ULONG uIPAddr,
  88. IN PCHAR szMachineName
  89. )
  90. {
  91. ULONG uHashEntry;
  92. ULONG uHashVal;
  93. char *szTemp;
  94. uHashEntry=AllocHashEntry();
  95. uHashVal=GetHashVal(uIPAddr);
  96. pHashEntries[uHashEntry].uIPAddr = uIPAddr;
  97. if (strlen(szMachineName) < MAXMACHINELEN)
  98. szTemp = strcpy(pHashEntries[uHashEntry].szMachineName,szMachineName);
  99. else {
  100. szTemp = strncpy(pHashEntries[uHashEntry].szMachineName,szMachineName, (size_t)MAXMACHINELEN);
  101. pHashEntries[uHashEntry].szMachineName[MAXMACHINELEN - 1] = '\0';
  102. }
  103. pHashEntries[uHashEntry].NextPtr=HashTable[uHashVal];
  104. HashTable[uHashVal] = uHashEntry;
  105. }
  106. VOID
  107. AddLocalMachineToCache(
  108. VOID
  109. )
  110. {
  111. INT err;
  112. CHAR nameBuf[MAX_PATH+1];
  113. PHOSTENT hostent;
  114. err = gethostname( nameBuf, sizeof(nameBuf));
  115. if ( err != 0 ) {
  116. return;
  117. }
  118. hostent = gethostbyname( nameBuf );
  119. if ( hostent == NULL ) {
  120. return;
  121. }
  122. AddEntryToCache(
  123. ((PIN_ADDR)hostent->h_addr_list[0])->s_addr,
  124. hostent->h_name
  125. );
  126. return;
  127. } // AddLocalMachineToCache
  128. PCHAR
  129. GetMachineName(
  130. IN PCHAR szClientIP
  131. )
  132. {
  133. IN_ADDR inaddr;
  134. PHOSTENT lpHostEnt;
  135. ULONG ulNumericIP;
  136. ULONG ulCurHashIndex;
  137. CHAR tmpIP[64];
  138. PCHAR szReturnString = szClientIP;
  139. strcpy(tmpIP,szClientIP);
  140. FindChar(tmpIP,',');
  141. inaddr.s_addr = inet_addr(tmpIP);
  142. //
  143. // invalid IP
  144. //
  145. if ( inaddr.s_addr == INADDR_NONE ) {
  146. goto exit;
  147. }
  148. if (bCachingEnabled) {
  149. ulNumericIP = inaddr.s_addr;
  150. if ((ulCurHashIndex=GetElementFromCache(ulNumericIP)) == NOCACHEENTRY) {
  151. lpHostEnt = gethostbyaddr(
  152. (char *)&inaddr, (int)4, (int)PF_INET);
  153. if (lpHostEnt != NULL) {
  154. szReturnString = lpHostEnt->h_name;
  155. }
  156. AddEntryToCache(ulNumericIP,szReturnString);
  157. ulCacheMisses++;
  158. } else { //Entry is in cache
  159. szReturnString=pHashEntries[ulCurHashIndex].szMachineName;
  160. ulCacheHits++;
  161. }
  162. } else { //Caching not enabled
  163. lpHostEnt = gethostbyaddr((char *)&inaddr, (int) 4, (int) PF_INET);
  164. if (lpHostEnt != NULL) {
  165. szReturnString = lpHostEnt->h_name;
  166. }
  167. }
  168. exit:
  169. return(szReturnString);
  170. }
  171. #if DBG
  172. VOID
  173. PrintCacheTotals()
  174. {
  175. if (bCachingEnabled) {
  176. DWORD dwTotal = ulCacheHits + ulCacheMisses;
  177. double dRatio;
  178. if ( ulCacheHits != 0 ) {
  179. dRatio = (double)ulCacheHits/(double)dwTotal;
  180. } else {
  181. dRatio = 0;
  182. }
  183. printfids(IDS_CACHE_HITS, ulCacheHits);
  184. printfids(IDS_CACHE_MISS, ulCacheMisses);
  185. printfids(IDS_CACHE_TOT, dRatio);
  186. }
  187. }
  188. #endif