Source code of Windows XP (NT5)
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.

410 lines
8.1 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. routing\ip\rtrmgr\asyncwrk.c
  5. Abstract:
  6. All functions called spooled to a worker function
  7. Revision History:
  8. Gurdeep Singh Pall 6/15/95 Created
  9. --*/
  10. #include "allinc.h"
  11. DWORD
  12. QueueAsyncFunction(
  13. WORKERFUNCTION pfnFunction,
  14. PVOID pvContext,
  15. BOOL bAlertable
  16. )
  17. /*++
  18. Routine Description
  19. Locks
  20. Arguments
  21. Return Value
  22. --*/
  23. {
  24. DWORD dwResult = NO_ERROR;
  25. BOOL bRetval;
  26. EnterCriticalSection(&RouterStateLock);
  27. if (RouterState.IRS_State is RTR_STATE_RUNNING)
  28. {
  29. RouterState.IRS_RefCount++;
  30. LeaveCriticalSection(&RouterStateLock);
  31. }
  32. else
  33. {
  34. LeaveCriticalSection(&RouterStateLock) ;
  35. return ERROR_ROUTER_STOPPED ;
  36. }
  37. bRetval = QueueUserWorkItem(
  38. (LPTHREAD_START_ROUTINE)pfnFunction,
  39. pvContext,
  40. bAlertable ? WT_EXECUTEINIOTHREAD : 0);
  41. //
  42. // If we successfully queued the item, dont decrement the count
  43. //
  44. if(bRetval isnot TRUE)
  45. {
  46. dwResult = GetLastError();
  47. Trace1(GLOBAL,
  48. "QueueAsyncWorker %x",
  49. pfnFunction);
  50. EnterCriticalSection(&RouterStateLock);
  51. RouterState.IRS_RefCount--;
  52. LeaveCriticalSection(&RouterStateLock);
  53. }
  54. return dwResult;
  55. }
  56. VOID
  57. RestoreStaticRoutes(
  58. PVOID pvContext
  59. )
  60. /*++
  61. Routine Description
  62. Locks
  63. Arguments
  64. Return Value
  65. --*/
  66. {
  67. PICB pIfToRestore, pOldIf;
  68. PRESTORE_INFO_CONTEXT pricInfo;
  69. DWORD dwResult, dwSize, dwIndex, dwSeq, i;
  70. PRTR_INFO_BLOCK_HEADER pribhIfInfo;
  71. HANDLE hDIM;
  72. TraceEnter("RestoreStaticRoutes");
  73. ENTER_READER(ICB_LIST);
  74. pricInfo = (PRESTORE_INFO_CONTEXT)pvContext;
  75. dwIndex = pricInfo->dwIfIndex;
  76. pIfToRestore = InterfaceLookupByIfIndex(dwIndex);
  77. HeapFree(IPRouterHeap,
  78. 0,
  79. pvContext);
  80. if(pIfToRestore is NULL)
  81. {
  82. Trace0(ERR,
  83. "RestoreStaticRoutes: Could not find ICB");
  84. TraceLeave("RestoreStaticRoutes");
  85. EXIT_LOCK(ICB_LIST);
  86. ExitRouterApi();
  87. return;
  88. }
  89. if(pIfToRestore->ritType is ROUTER_IF_TYPE_DEDICATED)
  90. {
  91. //
  92. // Now pick up the routes the stack may have added
  93. //
  94. AddAllStackRoutes(pIfToRestore);
  95. for ( i = 0; i < pIfToRestore->dwNumAddresses; i++)
  96. {
  97. AddLoopbackRoute(
  98. pIfToRestore->pibBindings[i].dwAddress,
  99. pIfToRestore->pibBindings[i].dwMask
  100. );
  101. }
  102. }
  103. pOldIf = pIfToRestore;
  104. hDIM = pIfToRestore->hDIMHandle;
  105. dwSeq = pIfToRestore->dwSeqNumber;
  106. EXIT_LOCK(ICB_LIST);
  107. Trace1(IF,
  108. "RestoreStaticRoutes: restoring for %S\n",
  109. pIfToRestore->pwszName);
  110. dwSize = 0;
  111. dwResult = RestoreInterfaceInfo(hDIM,
  112. PID_IP,
  113. NULL,
  114. &dwSize);
  115. if(dwResult isnot ERROR_BUFFER_TOO_SMALL)
  116. {
  117. //
  118. // This is the only error code which will give us a good info size
  119. //
  120. Trace2(ERR,
  121. "RestoreStaticRoutes: Error %d trying to get info size from DIM for i/f %d",
  122. dwResult,
  123. dwIndex);
  124. TraceLeave("RestoreStaticRoutes");
  125. ExitRouterApi();
  126. return;
  127. }
  128. //
  129. // So now we have the memory size we use double to
  130. // avoid any problem
  131. //
  132. dwSize = 2 * dwSize;
  133. pribhIfInfo = HeapAlloc(IPRouterHeap,
  134. HEAP_ZERO_MEMORY,
  135. dwSize);
  136. if(pribhIfInfo is NULL)
  137. {
  138. Trace2(ERR,
  139. "RestoreStaticRoutes: Error allocating %d bytes for info for i/f %d",
  140. dwSize,
  141. dwIndex);
  142. TraceLeave("RestoreStaticRoutes");
  143. ExitRouterApi();
  144. return;
  145. }
  146. dwResult = RestoreInterfaceInfo(hDIM,
  147. PID_IP,
  148. (PVOID)pribhIfInfo,
  149. &dwSize);
  150. if(dwResult isnot NO_ERROR)
  151. {
  152. Trace2(ERR,
  153. "RestoreStaticRoutes: Error %d getting info for i/f %d",
  154. dwResult,
  155. dwIndex);
  156. TraceLeave("RestoreStaticRoutes");
  157. ExitRouterApi();
  158. return;
  159. }
  160. ENTER_READER(ICB_LIST);
  161. pIfToRestore = InterfaceLookupByIfIndex(dwIndex);
  162. if(pIfToRestore is NULL)
  163. {
  164. EXIT_LOCK(ICB_LIST);
  165. HeapFree(IPRouterHeap,
  166. 0,
  167. pribhIfInfo);
  168. ExitRouterApi();
  169. return;
  170. }
  171. if((pIfToRestore->dwOperationalState <= IF_OPER_STATUS_UNREACHABLE) or
  172. (pIfToRestore->dwAdminState isnot IF_ADMIN_STATUS_UP))
  173. {
  174. Trace3(IF,
  175. "RestoreStaticRoutes: Not restoring routes on %S because states are %d %d",
  176. pIfToRestore->pwszName,
  177. pIfToRestore->dwOperationalState,
  178. pIfToRestore->dwAdminState);
  179. EXIT_LOCK(ICB_LIST);
  180. HeapFree(IPRouterHeap,
  181. 0,
  182. pribhIfInfo);
  183. ExitRouterApi();
  184. return;
  185. }
  186. IpRtAssert(pIfToRestore->dwSeqNumber is dwSeq);
  187. IpRtAssert(pIfToRestore is pOldIf);
  188. dwResult = SetRouteInfo(pIfToRestore,
  189. pribhIfInfo);
  190. if(dwResult isnot NO_ERROR)
  191. {
  192. Trace2(ERR,
  193. "RestoreStaticRoutes. Error %d setting routes for %S",
  194. dwResult,
  195. pIfToRestore->pwszName);
  196. }
  197. else
  198. {
  199. Trace1(IF,
  200. "RestoreStaticRoutes: Successfully set routes for %S",
  201. pIfToRestore->pwszName);
  202. }
  203. pIfToRestore->bRestoringRoutes = FALSE;
  204. EXIT_LOCK(ICB_LIST);
  205. HeapFree(IPRouterHeap,
  206. 0,
  207. pribhIfInfo);
  208. TraceLeave("RestoreStaticRoutes");
  209. ExitRouterApi();
  210. return;
  211. }
  212. VOID
  213. ResolveHbeatName(
  214. PVOID pvContext
  215. )
  216. {
  217. PHEARTBEAT_CONTEXT pInfo;
  218. HOSTENT *pHostEntry;
  219. CHAR pszGroup[MAX_GROUP_LEN];
  220. PMCAST_HBEAT_CB pHbeatCb;
  221. PICB picb;
  222. DWORD dwResult;
  223. pInfo = (PHEARTBEAT_CONTEXT) pvContext;
  224. WideCharToMultiByte(CP_ACP,
  225. 0,
  226. pInfo->pwszGroup,
  227. -1,
  228. pszGroup,
  229. MAX_GROUP_LEN,
  230. NULL,
  231. NULL);
  232. pHostEntry = gethostbyname(pszGroup);
  233. if(pHostEntry is NULL)
  234. {
  235. HeapFree(IPRouterHeap,
  236. 0,
  237. pvContext);
  238. Trace2(ERR,
  239. "ResolveHbeatName: Error %d resolving %S",
  240. GetLastError(),
  241. pInfo->pwszGroup);
  242. ExitRouterApi();
  243. return;
  244. }
  245. ENTER_WRITER(ICB_LIST);
  246. picb = InterfaceLookupByIfIndex(pInfo->dwIfIndex);
  247. if(picb is NULL)
  248. {
  249. EXIT_LOCK(ICB_LIST);
  250. HeapFree(IPRouterHeap,
  251. 0,
  252. pvContext);
  253. ExitRouterApi();
  254. return;
  255. }
  256. if(picb isnot pInfo->picb)
  257. {
  258. EXIT_LOCK(ICB_LIST);
  259. HeapFree(IPRouterHeap,
  260. 0,
  261. pvContext);
  262. ExitRouterApi();
  263. return;
  264. }
  265. pHbeatCb = &picb->mhcHeartbeatInfo;
  266. pHbeatCb->dwGroup = *((PDWORD)(pHostEntry->h_addr_list[0]));
  267. HeapFree(IPRouterHeap,
  268. 0,
  269. pvContext);
  270. dwResult = StartMHeartbeat(picb);
  271. if(dwResult isnot NO_ERROR)
  272. {
  273. Trace2(ERR,
  274. "ResolveHbeatName: Error %d starting hbeat for %S",
  275. dwResult,
  276. picb->pwszName);
  277. }
  278. EXIT_LOCK(ICB_LIST);
  279. ExitRouterApi();
  280. return;
  281. }