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.

1510 lines
31 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1992 - 1999
  3. Module Name:
  4. dgsvr.hxx
  5. Abstract:
  6. This is the server protocol definitions for a datagram rpc.
  7. Author:
  8. Dave Steckler (davidst) 15-Dec-1992
  9. Revision History:
  10. --*/
  11. #ifndef __DGSVR_HXX__
  12. #define __DGSVR_HXX__
  13. #define MIN_THREADS_WHILE_ACTIVE 3
  14. // Information on the source endpoint. To be used in
  15. // forwarding a packet to a dynamic endpoint from the epmapper.
  16. // disable "zero-length array" warning
  17. #pragma warning(disable:4200)
  18. struct FROM_ENDPOINT_INFO
  19. {
  20. unsigned long FromEndpointLen;
  21. DREP FromDataRepresentation;
  22. char FromEndpoint[0];
  23. };
  24. #pragma warning(default:4200)
  25. //----------------------------------------------------------------------
  26. class DG_SCALL;
  27. typedef DG_SCALL * PDG_SCALL;
  28. class DG_SCONNECTION;
  29. typedef DG_SCONNECTION * PDG_SCONNECTION;
  30. class DG_ADDRESS : public RPC_ADDRESS
  31. /*++
  32. Class Description:
  33. This class represents an endpoint.
  34. --*/
  35. {
  36. public:
  37. #define MIN_FREE_CALLS 2
  38. //--------------------------------------------------------------------
  39. inline void *
  40. operator new(
  41. IN size_t ObjectLength,
  42. IN TRANS_INFO * Transport
  43. );
  44. DG_ADDRESS(
  45. TRANS_INFO * LoadableTransport,
  46. RPC_STATUS * pStatus
  47. );
  48. virtual
  49. ~DG_ADDRESS ();
  50. void
  51. WaitForCalls(
  52. );
  53. virtual void
  54. EncourageCallCleanup(
  55. RPC_INTERFACE * Interface
  56. );
  57. virtual RPC_STATUS
  58. ServerSetupAddress (
  59. IN RPC_CHAR PAPI *NetworkAddress,
  60. IN RPC_CHAR PAPI * PAPI *Endpoint,
  61. IN unsigned int PendingQueueSize,
  62. IN void PAPI * SecurityDescriptor, OPTIONAL
  63. IN unsigned long EndpointFlags,
  64. IN unsigned long NICFlags
  65. );
  66. #ifndef NO_PLUG_AND_PLAY
  67. virtual void PnpNotify();
  68. #endif
  69. virtual RPC_STATUS
  70. ServerStartingToListen (
  71. IN unsigned int MinimumCallThreads,
  72. IN unsigned int MaximumConcurrentCalls
  73. );
  74. virtual void
  75. ServerStoppedListening (
  76. );
  77. virtual long
  78. InqNumberOfActiveCalls (
  79. );
  80. RPC_STATUS
  81. CheckThreadPool(
  82. );
  83. inline void
  84. DispatchPacket(
  85. DG_PACKET * Packet,
  86. IN DatagramTransportPair *AddressPair
  87. );
  88. inline PDG_PACKET AllocatePacket();
  89. inline void
  90. FreePacket(
  91. IN PDG_PACKET pPacket
  92. );
  93. inline PDG_SCALL AllocateCall();
  94. inline void
  95. FreeCall(
  96. PDG_SCALL pCall
  97. );
  98. DG_SCONNECTION * AllocateConnection();
  99. void
  100. FreeConnection(
  101. DG_SCONNECTION * Connection
  102. );
  103. RPC_STATUS CompleteListen ();
  104. inline RPC_STATUS
  105. SendPacketBack(
  106. NCA_PACKET_HEADER * Header,
  107. unsigned DataAfterHeader,
  108. DG_TRANSPORT_ADDRESS RemoteAddress
  109. )
  110. {
  111. Header->PacketFlags &= ~DG_PF_FORWARDED;
  112. Header->PacketFlags2 &= ~DG_PF2_FORWARDED_2;
  113. ASSERT( Header->PacketType <= 10 );
  114. unsigned Frag = (Header->PacketType << 16) | Header->GetFragmentNumber();
  115. LogEvent(SU_ADDRESS, EV_PKT_OUT, this, 0, Frag);
  116. return Endpoint.TransportInterface->Send(
  117. Endpoint.TransportEndpoint,
  118. RemoteAddress,
  119. 0,
  120. 0,
  121. Header,
  122. sizeof(NCA_PACKET_HEADER) + DataAfterHeader,
  123. 0,
  124. 0
  125. );
  126. }
  127. inline void
  128. SendRejectPacket(
  129. DG_PACKET * Packet,
  130. DWORD ErrorCode,
  131. DG_TRANSPORT_ADDRESS RemoteAddress
  132. )
  133. {
  134. InitErrorPacket(Packet, DG_REJECT, ErrorCode);
  135. SendPacketBack (&Packet->Header, Packet->GetPacketBodyLen(), RemoteAddress);
  136. }
  137. RPC_STATUS
  138. LaunchReceiveThread(
  139. );
  140. static void
  141. ScavengerProc(
  142. void * address
  143. );
  144. inline void
  145. DecrementActiveCallCount(
  146. )
  147. {
  148. ASSERT(ActiveCallCount < 0xffff0000UL);
  149. InterlockedDecrement((LONG *) &ActiveCallCount);
  150. Endpoint.NumberOfCalls = ActiveCallCount;
  151. }
  152. inline void
  153. IncrementActiveCallCount(
  154. )
  155. {
  156. ASSERT( ActiveCallCount < 0x100000 );
  157. InterlockedIncrement((LONG *) &ActiveCallCount);
  158. Endpoint.NumberOfCalls = ActiveCallCount;
  159. }
  160. void
  161. BeginAutoListenCall (
  162. ) ;
  163. void
  164. EndAutoListenCall (
  165. ) ;
  166. static inline DG_ADDRESS *
  167. FromEndpoint(
  168. IN DG_TRANSPORT_ENDPOINT Endpoint
  169. )
  170. {
  171. return CONTAINING_RECORD( Endpoint, DG_ADDRESS, Endpoint.TransportEndpoint );
  172. }
  173. NETWORK_ADDRESS_VECTOR *
  174. GetNetworkAddressVector (
  175. void
  176. )
  177. {
  178. return Endpoint.TransportInterface->GetNetworkAddressVector(&(Endpoint.TransportEndpoint));
  179. }
  180. //--------------------------------------------------------------------
  181. private:
  182. LONG TotalThreadsThisEndpoint;
  183. LONG ThreadsReceivingThisEndpoint;
  184. unsigned MinimumCallThreads;
  185. unsigned MaximumConcurrentCalls;
  186. DELAYED_ACTION_NODE ScavengerTimer;
  187. unsigned ActiveCallCount;
  188. UUID_HASH_TABLE_NODE * CachedConnections;
  189. INTERLOCKED_INTEGER AutoListenCallCount;
  190. public:
  191. // this needs to be the last member because the transport endpoint
  192. // follows it.
  193. //
  194. DG_ENDPOINT Endpoint;
  195. //--------------------------------------------------------------------
  196. unsigned ScavengePackets();
  197. unsigned ScavengeCalls();
  198. private:
  199. BOOL
  200. CaptureClientAddress(
  201. IN PDG_PACKET Packet,
  202. OUT DG_TRANSPORT_ADDRESS RemoteAddress
  203. );
  204. RPC_STATUS
  205. ForwardPacket(
  206. IN PDG_PACKET Packet,
  207. IN DG_TRANSPORT_ADDRESS RemoteAddress,
  208. IN char * ServerEndpointString
  209. );
  210. BOOL
  211. ForwardPacketIfNecessary(
  212. IN PDG_PACKET pReceivedPacket,
  213. IN void * pFromEndpoint
  214. );
  215. unsigned short
  216. ConvertSerialNum(
  217. IN PDG_PACKET pPacket
  218. );
  219. static inline void
  220. RemoveIdleConnections(
  221. DG_ADDRESS * Address
  222. );
  223. };
  224. typedef DG_ADDRESS PAPI * PDG_ADDRESS;
  225. inline void *
  226. DG_ADDRESS::operator new(
  227. IN size_t ObjectLength,
  228. IN TRANS_INFO * Transport
  229. )
  230. {
  231. RPC_DATAGRAM_TRANSPORT * TransportInterface = (RPC_DATAGRAM_TRANSPORT *) (Transport->InqTransInfo());
  232. return new char[ObjectLength + TransportInterface->ServerEndpointSize];
  233. }
  234. PDG_PACKET
  235. DG_ADDRESS::AllocatePacket(
  236. )
  237. /*++
  238. Routine Description:
  239. Allocates a packet and associates it with a particular transport address.
  240. Arguments:
  241. Return Value:
  242. a packet, or zero if out of memory
  243. --*/
  244. {
  245. return DG_PACKET::AllocatePacket(Endpoint.Stats.PreferredPduSize);
  246. }
  247. void
  248. DG_ADDRESS::FreePacket(
  249. IN PDG_PACKET pPacket
  250. )
  251. /*++
  252. Routine Description:
  253. Frees a packet. If there are less than MAX_FREE_PACKETS on the
  254. pre-allocated list, then just add it to the list, otherwise delete it.
  255. Arguments:
  256. pPacket - Packet to delete.
  257. Return Value:
  258. RPC_S_OK
  259. --*/
  260. {
  261. pPacket->Free();
  262. }
  263. class ASSOC_GROUP_TABLE;
  264. //
  265. // casting unsigned to/from void * is OK in this case.
  266. //
  267. #pragma warning(push)
  268. #pragma warning(disable:4312)
  269. NEW_SDICT2(SECURITY_CONTEXT, unsigned);
  270. #pragma warning(pop)
  271. class ASSOCIATION_GROUP : public ASSOCIATION_HANDLE
  272. //
  273. // This class represents an association group as defined by OSF. This means
  274. // a set of associations sharing an address space.
  275. //
  276. {
  277. friend class ASSOC_GROUP_TABLE;
  278. public:
  279. inline
  280. ASSOCIATION_GROUP(
  281. RPC_UUID * pUuid,
  282. unsigned short InitialPduSize,
  283. RPC_STATUS * pStatus
  284. )
  285. : Mutex(pStatus),
  286. ASSOCIATION_HANDLE(),
  287. Node(pUuid),
  288. CurrentPduSize(InitialPduSize),
  289. ReferenceCount(1),
  290. RemoteWindowSize(1)
  291. {
  292. ObjectType = DG_SASSOCIATION_TYPE;
  293. }
  294. ~ASSOCIATION_GROUP(
  295. )
  296. {
  297. }
  298. inline static ASSOCIATION_GROUP *
  299. ContainingRecord(
  300. UUID_HASH_TABLE_NODE * Node
  301. )
  302. {
  303. return CONTAINING_RECORD (Node, ASSOCIATION_GROUP, Node);
  304. }
  305. void
  306. RequestMutex(
  307. )
  308. {
  309. Mutex.Request();
  310. }
  311. void
  312. ClearMutex(
  313. )
  314. {
  315. Mutex.Clear();
  316. }
  317. void
  318. IncrementRefCount(
  319. )
  320. {
  321. long Count = ReferenceCount.Increment();
  322. LogEvent(SU_ASSOC, EV_INC, this, 0, Count);
  323. }
  324. long
  325. DecrementRefCount(
  326. )
  327. {
  328. long Count = ReferenceCount.Decrement();
  329. LogEvent(SU_ASSOC, EV_DEC, this, 0, Count);
  330. return Count;
  331. }
  332. private:
  333. INTERLOCKED_INTEGER ReferenceCount;
  334. MUTEX Mutex;
  335. //
  336. // This lets the object be added to the master ASSOC_GROUP_TABLE.
  337. //
  338. UUID_HASH_TABLE_NODE Node;
  339. unsigned short CurrentPduSize;
  340. unsigned short RemoteWindowSize;
  341. };
  342. //
  343. // Scurity callback results.
  344. //
  345. // CBI_VALID is true if the callback has occurred.
  346. // CBI_ALLOWED is true if the callback allowed the user to make the call.
  347. // CBI_CONTEXT_MASK is bitmask for the context (key sequence number).
  348. //
  349. // The remaining bits contain the interface sequence number;
  350. // (x >> CBI_SEQUENCE_SHIFT) extracts it.
  351. //
  352. #define CBI_VALID (0x00000800U)
  353. #define CBI_ALLOWED (0x00000400U)
  354. #define CBI_CONTEXT_MASK (0x000000ffU)
  355. #define CBI_SEQUENCE_SHIFT 12
  356. #define CBI_SEQUENCE_MASK (~((1 << CBI_SEQUENCE_SHIFT) - 1))
  357. class SECURITY_CALLBACK_INFO_DICT2 : public SIMPLE_DICT2
  358. {
  359. public:
  360. inline
  361. SECURITY_CALLBACK_INFO_DICT2 ( // Constructor.
  362. )
  363. {
  364. }
  365. inline
  366. ~SECURITY_CALLBACK_INFO_DICT2 ( // Destructor.
  367. )
  368. {
  369. }
  370. inline int
  371. Update (
  372. RPC_INTERFACE * Key,
  373. unsigned Item
  374. )
  375. {
  376. Remove(Key);
  377. return SIMPLE_DICT2::Insert(Key, UlongToPtr(Item));
  378. }
  379. inline unsigned
  380. Remove (
  381. RPC_INTERFACE * Key
  382. )
  383. {
  384. return PtrToUlong(SIMPLE_DICT2::Delete(Key));
  385. }
  386. inline unsigned
  387. Find (
  388. RPC_INTERFACE * Key
  389. )
  390. {
  391. return PtrToUlong(SIMPLE_DICT2::Find(Key));
  392. }
  393. };
  394. class DG_SCALL_TABLE
  395. {
  396. public:
  397. inline DG_SCALL_TABLE();
  398. inline ~DG_SCALL_TABLE();
  399. BOOL
  400. Add(
  401. PDG_SCALL Call,
  402. unsigned long Sequence
  403. );
  404. void
  405. Remove(
  406. PDG_SCALL Call
  407. );
  408. PDG_SCALL
  409. Find(
  410. unsigned long Sequence
  411. );
  412. PDG_SCALL
  413. Predecessor(
  414. unsigned long Sequence
  415. );
  416. PDG_SCALL
  417. Successor(
  418. PDG_SCALL Call
  419. );
  420. inline void
  421. RemoveIdleCalls(
  422. BOOL Aggressive,
  423. RPC_INTERFACE * Interface
  424. );
  425. private:
  426. PDG_SCALL ActiveCallHead;
  427. PDG_SCALL ActiveCallTail;
  428. };
  429. inline
  430. DG_SCALL_TABLE::DG_SCALL_TABLE()
  431. {
  432. ActiveCallHead = 0;
  433. ActiveCallTail = 0;
  434. }
  435. inline
  436. DG_SCALL_TABLE::~DG_SCALL_TABLE()
  437. {
  438. ASSERT( ActiveCallHead == 0 );
  439. ASSERT( ActiveCallTail == 0 );
  440. }
  441. class DG_SCONNECTION : public DG_COMMON_CONNECTION
  442. {
  443. public:
  444. DG_SCONNECTION *Next;
  445. CLIENT_AUTH_INFO AuthInfo;
  446. unsigned ActivityHint;
  447. ASSOCIATION_GROUP * pAssocGroup;
  448. PDG_ADDRESS pAddress;
  449. RPC_INTERFACE * LastInterface;
  450. DG_SCALL * CurrentCall;
  451. BOOL fFirstCall;
  452. enum CALLBACK_STATE
  453. {
  454. NoCallbackAttempted = 0x99,
  455. SetupInProgress,
  456. MsConvWayAuthInProgress,
  457. ConvWayAuthInProgress,
  458. MsConvWay2InProgress,
  459. ConvWay2InProgress,
  460. ConvWayInProgress,
  461. ConvWayAuthMoreInProgress,
  462. CallbackSucceeded,
  463. CallbackFailed
  464. };
  465. //--------------------------------------------------------------------
  466. // The message mutex is only used by ncadg_mq.
  467. MUTEX3 *pMessageMutex;
  468. //--------------------------------------------------------------------
  469. DG_SCONNECTION(
  470. DG_ADDRESS * a_Address,
  471. RPC_STATUS * pStatus
  472. );
  473. ~DG_SCONNECTION();
  474. virtual RPC_STATUS
  475. SealAndSendPacket(
  476. IN DG_ENDPOINT * SourceEndpoint,
  477. IN DG_TRANSPORT_ADDRESS RemoteAddress,
  478. IN UNALIGNED NCA_PACKET_HEADER * Header,
  479. IN unsigned long DataOffset
  480. );
  481. void
  482. Activate(
  483. PNCA_PACKET_HEADER pHeader,
  484. unsigned short NewHash
  485. );
  486. void Deactivate();
  487. PDG_SCALL AllocateCall();
  488. void
  489. FreeCall(
  490. PDG_SCALL Call
  491. );
  492. void CheckForExpiredCalls();
  493. inline BOOL HasExpired();
  494. inline void
  495. DispatchPacket(
  496. DG_PACKET * Packet,
  497. DatagramTransportPair *AddressPair
  498. );
  499. RPC_STATUS
  500. MakeApplicationSecurityCallback(
  501. RPC_INTERFACE * Interface,
  502. PDG_SCALL Call
  503. );
  504. inline void
  505. AddCallToCache(
  506. DG_SCALL * Call
  507. );
  508. inline LONG
  509. IncrementRefCount(
  510. )
  511. {
  512. ASSERT(ReferenceCount < 1000);
  513. return InterlockedIncrement(&ReferenceCount);
  514. }
  515. inline LONG
  516. DecrementRefCount(
  517. )
  518. {
  519. ASSERT(ReferenceCount > 0);
  520. return InterlockedDecrement(&ReferenceCount);
  521. }
  522. inline static DG_SCONNECTION *
  523. FromHashNode(
  524. UUID_HASH_TABLE_NODE * Node
  525. )
  526. {
  527. return CONTAINING_RECORD (Node, DG_SCONNECTION, ActivityNode);
  528. }
  529. inline LONG GetTimeStamp()
  530. {
  531. return TimeStamp;
  532. }
  533. inline BOOL DidCallbackFail()
  534. {
  535. if (Callback.State == CallbackFailed)
  536. {
  537. return TRUE;
  538. }
  539. return FALSE;
  540. }
  541. RPC_STATUS
  542. VerifyNonRequestPacket(
  543. DG_PACKET * Packet
  544. );
  545. RPC_STATUS
  546. VerifyRequestPacket(
  547. DG_PACKET * Packet
  548. );
  549. RPC_STATUS
  550. FindOrCreateSecurityContext(
  551. IN DG_PACKET * pPacket,
  552. IN DG_TRANSPORT_ADDRESS RemoteAddress,
  553. OUT unsigned long * pClientSequenceNumber
  554. );
  555. inline SECURITY_CONTEXT *
  556. FindMatchingSecurityContext(
  557. DG_PACKET * Packet
  558. );
  559. inline DG_SCALL *
  560. RemoveIdleCalls(
  561. DG_SCALL * List,
  562. BOOL Aggressive,
  563. RPC_INTERFACE * Interface
  564. );
  565. RPC_STATUS
  566. GetAssociationGroup(
  567. DG_TRANSPORT_ADDRESS RemoteAddress
  568. );
  569. inline void
  570. SubmitCallbackIfNecessary(
  571. PDG_SCALL Call,
  572. PDG_PACKET Packet,
  573. DG_TRANSPORT_ADDRESS RemoteAddress
  574. );
  575. void ConvCallCompleted();
  576. inline void MessageMutexInitialize( RPC_STATUS *pStatus )
  577. {
  578. pMessageMutex = new MUTEX3(pStatus);
  579. if (!pMessageMutex)
  580. {
  581. *pStatus = RPC_S_OUT_OF_MEMORY;
  582. }
  583. else if (*pStatus != RPC_S_OK)
  584. {
  585. delete pMessageMutex;
  586. pMessageMutex = 0;
  587. }
  588. }
  589. friend class ENDPOINT_MANAGER;
  590. private:
  591. DG_SCALL * CachedCalls;
  592. DG_SCALL_TABLE ActiveCalls;
  593. SECURITY_CONTEXT_DICT2 SecurityContextDict;
  594. unsigned MaxKeySeq;
  595. SECURITY_CALLBACK_INFO_DICT2 InterfaceCallbackResults;
  596. struct
  597. {
  598. CALLBACK_STATE State;
  599. RPC_BINDING_HANDLE Binding;
  600. RPC_ASYNC_STATE AsyncState;
  601. DG_SCALL * Call;
  602. SECURITY_CREDENTIALS * Credentials;
  603. SECURITY_CONTEXT * SecurityContext;
  604. BOOL ThirdLegNeeded;
  605. DWORD DataRep;
  606. DWORD KeySequence;
  607. RPC_UUID CasUuid;
  608. unsigned long ClientSequence;
  609. unsigned char * TokenBuffer;
  610. long TokenLength;
  611. unsigned char * ResponseBuffer;
  612. long ResponseLength;
  613. long MaxData;
  614. unsigned long DataIndex;
  615. unsigned long Status;
  616. }
  617. Callback;
  618. boolean BlockIdleCallRemoval;
  619. //--------------------------------------------------------------------
  620. void CallDispatchLoop();
  621. RPC_STATUS
  622. FinishConvCallback(
  623. RPC_STATUS Status
  624. );
  625. BOOL
  626. HandleMaybeCall(
  627. PDG_PACKET Packet,
  628. DatagramTransportPair *AddressPair
  629. );
  630. PDG_SCALL
  631. HandleNewCall(
  632. PDG_PACKET Packet,
  633. DatagramTransportPair *AddressPair
  634. );
  635. RPC_STATUS
  636. CreateCallbackBindingAndReleaseMutex(
  637. DG_TRANSPORT_ADDRESS RemoteAddress
  638. );
  639. static void RPC_ENTRY
  640. ConvNotificationRoutine (
  641. RPC_ASYNC_STATE * pAsync,
  642. void * Reserved,
  643. RPC_ASYNC_EVENT Event
  644. );
  645. };
  646. inline SECURITY_CONTEXT *
  647. DG_SCONNECTION::FindMatchingSecurityContext(
  648. DG_PACKET * Packet
  649. )
  650. {
  651. DG_SECURITY_TRAILER * Verifier = (DG_SECURITY_TRAILER *)
  652. (Packet->Header.Data + Packet->GetPacketBodyLen());
  653. return SecurityContextDict.Find(Verifier->key_vers_num);
  654. }
  655. class DG_SCALL : public SCALL, public DG_PACKET_ENGINE
  656. /*++
  657. Class Description:
  658. This class represents a call in progress on the server.
  659. Fields:
  660. Revision History:
  661. --*/
  662. {
  663. #ifdef MONITOR_SERVER_PACKET_COUNT
  664. long OutstandingPacketCount;
  665. #endif
  666. public:
  667. long TimeStamp;
  668. DG_SCALL * Next;
  669. DG_SCALL * Previous;
  670. //------------------------------------------------
  671. inline void *
  672. operator new(
  673. IN size_t ObjectLength,
  674. IN RPC_DATAGRAM_TRANSPORT * TransportInterface
  675. );
  676. DG_SCALL(
  677. DG_ADDRESS * Address,
  678. RPC_STATUS * pStatus
  679. );
  680. virtual ~DG_SCALL();
  681. //------------------------------------------------
  682. virtual RPC_STATUS
  683. NegotiateTransferSyntax (
  684. IN OUT PRPC_MESSAGE Message
  685. );
  686. virtual RPC_STATUS
  687. GetBuffer (
  688. IN OUT PRPC_MESSAGE Message,
  689. IN UUID *ObjectUuid
  690. );
  691. virtual void
  692. FreeBuffer (
  693. IN PRPC_MESSAGE Message
  694. );
  695. virtual void
  696. FreePipeBuffer (
  697. IN PRPC_MESSAGE Message
  698. ) ;
  699. virtual RPC_STATUS
  700. ReallocPipeBuffer (
  701. IN PRPC_MESSAGE Message,
  702. IN unsigned int NewSize
  703. ) ;
  704. virtual RPC_STATUS
  705. SendReceive (
  706. IN OUT PRPC_MESSAGE Message
  707. );
  708. virtual RPC_STATUS
  709. ToStringBinding (
  710. OUT RPC_CHAR PAPI * PAPI * StringBinding
  711. );
  712. virtual RPC_STATUS
  713. ImpersonateClient (
  714. );
  715. virtual RPC_STATUS
  716. RevertToSelf (
  717. );
  718. virtual RPC_STATUS
  719. GetAssociationContextCollection (
  720. OUT ContextCollection **CtxCollection
  721. );
  722. virtual void
  723. InquireObjectUuid (
  724. OUT RPC_UUID PAPI * ObjectUuid
  725. );
  726. virtual RPC_STATUS
  727. InquireAuthClient (
  728. OUT RPC_AUTHZ_HANDLE PAPI * Privileges,
  729. OUT RPC_CHAR PAPI * PAPI * ServerPrincipalName, OPTIONAL
  730. OUT unsigned long PAPI * AuthenticationLevel,
  731. OUT unsigned long PAPI * AuthenticationService,
  732. OUT unsigned long PAPI * AuthorizationService,
  733. IN unsigned long Flags
  734. );
  735. virtual RPC_STATUS
  736. ConvertToServerBinding (
  737. OUT RPC_BINDING_HANDLE __RPC_FAR * ServerBinding
  738. );
  739. virtual RPC_STATUS
  740. InqTransportType(
  741. OUT unsigned int __RPC_FAR * Type
  742. ) ;
  743. virtual RPC_STATUS
  744. Cancel(
  745. void * ThreadHandle
  746. );
  747. virtual unsigned TestCancel();
  748. virtual RPC_STATUS
  749. Receive(
  750. PRPC_MESSAGE Message,
  751. unsigned Size
  752. );
  753. virtual RPC_STATUS
  754. Send(
  755. PRPC_MESSAGE Message
  756. );
  757. virtual RPC_STATUS
  758. AsyncSend (
  759. IN OUT PRPC_MESSAGE Message
  760. );
  761. virtual RPC_STATUS
  762. AsyncReceive (
  763. IN OUT PRPC_MESSAGE Message,
  764. IN unsigned int Size
  765. );
  766. virtual RPC_STATUS
  767. IsClientLocal(
  768. IN OUT unsigned * pClientIsLocal
  769. )
  770. {
  771. return RPC_S_CANNOT_SUPPORT;
  772. }
  773. virtual void
  774. IsClientDisconnected (
  775. OUT BOOL *ClientIsDisconnected
  776. )
  777. {
  778. ASSERT(!"You shouldn't be here");
  779. }
  780. RPC_STATUS
  781. InqLocalConnAddress (
  782. IN OUT void *Buffer,
  783. IN OUT unsigned long *BufferSize,
  784. OUT unsigned long *AddressFormat
  785. );
  786. virtual RPC_STATUS
  787. AbortAsyncCall (
  788. IN PRPC_ASYNC_STATE pAsync,
  789. IN unsigned long ExceptionCode
  790. );
  791. virtual RPC_STATUS
  792. SetAsyncHandle (
  793. IN RPC_ASYNC_STATE * pAsync
  794. );
  795. virtual BOOL
  796. IsSyncCall ()
  797. {
  798. return !pAsync;
  799. }
  800. //------------------------------------------------
  801. inline void
  802. DispatchPacket(
  803. DG_PACKET * Packet,
  804. IN DG_TRANSPORT_ADDRESS RemoteAddress
  805. );
  806. void DealWithRequest ( PDG_PACKET pPacket );
  807. void DealWithResponse ( PDG_PACKET pPacket );
  808. void DealWithPing ( PDG_PACKET pPacket );
  809. void DealWithFack ( PDG_PACKET pPacket );
  810. void DealWithAck ( PDG_PACKET pPacket );
  811. void DealWithQuit ( PDG_PACKET pPacket );
  812. //------------------------------------------------
  813. inline void
  814. NewCall(
  815. DG_PACKET * pPacket,
  816. DatagramTransportPair *AddressPAir
  817. );
  818. inline void
  819. BindToConnection(
  820. PDG_SCONNECTION a_Connection
  821. );
  822. BOOL
  823. DG_SCALL::FinishSendOrReceive(
  824. BOOL Abort
  825. );
  826. inline BOOL ReadyToDispatch();
  827. void ProcessRpcCall();
  828. inline BOOL
  829. HasExpired(
  830. BOOL Aggressive,
  831. RPC_INTERFACE * Interface
  832. );
  833. BOOL Cleanup();
  834. inline BOOL IsSynchronous();
  835. void
  836. FreeAPCInfo (
  837. IN RPC_APC_INFO *pAPCInfo
  838. );
  839. inline void IncrementRefCount();
  840. inline void DecrementRefCount();
  841. inline void
  842. ConvCallbackFailed(
  843. DWORD Status
  844. )
  845. {
  846. pSavedPacket->Header.SequenceNumber = SequenceNumber;
  847. InitErrorPacket(pSavedPacket, DG_REJECT, Status);
  848. SealAndSendPacket(&pSavedPacket->Header);
  849. Cleanup();
  850. }
  851. virtual RPC_STATUS
  852. InqConnection (
  853. OUT void **ConnId,
  854. OUT BOOL *pfFirstCall
  855. )
  856. {
  857. ASSERT(Connection);
  858. *ConnId = Connection;
  859. if (InterlockedIncrement((LONG *) &(Connection->fFirstCall)) == 1)
  860. {
  861. *pfFirstCall = 1;
  862. }
  863. else
  864. {
  865. *pfFirstCall = 0;
  866. }
  867. return RPC_S_OK;
  868. }
  869. private:
  870. enum CALL_STATE
  871. {
  872. CallInit = 0x201,
  873. CallBeforeDispatch,
  874. CallDispatched,
  875. xxxxObsolete,
  876. CallAfterDispatch,
  877. CallSendingResponse,
  878. CallComplete,
  879. CallBogus = 0xfffff004
  880. };
  881. CALL_STATE State;
  882. CALL_STATE PreviousState;
  883. boolean CallInProgress;
  884. boolean CallWasForwarded;
  885. boolean KnowClientAddress;
  886. boolean TerminateWhenConvenient;
  887. DG_SCONNECTION * Connection;
  888. RPC_INTERFACE * Interface;
  889. //
  890. // Data to monitor pipe data transfer.
  891. //
  892. unsigned long PipeThreadId;
  893. PENDING_OPERATION PipeWaitType;
  894. unsigned long PipeWaitLength;
  895. //
  896. // The only unusual aspect of this is that it's an auto-reset event.
  897. // It is created during the first call on a pipe interface.
  898. //
  899. EVENT * PipeWaitEvent;
  900. //
  901. // Stuff for RpcBindingInqAuthClient.
  902. //
  903. RPC_AUTHZ_HANDLE Privileges;
  904. unsigned long AuthorizationService;
  905. DWORD LocalAddress; // IP address, network byte order encoded
  906. //---------------------------------------------------------------------
  907. inline void
  908. SetState(
  909. CALL_STATE NewState
  910. )
  911. {
  912. if (NewState != State)
  913. {
  914. LogEvent(SU_SCALL, EV_STATE, this, 0, NewState);
  915. }
  916. PreviousState = State;
  917. State = NewState;
  918. }
  919. virtual BOOL
  920. IssueNotification (
  921. IN RPC_ASYNC_EVENT Event
  922. );
  923. void
  924. AddPacketToReceiveList(
  925. PDG_PACKET pPacket
  926. );
  927. RPC_STATUS
  928. UnauthenticatedCallback(
  929. unsigned * pClientSequenceNumber
  930. );
  931. RPC_STATUS
  932. SendFragment(
  933. PRPC_MESSAGE pMessage,
  934. unsigned FragNum,
  935. unsigned char PacketType
  936. );
  937. RPC_STATUS
  938. SealAndSendPacket(
  939. NCA_PACKET_HEADER * Header
  940. );
  941. RPC_STATUS
  942. SendPacketBack(
  943. NCA_PACKET_HEADER * pNcaPacketHeader,
  944. unsigned TrailerSize
  945. );
  946. RPC_STATUS
  947. CreateReverseBinding (
  948. RPC_BINDING_HANDLE * pServerBinding,
  949. BOOL IncludeEndpoint
  950. );
  951. void
  952. SaveOriginalClientInfo(
  953. DG_PACKET * pPacket
  954. );
  955. inline RPC_STATUS
  956. AssembleBufferFromPackets(
  957. IN OUT PRPC_MESSAGE Message
  958. );
  959. RPC_STATUS WaitForPipeEvent();
  960. //------------------------------------------------
  961. // ConvertSidToUserW() is used to get transport supplied
  962. // auth. info. The only DG transport that uses this is
  963. // Falcon. The SID for the client user that sent the
  964. // "current" request is cashed along with the user name.
  965. // So, if the next call on this activity has the same
  966. // SID we can return the user without hitting the domain
  967. // server.
  968. RPC_STATUS
  969. ConvertSidToUserW(
  970. IN SID *pSid,
  971. OUT RPC_CHAR **ppwsPrincipal
  972. );
  973. SID *pCachedSid;
  974. RPC_CHAR *pwsCachedUserName;
  975. DWORD dwCachedUserNameSize;
  976. boolean FinalSendBufferPresent;
  977. RPC_MESSAGE RpcMessage;
  978. RPC_RUNTIME_INFO RpcRuntimeInfo ;
  979. };
  980. inline void *
  981. DG_SCALL::operator new(
  982. IN size_t ObjectLength,
  983. IN RPC_DATAGRAM_TRANSPORT * TransportInterface
  984. )
  985. {
  986. return new char[ObjectLength + TransportInterface->AddressSize];
  987. }
  988. inline void DG_SCALL::DecrementRefCount()
  989. {
  990. Connection->Mutex.VerifyOwned();
  991. --ReferenceCount;
  992. LogEvent(SU_SCALL, EV_DEC, this, 0, ReferenceCount);
  993. }
  994. inline void DG_SCALL::IncrementRefCount()
  995. {
  996. Connection->Mutex.VerifyOwned();
  997. ++ReferenceCount;
  998. LogEvent(SU_SCALL, EV_INC, this, 0, ReferenceCount);
  999. }
  1000. void
  1001. DG_SCALL::BindToConnection(
  1002. PDG_SCONNECTION a_Connection
  1003. )
  1004. {
  1005. Connection = a_Connection;
  1006. ReadConnectionInfo(Connection, this + 1);
  1007. pSavedPacket->Header.ServerBootTime = ProcessStartTime;
  1008. pSavedPacket->Header.ActivityHint = (unsigned short) Connection->ActivityHint;
  1009. pSavedPacket->Header.InterfaceHint = 0xffff;
  1010. }
  1011. inline BOOL
  1012. DG_SCALL::IsSynchronous(
  1013. )
  1014. /*++
  1015. Routine Description:
  1016. Simply tells whether the call is sycnhronous or asynchronous.
  1017. The return value won't be reliable if the call was instantiated
  1018. by a packet other than a REQUEST and no REQUEST has yet arrived,
  1019. so be careful to call it only after a REQUEST has arrived.
  1020. Arguments:
  1021. none
  1022. Return Value:
  1023. TRUE if synchronous
  1024. FALSE if asynchronous
  1025. --*/
  1026. {
  1027. if (BufferFlags & RPC_BUFFER_ASYNC)
  1028. {
  1029. return FALSE;
  1030. }
  1031. else
  1032. {
  1033. return TRUE;
  1034. }
  1035. }
  1036. inline RPC_STATUS
  1037. DG_SCALL::AssembleBufferFromPackets(
  1038. IN OUT PRPC_MESSAGE Message
  1039. )
  1040. {
  1041. RPC_STATUS Status = DG_PACKET_ENGINE::AssembleBufferFromPackets(Message, this);
  1042. if (RPC_S_OK == Status && (Message->RpcFlags & RPC_BUFFER_EXTRA))
  1043. {
  1044. PRPC_RUNTIME_INFO Info = (PRPC_RUNTIME_INFO) Message->ReservedForRuntime;
  1045. Info->OldBuffer = Message->Buffer;
  1046. }
  1047. return Status;
  1048. }
  1049. inline RPC_STATUS
  1050. DG_SCALL::InqTransportType(
  1051. OUT unsigned int __RPC_FAR * Type
  1052. )
  1053. {
  1054. *Type = TRANSPORT_TYPE_DG ;
  1055. return (RPC_S_OK) ;
  1056. }
  1057. inline RPC_STATUS
  1058. DG_SCALL::SealAndSendPacket(
  1059. NCA_PACKET_HEADER * Header
  1060. )
  1061. {
  1062. Header->ServerBootTime = ProcessStartTime;
  1063. SetMyDataRep(Header);
  1064. unsigned Frag = (Header->PacketType << 16) | Header->FragmentNumber;
  1065. LogEvent(SU_SCALL, EV_PKT_OUT, this, 0, Frag);
  1066. return Connection->SealAndSendPacket(SourceEndpoint, RemoteAddress, Header, 0);
  1067. }
  1068. //------------------------------------------------------------------------
  1069. class SERVER_ACTIVITY_TABLE : private UUID_HASH_TABLE
  1070. {
  1071. public:
  1072. inline
  1073. SERVER_ACTIVITY_TABLE(
  1074. RPC_STATUS * pStatus
  1075. ) :
  1076. UUID_HASH_TABLE ( pStatus )
  1077. {
  1078. LastFinishTime = 0;
  1079. BucketCounter = 0;
  1080. }
  1081. inline
  1082. ~SERVER_ACTIVITY_TABLE(
  1083. )
  1084. {
  1085. }
  1086. inline DG_SCONNECTION *
  1087. FindOrCreate(
  1088. DG_ADDRESS * Address,
  1089. PDG_PACKET pPacket
  1090. );
  1091. inline void Prune();
  1092. BOOL
  1093. PruneEntireTable(
  1094. RPC_INTERFACE * Interface
  1095. );
  1096. BOOL PruneSpecificBucket(
  1097. unsigned Bucket,
  1098. BOOL Aggressive,
  1099. RPC_INTERFACE * Interface
  1100. );
  1101. void SERVER_ACTIVITY_TABLE::BeginIdlePruning();
  1102. static void SERVER_ACTIVITY_TABLE::PruneWhileIdle( PVOID unused );
  1103. private:
  1104. long LastFinishTime;
  1105. long BucketCounter;
  1106. DELAYED_ACTION_NODE IdleScavengerTimer;
  1107. };
  1108. class ASSOC_GROUP_TABLE : private UUID_HASH_TABLE
  1109. {
  1110. public:
  1111. inline
  1112. ASSOC_GROUP_TABLE(
  1113. RPC_STATUS * pStatus
  1114. )
  1115. : UUID_HASH_TABLE(pStatus)
  1116. {
  1117. }
  1118. inline
  1119. ~ASSOC_GROUP_TABLE(
  1120. )
  1121. {
  1122. }
  1123. inline ASSOCIATION_GROUP *
  1124. FindOrCreate(
  1125. RPC_UUID * pUuid,
  1126. unsigned short InitialPduSize
  1127. );
  1128. inline void
  1129. DecrementRefCount(
  1130. ASSOCIATION_GROUP * pClient
  1131. );
  1132. };
  1133. inline void
  1134. DG_SCONNECTION::AddCallToCache(
  1135. DG_SCALL * Call
  1136. )
  1137. {
  1138. Mutex.VerifyOwned();
  1139. ASSERT( !Call->InvalidHandle(DG_SCALL_TYPE) );
  1140. ASSERT( !CachedCalls || !CachedCalls->InvalidHandle(DG_SCALL_TYPE) );
  1141. Call->TimeStamp = GetTickCount();
  1142. Call->Next = CachedCalls;
  1143. CachedCalls = Call;
  1144. LogEvent(SU_SCALL, EV_STOP, Call, this, Call->GetSequenceNumber() );
  1145. }
  1146. //------------------------------------------------------------------------
  1147. BOOL
  1148. StripForwardedPacket(
  1149. IN PDG_PACKET pPacket,
  1150. IN void * pFromEndpoint
  1151. );
  1152. extern unsigned long ServerBootTime;
  1153. #endif // __DGSVR_HXX__