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.

1159 lines
21 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. //
  11. // Initialize the static member
  12. //
  13. ULONG CSockDispatcher::UniqueId = 0;
  14. const PCHAR CSockDispatcher::ObjectNamep = "CSockDispatcher";
  15. const PCHAR DispatcheeNode::ObjectNamep = "DispatcheeNode";
  16. const PCHAR _Dispatchee::ObjectNamep = "DISPATCHEE";
  17. //
  18. // Anythin to initialize?
  19. //
  20. CSockDispatcher::CSockDispatcher()
  21. {
  22. ICQ_TRC(TM_DISP, TL_DUMP, (" CSockDispatcher - Default Constructor "));
  23. }
  24. //
  25. //
  26. CSockDispatcher::CSockDispatcher
  27. (
  28. ULONG IpAddress,
  29. USHORT port
  30. )
  31. /*++
  32. Routine Description:
  33. This function Should simplY call the InitDispatcher with the appropriate
  34. parameters passed here.
  35. Arguments:
  36. none.
  37. Return Value:
  38. --*/
  39. {
  40. ICQ_TRC(TM_DISP, TL_DUMP, (" CSockDispatcher - CNSTR with IP and PORT %hu ", htons(port)));
  41. this->InitDispatcher(IpAddress, port);
  42. }
  43. //
  44. // What needs to be deleted. ?
  45. // All the DispatcheeNodes needs to be deleted.
  46. //
  47. CSockDispatcher::~CSockDispatcher()
  48. {
  49. ICQ_TRC(TM_DISP, TL_DUMP, ("CSockDispatcher - ~ DESTRUCTOR "));
  50. if(this->bCleanupCalled is FALSE)
  51. {
  52. CSockDispatcher::ComponentCleanUpRoutine();
  53. }
  54. //
  55. // This will cause the Destructors of inherited classes to
  56. // be called which will call their respective Cleanups
  57. //
  58. this->bCleanupCalled = FALSE;
  59. }
  60. //
  61. //
  62. ULONG
  63. CSockDispatcher::InitDispatcher
  64. (
  65. ULONG IpAddress,
  66. USHORT port
  67. )
  68. /*++
  69. Routine Description:
  70. InitDispatcher initializes the socket and issues an Accept
  71. Furthermore It needs to Reference for the Accept call
  72. (which should be dereferenced at at the AcceptCompletion
  73. Arguments:
  74. ULONG IpAddress - IP on which the TCP socket (for accept) should wait on.
  75. USHORT port - Port on which the TCP socket (for accept) should wait on.
  76. Return Value:
  77. Returns the ULONG Win32/Winsock2 Error code
  78. --*/
  79. {
  80. ULONG Error = NO_ERROR;
  81. ICQ_TRC(TM_DISP, TL_DUMP, ("CSockDispatcher - InitDispatcher "));
  82. //
  83. // Create a stream scoket on the given IP and PORT
  84. //
  85. Error = this->NhCreateStreamSocket(IpAddress, port, NULL);
  86. if(Error)
  87. {
  88. ErrorOut();
  89. ICQ_TRC(TM_DISP, TL_ERROR,
  90. ("CSockDispatcher - Init> can't create the SOCKET"));
  91. return Error;
  92. }
  93. Error = listen(this->Socket, SOMAXCONN);
  94. if(Error)
  95. {
  96. ICQ_TRC(TM_DISP, TL_ERROR,
  97. ("CSockDispatcher - Init> Can' Listen the Created socket"));
  98. ErrorOut();
  99. return Error;
  100. }
  101. //
  102. // Since the Socket inheritance guarantees that
  103. // the REFERENCING of the self-object will be done
  104. // we should not reference ourselves again here.
  105. //
  106. Error = this->NhAcceptStreamSocket(g_IcqComponentReferencep,
  107. NULL,
  108. NULL,
  109. DispatcherAcceptCompletionRoutine,
  110. this,
  111. NULL);
  112. if(Error)
  113. {
  114. ICQ_TRC(TM_DISP, TL_ERROR,
  115. ("CSockDispatch - Init> Accept call has failed"));
  116. ErrorOut();
  117. }
  118. return Error;
  119. }
  120. void
  121. CSockDispatcher::ComponentCleanUpRoutine(void)
  122. /*++
  123. Routine Description:
  124. Arguments:
  125. none.
  126. Return Value:
  127. --*/
  128. {
  129. DispatcheeNode * DNp = NULL;
  130. ICQ_TRC(TM_DISP, TL_DUMP, (" CSockDispatcher - ComponentCleanUpRoutine "));
  131. this->bCleanupCalled = TRUE;
  132. }
  133. void
  134. CSockDispatcher::StopSync(void)
  135. /*++
  136. Routine Description:
  137. Arguments:
  138. none.
  139. Return Value:
  140. --*/
  141. {
  142. this->NhDeleteSocket();
  143. this->Deleted = TRUE;
  144. }
  145. //
  146. //
  147. ULONG
  148. CSockDispatcher::InitDispatchee(PDISPATCHEE Dispatchp)
  149. /*++
  150. Routine Description:
  151. Gives a unique ID to the Dispatchee and then
  152. creates a Dispatchee node to put the dispatchee into a List..
  153. (If it is not there already) the counter of the dispatcher
  154. should be incremented.
  155. Arguments:
  156. none.
  157. Return Value:
  158. --*/
  159. {
  160. DispatcheeNode * DNp = NULL;
  161. ICQ_TRC(TM_DISP, TL_DUMP, ("CSockDispatcher - InitDispatchee "));
  162. if(Dispatchp is NULL) return 0; // Unknown Parameter
  163. if(Dispatchp->GetID() != 0) return 0; // " "
  164. this->AcquireLock();
  165. Dispatchp->SetID(++UniqueId);
  166. this->ReleaseLock();
  167. NEW_OBJECT(DNp, DispatcheeNode);
  168. //DNp = new DispatcheeNode();
  169. if(DNp is NULL)
  170. {
  171. Dispatchp->SetID(0);
  172. return FALSE;
  173. }
  174. DNp->InitDispatcheeNode( Dispatchp );
  175. this->listDispNodes.InsertSorted( DNp );
  176. //
  177. // We dereference the DispatcheeNode so that its life time ends,
  178. // when it is removed from the list.
  179. //
  180. DEREF_COMPONENT( DNp, eRefInitialization );
  181. return S_OK;
  182. }
  183. //
  184. //
  185. ULONG
  186. CSockDispatcher::RemoveDispatchee(PDISPATCHEE Dispatchp)
  187. {
  188. DispatcheeNode* DNp = NULL;
  189. ICQ_TRC(TM_DISP, TL_INFO, ("CSockDispatcher - InitDispatchee "));
  190. if ( Dispatchp is NULL ) { ASSERT( FALSE ); return E_INVALIDARG;}
  191. if ( Dispatchp->GetID() == 0) { ASSERT(FALSE); return E_INVALIDARG;}
  192. DNp = dynamic_cast<DispatcheeNode*>(this->listDispNodes.SearchNodeKeys(Dispatchp->GetID(), 0));
  193. if ( DNp is NULL) { ASSERT( FALSE ); return E_INVALIDARG; }
  194. this->listDispNodes.RemoveNodeFromList(DNp);
  195. return S_OK;
  196. }
  197. //
  198. //
  199. ULONG
  200. CSockDispatcher::GetDispatchInfo
  201. (
  202. PULONG IPp,
  203. PUSHORT Portp
  204. )
  205. /*++
  206. Routine Description:
  207. Should Return the IP and Port on which this Dispatcher is operating.
  208. Arguments:
  209. PULONG IPp - The IP on which the Dispatcher is operating .
  210. PUSHORT Portp - The
  211. Return Value:
  212. --*/
  213. {
  214. if(IPp is NULL || Portp is NULL)
  215. return 0; // Fail
  216. this->NhQueryLocalEndpointSocket(IPp, Portp);
  217. return 1;
  218. }
  219. //
  220. //
  221. ULONG
  222. CSockDispatcher::AddDispatchRequest
  223. (
  224. PDISPATCHEE Dispatchp,
  225. PDispatchRequest DispatchRequestp
  226. )
  227. /*++
  228. Routine Description:
  229. This will add a Dispatch Request to the related Dispatch Node's request list.
  230. Arguments:
  231. none.
  232. Return Value:
  233. --*/
  234. {
  235. DispatcheeNode * DNp = NULL;
  236. if(Dispatchp is NULL || DispatchRequestp is NULL)
  237. {
  238. return E_INVALIDARG; // FAIL.
  239. }
  240. //
  241. // Is there such an entry?
  242. //
  243. DNp = dynamic_cast<DispatcheeNode*>
  244. (this->listDispNodes.SearchNodeKeys(Dispatchp->GetID(), 0));
  245. if(DNp is NULL)
  246. {
  247. ASSERT ( FALSE );
  248. return E_INVALIDARG; // FAIL
  249. }
  250. DNp->AddDispatchRequest(DispatchRequestp);
  251. return 1;
  252. }
  253. //
  254. // This will Delete a DispatchRequest. Note that Dispatched Requests are removed
  255. // from the list
  256. //
  257. ULONG
  258. CSockDispatcher::DeleteDispatchRequest
  259. (
  260. PDispatchRequest DispatchRequestp
  261. )
  262. /*++
  263. Routine Description:
  264. Arguments:
  265. none.
  266. Return Value:
  267. --*/
  268. {
  269. DispatcheeNode * DNp = NULL;
  270. DispatchReply DR;
  271. if(DispatchRequestp is NULL)
  272. return E_FAIL; // FAIL
  273. ZeroMemory(&DR, sizeof(DispatchReply));
  274. DR.dispatch.dstIp = DispatchRequestp->dstIp;
  275. DR.dispatch.dstPort = DispatchRequestp->dstPort;
  276. DR.dispatch.srcIp = DispatchRequestp->srcIp;
  277. DR.dispatch.srcPort = DispatchRequestp->srcPort;
  278. this->AcquireLock();
  279. for (DNp = dynamic_cast<DispatcheeNode*>(this->listDispNodes.SearchNodeKeys(0,0));
  280. DNp != NULL;
  281. DNp = dynamic_cast<DispatcheeNode*>(DNp->Nextp))
  282. {
  283. if(DNp->isDispatchYours(&DR))
  284. {
  285. DNp->DeleteDispatchRequest(DispatchRequestp);
  286. this->ReleaseLock();
  287. return NO_ERROR;
  288. }
  289. }
  290. this->ReleaseLock();
  291. return NO_ERROR;
  292. }
  293. //
  294. // DispatcherNode MEMBER functions.
  295. //
  296. //
  297. //
  298. //
  299. DispatcheeNode::~DispatcheeNode()
  300. /*++
  301. Routine Description:
  302. Arguments:
  303. none.
  304. Return Value:
  305. --*/
  306. {
  307. ICQ_TRC(TM_DISP, TL_DUMP, (" DispatcheeNode - Destructor"));
  308. if(this->bCleanupCalled is FALSE)
  309. {
  310. DispatcheeNode::ComponentCleanUpRoutine();
  311. }
  312. this->bCleanupCalled = FALSE;
  313. }
  314. //
  315. //
  316. //
  317. void
  318. DispatcheeNode::ComponentCleanUpRoutine(void)
  319. /*++
  320. Routine Description:
  321. Arguments:
  322. none.
  323. Return Value:
  324. --*/
  325. {
  326. ICQ_TRC(TM_DISP, TL_DUMP, (" DispatcheeNode - CLEAN UP"));
  327. // PDispatchRequest DRp = NULL;
  328. // Dereference the Dispatchee.
  329. DEREF_COMPONENT( DispatchTop, eRefInitialization );
  330. DispatchTop = NULL;
  331. // Remove the List elements.
  332. // Destructor of the List class will handle this
  333. this->bCleanupCalled = TRUE;
  334. }
  335. VOID
  336. DispatcheeNode::InitDispatcheeNode(PDISPATCHEE Dispatchp)
  337. /*++
  338. Routine Description:
  339. Note that a This Dispatching is intended to work on redirected TCP connections
  340. Thus the search Key is working on Destinations pairs
  341. Arguments:
  342. none.
  343. Return Value:
  344. NOTE:
  345. It references the Dispatchee Pointer. and the dereferencing will be done only
  346. When this OBJECT is dereferenced to NULL,
  347. Which happens only if this Node is deleted from the Dispatchee Node List
  348. within the CSockDispatcher. (At the time of destruction.)
  349. --*/
  350. {
  351. DispatchTop = Dispatchp;
  352. //ASSERT(Dispatchp);
  353. REF_COMPONENT( Dispatchp, eRefSecondLevel );
  354. if(DispatchTop != NULL)
  355. {
  356. this->iKey1 = Dispatchp->GetID();
  357. this->iKey2 = 0;
  358. }
  359. else
  360. {
  361. this->iKey1 = 0;
  362. this->iKey2 = 0;
  363. }
  364. }
  365. ULONG
  366. DispatcheeNode::isDispatchYours(PDispatchReply DispatchReplyp)
  367. /*++
  368. Routine Description:
  369. From the Reply structure we search for the existing Dispatch Requests
  370. This will reveal us wether such a query exists or not.
  371. Note that the Search Keys just contain the destination
  372. metric (IP:PORT)
  373. Arguments:
  374. none.
  375. Return Value:
  376. --*/
  377. {
  378. PDispatchRequest DRp = NULL;
  379. // DispatchReplyp->dispatch
  380. if(DispatchReplyp is NULL) return 0; //FAIL
  381. DRp = dynamic_cast<PDispatchRequest>
  382. (listRequests.SearchNodeKeys(DispatchReplyp->dispatch.dstIp,
  383. DispatchReplyp->dispatch.dstPort
  384. )
  385. );
  386. if(DRp != NULL)
  387. {
  388. //
  389. // So that we know where the data came from..
  390. // NOTE: that along with the interfaces this schema may change.
  391. //
  392. DispatchReplyp->dispatch.DirectionContext = DRp->DirectionContext;
  393. // check the source addresses as well. Unless they are zero
  394. if((DRp->srcIp != 0) &&
  395. (DispatchReplyp->dispatch.srcIp != NULL))
  396. {
  397. if(DispatchReplyp->dispatch.srcIp is DRp->srcIp )
  398. {
  399. return TRUE;
  400. }
  401. return FALSE;
  402. }
  403. return TRUE;
  404. }
  405. return FALSE;
  406. }
  407. //
  408. // Add a Request for Dispatch to the existing list of items - if it is not existing
  409. //
  410. ULONG
  411. DispatcheeNode::AddDispatchRequest(PDispatchRequest DispatchRequestp)
  412. /*++
  413. Routine Description:
  414. Arguments:
  415. none.
  416. Return Value:
  417. --*/
  418. {
  419. PDispatchRequest DRp = NULL;
  420. if(DispatchRequestp is NULL) return 0; // FAIL
  421. //
  422. // Is there such an entry already? IF there is one than ignore !?!?
  423. DRp = dynamic_cast<PDispatchRequest>
  424. (listRequests.SearchNodeKeys(DispatchRequestp->dstIp,
  425. DispatchRequestp->dstPort));
  426. if(DRp is NULL)
  427. {
  428. listRequests.InsertSorted(DispatchRequestp);
  429. }
  430. return TRUE;
  431. }
  432. //
  433. //
  434. //
  435. ULONG
  436. DispatcheeNode::DeleteDispatchRequest(PDispatchRequest DispatchRequestp)
  437. /*++
  438. Routine Description:
  439. Arguments:
  440. none.
  441. Return Value:
  442. --*/
  443. {
  444. PDispatchRequest DRp = NULL;
  445. if(DispatchRequestp is NULL) return 0; // FAIL
  446. DRp = dynamic_cast<PDispatchRequest>
  447. (listRequests.SearchNodeKeys(DispatchRequestp->dstIp,
  448. DispatchRequestp->dstPort));
  449. if(DRp is NULL)
  450. {
  451. return TRUE;
  452. }
  453. else
  454. {
  455. listRequests.RemoveNodeFromList(DRp);
  456. }
  457. return NO_ERROR; // SUCCESS
  458. }
  459. ULONG
  460. CSockDispatcher::GetOriginalDestination(
  461. PNH_BUFFER Bufferp,
  462. PULONG OriginalDestinationAddressp,
  463. PUSHORT OriginalDestinationPortp
  464. )
  465. /*++
  466. Routine Description:
  467. Arguments:
  468. none.
  469. Return Value:
  470. --*/
  471. {
  472. PCNhSock AcceptedSocketp = NULL;
  473. ULONG Error = 0, LocalAddress = 0, ActualClientAddress = 0;
  474. USHORT LocalPort = 0, ActualClientPort = 0;
  475. DispatcheeNode* DispatcheeNodep = NULL;
  476. ICQ_TRC(TM_DISP, TL_TRACE, (" Dispatcher - GetOrigDest"));
  477. do
  478. {
  479. AcceptedSocketp = Bufferp->Socketp;
  480. ASSERT(AcceptedSocketp != NULL);
  481. AcceptedSocketp->NhQueryRemoteEndpointSocket(&ActualClientAddress,
  482. &ActualClientPort);
  483. ICQ_TRC(TM_DISP, TL_INFO,
  484. (" Dispatcher> Accept Completion SRC IP %s, PORT %hu",
  485. INET_NTOA(ActualClientAddress), htons(ActualClientPort)));
  486. //
  487. // Get a Sample Dispatchee Node which has a SecondaryControlChannel
  488. // to ask the Destinations.
  489. //
  490. DispatcheeNodep = dynamic_cast<DispatcheeNode*>
  491. (this->listDispNodes.SearchNodeKeys(0,0));
  492. ASSERT(DispatcheeNodep != NULL);
  493. Error = DispatcheeNodep->GetOriginalDestination(ActualClientAddress,
  494. ActualClientPort,
  495. OriginalDestinationAddressp,
  496. OriginalDestinationPortp);
  497. if( FAILED(Error) )
  498. {
  499. ICQ_TRC(TM_DISP, TL_ERROR,
  500. ("** !! Getting the ORIGINAL destination has failed "));
  501. ASSERT( FALSE );
  502. break;
  503. }
  504. ICQ_TRC(TM_DISP, TL_INFO,
  505. ("Original Destionation IP:(PORT) is %s:(%hu)",
  506. INET_NTOA(*OriginalDestinationAddressp),
  507. htons(*OriginalDestinationPortp)));
  508. } while(FALSE);
  509. return Error;
  510. }
  511. ULONG
  512. DispatcheeNode::GetOriginalDestination(ULONG SrcAddress,
  513. USHORT SrcPort,
  514. PULONG DestAddrp,
  515. PUSHORT DestPortp)
  516. {
  517. return
  518. DispatchTop->IncomingRedirectForPeerToClientp->GetOriginalDestinationInformation(SrcAddress,
  519. SrcPort,
  520. DestAddrp,
  521. DestPortp,
  522. NULL);
  523. }
  524. VOID
  525. DispatcherAcceptCompletionRoutine
  526. (
  527. ULONG ErrorCode,
  528. ULONG BytesTransferred,
  529. PNH_BUFFER Bufferp
  530. )
  531. /*++
  532. Routine Description:
  533. Arguments:
  534. none.
  535. Return Value:
  536. --*/
  537. {
  538. CSockDispatcher * SDp = NULL;
  539. PCNhSock AcceptedSocketp = NULL;
  540. ULONG Error = 0, ErrorLevel = 0;
  541. DispatcheeNode * DNp;
  542. ULONG ActualClientAddress = 0, ActualDestinationAddress = 0;
  543. USHORT ActualClientPort = 0, ActualDestinationPort = 0;
  544. // NAT_KEY_SESSION_MAPPING_EX_INFORMATION natKey;
  545. ULONG keyLength;
  546. PDispatchReply DRp = NULL;
  547. ICQ_TRC(TM_DISP, TL_TRACE, (" Dispatcher - AcceptCompletionRoutine"));
  548. do
  549. {
  550. SDp = reinterpret_cast<CSockDispatcher *> (Bufferp->Context);
  551. AcceptedSocketp = Bufferp->Socketp;
  552. ErrorLevel = 1;
  553. //
  554. // Process the accept-completion.
  555. // first look for an error code. If an error occurred
  556. // and the interface is no longer active, end the completion-handling.
  557. // Otherwise, attempt to reissue the accept-request.
  558. //
  559. if(ErrorCode)
  560. {
  561. ICQ_TRC(TM_DISP, TL_DUMP, (" Dispatcher - AcceptCompletion> Error !!"));
  562. //
  563. // Critical Error.. how to notify ?
  564. //
  565. // Delete the AcceptedSocketp - as it is a resource allocated previously.
  566. break;
  567. }
  568. //
  569. // Re issue the accept call,
  570. REF_COMPONENT( SDp, eRefIoAccept );
  571. Error = SDp->NhAcceptStreamSocket(NULL,
  572. NULL,
  573. NULL,
  574. DispatcherAcceptCompletionRoutine,
  575. SDp,
  576. NULL);
  577. if(Error)
  578. {
  579. // NOTE: Defer the Acceptance of the socket.
  580. DEREF_COMPONENT( SDp, eRefIoAccept );
  581. ICQ_TRC(TM_DISP, TL_ERROR,
  582. (" Error - Reissuing the Accept has failed on the Dispatcher"));
  583. break;
  584. }
  585. //
  586. // MAJOR HANDLING SECTION - Dispatching the Accept
  587. //
  588. // Let the Accepted Socket inherit the same attributes as the Listening socket
  589. SOCKET tempSock = SDp->GetSock();
  590. Error = setsockopt(AcceptedSocketp->GetSock(),
  591. SOL_SOCKET,
  592. SO_UPDATE_ACCEPT_CONTEXT,
  593. (PCHAR)&tempSock,
  594. sizeof(tempSock));
  595. if(Error is SOCKET_ERROR)
  596. {
  597. ErrorOut();
  598. Error = WSAGetLastError();
  599. ICQ_TRC(TM_DISP, TL_ERROR,
  600. ("ERROR - Major Socket Error in Accept Completion %d", Error));
  601. break;
  602. }
  603. //
  604. // - Create a DispatchReply structure : find out the original addresses.
  605. AcceptedSocketp->NhQueryRemoteEndpointSocket(&ActualClientAddress,
  606. &ActualClientPort);
  607. Error = SDp->GetOriginalDestination(Bufferp,
  608. &ActualDestinationAddress,
  609. &ActualDestinationPort);
  610. if( FAILED(Error) )
  611. {
  612. ICQ_TRC(TM_DISP, TL_ERROR, ("Can't get the Destination Information"));
  613. ASSERT( FALSE );
  614. break;
  615. }
  616. // createDispatchReply
  617. DRp = new DispatchReply;
  618. if(DRp is NULL)
  619. {
  620. Error = E_OUTOFMEMORY;
  621. ICQ_TRC(TM_DISP, TL_ERROR, (" Can't create a Reply structure - out of memory"));
  622. break;
  623. }
  624. // Store the original header informations of the packet.
  625. DRp->dispatch.dstIp = ActualDestinationAddress;
  626. DRp->dispatch.dstPort = ActualDestinationPort;
  627. DRp->dispatch.srcIp = ActualClientAddress;
  628. DRp->dispatch.srcPort = ActualClientPort;
  629. DRp->Socketp = AcceptedSocketp;
  630. //
  631. // - Ask each DispatcheeNode in the List wether this DispatchReply is its or not.
  632. // How to traverse the List ??
  633. for (DNp = dynamic_cast<DispatcheeNode*>(SDp->listDispNodes.SearchNodeKeys(0,0));
  634. DNp != NULL;
  635. DNp = dynamic_cast<DispatcheeNode*>(DNp->Nextp))
  636. {
  637. if(DNp->isDispatchYours(DRp))
  638. {
  639. PDISPATCHEE Disp = NULL;
  640. //
  641. // - if there is a hit Dispatch the Accepted socket.
  642. //
  643. Disp = DNp->GetDispatchee();
  644. // ASSERT (Disp);
  645. //
  646. // This completion routine will clear the socket up
  647. // if it is not using it.
  648. //
  649. Error = Disp->DispatchCompletionRoutine(DRp);
  650. //
  651. // Should we keep asking until finished? NOPE
  652. //
  653. DEREF_COMPONENT( SDp, eRefIoAccept );
  654. DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoAccept );
  655. return;
  656. }
  657. }
  658. //
  659. // - if there is NO hit close the connection and delete every resource.
  660. Error = 1;
  661. ErrorLevel = 2;
  662. } while(FALSE);
  663. if( Error != NO_ERROR )
  664. {
  665. //
  666. // Each errorlevel contains the one level below.
  667. switch( ErrorLevel )
  668. {
  669. case 2: // delete the allocated reply
  670. delete DRp;
  671. case 1: // close the socket
  672. DEREF_COMPONENT( AcceptedSocketp, eRefInitialization );
  673. break;
  674. default:
  675. // ASSERT(FALSE);
  676. break;
  677. }
  678. }
  679. // De-Reference Local Accept
  680. DEREF_COMPONENT( SDp, eRefIoAccept );
  681. DEREF_COMPONENT( g_IcqComponentReferencep, eRefIoAccept );
  682. }
  683. ULONG
  684. _Dispatchee::DispatchCompletionRoutine(PDispatchReply DispatchReplyp)
  685. /*++
  686. Routine Description:
  687. Arguments:
  688. none.
  689. Return Value:
  690. --*/
  691. {
  692. ICQ_TRC(TM_DISP, TL_DUMP, ("> Dispatchee - DispatchCompletionRoutine"));
  693. if(DispatchReplyp is NULL) return -1; // FAIL
  694. this->AcquireLock();
  695. ICQ_TRC(TM_DISP, TL_TRACE, ("Dispatch Reply is as follows ORG dst %s - port %hu",
  696. INET_NTOA(DispatchReplyp->dispatch.dstIp),
  697. htons(DispatchReplyp->dispatch.dstPort)));
  698. DEREF_COMPONENT( DispatchReplyp->Socketp, eRefInitialization );
  699. ICQ_TRC(TM_DISP, TL_DUMP, ("> Dispatchee - DispatchCompletionRoutine"));
  700. this->ReleaseLock();
  701. return 0;
  702. }
  703. _Dispatchee::_Dispatchee()
  704. :DispatchUniqueId(0),
  705. IncomingRedirectForPeerToClientp(NULL)
  706. /*++
  707. Routine Description:
  708. Arguments:
  709. none.
  710. Return Value:
  711. --*/
  712. {
  713. ICQ_TRC(TM_DISP, TL_DUMP, ("DISPATCHEE - DEFAULT CONSTRUCTOR"));
  714. }
  715. _Dispatchee::~_Dispatchee()
  716. /*++
  717. Routine Description:
  718. Arguments:
  719. none.
  720. Return Value:
  721. --*/
  722. {
  723. ICQ_TRC(TM_DISP, TL_DUMP, ("DISPATCHEE - DESTRUCTOR"));
  724. }
  725. void
  726. _Dispatchee::ComponentCleanUpRoutine(void)
  727. /*++
  728. Routine Description:
  729. Arguments:
  730. none.
  731. Return Value:
  732. --*/
  733. {
  734. ICQ_TRC(TM_DISP, TL_DUMP, ("DISPATCHEE - Component Clean Up Routine"));
  735. }
  736. //=-=-=-=-=-
  737. PCHAR _Dispatchee::GetObjectName() { return ObjectNamep; }
  738. PCHAR DispatcheeNode::GetObjectName() { return ObjectNamep;}
  739. PCHAR CSockDispatcher::GetObjectName() { return ObjectNamep;}