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.

1487 lines
28 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1993 - 1999
  3. Module Name:
  4. dgpkt.hxx
  5. Abstract:
  6. This file contains the definitions for a dg packet.
  7. Author:
  8. Dave Steckler (davidst) 3-Mar-1992
  9. Revision History:
  10. EdwardR 09-Jul-1997 Added support for large packets (Falcon).
  11. --*/
  12. #ifndef __DGPKT_HXX__
  13. #define __DGPKT_HXX__
  14. #include <rpctrans.hxx>
  15. #include <limits.h>
  16. #include <hashtabl.hxx>
  17. typedef MESSAGE_OBJECT * PMESSAGE_OBJECT;
  18. #define MULTITHREADED
  19. #include <threads.hxx>
  20. #include <delaytab.hxx>
  21. #define DG_RPC_PROTOCOL_VERSION 4
  22. //
  23. // Our code allows only one additional ULONG in a FACK packet body.
  24. //
  25. #define MAX_WINDOW_SIZE (CHAR_BIT * sizeof(unsigned))
  26. //
  27. // delay times
  28. //
  29. #define TWO_SECS_IN_MSEC (2 * 1000)
  30. #define THREE_SECS_IN_MSEC (3 * 1000)
  31. #define TEN_SECS_IN_MSEC (10 * 1000)
  32. #define FIFTEEN_SECS_IN_MSEC (15 * 1000)
  33. #define ONE_MINUTE_IN_MSEC (60 * 1000)
  34. #define FIVE_MINUTES_IN_MSEC (5 * 60 * 1000)
  35. //
  36. // test hook identifiers
  37. //
  38. //
  39. // sending the delayed ack
  40. //
  41. #define TH_DG_SEND_ACK (TH_DG_BASE+1)
  42. #define TH_DG_CONN (TH_DG_BASE+2)
  43. inline unsigned long
  44. CurrentTimeInMsec(
  45. void
  46. )
  47. {
  48. #ifdef MULTITHREADED
  49. return GetTickCount();
  50. #else
  51. return 0;
  52. #endif
  53. }
  54. // PacketType values:
  55. #define DG_REQUEST 0
  56. #define DG_PING 1
  57. #define DG_RESPONSE 2
  58. #define DG_FAULT 3
  59. #define DG_WORKING 4
  60. #define DG_NOCALL 5
  61. #define DG_REJECT 6
  62. #define DG_ACK 7
  63. #define DG_QUIT 8
  64. #define DG_FACK 9
  65. #define DG_QUACK 10
  66. // PacketFlags values:
  67. #define DG_PF_INIT 0x0000
  68. #define DG_PF_FORWARDED 0x0001
  69. #define DG_PF_LAST_FRAG 0x0002
  70. #define DG_PF_FRAG 0x0004
  71. #define DG_PF_NO_FACK 0x0008
  72. #define DG_PF_MAYBE 0x0010
  73. #define DG_PF_IDEMPOTENT 0x0020
  74. #define DG_PF_BROADCAST 0x0040
  75. //
  76. // for PacketFlags2:
  77. //
  78. #define DG_PF2_FORWARDED_2 0x0001
  79. #define DG_PF2_CANCEL_PENDING 0x0002
  80. #define DG_PF2_LARGE_PACKET 0x0080
  81. // In the AES this bit is reserved.
  82. //
  83. #define DG_PF2_UNRELATED 0x0004
  84. //
  85. // For DG_PACKET.Flags
  86. //
  87. #define DG_PF_PARTIAL 0x1
  88. // for DREP[0]:
  89. #define DG_DREP_CHAR_ASCII 0
  90. #define DG_DREP_CHAR_EBCDIC 1
  91. #define DG_DREP_INT_BIG 0
  92. #define DG_DREP_INT_LITTLE 16
  93. // for DREP[1]
  94. #define DG_DREP_FP_IEEE 0
  95. #define DG_DREP_FP_VAX 1
  96. #define DG_DREP_FP_CRAY 2
  97. #define DG_DREP_FP_IBM 3
  98. #define DG_MSG_DREP_INITIALIZE 0x11111100
  99. #define NDR_DREP_ENDIAN_MASK 0xF0
  100. #define RPC_NCA_PACKET_FLAGS (RPC_NCA_FLAGS_IDEMPOTENT | RPC_NCA_FLAGS_BROADCAST | RPC_NCA_FLAGS_MAYBE)
  101. //
  102. // The RPC packet header and security verifier must each be 8-aligned.
  103. //
  104. #define PACKET_HEADER_ALIGNMENT (8)
  105. #define SECURITY_HEADER_ALIGNMENT (8)
  106. enum PENDING_OPERATION
  107. {
  108. PWT_NONE = 0x111,
  109. PWT_RECEIVE,
  110. PWT_SEND,
  111. PWT_SEND_RECEIVE
  112. };
  113. extern const unsigned RpcToPacketFlagsArray[];
  114. extern const unsigned PacketToRpcFlagsArray[];
  115. extern unsigned DefaultSocketBufferLength;
  116. extern unsigned DefaultMaxDatagramSize;
  117. //
  118. // Controls on the number of packets in the packet cache.
  119. // Note that these values are for each packet size, not the
  120. // cache as a whole.
  121. //
  122. #ifndef NO_PACKET_CACHE
  123. #define MIN_FREE_PACKETS 3
  124. #if defined(__RPC_DOS__)
  125. #define MAX_FREE_PACKETS 8
  126. #elif defined(__RPC_WIN16__)
  127. #define MAX_FREE_PACKETS 20
  128. #else
  129. #define MAX_FREE_PACKETS 1000
  130. #endif
  131. #else
  132. #define MIN_FREE_PACKETS 0
  133. #define MAX_FREE_PACKETS 0
  134. #endif
  135. #if defined(DOS) && !defined(WIN)
  136. typedef long LONG;
  137. typedef long PAPI * PLONG;
  138. #endif // Windows
  139. #if defined(MAC)
  140. typedef long LONG;
  141. typedef long PAPI * PLONG;
  142. #endif // Windows
  143. #ifndef min
  144. #define min(a,b) (((a) < (b)) ? (a) : (b))
  145. #endif
  146. typedef unsigned char boolean;
  147. #ifndef DISABLE_DG_LOGGING
  148. inline void
  149. DgLogEvent(
  150. IN unsigned char Subject,
  151. IN unsigned char Verb,
  152. IN void * SubjectPointer,
  153. IN void * ObjectPointer = 0,
  154. IN ULONG_PTR Data = 0,
  155. IN BOOL fCaptureStackTrace = 0,
  156. IN int AdditionalFramesToSkip = 0
  157. )
  158. {
  159. LogEvent( Subject,
  160. Verb,
  161. SubjectPointer,
  162. ObjectPointer,
  163. Data,
  164. fCaptureStackTrace,
  165. AdditionalFramesToSkip
  166. );
  167. }
  168. #else
  169. inline void
  170. DgxLogEvent(
  171. IN unsigned char Subject,
  172. IN unsigned char Verb,
  173. IN void * SubjectPointer,
  174. IN void * ObjectPointer = 0,
  175. IN ULONG_PTR Data = 0,
  176. IN BOOL fCaptureStackTrace = 0,
  177. IN int AdditionalFramesToSkip = 0
  178. )
  179. {
  180. }
  181. #endif
  182. //-------------------------------------------------------------------
  183. extern unsigned long __RPC_FAR
  184. MapToNcaStatusCode (
  185. IN RPC_STATUS RpcStatus
  186. );
  187. extern RPC_STATUS __RPC_FAR
  188. MapFromNcaStatusCode (
  189. IN unsigned long NcaStatus
  190. );
  191. inline unsigned
  192. PacketToRpcFlags(
  193. unsigned PacketFlags
  194. )
  195. {
  196. return PacketToRpcFlagsArray[(PacketFlags >> 4) & 7];
  197. }
  198. #ifndef WIN32
  199. inline LONG
  200. InterlockedExchange(
  201. LONG * pDest,
  202. LONG New
  203. )
  204. {
  205. LONG Old = *pDest;
  206. *pDest = New;
  207. return Old;
  208. }
  209. inline LONG
  210. InterlockedIncrement(
  211. LONG * pDest
  212. )
  213. {
  214. LONG Old = *pDest;
  215. *pDest = 1+Old;
  216. return Old;
  217. }
  218. inline LONG
  219. InterlockedDecrement(
  220. LONG * pDest
  221. )
  222. {
  223. LONG Old = *pDest;
  224. *pDest = -1+Old;
  225. return Old;
  226. }
  227. #endif
  228. //-------------------------------------------------------------------
  229. struct DG_SECURITY_TRAILER
  230. {
  231. unsigned char protection_level;
  232. unsigned char key_vers_num;
  233. };
  234. typedef DG_SECURITY_TRAILER __RPC_FAR * PDG_SECURITY_TRAILER;
  235. struct FACK_BODY_VER_0
  236. {
  237. // FACK body version; we understand only zero.
  238. //
  239. unsigned char Version;
  240. // pad byte
  241. //
  242. unsigned char Pad1;
  243. // Window size, in packets.
  244. // AES/DC contradicts itself on page 12-18, sometimes saying kilobytes.
  245. //
  246. unsigned short WindowSize;
  247. // Largest datagram the sender can handle, in bytes.
  248. //
  249. unsigned long MaxDatagramSize;
  250. // Largest datagram that won't be fragmented over the wire, in bytes.
  251. //
  252. unsigned long MaxPacketSize;
  253. // Serial number of packet that caused this FACK.
  254. //
  255. unsigned short SerialNumber;
  256. // Number of unsigned longs in the Acks[] array.
  257. //
  258. unsigned short AckWordCount;
  259. #pragma warning(disable:4200)
  260. // Array of bit masks.
  261. //
  262. unsigned long Acks[0];
  263. #pragma warning(default:4200)
  264. };
  265. void
  266. ByteSwapFackBody0(
  267. FACK_BODY_VER_0 __RPC_FAR * pBody
  268. );
  269. typedef unsigned char DREP[4];
  270. //
  271. // The following structure is the NCA Datagram RPC packet header.
  272. //
  273. struct _NCA_PACKET_HEADER
  274. {
  275. unsigned char RpcVersion;
  276. unsigned char PacketType;
  277. unsigned char PacketFlags;
  278. unsigned char PacketFlags2;
  279. DREP DataRep;
  280. RPC_UUID ObjectId;
  281. RPC_UUID InterfaceId;
  282. RPC_UUID ActivityId;
  283. unsigned long ServerBootTime;
  284. RPC_VERSION InterfaceVersion;
  285. unsigned long SequenceNumber;
  286. unsigned short OperationNumber;
  287. unsigned short InterfaceHint;
  288. unsigned short ActivityHint;
  289. unsigned short PacketBodyLen;
  290. unsigned short FragmentNumber;
  291. unsigned char AuthProto;
  292. unsigned char SerialLo;
  293. #pragma warning(disable:4200)
  294. unsigned char Data[0];
  295. #pragma warning(default:4200)
  296. //--------------------------------------------------------
  297. // Large packet support
  298. inline BOOL
  299. IsLargePacket()
  300. {
  301. return (PacketFlags2 & DG_PF2_LARGE_PACKET);
  302. }
  303. inline void
  304. SetPacketBodyLen(
  305. unsigned long ulPacketBodyLen
  306. )
  307. {
  308. if (ulPacketBodyLen <= 65535)
  309. {
  310. PacketBodyLen = (unsigned short)ulPacketBodyLen;
  311. // NOTE: FragmentNumber isn't touched in this case.
  312. PacketFlags2 &= ~DG_PF2_LARGE_PACKET;
  313. }
  314. else
  315. {
  316. PacketBodyLen = (unsigned short)(ulPacketBodyLen & 0x0000ffff);
  317. FragmentNumber = (unsigned short)( (ulPacketBodyLen>>16) & 0x0000ffff );
  318. PacketFlags2 |= DG_PF2_LARGE_PACKET;
  319. }
  320. }
  321. inline unsigned long
  322. GetPacketBodyLen()
  323. {
  324. if (PacketFlags2 & DG_PF2_LARGE_PACKET)
  325. {
  326. unsigned long ulLen = ((unsigned long) PacketBodyLen)|( ((unsigned long)FragmentNumber)<<16 );
  327. return ulLen;
  328. }
  329. else
  330. {
  331. return PacketBodyLen;
  332. }
  333. }
  334. inline void
  335. SetFragmentNumber(
  336. unsigned short usFragmentNumber
  337. )
  338. {
  339. if ( !(PacketFlags2 & DG_PF2_LARGE_PACKET) )
  340. {
  341. FragmentNumber = usFragmentNumber;
  342. }
  343. }
  344. inline unsigned short
  345. GetFragmentNumber()
  346. {
  347. if (PacketFlags2 & DG_PF2_LARGE_PACKET)
  348. {
  349. return 0;
  350. }
  351. else
  352. {
  353. return FragmentNumber;
  354. }
  355. }
  356. };
  357. typedef struct _NCA_PACKET_HEADER NCA_PACKET_HEADER, PAPI * PNCA_PACKET_HEADER;
  358. struct QUIT_BODY_0
  359. {
  360. unsigned long Version;
  361. unsigned long EventId;
  362. };
  363. struct QUACK_BODY_0
  364. {
  365. unsigned long Version;
  366. unsigned long EventId;
  367. unsigned char Accepted;
  368. };
  369. //
  370. // The nornal DCE fault or reject packet contains only a single ulong status code.
  371. // A fault or reject packet containing Microsoft extended error info looks more like
  372. // this. The offset of the EE info buffer needs to 0 mod 16, so that 64-bit platforms
  373. // can unmarshal the info without relocating the buffer in memory.
  374. //
  375. #define DG_EE_MAGIC_VALUE ('M' + (('S' + (('E' + ('E' << 8)) << 8)) << 8))
  376. struct EXTENDED_FAULT_BODY
  377. {
  378. unsigned long NcaStatus;
  379. unsigned long Magic;
  380. unsigned long reserved1;
  381. unsigned long reserved2;
  382. char EeInfo[1];
  383. };
  384. class DG_PACKET;
  385. typedef DG_PACKET PAPI * PDG_PACKET;
  386. class __RPC_FAR DG_PACKET
  387. /*++
  388. Class Description:
  389. This class represents a packet that will be sent or received on the
  390. network.
  391. Fields:
  392. pTransAddress - A pointer to either a DG_CLIENT_TRANS_ADDRESS or
  393. a DG_SERVER_TRANS_ADDRESS that this packet will be sent or
  394. received through.
  395. pNcaPacketHeader - Where the packet information goes. Marshalled data
  396. follows immediately after this header.
  397. DataLength - Length of the marshalled data.
  398. TimeReceive - Time in seconds that this packet was
  399. received. This is filled in by the transport.
  400. pNext, pPrevious - Used to keep these packets in a list.
  401. --*/
  402. {
  403. public:
  404. unsigned MaxDataLength;
  405. unsigned DataLength;
  406. DG_PACKET * pNext;
  407. DG_PACKET * pPrevious;
  408. unsigned Flags;
  409. // Tick count when the packet was added to the free list.
  410. //
  411. unsigned TimeReceived;
  412. #ifdef MONITOR_SERVER_PACKET_COUNT
  413. unsigned unused;
  414. long * pCount;
  415. #endif
  416. // WARNING: Header must be 8-byte-aligned.
  417. //
  418. NCA_PACKET_HEADER Header;
  419. //--------------------------------------------------------------------
  420. DG_PACKET(
  421. unsigned PacketLength
  422. );
  423. ~DG_PACKET();
  424. void PAPI *
  425. operator new(
  426. size_t ObjectSize,
  427. unsigned BufferLength
  428. );
  429. void
  430. operator delete(
  431. void PAPI * UserBuffer,
  432. size_t ObjectSize
  433. );
  434. static PDG_PACKET
  435. AllocatePacket(
  436. unsigned BufferLength
  437. );
  438. static void
  439. FreePacket(
  440. PDG_PACKET pPacket,
  441. BOOL fCreateNewList = TRUE
  442. );
  443. static BOOL
  444. DeleteIdlePackets(
  445. long CurrentTime
  446. );
  447. static void
  448. FlushPacketLists(
  449. );
  450. static RPC_STATUS
  451. Initialize(
  452. );
  453. inline void
  454. Free(
  455. BOOL CreateNewList = TRUE
  456. )
  457. {
  458. FreePacket(this, CreateNewList);
  459. }
  460. inline static PDG_PACKET
  461. FromStubData(
  462. void * Buffer
  463. )
  464. {
  465. return CONTAINING_RECORD (Buffer, DG_PACKET, Header.Data);
  466. }
  467. inline static PDG_PACKET
  468. FromPacketHeader(
  469. void * Buffer
  470. )
  471. {
  472. return CONTAINING_RECORD(Buffer, DG_PACKET, Header);
  473. }
  474. //--------------------------------------------------------
  475. // Large packet support
  476. inline BOOL
  477. IsLargePacket()
  478. {
  479. return Header.IsLargePacket();
  480. }
  481. inline void
  482. SetPacketBodyLen(
  483. unsigned long ulPacketBodyLen
  484. )
  485. {
  486. Header.SetPacketBodyLen( ulPacketBodyLen );
  487. }
  488. inline unsigned long
  489. GetPacketBodyLen()
  490. {
  491. return Header.GetPacketBodyLen();
  492. }
  493. inline void
  494. SetFragmentNumber(
  495. unsigned short usFragmentNumber
  496. )
  497. {
  498. Header.SetFragmentNumber( usFragmentNumber );
  499. }
  500. inline unsigned short
  501. GetFragmentNumber()
  502. {
  503. return Header.GetFragmentNumber();
  504. }
  505. private:
  506. enum
  507. {
  508. NUMBER_OF_PACKET_LISTS = 6,
  509. IDLE_PACKET_LIFETIME = (30 * 1000)
  510. };
  511. struct PACKET_LIST
  512. {
  513. unsigned PacketLength;
  514. unsigned Count;
  515. PDG_PACKET Head;
  516. };
  517. static long PacketListTimeStamp;
  518. static MUTEX * PacketListMutex;
  519. static PACKET_LIST PacketLists[NUMBER_OF_PACKET_LISTS];
  520. };
  521. inline
  522. DG_PACKET::DG_PACKET(
  523. unsigned PacketLength
  524. )
  525. {
  526. MaxDataLength = PacketLength;
  527. LogEvent(SU_PACKET, EV_CREATE, this, 0, MaxDataLength);
  528. #ifdef MONITOR_SERVER_PACKET_COUNT
  529. pCount = 0;
  530. #endif
  531. }
  532. inline
  533. DG_PACKET::~DG_PACKET()
  534. {
  535. #ifdef MONITOR_SERVER_PACKET_COUNT
  536. ASSERT( pCount == 0 );
  537. #endif
  538. LogEvent(SU_PACKET, EV_DELETE, this, 0, MaxDataLength);
  539. }
  540. inline void PAPI *
  541. DG_PACKET::operator new(
  542. size_t ObjectSize,
  543. unsigned BufferLength
  544. )
  545. /*++
  546. Routine Description:
  547. Allocates a DG_PACKET with the specified buffer size.
  548. Arguments:
  549. ObjectSize - generated by compiler; same as sizeof(DG_PACKET)
  550. BufferLength - PDU size, including NCA header
  551. Return Value:
  552. an 8-byte-aligned pointer to an obect of the requested size
  553. --*/
  554. {
  555. unsigned Size = ObjectSize + BufferLength - sizeof(NCA_PACKET_HEADER);
  556. return RpcAllocateBuffer(Size);
  557. }
  558. inline void
  559. DG_PACKET::operator delete(
  560. void PAPI * UserBuffer,
  561. size_t ObjectSize
  562. )
  563. {
  564. RpcFreeBuffer(UserBuffer);
  565. }
  566. inline
  567. PDG_PACKET
  568. DG_PACKET::AllocatePacket(
  569. unsigned BufferLength
  570. )
  571. /*++
  572. Routine Description:
  573. Allocates a DG_PACKET with the specified buffer size.
  574. Arguments:
  575. ObjectSize - generated by compiler; same as sizeof(DG_PACKET)
  576. BufferLength - actual packet size
  577. Return Value:
  578. an 8-byte-aligned pointer to an obect of the requested size
  579. --*/
  580. {
  581. PDG_PACKET Packet;
  582. Packet = new (BufferLength) DG_PACKET(BufferLength);
  583. #if defined(DEBUGRPC)
  584. if (Packet)
  585. {
  586. Packet->TimeReceived = 0x31415926;
  587. }
  588. #endif
  589. if (Packet)
  590. {
  591. Packet->Flags = 0;
  592. }
  593. LogEvent(SU_PACKET, EV_START, Packet);
  594. return Packet;
  595. }
  596. inline
  597. void
  598. DG_PACKET::FreePacket(
  599. PDG_PACKET Packet,
  600. BOOL fCreateNewList
  601. )
  602. {
  603. LogEvent(SU_PACKET, EV_STOP, Packet);
  604. #ifdef DEBUGRPC
  605. ASSERT(Packet->TimeReceived == 0x31415926);
  606. Packet->TimeReceived = 0;
  607. #endif
  608. #ifdef MONITOR_SERVER_PACKET_COUNT
  609. if (Packet->pCount)
  610. {
  611. InterlockedDecrement( Packet->pCount );
  612. LogEvent( SU_SCALL, ')', PVOID(((ULONG_PTR) Packet->pCount)-0x260), Packet, *Packet->pCount );
  613. Packet->pCount = 0;
  614. }
  615. #endif
  616. delete Packet;
  617. }
  618. void
  619. ByteSwapPacketHeader(
  620. PDG_PACKET pPacket
  621. );
  622. inline BOOL
  623. NeedsByteSwap(
  624. PNCA_PACKET_HEADER pHeader
  625. )
  626. {
  627. #ifdef __RPC_MAC__
  628. if (pHeader->DataRep[0] & DG_DREP_INT_LITTLE)
  629. {
  630. return TRUE;
  631. }
  632. else
  633. {
  634. return FALSE;
  635. }
  636. #else
  637. if (pHeader->DataRep[0] & DG_DREP_INT_LITTLE)
  638. {
  639. return FALSE;
  640. }
  641. else
  642. {
  643. return TRUE;
  644. }
  645. #endif
  646. }
  647. inline void
  648. ByteSwapPacketHeaderIfNecessary(
  649. PDG_PACKET pPacket
  650. )
  651. {
  652. if (NeedsByteSwap(&pPacket->Header))
  653. {
  654. ByteSwapPacketHeader(pPacket);
  655. }
  656. }
  657. inline unsigned short
  658. ReadSerialNumber(
  659. PNCA_PACKET_HEADER pHeader
  660. )
  661. {
  662. unsigned short SerialNum = 0;
  663. SerialNum = pHeader->SerialLo;
  664. SerialNum |= (pHeader->DataRep[3] << 8);
  665. return SerialNum;
  666. }
  667. inline void
  668. SetMyDataRep(
  669. PNCA_PACKET_HEADER pHeader
  670. )
  671. {
  672. #ifdef __RPC_MAC__
  673. pHeader->DataRep[0] = DG_DREP_CHAR_ASCII | DG_DREP_INT_BIG;
  674. pHeader->DataRep[1] = DG_DREP_FP_IEEE;
  675. pHeader->DataRep[2] = 0;
  676. #else
  677. pHeader->DataRep[0] = DG_DREP_CHAR_ASCII | DG_DREP_INT_LITTLE;
  678. pHeader->DataRep[1] = DG_DREP_FP_IEEE;
  679. pHeader->DataRep[2] = 0;
  680. #endif
  681. }
  682. inline void
  683. DeleteSpuriousAuthProto(
  684. PDG_PACKET pPacket
  685. )
  686. /*++
  687. Routine Description:
  688. Some versions of OSF DCE generate packets that specify an auth proto,
  689. but do not actually have an auth trailer. They should be interpreted
  690. as unsecure packets.
  691. Arguments:
  692. the packet to clean up
  693. Return Value:
  694. none
  695. --*/
  696. {
  697. if (pPacket->Header.AuthProto != 0 &&
  698. pPacket->GetPacketBodyLen() == pPacket->DataLength)
  699. {
  700. pPacket->Header.AuthProto = 0;
  701. }
  702. }
  703. #pragma warning(disable:4200) // nonstandard extension: zero-length array
  704. struct DG_ENDPOINT
  705. {
  706. RPC_DATAGRAM_TRANSPORT * TransportInterface;
  707. BOOL Async;
  708. DWORD Flags;
  709. long TimeStamp;
  710. struct DG_ENDPOINT * Next;
  711. LONG NumberOfCalls;
  712. DG_ENDPOINT_STATS Stats;
  713. PVOID TransportEndpoint[];
  714. static DG_ENDPOINT *
  715. FromEndpoint(
  716. IN DG_TRANSPORT_ENDPOINT Endpoint
  717. )
  718. {
  719. return CONTAINING_RECORD( Endpoint, DG_ENDPOINT, TransportEndpoint );
  720. }
  721. };
  722. #pragma warning(3:4200) // nonstandard extension: zero-length array
  723. class NO_VTABLE DG_COMMON_CONNECTION : public GENERIC_OBJECT
  724. {
  725. public:
  726. RPC_DATAGRAM_TRANSPORT *TransportInterface;
  727. UUID_HASH_TABLE_NODE ActivityNode;
  728. SECURITY_CONTEXT * ActiveSecurityContext;
  729. MUTEX Mutex;
  730. unsigned CurrentPduSize;
  731. unsigned RemoteWindowSize;
  732. boolean RemoteDataUpdated;
  733. long TimeStamp;
  734. //--------------------------------------------------------------------
  735. virtual RPC_STATUS
  736. SealAndSendPacket(
  737. IN DG_ENDPOINT * SourceEndpoint,
  738. IN DG_TRANSPORT_ADDRESS RemoteAddress,
  739. IN UNALIGNED NCA_PACKET_HEADER * pHeader,
  740. IN unsigned long DataOffset
  741. ) = 0;
  742. DG_COMMON_CONNECTION(
  743. RPC_DATAGRAM_TRANSPORT *TransportInterface,
  744. RPC_STATUS * pStatus
  745. );
  746. ~DG_COMMON_CONNECTION(
  747. );
  748. protected:
  749. long ReferenceCount;
  750. unsigned LowestActiveSequence;
  751. unsigned LowestUnusedSequence;
  752. };
  753. struct QUEUED_BUFFER
  754. {
  755. QUEUED_BUFFER * Next;
  756. void * Buffer;
  757. unsigned BufferLength;
  758. unsigned long BufferFlags;
  759. };
  760. class NO_VTABLE DG_PACKET_ENGINE
  761. {
  762. public:
  763. unsigned short ActivityHint;
  764. unsigned short InterfaceHint;
  765. //--------------------------------------------------------------------
  766. DG_PACKET_ENGINE(
  767. unsigned char PacketType,
  768. DG_PACKET * Packet,
  769. RPC_STATUS * pStatus
  770. );
  771. ~DG_PACKET_ENGINE(
  772. );
  773. virtual RPC_STATUS
  774. SendSomeFragments();
  775. unsigned long GetSequenceNumber()
  776. {
  777. return SequenceNumber;
  778. }
  779. void
  780. SetSequenceNumber(
  781. unsigned long Seq
  782. )
  783. {
  784. SequenceNumber = Seq;
  785. pSavedPacket->Header.SequenceNumber = Seq;
  786. }
  787. void CheckForLeakedPackets();
  788. void
  789. AddActivePacket(
  790. DG_PACKET * Packet
  791. );
  792. void
  793. RemoveActivePacket(
  794. DG_PACKET * Packet
  795. );
  796. unsigned long SequenceNumber;
  797. PDG_PACKET pSavedPacket;
  798. DG_ENDPOINT * SourceEndpoint;
  799. DG_TRANSPORT_ADDRESS RemoteAddress;
  800. unsigned ReferenceCount;
  801. unsigned long CancelEventId;
  802. unsigned char PacketType;
  803. unsigned char BasePacketFlags;
  804. unsigned char BasePacketFlags2;
  805. //--------------------------------------------------------------------
  806. PDG_PACKET
  807. AllocatePacket(
  808. )
  809. {
  810. PDG_PACKET Packet = 0;
  811. Packet = DG_PACKET::AllocatePacket(CurrentPduSize);
  812. #ifdef DEBUGRPC
  813. if (Packet)
  814. {
  815. Packet->Flags = PtrToUlong(this);
  816. ASSERT( 0 == (Packet->Flags & DG_PF_PARTIAL) );
  817. }
  818. #endif
  819. return Packet;
  820. }
  821. void
  822. FreePacket(
  823. PDG_PACKET Packet
  824. )
  825. {
  826. #ifdef DEBUGRPC
  827. Packet->Flags &= ~DG_PF_PARTIAL;
  828. ASSERT( Packet->Flags == 0 ||
  829. Packet->Flags == PtrToUlong(this) );
  830. #endif
  831. Packet->Free(FALSE);
  832. }
  833. //
  834. //--------------data common to send and receive buffers-------------------
  835. //
  836. //
  837. // used to be MaxPdu
  838. //
  839. unsigned short Reserved0;
  840. //
  841. // Biggest packet that transport won't fragment.
  842. //
  843. unsigned short MaxPacketSize;
  844. //
  845. // Largest PDU that this object will send.
  846. //
  847. unsigned short CurrentPduSize;
  848. //
  849. // Number of bytes of stub data in a datagram.
  850. //
  851. unsigned short MaxFragmentSize;
  852. //
  853. // Number of bytes of security trailer in a datagram.
  854. //
  855. unsigned short SecurityTrailerSize;
  856. //
  857. // number of consecutive unacknowledged packets, including retransmissions
  858. //
  859. unsigned TimeoutCount;
  860. unsigned short SendSerialNumber;
  861. unsigned short ReceiveSerialNumber;
  862. LONG Cancelled;
  863. // Many of these could be made [private].
  864. //
  865. // -------------------data concerning send buffer-------------------------
  866. //
  867. void PAPI * Buffer;
  868. unsigned BufferLength;
  869. unsigned long BufferFlags;
  870. //
  871. // maximum number of packets in send window
  872. //
  873. unsigned short SendWindowSize;
  874. //
  875. // number of packets to transmit in one shot
  876. //
  877. unsigned short SendBurstLength;
  878. //
  879. // lowest unacknowledged fragment
  880. //
  881. unsigned short SendWindowBase;
  882. //
  883. // first fragment that has never been sent
  884. //
  885. unsigned short FirstUnsentFragment;
  886. //
  887. // Buffer offset of FirstUnsentFragment.
  888. //
  889. unsigned FirstUnsentOffset;
  890. //
  891. // bit mask showing which fragments to send
  892. // (same format as in FACK packet with body)
  893. //
  894. unsigned SendWindowBits;
  895. //
  896. // For each unacknowledged fragment, we need to know the serial number
  897. // of the last retransmission. When a FACK arrives, we will retransmit
  898. // only those packets with a serial number less than that of the FACK.
  899. //
  900. struct
  901. {
  902. unsigned long SerialNumber;
  903. unsigned long Length;
  904. unsigned long Offset;
  905. }
  906. FragmentRingBuffer[MAX_WINDOW_SIZE];
  907. unsigned RingBufferBase;
  908. //
  909. // last fragment of buffer
  910. //
  911. unsigned short FinalSendFrag;
  912. // serial number of last packet FACKed by other end
  913. //
  914. unsigned short FackSerialNumber;
  915. //
  916. // ----------------data concerning receive buffer-------------------------
  917. //
  918. //
  919. // all received packets
  920. //
  921. PDG_PACKET pReceivedPackets;
  922. //
  923. // last packet before a gap
  924. //
  925. PDG_PACKET pLastConsecutivePacket;
  926. //
  927. // used to be ReceiveWindowSize
  928. //
  929. unsigned short Reserved1;
  930. //
  931. // First fragment we should keep. Elder fragments belong to a previous
  932. // pipe buffer.
  933. //
  934. unsigned short ReceiveFragmentBase;
  935. //
  936. // Length of the underlying transport's socket buffer.
  937. //
  938. unsigned TransportBufferLength;
  939. //
  940. // Number of bytes in consecutive fragments.
  941. //
  942. unsigned ConsecutiveDataBytes;
  943. //
  944. // The last-allocated pipe receive buffer, and its length.
  945. //
  946. void __RPC_FAR *LastReceiveBuffer;
  947. unsigned LastReceiveBufferLength;
  948. boolean fReceivedAllFragments;
  949. boolean fRetransmitted;
  950. unsigned RepeatedFack;
  951. DG_COMMON_CONNECTION * BaseConnection;
  952. //--------------------------------------------------------------------
  953. RPC_STATUS
  954. PushBuffer(
  955. PRPC_MESSAGE Message
  956. );
  957. RPC_STATUS
  958. PopBuffer(
  959. BOOL fSendPackets
  960. );
  961. RPC_STATUS
  962. FixupPartialSend(
  963. RPC_MESSAGE * Message
  964. );
  965. void
  966. CommonFreeBuffer(
  967. RPC_MESSAGE * Message
  968. );
  969. RPC_STATUS
  970. CommonGetBuffer(
  971. RPC_MESSAGE * MEssage
  972. );
  973. RPC_STATUS
  974. CommonReallocBuffer(
  975. IN RPC_MESSAGE * Message,
  976. IN unsigned int NewSize
  977. );
  978. void
  979. ReadConnectionInfo(
  980. DG_COMMON_CONNECTION * a_Connection,
  981. DG_TRANSPORT_ADDRESS a_RemoteAddress
  982. );
  983. void NewCall();
  984. RPC_STATUS
  985. SetupSendWindow(
  986. PRPC_MESSAGE Message
  987. );
  988. void CleanupSendWindow();
  989. void CleanupReceiveWindow();
  990. RPC_STATUS
  991. SendFragment(
  992. unsigned FragNum,
  993. unsigned char PacketType,
  994. BOOL fFack
  995. );
  996. RPC_STATUS
  997. SendFackOrNocall(
  998. PDG_PACKET pPacket,
  999. unsigned char PacketType
  1000. );
  1001. RPC_STATUS
  1002. UpdateSendWindow(
  1003. PDG_PACKET pPacket,
  1004. BOOL * pfUpdated
  1005. );
  1006. BOOL
  1007. UpdateReceiveWindow(
  1008. PDG_PACKET pPacket
  1009. );
  1010. RPC_STATUS
  1011. AssembleBufferFromPackets(
  1012. IN OUT RPC_MESSAGE * Message,
  1013. IN CALL * Call
  1014. );
  1015. void SetFragmentLengths();
  1016. void RecalcReceiveWindow();
  1017. unsigned short LastConsecutiveFragment()
  1018. {
  1019. if (0 == pLastConsecutivePacket)
  1020. {
  1021. return 0xffff;
  1022. }
  1023. else
  1024. {
  1025. return pLastConsecutivePacket->GetFragmentNumber();
  1026. }
  1027. }
  1028. void MarkAllPacketsReceived()
  1029. {
  1030. ASSERT( FirstUnsentFragment > FinalSendFrag );
  1031. unsigned short Diff = FinalSendFrag+1 - SendWindowBase;
  1032. ASSERT(Diff <= MAX_WINDOW_SIZE);
  1033. ASSERT( SendWindowBase+Diff <= FirstUnsentFragment );
  1034. SendWindowBase += Diff;
  1035. RingBufferBase += Diff;
  1036. RingBufferBase %= MAX_WINDOW_SIZE;
  1037. PopBuffer(TRUE);
  1038. }
  1039. BOOL
  1040. IsBufferAcknowledged(
  1041. )
  1042. {
  1043. if (SendWindowBase > FinalSendFrag)
  1044. {
  1045. return TRUE;
  1046. }
  1047. return FALSE;
  1048. }
  1049. BOOL
  1050. IsBufferSent(
  1051. )
  1052. {
  1053. if (FirstUnsentFragment > FinalSendFrag)
  1054. {
  1055. return TRUE;
  1056. }
  1057. return FALSE;
  1058. }
  1059. inline void
  1060. AddSerialNumber(
  1061. UNALIGNED NCA_PACKET_HEADER *pHeader
  1062. );
  1063. private:
  1064. QUEUED_BUFFER * QueuedBufferHead;
  1065. QUEUED_BUFFER * QueuedBufferTail;
  1066. PDG_PACKET CachedPacket;
  1067. void
  1068. SetCurrentBuffer(
  1069. void * a_Buffer,
  1070. unsigned a_BufferLength,
  1071. unsigned long BufferFlags
  1072. );
  1073. };
  1074. typedef DG_PACKET_ENGINE * PDG_PACKET_ENGINE;
  1075. inline void
  1076. SetSerialNumber(
  1077. UNALIGNED NCA_PACKET_HEADER *pHeader,
  1078. unsigned short SerialNumber
  1079. )
  1080. {
  1081. pHeader->SerialLo = SerialNumber & 0x00ffU;
  1082. pHeader->DataRep[3] = (unsigned char) (SerialNumber >> 8);
  1083. }
  1084. inline void
  1085. DG_PACKET_ENGINE::AddSerialNumber(
  1086. UNALIGNED NCA_PACKET_HEADER *pHeader
  1087. )
  1088. {
  1089. SetSerialNumber(pHeader, SendSerialNumber);
  1090. }
  1091. extern unsigned long ProcessStartTime;
  1092. inline void
  1093. CleanupPacket(
  1094. NCA_PACKET_HEADER * pHeader
  1095. )
  1096. {
  1097. pHeader->RpcVersion = DG_RPC_PROTOCOL_VERSION;
  1098. pHeader->ServerBootTime = ProcessStartTime;
  1099. SetMyDataRep(pHeader);
  1100. pHeader->PacketFlags &= DG_PF_IDEMPOTENT;
  1101. pHeader->PacketFlags2 = 0;
  1102. pHeader->AuthProto = 0;
  1103. }
  1104. //------------------------------------------------------------------------
  1105. RPC_STATUS
  1106. SendSecurePacket(
  1107. IN DG_ENDPOINT * SourceEndpoint,
  1108. IN DG_TRANSPORT_ADDRESS RemoteAddress,
  1109. IN UNALIGNED NCA_PACKET_HEADER *pHeader,
  1110. IN unsigned long DataOffset,
  1111. IN SECURITY_CONTEXT * SecurityContext
  1112. );
  1113. RPC_STATUS
  1114. VerifySecurePacket(
  1115. PDG_PACKET pPacket,
  1116. SECURITY_CONTEXT * pSecurityContext
  1117. );
  1118. void
  1119. InitErrorPacket(
  1120. DG_PACKET * Packet,
  1121. unsigned char PacketType,
  1122. RPC_STATUS RpcStatus
  1123. );
  1124. void
  1125. DumpBuffer(
  1126. void FAR * Buffer,
  1127. unsigned Length
  1128. );
  1129. extern void EnableGlobalScavenger();
  1130. extern DELAYED_ACTION_TABLE * DelayedProcedures;
  1131. extern unsigned RandomCounter;
  1132. inline unsigned GetRandomCounter()
  1133. {
  1134. ::RandomCounter *= 37;
  1135. ::RandomCounter += GetTickCount();
  1136. return ::RandomCounter;
  1137. }
  1138. #endif // __DGPKT_HXX__