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.

467 lines
10 KiB

  1. /*++
  2. Copyright (c) 2000, Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. Author:
  6. Savas Guven (savasg) 27-Nov-2000
  7. Revision History:
  8. */
  9. #include "stdafx.h"
  10. CLIST g_IcqClientList;
  11. CSockDispatcher * g_IcqPeerDispatcherp = NULL;
  12. IcqPrx::IcqPrx()
  13. :m_Socketp(NULL),
  14. m_ControlChannelp(NULL)
  15. {
  16. ICQ_TRC(TM_IO, TL_DUMP, (" ICQPRX - Default - Constructor"));
  17. g_IcqComponentReferencep = dynamic_cast<PCOMPONENT_SYNC>(this);
  18. }
  19. IcqPrx::~IcqPrx()
  20. {
  21. ICQ_TRC(TM_IO, TL_DUMP, ("ICQPRX - ~ DESTRUCTOR"));
  22. if(this->bCleanupCalled is FALSE)
  23. {
  24. IcqPrx::ComponentCleanUpRoutine();
  25. }
  26. this->bCleanupCalled = FALSE;
  27. }
  28. //
  29. // The Local Socket is a resource which needs to be freed up.
  30. // All the Clients needs to be deleted from the entries?
  31. // The CSockDispatcher needs to be cleared up.
  32. //
  33. void
  34. IcqPrx::ComponentCleanUpRoutine(void)
  35. {
  36. if( m_Socketp )
  37. {
  38. DELETE_COMPONENT( m_Socketp );
  39. m_Socketp = NULL;
  40. }
  41. if( g_IcqPeerDispatcherp )
  42. {
  43. DELETE_COMPONENT( g_IcqPeerDispatcherp );
  44. }
  45. if ( m_ControlChannelp )
  46. {
  47. m_ControlChannelp->Cancel();
  48. m_ControlChannelp->Release();
  49. m_ControlChannelp = NULL;
  50. }
  51. this->bCleanupCalled = TRUE;
  52. }
  53. void
  54. IcqPrx::StopSync()
  55. {
  56. ULONG hr = S_OK;
  57. if( m_Socketp )
  58. {
  59. STOP_COMPONENT( m_Socketp );
  60. }
  61. if( g_IcqPeerDispatcherp )
  62. {
  63. STOP_COMPONENT( g_IcqPeerDispatcherp );
  64. }
  65. if( m_ControlChannelp )
  66. {
  67. hr = m_ControlChannelp->Cancel();
  68. if( FAILED(hr) )
  69. {
  70. ICQ_TRC(TM_PRX, TL_ERROR,
  71. ("** !! Can't cancel the PRIMARY redirect e(%X)", hr));
  72. }
  73. else
  74. {
  75. m_ControlChannelp = NULL;
  76. }
  77. }
  78. }
  79. ULONG
  80. IcqPrx::RunIcq99Proxy(
  81. ULONG BoundaryIp
  82. )
  83. /*++
  84. Routine Description:
  85. Arguments:
  86. none.
  87. Return Value:
  88. --*/
  89. {
  90. ULONG hr = S_OK;
  91. USHORT port;
  92. ULONG ip;
  93. ICQ_TRC(TM_PRX, TL_INFO, ("> ICQ 99 PRxY %lu", BoundaryIp));
  94. ASSERT(BoundaryIp != 0);
  95. NEW_OBJECT( m_Socketp, CNhSock );
  96. if( m_Socketp is NULL) return E_OUTOFMEMORY;
  97. //
  98. // Get the Public IP information
  99. ip = BoundaryIp;
  100. g_MyPublicIp = ip;
  101. // __asm int 3
  102. do
  103. {
  104. // Init globals
  105. __try
  106. {
  107. g_IcqPeerDispatcherp = new CSockDispatcher(ip, 0);
  108. }
  109. __except( EXCEPTION_EXECUTE_HANDLER )
  110. {
  111. delete g_IcqPeerDispatcherp;
  112. hr = E_OUTOFMEMORY;
  113. g_IcqPeerDispatcherp = NULL;
  114. }
  115. if ( g_IcqPeerDispatcherp is NULL )
  116. {
  117. ICQ_TRC(TM_PRX, TL_ERROR,("Dispatcher creation failed - mem alloc"));
  118. hr = E_OUTOFMEMORY;
  119. break;
  120. }
  121. //
  122. // Create UDP socket with the given IP:Port in the argv
  123. //
  124. hr = m_Socketp->NhCreateDatagramSocket(ip, 0, NULL);
  125. if ( hr )
  126. {
  127. hr = HRESULT_FROM_WIN32( hr );
  128. ICQ_TRC(TM_PRX, TL_ERROR,
  129. ("Can't Create the Primary UDP socket E(%X)", hr));
  130. break;
  131. }
  132. m_Socketp->NhQueryLocalEndpointSocket( NULL, &port );
  133. //
  134. // Create Dynamic SRC redirection to the IP and port
  135. //
  136. hr = g_IAlgServicesp->CreatePrimaryControlChannel(eALG_UDP,
  137. ICQ99_SERVER_PORT,
  138. eALG_DESTINATION_CAPTURE,
  139. FALSE,
  140. ip,
  141. port,
  142. &m_ControlChannelp);
  143. if( FAILED(hr) )
  144. {
  145. ICQ_TRC(TM_PRX, TL_ERROR,
  146. ("ERROR !!> DynamicPortRedirect Has Failed E(%X)", hr));
  147. break;
  148. }
  149. ICQ_TRC(TM_PRX, TL_INFO,
  150. ("All Outgoing redirects will be sent to %s(%hu)",
  151. INET_NTOA(ip), htons(port)));
  152. // Issue a read operation on the UDP socket.
  153. hr = m_Socketp->NhReadDatagramSocket(g_IcqComponentReferencep,
  154. NULL,
  155. IcqReadClientUdpCompletionRoutine,
  156. NULL,
  157. NULL);
  158. if ( hr )
  159. {
  160. hr = HRESULT_FROM_WIN32( hr );
  161. ICQ_TRC(TM_PRX, TL_ERROR, ("hr Level E(%X)", hr));
  162. ASSERT( FALSE );
  163. }
  164. } while (0);
  165. //
  166. // Handle the error case
  167. //
  168. if ( FAILED(hr) )
  169. {
  170. //
  171. // Delete Dispatcher
  172. if ( g_IcqPeerDispatcherp != NULL )
  173. {
  174. DELETE_COMPONENT( g_IcqPeerDispatcherp );
  175. g_IcqPeerDispatcherp = NULL;
  176. }
  177. //
  178. // Delete Socket
  179. if ( m_Socketp != NULL )
  180. {
  181. DELETE_COMPONENT( m_Socketp );
  182. m_Socketp = NULL;
  183. }
  184. //
  185. // Delete The Primary Control Channel
  186. if ( m_ControlChannelp )
  187. {
  188. m_ControlChannelp->Cancel();
  189. m_ControlChannelp->Release();
  190. m_ControlChannelp = NULL;
  191. }
  192. }
  193. return hr;
  194. }
  195. ULONG
  196. IcqPrx::ReadFromClientCompletionRoutine
  197. (
  198. ULONG ErrorCode,
  199. ULONG BytesTransferred,
  200. PNH_BUFFER Bufferp
  201. )
  202. /*++
  203. Routine Description:
  204. This is the READ - DISPATCHER for the UDP
  205. Clients sending packets to the server will be caught here..
  206. it will dispatch the packet to the appropriate ICQ client objects READER
  207. Arguments:
  208. none.
  209. Return Value:
  210. --*/
  211. {
  212. PCNhSock Socketp = Bufferp->Socketp;
  213. PICQ_CLIENT IcqClientp = NULL;
  214. // NAT_KEY_SESSION_MAPPING_EX_INFORMATION Key;
  215. // ULONG Length = sizeof(NAT_KEY_SESSION_MAPPING_EX_INFORMATION);
  216. ULONG hr = NO_ERROR;
  217. ULONG LocalIp, ActualClientIp, ActualDestinationIp;
  218. USHORT LocalPort, ActualClientPort, ActualDestinationPort;
  219. if(ErrorCode)
  220. {
  221. //
  222. // Delete the List of the Clients here.
  223. // Starts from the head of the List
  224. // Don't try to use a Removed Element unless you're damn sure
  225. // that its Ref Count hasn't reached zero yet.
  226. //
  227. ICQ_TRC(TM_PRX, TL_CRIT, ("STOPPING the MAIN READ Socket for UDP"));
  228. for(IcqClientp = dynamic_cast<PICQ_CLIENT>(g_IcqClientList.RemoveSortedKeys(0,0));
  229. IcqClientp != NULL;
  230. IcqClientp = dynamic_cast<PICQ_CLIENT>(g_IcqClientList.RemoveSortedKeys(0,0))
  231. )
  232. {
  233. // NOTE: decide what to do.
  234. }
  235. hr = E_FAIL;
  236. }
  237. else
  238. {
  239. //
  240. // Read about the local client..
  241. //
  242. // Socketp->NhQueryLocalEndpointSocket(&LocalIp, &LocalPort);
  243. ActualClientIp = Bufferp->ReadAddress.sin_addr.S_un.S_addr;
  244. ActualClientPort = Bufferp->ReadAddress.sin_port;
  245. //
  246. // Get Information about the actual destination
  247. //
  248. hr = m_ControlChannelp->GetOriginalDestinationInformation(ActualClientIp,
  249. ActualClientPort,
  250. &ActualDestinationIp,
  251. &ActualDestinationPort,
  252. NULL);
  253. if( FAILED(hr) )
  254. {
  255. ICQ_TRC(TM_PRX, TL_ERROR,
  256. ("Can't use the GetOriginalDestination Information Interface E(%X)", hr ));
  257. }
  258. else
  259. {
  260. ICQ_TRC(TM_PRX, TL_TRACE,("DATA CAME from %s-%hu",
  261. INET_NTOA(ActualClientIp), htons(ActualClientPort)));
  262. ICQ_TRC(TM_PRX, TL_TRACE,("DATA WILL BE SEND TO %s-%hu",
  263. INET_NTOA(ActualDestinationIp), htons(ActualDestinationPort)));
  264. }
  265. //
  266. // Find the appropriate ICQ client entry for this
  267. // ICQ CLIENT ~ ICQ SERVER UDP connection
  268. // Search the Created ICQ Client List to handle proper one.
  269. //
  270. // NOTE: Should we handle this with just IPs?
  271. // and the other Key might just be the server IP???
  272. //
  273. IcqClientp = dynamic_cast<PICQ_CLIENT>
  274. (g_IcqClientList.SearchNodeKeys(ActualClientIp, 0));
  275. //
  276. // If there is no such entry than create one.
  277. //
  278. if(IcqClientp is NULL)
  279. {
  280. ICQ_TRC(TM_PRX, TL_INFO, ("PRX> NEW ICQ CLIENT DETECTED %s",
  281. INET_NTOA(ActualClientIp)));
  282. NEW_OBJECT(IcqClientp, ICQ_CLIENT);
  283. //
  284. // NOTE : ERROR CASE - proper handling pls.
  285. if(IcqClientp is NULL)
  286. {
  287. ICQ_TRC(TM_PRX, TL_ERROR, ("PRX> MEMORY ALLOC ERROR"));
  288. hr = E_OUTOFMEMORY;
  289. return hr;
  290. }
  291. //
  292. // Write the IP-PORT information Here The client class
  293. // will collect rest of the information along the way
  294. //
  295. hr = IcqClientp->Initialize(Bufferp,
  296. ActualClientIp,
  297. ActualClientPort,
  298. ActualDestinationIp,
  299. ActualDestinationPort,
  300. Socketp);
  301. _ASSERT( SUCCEEDED(hr) );
  302. if( FAILED(hr) )
  303. {
  304. DELETE_COMPONENT( IcqClientp );
  305. }
  306. else // Add the client to the List
  307. {
  308. g_IcqClientList.InsertSorted(IcqClientp);
  309. }
  310. }
  311. else
  312. {
  313. ICQ_TRC(TM_PRX, TL_TRACE,
  314. ("PRX> ICQ CLIENT EXISTS - READ-client will be called"));
  315. hr = IcqClientp->ClientRead( Bufferp,
  316. ActualDestinationIp,
  317. ActualDestinationPort );
  318. }
  319. }
  320. if ( FAILED(hr) )
  321. {
  322. }
  323. return hr;
  324. }