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.

450 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. routing\ip\priority\priority.c
  5. Abstract:
  6. Route Priority DLL
  7. Revision History:
  8. Gurdeep Singh Pall 7/19/95 Created
  9. --*/
  10. #include "priority.h"
  11. PRTR_TOC_ENTRY
  12. GetPointerToTocEntry(
  13. DWORD dwType,
  14. PRTR_INFO_BLOCK_HEADER pInfoHdr
  15. )
  16. {
  17. DWORD i;
  18. if(pInfoHdr == NULL)
  19. {
  20. return NULL;
  21. }
  22. for(i = 0; i < pInfoHdr->TocEntriesCount; i++)
  23. {
  24. if(pInfoHdr->TocEntry[i].InfoType == dwType)
  25. {
  26. return &(pInfoHdr->TocEntry[i]);
  27. }
  28. }
  29. return NULL;
  30. }
  31. VOID
  32. InitHashTable(
  33. VOID
  34. )
  35. /*++
  36. Routine Description
  37. Initializes the hash tables where the priority information is kept
  38. Locks
  39. None
  40. Arguments
  41. None
  42. Return Value
  43. None
  44. --*/
  45. {
  46. DWORD i;
  47. for(i=0; i < HASH_TABLE_SIZE; i++)
  48. {
  49. InitializeListHead(&HashTable[i]);
  50. }
  51. }
  52. BOOL
  53. InitPriorityDLL (
  54. HANDLE hInst,
  55. DWORD ulCallReason,
  56. PVOID pReserved
  57. )
  58. {
  59. static BOOL bPriorityLockInitialized = FALSE;
  60. switch(ulCallReason)
  61. {
  62. case DLL_PROCESS_ATTACH:
  63. {
  64. //
  65. // Not interested in any XXX_THREAD_XXX reasons
  66. //
  67. DisableThreadLibraryCalls(hInst);
  68. //
  69. // Initialize Critical Section for routing protocol list
  70. //
  71. try
  72. {
  73. InitializeCriticalSection(&PriorityLock);
  74. }
  75. except (EXCEPTION_EXECUTE_HANDLER)
  76. {
  77. return FALSE;
  78. }
  79. bPriorityLockInitialized = TRUE;
  80. //
  81. // Initialize Hash Table
  82. //
  83. InitHashTable();
  84. break;
  85. }
  86. case DLL_PROCESS_DETACH:
  87. {
  88. if ( bPriorityLockInitialized )
  89. {
  90. DeleteCriticalSection(&PriorityLock);
  91. bPriorityLockInitialized = FALSE;
  92. }
  93. break;
  94. }
  95. case DLL_THREAD_ATTACH:
  96. case DLL_THREAD_DETACH:
  97. {
  98. break;
  99. }
  100. }
  101. return TRUE;
  102. }
  103. DWORD
  104. ComputeRouteMetric(
  105. IN DWORD dwProtoId
  106. )
  107. /*++
  108. Routine Description
  109. This is the main function that computes the priority of a route.
  110. The priority is filled into the
  111. Locks
  112. Takes the lock guarding the hash table
  113. Arguments
  114. pRoute Pointer to route
  115. Return Value
  116. DWORD priority for the protocol
  117. --*/
  118. {
  119. PLIST_ENTRY pleNode;
  120. RoutingProtocolBlock *pProtoBlk;
  121. DWORD dwMetric;
  122. //
  123. // Initialize in case the specified protocol is not in the list
  124. //
  125. dwMetric = IP_PRIORITY_DEFAULT_METRIC;
  126. EnterCriticalSection(&PriorityLock);
  127. //
  128. // Walk the hash bucket for the protocol
  129. //
  130. for(pleNode = HashTable[dwProtoId % HASH_TABLE_SIZE].Flink;
  131. pleNode != &(HashTable[dwProtoId % HASH_TABLE_SIZE]);
  132. pleNode = pleNode->Flink)
  133. {
  134. //
  135. // Cast to appropriate structure
  136. //
  137. pProtoBlk = CONTAINING_RECORD(pleNode,
  138. RoutingProtocolBlock,
  139. RPB_List);
  140. //
  141. // If the info is for the protocol, copy out the priority metric
  142. //
  143. if(pProtoBlk->RPB_ProtocolMetric.dwProtocolId == dwProtoId)
  144. {
  145. dwMetric = pProtoBlk->RPB_ProtocolMetric.dwMetric;
  146. break;
  147. }
  148. }
  149. //
  150. // *** Exclusion End ***
  151. //
  152. LeaveCriticalSection(&PriorityLock);
  153. return dwMetric;
  154. }
  155. DWORD
  156. SetPriorityInfo(
  157. PRTR_INFO_BLOCK_HEADER pInfoHdr
  158. )
  159. /*++
  160. Routine Description
  161. This function is called by the IP Router Manager to set the priority
  162. information in the DLL. The structure and contents of this information
  163. are opaque to all but the setup and this DLL
  164. Locks
  165. Takes the hash table lock since the information is changing
  166. Arguments
  167. pInfoHdr Pointer to the InfoBlock header
  168. Return Value
  169. NO_ERROR Everything worked OK
  170. ERROR_NOT_ENOUGH_MEMORY Couldnt allocate memory
  171. --*/
  172. {
  173. DWORD i;
  174. PLIST_ENTRY pleListHead;
  175. PPRIORITY_INFO pInfo;
  176. RoutingProtocolBlock *currentblock;
  177. PRTR_TOC_ENTRY pToc;
  178. pToc = GetPointerToTocEntry(IP_PROT_PRIORITY_INFO,
  179. pInfoHdr);
  180. //
  181. // No info means leave things as they are
  182. //
  183. if(!pToc)
  184. {
  185. return NO_ERROR;
  186. }
  187. pInfo = (PPRIORITY_INFO)GetInfoFromTocEntry(pInfoHdr,
  188. pToc);
  189. if(!pInfo)
  190. {
  191. return NO_ERROR;
  192. }
  193. //
  194. // *** Exclusion Begin ***
  195. //
  196. EnterCriticalSection(&PriorityLock);
  197. //
  198. // If we already have the hash table populated - free the whole table.
  199. //
  200. if(RoutingProtocolBlockPtr)
  201. {
  202. HeapFree(GetProcessHeap(),
  203. 0,
  204. RoutingProtocolBlockPtr);
  205. InitHashTable();
  206. }
  207. if(pToc->InfoSize == 0)
  208. {
  209. //
  210. // Means delete all the info - which is done above
  211. //
  212. LeaveCriticalSection(&PriorityLock);
  213. return NO_ERROR;
  214. }
  215. //
  216. // Allocate enough RoutingProtocolBlocks to hold the newly specified info
  217. //
  218. RoutingProtocolBlockPtr =
  219. HeapAlloc(GetProcessHeap(),
  220. HEAP_ZERO_MEMORY,
  221. pInfo->dwNumProtocols * sizeof (RoutingProtocolBlock));
  222. if(RoutingProtocolBlockPtr == NULL)
  223. {
  224. //
  225. // *** Exclusion End ***
  226. //
  227. LeaveCriticalSection (&PriorityLock);
  228. return ERROR_NOT_ENOUGH_MEMORY;
  229. }
  230. //
  231. // Keep a count of the number of protocols
  232. //
  233. NumProtocols = pInfo->dwNumProtocols;
  234. //
  235. // Go thru pInfo and add each protocol and metric to the hash table
  236. //
  237. currentblock = RoutingProtocolBlockPtr;
  238. for(i=0; i < NumProtocols; i++)
  239. {
  240. currentblock->RPB_ProtocolMetric.dwProtocolId =
  241. pInfo->ppmProtocolMetric[i].dwProtocolId;
  242. currentblock->RPB_ProtocolMetric.dwMetric =
  243. pInfo->ppmProtocolMetric[i].dwMetric;
  244. pleListHead = &HashTable[pInfo->ppmProtocolMetric[i].dwProtocolId % HASH_TABLE_SIZE];
  245. InsertTailList(pleListHead,
  246. &currentblock->RPB_List);
  247. currentblock++;
  248. }
  249. //
  250. // *** Exclusion End ***
  251. //
  252. LeaveCriticalSection (&PriorityLock);
  253. return NO_ERROR;
  254. }
  255. DWORD
  256. GetPriorityInfo(
  257. IN PVOID pvBuffer,
  258. OUT PDWORD pdwBufferSize
  259. )
  260. /*++
  261. Routine Description
  262. Called by router manager to get a copy of our priority information
  263. Locks
  264. Takes the table lock to ensure consistency
  265. Arguments
  266. pvBuffer Pointer to buffer into which info is to be written
  267. pdwBufferSize [IN] Size of the buffer pointed to by pvBuffer
  268. [OUT] Size of data copied out, or size of buffer needed
  269. Return Value
  270. NO_ERROR Buffer of size *pdwBufferSize was copied out
  271. ERROR_INSUFFICIENT_BUFFER The buffer was too small to copy out the info
  272. The size of buffer needed is in *pdwBufferSize
  273. --*/
  274. {
  275. DWORD i, dwSizeReqd;
  276. PPRIORITY_INFO ppiPriorityInfo;
  277. RoutingProtocolBlock *currentblock;
  278. ppiPriorityInfo = pvBuffer;
  279. //
  280. // *** Exclusion Begin ***
  281. //
  282. EnterCriticalSection (&PriorityLock);
  283. dwSizeReqd = SIZEOF_PRIORITY_INFO(NumProtocols);
  284. if(dwSizeReqd > *pdwBufferSize)
  285. {
  286. *pdwBufferSize = dwSizeReqd;
  287. //
  288. // *** Exclusion End ***
  289. //
  290. LeaveCriticalSection (&PriorityLock);
  291. return ERROR_INSUFFICIENT_BUFFER;
  292. }
  293. *pdwBufferSize = dwSizeReqd;
  294. //
  295. // Go thru pinfo and get each protocol and metric
  296. //
  297. currentblock = RoutingProtocolBlockPtr;
  298. for(i=0; i < NumProtocols; i++)
  299. {
  300. ppiPriorityInfo->ppmProtocolMetric[i].dwProtocolId =
  301. currentblock->RPB_ProtocolMetric.dwProtocolId;
  302. ppiPriorityInfo->ppmProtocolMetric[i].dwMetric =
  303. currentblock->RPB_ProtocolMetric.dwMetric;
  304. currentblock++;
  305. }
  306. ppiPriorityInfo->dwNumProtocols = NumProtocols;
  307. //
  308. // *** Exclusion End ***
  309. //
  310. LeaveCriticalSection(&PriorityLock);
  311. return NO_ERROR;
  312. }