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.

2195 lines
58 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1994 - 1999
  6. //
  7. // File: dgpkt.cxx
  8. //
  9. //--------------------------------------------------------------------------
  10. /*++
  11. Module Name:
  12. dgpkt.cxx
  13. Abstract:
  14. Author:
  15. Jeff Roberts (jroberts) 22-May-1995
  16. Revision History:
  17. 22-May-1995 jroberts
  18. Created this module.
  19. 09-Jul-1997 edwardr
  20. Added support for large packets (>65535) for Falcon/RPC.
  21. --*/
  22. #include <precomp.hxx>
  23. #include <dgpkt.hxx>
  24. unsigned long ProcessStartTime;
  25. unsigned RandomCounter = 0x6789abce;
  26. const unsigned
  27. RpcToPacketFlagsArray[8] =
  28. {
  29. 0,
  30. DG_PF_IDEMPOTENT,
  31. DG_PF_BROADCAST,
  32. DG_PF_IDEMPOTENT | DG_PF_BROADCAST,
  33. DG_PF_MAYBE,
  34. DG_PF_IDEMPOTENT | DG_PF_MAYBE,
  35. DG_PF_BROADCAST | DG_PF_MAYBE,
  36. DG_PF_IDEMPOTENT | DG_PF_BROADCAST | DG_PF_MAYBE,
  37. };
  38. const unsigned
  39. PacketToRpcFlagsArray[8] =
  40. {
  41. 0 | 0 | 0 ,
  42. RPC_NCA_FLAGS_MAYBE | 0 | 0 ,
  43. 0 | RPC_NCA_FLAGS_IDEMPOTENT | 0 ,
  44. RPC_NCA_FLAGS_MAYBE | RPC_NCA_FLAGS_IDEMPOTENT | 0 ,
  45. 0 | 0 | RPC_NCA_FLAGS_BROADCAST,
  46. RPC_NCA_FLAGS_MAYBE | 0 | RPC_NCA_FLAGS_BROADCAST,
  47. 0 | RPC_NCA_FLAGS_IDEMPOTENT | RPC_NCA_FLAGS_BROADCAST,
  48. RPC_NCA_FLAGS_MAYBE | RPC_NCA_FLAGS_IDEMPOTENT | RPC_NCA_FLAGS_BROADCAST,
  49. };
  50. DG_PACKET_ENGINE::DG_PACKET_ENGINE(
  51. unsigned char a_PacketType,
  52. DG_PACKET * a_Packet,
  53. RPC_STATUS * pStatus
  54. ) :
  55. pSavedPacket (a_Packet),
  56. PacketType (a_PacketType),
  57. ReferenceCount (0),
  58. BaseConnection (0),
  59. SourceEndpoint (0),
  60. RemoteAddress (0),
  61. Buffer (0),
  62. BufferLength (0),
  63. QueuedBufferHead (0),
  64. QueuedBufferTail (0),
  65. pReceivedPackets (0),
  66. pLastConsecutivePacket(0),
  67. ConsecutiveDataBytes (0),
  68. ReceiveFragmentBase (0),
  69. CachedPacket (0),
  70. LastReceiveBuffer (0),
  71. LastReceiveBufferLength(0),
  72. Cancelled (FALSE)
  73. {
  74. if (!a_Packet)
  75. {
  76. *pStatus = RPC_S_OUT_OF_MEMORY;
  77. }
  78. if (*pStatus)
  79. {
  80. return;
  81. }
  82. pSavedPacket->Header.RpcVersion = DG_RPC_PROTOCOL_VERSION;
  83. pSavedPacket->Header.PacketFlags = 0;
  84. SetMyDataRep(&pSavedPacket->Header);
  85. #ifdef DEBUGRPC
  86. BasePacketFlags = ~0;
  87. #endif
  88. }
  89. void
  90. DG_PACKET_ENGINE::ReadConnectionInfo(
  91. DG_COMMON_CONNECTION * a_Connection,
  92. DG_TRANSPORT_ADDRESS a_RemoteAddress
  93. )
  94. {
  95. BaseConnection = a_Connection;
  96. RemoteAddress = a_RemoteAddress;
  97. CurrentPduSize = 0;
  98. SetFragmentLengths();
  99. pSavedPacket->Header.InterfaceHint = 0xffff;
  100. RpcpMemoryCopy( &pSavedPacket->Header.ActivityId,
  101. &a_Connection->ActivityNode.Uuid,
  102. sizeof(UUID)
  103. );
  104. }
  105. DG_PACKET_ENGINE::~DG_PACKET_ENGINE(
  106. )
  107. {
  108. ASSERT( !LastReceiveBuffer );
  109. ASSERT( !pReceivedPackets );
  110. ASSERT( !QueuedBufferHead );
  111. ASSERT( !Buffer );
  112. if (pSavedPacket)
  113. {
  114. FreePacket(pSavedPacket);
  115. }
  116. if (CachedPacket)
  117. {
  118. FreePacket(CachedPacket);
  119. }
  120. CleanupReceiveWindow();
  121. }
  122. void
  123. DG_PACKET_ENGINE::NewCall()
  124. /*++
  125. Routine Description:
  126. A new call dawns.
  127. Arguments:
  128. Return Value:
  129. none
  130. --*/
  131. {
  132. ASSERT( !pLastConsecutivePacket );
  133. ASSERT( !ConsecutiveDataBytes );
  134. ASSERT( !LastReceiveBuffer );
  135. SetFragmentLengths();
  136. Buffer = 0;
  137. fReceivedAllFragments = FALSE;
  138. fRetransmitted = FALSE;
  139. TimeoutCount = 0;
  140. RepeatedFack = 0;
  141. FackSerialNumber = 0;
  142. SendSerialNumber = 0;
  143. ReceiveSerialNumber = 0;
  144. SendWindowBase = 0;
  145. FirstUnsentFragment = 0;
  146. SendBurstLength = SendWindowSize;
  147. ReceiveFragmentBase = 0;
  148. RingBufferBase = 0;
  149. #ifdef DEBUGRPC
  150. for (unsigned i=0; i < MAX_WINDOW_SIZE; i++)
  151. {
  152. FragmentRingBuffer[i].SerialNumber = 0xeeee0000;
  153. FragmentRingBuffer[i].Length = 0xdd000000;
  154. FragmentRingBuffer[i].Offset = 0xb000b000;
  155. }
  156. #endif
  157. BasePacketFlags2 = 0;
  158. }
  159. RPC_STATUS
  160. DG_PACKET_ENGINE::PushBuffer(
  161. PRPC_MESSAGE Message
  162. )
  163. /*++
  164. Function Description:
  165. Submits a buffer to be sent over the network.
  166. If a buffer is in progress, the new buffer is added to the
  167. "pending" list. IF not, the buffer is placed in the "active" slot.
  168. The only time a buffer will not go in the active slot is during an
  169. async pipe call when the app is not waiting for send-complete
  170. notifications before submitting new buffers.
  171. Notes:
  172. The buffer sent will be truncated to the nearest packet if
  173. RPC_BUFFER_PARTIAL is set, and Message.BufferLength is set to
  174. the amount actually sent.
  175. --*/
  176. {
  177. // ASSERT( Buffer == 0 || IsBufferAcknowledged() );
  178. RPC_STATUS Status = 0;
  179. RPC_STATUS FixupStatus = 0;
  180. unsigned FractionalPart = Message->BufferLength % MaxFragmentSize;
  181. unsigned SendLength = Message->BufferLength;
  182. if (Message->RpcFlags & RPC_BUFFER_PARTIAL)
  183. {
  184. SendLength -= FractionalPart;
  185. }
  186. if (!Buffer || IsBufferAcknowledged())
  187. {
  188. SetCurrentBuffer(Message->Buffer,
  189. SendLength,
  190. Message->RpcFlags
  191. );
  192. Status = SendSomeFragments();
  193. }
  194. else
  195. {
  196. QUEUED_BUFFER * Node = new QUEUED_BUFFER;
  197. if (!Node)
  198. {
  199. return RPC_S_OUT_OF_MEMORY;
  200. }
  201. Node->Buffer = Message->Buffer;
  202. Node->BufferLength = SendLength;
  203. Node->BufferFlags = Message->RpcFlags;
  204. Node->Next = 0;
  205. if (QueuedBufferTail)
  206. {
  207. QueuedBufferTail->Next = Node;
  208. }
  209. else
  210. {
  211. ASSERT( !QueuedBufferHead );
  212. QueuedBufferHead = Node;
  213. }
  214. QueuedBufferTail = Node;
  215. Status = 0;
  216. }
  217. FixupStatus = FixupPartialSend(Message);
  218. if (!Status)
  219. {
  220. Status = FixupStatus;
  221. }
  222. return Status;
  223. }
  224. RPC_STATUS
  225. DG_PACKET_ENGINE::PopBuffer(
  226. BOOL fSend
  227. )
  228. /*++
  229. Function Description:
  230. Move the next pending send buffer into the active send buffer slot.
  231. This is a no-op except unless this is an async pipe call and the app
  232. is not waiting for send-complete notifications.
  233. Notes:
  234. The buffer sent will be truncated to the nearest packet if
  235. RPC_BUFFER_PARTIAL is set, and Message.BufferLength is set to
  236. the amount actually sent.
  237. --*/
  238. {
  239. RPC_STATUS Status = 0;
  240. RPC_MESSAGE Message;
  241. Message.Buffer = Buffer;
  242. Message.BufferLength = BufferLength;
  243. QUEUED_BUFFER * Node = QueuedBufferHead;
  244. if (Node)
  245. {
  246. QueuedBufferHead = Node->Next;
  247. if (!QueuedBufferHead)
  248. {
  249. QueuedBufferTail = 0;
  250. }
  251. SetCurrentBuffer(Node->Buffer, Node->BufferLength, Node->BufferFlags);
  252. if (fSend)
  253. {
  254. Status = SendSomeFragments();
  255. }
  256. delete Node;
  257. }
  258. else
  259. {
  260. Buffer = 0;
  261. BufferLength = 0;
  262. BufferFlags = 0;
  263. }
  264. if (Message.Buffer)
  265. {
  266. CommonFreeBuffer(&Message);
  267. }
  268. return Status;
  269. }
  270. RPC_STATUS
  271. DG_PACKET_ENGINE::FixupPartialSend(
  272. RPC_MESSAGE * Message
  273. )
  274. /*++
  275. Function Description:
  276. This fn "does the right thing" with the unsent bit at the end of
  277. a pipe send. For sync sends, this means moving the unsent bit
  278. to the front of the existing buffer. For async sends, this means
  279. allocating a new buffer and copying the unsent bit into it.
  280. --*/
  281. {
  282. if (!(Message->RpcFlags & RPC_BUFFER_PARTIAL))
  283. {
  284. // We need this so Receive will be passed a null buffer
  285. // unless the stub sticks one in the message.
  286. Message->Buffer = 0;
  287. Message->BufferLength = 0;
  288. return RPC_S_OK;
  289. }
  290. unsigned FractionalPart;
  291. // if (Message->RpcFlags & RPC_BUFFER_ASYNC)
  292. // {
  293. RPC_MESSAGE NewMessage;
  294. FractionalPart = Message->BufferLength % MaxFragmentSize;
  295. if (!FractionalPart)
  296. {
  297. Message->Buffer = 0;
  298. Message->BufferLength = 0;
  299. return RPC_S_OK;
  300. }
  301. DG_PACKET * Packet = DG_PACKET::AllocatePacket(CurrentPduSize);
  302. if (!Packet)
  303. {
  304. return RPC_S_OUT_OF_MEMORY;
  305. }
  306. RpcpMemoryCopy(Packet->Header.Data,
  307. ((char *) Message->Buffer) + (Message->BufferLength - FractionalPart),
  308. FractionalPart
  309. );
  310. Message->Buffer = Packet->Header.Data;
  311. Message->BufferLength = FractionalPart;
  312. // }
  313. // else
  314. // {
  315. // char * Temp = (char *) Message->Buffer;
  316. //
  317. // FractionalPart = Message->BufferLength - FirstUnsentOffset;
  318. // if (!FractionalPart)
  319. // {
  320. // return RPC_S_OK;
  321. // }
  322. //
  323. // RpcpMemoryMove(Message->Buffer, Temp + FirstUnsentOffset, FractionalPart);
  324. // Message->BufferLength = FractionalPart;
  325. // }
  326. return RPC_S_OK;
  327. }
  328. void
  329. DG_PACKET_ENGINE::SetCurrentBuffer(
  330. void * a_Buffer,
  331. unsigned a_BufferLength,
  332. unsigned long a_BufferFlags
  333. )
  334. {
  335. Buffer = a_Buffer;
  336. BufferLength = a_BufferLength;
  337. BufferFlags = a_BufferFlags;
  338. TimeoutCount = 0;
  339. SendWindowBits = 0;
  340. FirstUnsentOffset = 0;
  341. if (BufferLength == 0)
  342. {
  343. FinalSendFrag = SendWindowBase;
  344. }
  345. else
  346. {
  347. FinalSendFrag = SendWindowBase + (BufferLength-1) / MaxFragmentSize;
  348. }
  349. }
  350. RPC_STATUS
  351. DG_PACKET_ENGINE::CommonGetBuffer(
  352. RPC_MESSAGE * Message
  353. )
  354. {
  355. unsigned char SubjectType;
  356. void * Subject;
  357. unsigned Length;
  358. PDG_PACKET pPacket;
  359. Length = sizeof(NCA_PACKET_HEADER)
  360. + Align8(Message->BufferLength)
  361. + SecurityTrailerSize;
  362. unsigned BaseLength = BaseConnection->TransportInterface->BasePduSize;
  363. // if (Length <= BaseLength)
  364. // {
  365. // pPacket = DG_PACKET::AllocatePacket(BaseLength);
  366. // }
  367. // else if (Length <= CurrentPduSize)
  368. // {
  369. // pPacket = AllocatePacket();
  370. // }
  371. // else
  372. {
  373. pPacket = DG_PACKET::AllocatePacket(Length);
  374. }
  375. if (0 == pPacket)
  376. {
  377. return RPC_S_OUT_OF_MEMORY;
  378. }
  379. //
  380. // Point the buffer at the appropriate place in the packet.
  381. //
  382. Message->Buffer = pPacket->Header.Data;
  383. // if (pPacket->MaxDataLength < 256)
  384. // {
  385. // AddActivePacket(pPacket);
  386. // }
  387. return RPC_S_OK;
  388. }
  389. void
  390. DG_PACKET_ENGINE::CommonFreeBuffer(
  391. RPC_MESSAGE * Message
  392. )
  393. {
  394. if (!Message->Buffer)
  395. {
  396. return;
  397. }
  398. PDG_PACKET Packet = DG_PACKET::FromStubData(Message->Buffer);
  399. LogEvent(SU_ENGINE, EV_PROC, this, Message->Buffer, 'F' + (('B' + (('u' + ('f' << 8)) << 8)) << 8));
  400. ASSERT( Packet->MaxDataLength < 0x7fffffffUL );
  401. // if (Packet && Packet->MaxDataLength < 256)
  402. // {
  403. // RemoveActivePacket(Packet);
  404. // }
  405. FreePacket(Packet);
  406. if (Message->Buffer == LastReceiveBuffer)
  407. {
  408. LastReceiveBuffer = 0;
  409. LastReceiveBufferLength = 0;
  410. }
  411. Message->Buffer = 0;
  412. }
  413. RPC_STATUS
  414. DG_PACKET_ENGINE::CommonReallocBuffer(
  415. IN RPC_MESSAGE * Message,
  416. IN unsigned int NewSize
  417. )
  418. {
  419. if (Message->Buffer == LastReceiveBuffer &&
  420. NewSize <= LastReceiveBufferLength)
  421. {
  422. Message->BufferLength = NewSize;
  423. return RPC_S_OK;
  424. }
  425. RPC_STATUS Status;
  426. RPC_MESSAGE NewMessage;
  427. NewMessage.BufferLength = NewSize;
  428. Status = CommonGetBuffer(&NewMessage);
  429. if (RPC_S_OK != Status)
  430. {
  431. return Status;
  432. }
  433. LastReceiveBuffer = NewMessage.Buffer;
  434. LastReceiveBufferLength = NewMessage.BufferLength;
  435. if (NewSize >= Message->BufferLength)
  436. {
  437. RpcpMemoryCopy(NewMessage.Buffer,
  438. Message->Buffer,
  439. Message->BufferLength
  440. );
  441. }
  442. CommonFreeBuffer(Message);
  443. Message->Buffer = NewMessage.Buffer;
  444. Message->BufferLength = NewMessage.BufferLength;
  445. return RPC_S_OK;
  446. }
  447. void
  448. DG_PACKET_ENGINE::CleanupSendWindow()
  449. {
  450. while (Buffer)
  451. {
  452. PopBuffer(FALSE);
  453. }
  454. }
  455. void
  456. DG_PACKET_ENGINE::CleanupReceiveWindow()
  457. {
  458. //
  459. // Free any response packets.
  460. //
  461. while (pReceivedPackets)
  462. {
  463. PDG_PACKET Next = pReceivedPackets->pNext;
  464. FreePacket(pReceivedPackets);
  465. pReceivedPackets = Next;
  466. }
  467. pLastConsecutivePacket = 0;
  468. ConsecutiveDataBytes = 0;
  469. }
  470. RPC_STATUS
  471. DG_PACKET_ENGINE::SendSomeFragments()
  472. /*++
  473. Routine Description:
  474. Sends some fragments of the user buffer.
  475. Arguments:
  476. Return Value:
  477. result of the send operation
  478. --*/
  479. {
  480. RPC_STATUS Status = RPC_S_OK;
  481. unsigned short i = 0;
  482. unsigned short AckFragment;
  483. unsigned short Frag;
  484. unsigned short Remainder;
  485. unsigned Offset;
  486. unsigned FragmentsSent = 0;
  487. #ifdef DEBUGRPC
  488. if (!Buffer &&
  489. (BufferFlags & RPC_BUFFER_PARTIAL))
  490. {
  491. // return RPC_S_SEND_INCOMPLETE;
  492. RpcpBreakPoint();
  493. }
  494. #endif
  495. if (SendBurstLength > SendWindowSize)
  496. {
  497. SendBurstLength = SendWindowSize;
  498. }
  499. //
  500. // If we can extend the window, do so; otherwise, resend old packets.
  501. //
  502. if (FirstUnsentFragment <= FinalSendFrag &&
  503. FirstUnsentFragment < SendWindowBase + SendWindowSize)
  504. {
  505. unsigned short ThisBurstLength;
  506. Frag = FirstUnsentFragment;
  507. ThisBurstLength = SendBurstLength;
  508. if (ThisBurstLength > FinalSendFrag + 1 - Frag)
  509. {
  510. ThisBurstLength = FinalSendFrag + 1 - Frag;
  511. }
  512. if (Frag + ThisBurstLength > SendWindowBase + SendWindowSize)
  513. {
  514. ThisBurstLength = (SendWindowBase + SendWindowSize) - Frag;
  515. }
  516. while (++FragmentsSent <= ThisBurstLength && Status == RPC_S_OK)
  517. {
  518. if (FragmentsSent == ThisBurstLength &&
  519. (Frag != FinalSendFrag || (BufferFlags & RPC_BUFFER_PARTIAL) || (BasePacketFlags2 & DG_PF2_UNRELATED)))
  520. {
  521. Status = SendFragment(Frag, PacketType, TRUE);
  522. }
  523. else
  524. {
  525. Status = SendFragment(Frag, PacketType, FALSE);
  526. }
  527. ++Frag;
  528. }
  529. //
  530. // Cut down the burst length if our window is maxed out.
  531. //
  532. if (Frag - SendWindowBase >= SendWindowSize)
  533. {
  534. SendBurstLength = (1+SendBurstLength)/2;
  535. }
  536. }
  537. if (0 == FragmentsSent && !IsBufferAcknowledged())
  538. {
  539. // We can get here if all the unacknowledged fragments have serial
  540. // numbers greater than the one the client last acknowledged, and
  541. // the window is also maxed out.
  542. //
  543. // This could mean the network is very slow, or the unack'ed packets
  544. // have been lost.
  545. //
  546. Status = SendFragment(SendWindowBase, PacketType, TRUE);
  547. }
  548. return Status;
  549. }
  550. RPC_STATUS
  551. DG_PACKET_ENGINE::SendFragment(
  552. unsigned FragNum,
  553. unsigned char PacketType,
  554. BOOL fFack
  555. )
  556. {
  557. NCA_PACKET_HEADER PriorData;
  558. UNALIGNED NCA_PACKET_HEADER __RPC_FAR * pHeader;
  559. //
  560. // Figure out where the packet starts and how long it is.
  561. //
  562. unsigned Offset;
  563. unsigned Length;
  564. unsigned Index = (FragNum - SendWindowBase + RingBufferBase) % MAX_WINDOW_SIZE;
  565. unsigned DistanceToEnd;
  566. if (FragNum < FirstUnsentFragment)
  567. {
  568. Offset = FragmentRingBuffer[Index].Offset;
  569. Length = FragmentRingBuffer[Index].Length;
  570. DistanceToEnd = BufferLength - Offset;
  571. #ifdef DEBUGRPC
  572. if (Offset >= 0xb000b000 || Length >= 0xdd000000)
  573. {
  574. RpcpBreakPoint();
  575. }
  576. #endif
  577. fRetransmitted = TRUE;
  578. }
  579. else
  580. {
  581. ASSERT(FragNum == FirstUnsentFragment);
  582. Offset = FirstUnsentOffset;
  583. Length = MaxFragmentSize;
  584. DistanceToEnd = BufferLength - Offset;
  585. if (DistanceToEnd < Length)
  586. {
  587. Length = DistanceToEnd;
  588. }
  589. FirstUnsentOffset += Length;
  590. FirstUnsentFragment = 1 + FragNum;
  591. }
  592. if (BufferLength)
  593. {
  594. // this is harmless and can sometimes be triggered on the first call of an activity
  595. // ASSERT(Length);
  596. // ASSERT(Offset < BufferLength);
  597. }
  598. else
  599. {
  600. ASSERT(!Length);
  601. ASSERT(!Offset);
  602. }
  603. //
  604. // Time to start assembling the buffer.
  605. //
  606. pHeader = (PNCA_PACKET_HEADER) (PCHAR(Buffer) - sizeof(NCA_PACKET_HEADER));
  607. *pHeader = pSavedPacket->Header;
  608. pHeader->PacketType = PacketType;
  609. pHeader->PacketFlags = BasePacketFlags;
  610. pHeader->PacketFlags2 = BasePacketFlags2;
  611. if (FinalSendFrag != 0 ||
  612. (BufferFlags & RPC_BUFFER_PARTIAL))
  613. {
  614. pHeader->PacketFlags |= DG_PF_FRAG;
  615. if (FragNum == FinalSendFrag &&
  616. 0 == (BufferFlags & RPC_BUFFER_PARTIAL))
  617. {
  618. pHeader->PacketFlags |= DG_PF_LAST_FRAG;
  619. }
  620. }
  621. pHeader->SetPacketBodyLen (Length);
  622. pHeader->SetFragmentNumber((unsigned short) FragNum);
  623. if (FALSE == fFack)
  624. {
  625. pHeader->PacketFlags |= DG_PF_NO_FACK;
  626. }
  627. AddSerialNumber(pHeader);
  628. RPC_STATUS Status;
  629. //
  630. // Stub data is encrypted in-place; we need not to encrypt the original data
  631. // so we can retransmit it if necessary.
  632. //
  633. unsigned Frag = (pHeader->PacketType << 16) | pHeader->GetFragmentNumber();
  634. LogEvent(SU_ENGINE, EV_PKT_OUT, this, 0, Frag);
  635. if (BaseConnection->ActiveSecurityContext &&
  636. BaseConnection->ActiveSecurityContext->AuthenticationLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
  637. {
  638. RpcpMemoryCopy(&pSavedPacket->Header, pHeader, sizeof(NCA_PACKET_HEADER));
  639. RpcpMemoryCopy(pSavedPacket->Header.Data, pHeader->Data + Offset, pHeader->GetPacketBodyLen());
  640. Status = BaseConnection->SealAndSendPacket(SourceEndpoint, RemoteAddress, &pSavedPacket->Header, 0);
  641. }
  642. else
  643. {
  644. Status = BaseConnection->SealAndSendPacket(SourceEndpoint, RemoteAddress, pHeader, Offset);
  645. }
  646. FragmentRingBuffer[Index].SerialNumber = SendSerialNumber;
  647. FragmentRingBuffer[Index].Length = Length;
  648. FragmentRingBuffer[Index].Offset = Offset;
  649. ++SendSerialNumber;
  650. if (Status)
  651. {
  652. LogError(SU_ENGINE, EV_STATUS, this, 0, Status);
  653. }
  654. return Status;
  655. }
  656. RPC_STATUS
  657. DG_PACKET_ENGINE::UpdateSendWindow(
  658. PDG_PACKET pPacket,
  659. BOOL * pfUpdated
  660. )
  661. /*++
  662. Routine Description:
  663. Update the send window based upon a received FACK or NOCALL.
  664. The caller should filter out other packet types.
  665. Arguments:
  666. pPacket - the packet received
  667. Return Value:
  668. return code:
  669. TRUE if PDU size or window size changed
  670. FALSE if not
  671. --*/
  672. {
  673. RPC_STATUS Status = 0;
  674. FACK_BODY_VER_0 PAPI * pBody = (FACK_BODY_VER_0 PAPI *) pPacket->Header.Data;
  675. *pfUpdated = FALSE;
  676. unsigned short Diff;
  677. unsigned short RemoteBase = 1+pPacket->GetFragmentNumber();
  678. ASSERT(pPacket->TimeReceived == 0x31415926);
  679. //
  680. // Check that we can understand this packet.
  681. //
  682. if (0 != pPacket->GetPacketBodyLen())
  683. {
  684. //
  685. // Version 0 and version 1 are identical.
  686. //
  687. if (0 != pBody->Version &&
  688. 1 != pBody->Version)
  689. {
  690. #ifdef DEBUGRPC
  691. PrintToDebugger("RPC DG: warning - FACK body version %u\n", pBody->Version);
  692. #endif
  693. pPacket->SetPacketBodyLen(0);
  694. }
  695. else if (pPacket->GetPacketBodyLen() < sizeof(FACK_BODY_VER_0))
  696. {
  697. #ifdef DEBUGRPC
  698. PrintToDebugger("RPC DG: warning - FACK body truncated\n");
  699. #endif
  700. pPacket->SetPacketBodyLen(0);
  701. }
  702. else if (pPacket->GetPacketBodyLen() < sizeof(FACK_BODY_VER_0) + pBody->AckWordCount * sizeof(unsigned long))
  703. {
  704. #ifdef DEBUGRPC
  705. PrintToDebugger("RPC DG: warning - FACK body length inconsistent\n");
  706. #endif
  707. pPacket->SetPacketBodyLen(0);
  708. }
  709. else
  710. {
  711. if (NeedsByteSwap(&pPacket->Header))
  712. {
  713. ByteSwapFackBody0(pBody);
  714. }
  715. //
  716. // NT 1057 used 0xffff to signal no packets have been received.
  717. // This doesn't match OSF.
  718. //
  719. if (0xffff == pBody->SerialNumber)
  720. {
  721. pBody->SerialNumber = 0;
  722. }
  723. //
  724. // If the other guy is resending the same FACK, we should resend.
  725. // If it's different, then we are likely OK.
  726. //
  727. if (pBody->SerialNumber == FackSerialNumber)
  728. {
  729. goto send;
  730. }
  731. if (pBody->SerialNumber < FackSerialNumber)
  732. {
  733. FackSerialNumber = pBody->SerialNumber;
  734. goto dont_send;
  735. }
  736. FackSerialNumber = pBody->SerialNumber;
  737. }
  738. }
  739. //
  740. // Update send window.
  741. //
  742. if (RemoteBase < SendWindowBase)
  743. {
  744. //
  745. // Fragments previously acknowledged are now missing. Either this
  746. // packet was delivered out of order, or the server crashed and
  747. // restarted. Ignore the packet.
  748. //
  749. goto dont_send;
  750. }
  751. if (RemoteBase > FirstUnsentFragment)
  752. {
  753. #ifdef DEBUGRPC
  754. PrintToDebugger("RPC DG: bogus FACK packet received\n");
  755. #endif
  756. goto dont_send;
  757. }
  758. //
  759. // We are moving the window base forward. We need to advance the
  760. // ring buffer base by the same amount, and clear the entries
  761. // corresponding to unsent packets.
  762. //
  763. Diff = RemoteBase - SendWindowBase;
  764. ASSERT(Diff <= MAX_WINDOW_SIZE);
  765. #ifdef DEBUGRPC
  766. while (Diff)
  767. {
  768. FragmentRingBuffer[RingBufferBase].SerialNumber |= 0xeeee0000;
  769. FragmentRingBuffer[RingBufferBase].Length |= 0xdd000000;
  770. FragmentRingBuffer[RingBufferBase].Offset |= 0xb0000000;
  771. ++RingBufferBase;
  772. RingBufferBase %= MAX_WINDOW_SIZE;
  773. --Diff;
  774. }
  775. #else
  776. RingBufferBase += Diff;
  777. RingBufferBase %= MAX_WINDOW_SIZE;
  778. #endif
  779. SendWindowBase = RemoteBase;
  780. SendWindowBits = 0;
  781. ASSERT( SendWindowBase <= FirstUnsentFragment );
  782. if (IsBufferAcknowledged())
  783. {
  784. PopBuffer(FALSE);
  785. }
  786. if (0 != pPacket->GetPacketBodyLen())
  787. {
  788. LogEvent(SU_ENGINE, EV_WINDOW, this, (void *) pBody->WindowSize, pBody->Acks[0]);
  789. if (pBody->AckWordCount)
  790. {
  791. //
  792. // Save missing-packet bitmask.
  793. //
  794. SendWindowBits = pBody->Acks[0];
  795. }
  796. //
  797. // Adjust window size.
  798. //
  799. if (pBody->WindowSize > MAX_WINDOW_SIZE)
  800. {
  801. pBody->WindowSize = MAX_WINDOW_SIZE;
  802. }
  803. SendWindowSize = pBody->WindowSize;
  804. if (SendBurstLength > SendWindowSize)
  805. {
  806. SendBurstLength = SendWindowSize;
  807. }
  808. //
  809. // Adjust maximum PDU length.
  810. //
  811. unsigned NewPduSize;
  812. NewPduSize = pBody->MaxDatagramSize;
  813. if (NewPduSize > SourceEndpoint->Stats.PreferredPduSize)
  814. {
  815. NewPduSize = SourceEndpoint->Stats.PreferredPduSize;
  816. }
  817. BaseConnection->CurrentPduSize = (unsigned short) NewPduSize;
  818. BaseConnection->RemoteWindowSize = pBody->WindowSize;
  819. //
  820. // If no packets are getting through, we probably are sending
  821. // packets that are too large.
  822. //
  823. if (0 == RemoteBase &&
  824. 0 == SendWindowBits &&
  825. NewPduSize < CurrentPduSize)
  826. {
  827. CurrentPduSize = (unsigned short) NewPduSize;
  828. SetFragmentLengths();
  829. FirstUnsentFragment = 0;
  830. FirstUnsentOffset = 0;
  831. FinalSendFrag = SendWindowBase + (BufferLength-1) / MaxFragmentSize;
  832. }
  833. *pfUpdated = TRUE;
  834. }
  835. send:
  836. Status = SendSomeFragments();
  837. dont_send:
  838. return Status;
  839. }
  840. BOOL
  841. DG_PACKET_ENGINE::UpdateReceiveWindow(
  842. PDG_PACKET pPacket
  843. )
  844. /*++
  845. Routine Description:
  846. Adds a fragment to the receive list, and sends a FACK.
  847. Arguments:
  848. Return Value:
  849. --*/
  850. {
  851. ASSERT(pPacket->TimeReceived == 0x31415926);
  852. //
  853. // Don't retain data from previous pipe buffers.
  854. //
  855. if (pPacket->GetFragmentNumber() < ReceiveFragmentBase)
  856. {
  857. if (0 == (pPacket->Header.PacketFlags & DG_PF_NO_FACK))
  858. {
  859. SendFackOrNocall(pPacket, DG_FACK);
  860. }
  861. return FALSE;
  862. }
  863. //
  864. // Attempt to guess the client's max PDU size. Round down to a multiple
  865. // of eight, for NDR.
  866. //
  867. if (pPacket->DataLength + sizeof(NCA_PACKET_HEADER) > BaseConnection->CurrentPduSize)
  868. {
  869. unsigned RemoteTransportBuffer = BaseConnection->CurrentPduSize * BaseConnection->RemoteWindowSize;
  870. BaseConnection->CurrentPduSize = ((pPacket->DataLength + sizeof(NCA_PACKET_HEADER)) & ~7);
  871. BaseConnection->RemoteWindowSize = RemoteTransportBuffer / BaseConnection->CurrentPduSize;
  872. if (0 == BaseConnection->RemoteWindowSize)
  873. {
  874. BaseConnection->RemoteWindowSize = 1;
  875. }
  876. }
  877. PNCA_PACKET_HEADER pHeader = &pPacket->Header;
  878. unsigned short Serial = ReadSerialNumber(pHeader);
  879. if (Serial > ReceiveSerialNumber)
  880. {
  881. ReceiveSerialNumber = Serial;
  882. }
  883. //
  884. // Authentication levels above AUTHN_LEVEL_PKT will checksum the packet,
  885. // so we must remove these bits from the header.
  886. //
  887. pPacket->Header.PacketFlags &= ~(DG_PF_FORWARDED);
  888. pPacket->Header.PacketFlags2 &= ~(DG_PF2_FORWARDED_2);
  889. //
  890. // Check the easy case: is this a single packet call?
  891. //
  892. if ((pHeader->PacketFlags & DG_PF_FRAG) == 0 &&
  893. (pHeader->PacketFlags & DG_PF_LAST_FRAG) == 0)
  894. {
  895. if (pReceivedPackets)
  896. {
  897. CORRUPTION_ASSERT( pReceivedPackets->Header.SequenceNumber == pPacket->Header.SequenceNumber );
  898. return FALSE;
  899. }
  900. pReceivedPackets = pPacket;
  901. pLastConsecutivePacket = pPacket;
  902. pPacket->pNext = pPacket->pPrevious = 0;
  903. ConsecutiveDataBytes += pHeader->GetPacketBodyLen();
  904. fReceivedAllFragments = TRUE;
  905. return TRUE;
  906. }
  907. //
  908. // This is a multi-packet call. Insert the packet in pReceivedPackets
  909. // and send a FACK.
  910. //
  911. PDG_PACKET pScan;
  912. PDG_PACKET pTrail;
  913. BOOL PacketAddedToList = TRUE;
  914. if (pReceivedPackets == 0)
  915. {
  916. pReceivedPackets = pPacket;
  917. if (ReceiveFragmentBase == pHeader->GetFragmentNumber())
  918. {
  919. pLastConsecutivePacket = pPacket;
  920. ConsecutiveDataBytes += pHeader->GetPacketBodyLen();
  921. }
  922. pPacket->pNext = pPacket->pPrevious = 0;
  923. }
  924. else
  925. {
  926. //
  927. // Not the first packet to be received. So scan for its place in the
  928. // list.
  929. //
  930. unsigned short FragNum = pHeader->GetFragmentNumber();
  931. if (pLastConsecutivePacket)
  932. {
  933. pScan = pLastConsecutivePacket;
  934. }
  935. else
  936. {
  937. pScan = pReceivedPackets;
  938. }
  939. pTrail = 0;
  940. while (pScan && pScan->GetFragmentNumber() < FragNum)
  941. {
  942. ASSERT(pScan->TimeReceived == 0x31415926);
  943. ASSERT(pScan->Header.SequenceNumber == SequenceNumber);
  944. pTrail = pScan;
  945. pScan = pScan->pNext;
  946. }
  947. if (pScan != 0)
  948. {
  949. if (pScan->GetFragmentNumber() > FragNum)
  950. {
  951. if (pScan->pPrevious &&
  952. pScan->pPrevious->GetFragmentNumber() >= FragNum)
  953. {
  954. //
  955. // The new packet is a duplicate of a preexisting one
  956. // upstream from pLastConsecutivePacket.
  957. //
  958. PacketAddedToList = FALSE;
  959. }
  960. else
  961. {
  962. //
  963. // Our fragment fills a gap in the series.
  964. //
  965. pPacket->pPrevious = pScan->pPrevious;
  966. pPacket->pNext = pScan;
  967. if (pScan->pPrevious == 0)
  968. {
  969. pReceivedPackets = pPacket;
  970. }
  971. else
  972. {
  973. pScan->pPrevious->pNext = pPacket;
  974. }
  975. pScan->pPrevious = pPacket;
  976. }
  977. }
  978. else
  979. {
  980. //
  981. // The new packet is a duplicate of a preexisting one
  982. // downstream from pLastConsecutivePacket.
  983. //
  984. PacketAddedToList = FALSE;
  985. }
  986. }
  987. else
  988. {
  989. //
  990. // The fragnum is larger than everything seen so far.
  991. //
  992. pTrail->pNext = pPacket;
  993. pPacket->pPrevious = pTrail;
  994. pPacket->pNext = 0;
  995. }
  996. }
  997. if (TRUE == PacketAddedToList)
  998. {
  999. //
  1000. // Scan the list for the first missing fragment.
  1001. //
  1002. unsigned short ScanNum;
  1003. if (pLastConsecutivePacket)
  1004. {
  1005. pScan = pLastConsecutivePacket->pNext;
  1006. ScanNum = pLastConsecutivePacket->GetFragmentNumber() + 1;
  1007. }
  1008. else
  1009. {
  1010. pScan = pReceivedPackets;
  1011. ScanNum = ReceiveFragmentBase;
  1012. }
  1013. while (pScan)
  1014. {
  1015. if (ScanNum == pScan->GetFragmentNumber())
  1016. {
  1017. ConsecutiveDataBytes += pScan->GetPacketBodyLen();
  1018. pLastConsecutivePacket = pScan;
  1019. }
  1020. pScan = pScan->pNext;
  1021. ++ScanNum;
  1022. }
  1023. //
  1024. // We have updated pLastConsecutivePacket; is the whole buffer here?
  1025. //
  1026. if (pLastConsecutivePacket &&
  1027. pLastConsecutivePacket->Header.PacketFlags & DG_PF_LAST_FRAG)
  1028. {
  1029. fReceivedAllFragments = TRUE;
  1030. }
  1031. }
  1032. ASSERT(pReceivedPackets);
  1033. //
  1034. // Fack the fragment if necessary.
  1035. //
  1036. if (0 == (pHeader->PacketFlags & DG_PF_NO_FACK))
  1037. {
  1038. SendFackOrNocall(pPacket, DG_FACK);
  1039. }
  1040. return PacketAddedToList;
  1041. }
  1042. RPC_STATUS
  1043. DG_PACKET_ENGINE::SendFackOrNocall(
  1044. PDG_PACKET pPacket,
  1045. unsigned char PacketType
  1046. )
  1047. {
  1048. unsigned ReceiveWindowSize;
  1049. ReceiveWindowSize = SourceEndpoint->Stats.ReceiveBufferSize
  1050. / ((1+SourceEndpoint->NumberOfCalls) * CurrentPduSize);
  1051. if (0 == ReceiveWindowSize)
  1052. {
  1053. ReceiveWindowSize = 1;
  1054. }
  1055. else if (ReceiveWindowSize > MAX_WINDOW_SIZE)
  1056. {
  1057. ReceiveWindowSize = MAX_WINDOW_SIZE;
  1058. }
  1059. pSavedPacket->Header.PacketType = PacketType;
  1060. pSavedPacket->Header.SequenceNumber = SequenceNumber;
  1061. pSavedPacket->Header.PacketFlags2 = 0;
  1062. FACK_BODY_VER_0 PAPI * pBody = (FACK_BODY_VER_0 PAPI *) pSavedPacket->Header.Data;
  1063. pBody->Version = 1;
  1064. pBody->Pad1 = 0;
  1065. pBody->MaxDatagramSize = SourceEndpoint->Stats.PreferredPduSize;
  1066. pBody->MaxPacketSize = SourceEndpoint->Stats.MaxPacketSize;
  1067. pBody->AckWordCount = 1;
  1068. pBody->WindowSize = (unsigned short) ReceiveWindowSize;
  1069. if (pPacket)
  1070. {
  1071. pBody->SerialNumber = ReadSerialNumber(&pPacket->Header);
  1072. }
  1073. else
  1074. {
  1075. pBody->SerialNumber = ReceiveSerialNumber;
  1076. }
  1077. unsigned short FragNum = ReceiveFragmentBase-1;
  1078. PDG_PACKET pScan = 0;
  1079. if (pLastConsecutivePacket)
  1080. {
  1081. FragNum = pLastConsecutivePacket->GetFragmentNumber();
  1082. pScan = pLastConsecutivePacket->pNext;
  1083. }
  1084. else if (pReceivedPackets)
  1085. {
  1086. pScan = pReceivedPackets->pNext;
  1087. }
  1088. unsigned Bit;
  1089. pBody->Acks[0] = 0;
  1090. while ( pScan )
  1091. {
  1092. Bit = pScan->GetFragmentNumber() - FragNum - 1;
  1093. pBody->Acks[0] |= (1 << Bit);
  1094. pScan = pScan->pNext;
  1095. }
  1096. if (pBody->Acks[0] == 0)
  1097. {
  1098. pBody->AckWordCount = 0;
  1099. }
  1100. pSavedPacket->SetPacketBodyLen( sizeof(FACK_BODY_VER_0) + sizeof(unsigned long) );
  1101. pSavedPacket->SetFragmentNumber(FragNum);
  1102. AddSerialNumber(&pSavedPacket->Header);
  1103. unsigned Frag = (pSavedPacket->Header.PacketType << 16) | pSavedPacket->GetFragmentNumber();
  1104. LogEvent(SU_ENGINE, EV_PKT_OUT, this, 0, Frag);
  1105. RPC_STATUS Status;
  1106. Status = BaseConnection->SealAndSendPacket(SourceEndpoint, RemoteAddress, &pSavedPacket->Header, 0);
  1107. if (Status)
  1108. {
  1109. LogError(SU_ENGINE, EV_STATUS, this, 0, Status);
  1110. }
  1111. return Status;
  1112. }
  1113. RPC_STATUS
  1114. DG_PACKET_ENGINE::AssembleBufferFromPackets(
  1115. RPC_MESSAGE * Message,
  1116. CALL * Call
  1117. )
  1118. /*++
  1119. Routine Description:
  1120. This function coalesces the list of consecutive packets into a monolithic
  1121. buffer.
  1122. Arguments:
  1123. Message - if .Buffer != 0 , use it. Otherwise allocate one.
  1124. Call - in case we need to call GetBuffer
  1125. Return Value:
  1126. RPC_S_OK - success
  1127. RPC_S_OUT_OF_MEMORY - we couldn't allocate or reallocate Message.Buffer
  1128. --*/
  1129. {
  1130. ASSERT( pLastConsecutivePacket );
  1131. //
  1132. // If only one packet is available, use the packet buffer itself.
  1133. //
  1134. if (0 == Message->Buffer && 0 == pReceivedPackets->pNext)
  1135. {
  1136. ASSERT(ConsecutiveDataBytes == pReceivedPackets->GetPacketBodyLen());
  1137. Message->Buffer = pReceivedPackets->Header.Data;
  1138. Message->BufferLength = ConsecutiveDataBytes;
  1139. Message->DataRepresentation = 0x00ffffff & (*(unsigned long PAPI *) &pReceivedPackets->Header.DataRep);
  1140. if (0 == (pReceivedPackets->Header.PacketFlags & DG_PF_FRAG))
  1141. {
  1142. Message->RpcFlags |= RPC_BUFFER_COMPLETE;
  1143. }
  1144. if (pReceivedPackets->Header.PacketFlags & DG_PF_LAST_FRAG)
  1145. {
  1146. Message->RpcFlags |= RPC_BUFFER_COMPLETE;
  1147. }
  1148. pReceivedPackets = 0;
  1149. pLastConsecutivePacket = 0;
  1150. ConsecutiveDataBytes = 0;
  1151. ++ReceiveFragmentBase;
  1152. LastReceiveBuffer = Message->Buffer;
  1153. LastReceiveBufferLength = Message->BufferLength;
  1154. return RPC_S_OK;
  1155. }
  1156. //
  1157. // Get a buffer if we need it.
  1158. //
  1159. RPC_STATUS Status;
  1160. if (0 == Message->Buffer)
  1161. {
  1162. ASSERT(0 == (Message->RpcFlags & RPC_BUFFER_EXTRA));
  1163. Message->BufferLength = ConsecutiveDataBytes;
  1164. Status = Call->GetBuffer(Message, 0);
  1165. if (RPC_S_OK != Status)
  1166. {
  1167. return Status;
  1168. }
  1169. LastReceiveBuffer = Message->Buffer;
  1170. LastReceiveBufferLength = Message->BufferLength;
  1171. }
  1172. //
  1173. // Reallocate the buffer if it is too small.
  1174. //
  1175. char __RPC_FAR * CopyBuffer = (char __RPC_FAR *) Message->Buffer;
  1176. if (Message->RpcFlags & (RPC_BUFFER_EXTRA | RPC_BUFFER_PARTIAL))
  1177. {
  1178. ASSERT( !LastReceiveBufferLength ||
  1179. (CopyBuffer >= LastReceiveBuffer &&
  1180. CopyBuffer <= ((char __RPC_FAR *) LastReceiveBuffer) + LastReceiveBufferLength) );
  1181. if (0 == (Message->RpcFlags & RPC_BUFFER_EXTRA))
  1182. {
  1183. Message->BufferLength = 0;
  1184. }
  1185. unsigned Offset = Message->BufferLength;
  1186. CopyBuffer += Offset;
  1187. if (CopyBuffer + ConsecutiveDataBytes > ((char __RPC_FAR *) LastReceiveBuffer) + LastReceiveBufferLength)
  1188. {
  1189. Status = I_RpcReallocPipeBuffer(Message, Offset + ConsecutiveDataBytes);
  1190. if (RPC_S_OK != Status)
  1191. {
  1192. return Status;
  1193. }
  1194. CopyBuffer = (char __RPC_FAR *) Message->Buffer + Offset;
  1195. }
  1196. else
  1197. {
  1198. Message->BufferLength += ConsecutiveDataBytes;
  1199. }
  1200. }
  1201. else
  1202. {
  1203. Message->BufferLength = ConsecutiveDataBytes;
  1204. }
  1205. Message->DataRepresentation = 0x00ffffff & (*(unsigned long PAPI *) &pReceivedPackets->Header.DataRep);
  1206. {
  1207. PDG_PACKET pkt = DG_PACKET::FromStubData(Message->Buffer);
  1208. ASSERT( pkt->MaxDataLength >= Message->BufferLength );
  1209. }
  1210. //
  1211. // Copy the stub data into the buffer.
  1212. //
  1213. #ifdef DEBUGRPC
  1214. unsigned long Count = 0;
  1215. #endif
  1216. PDG_PACKET Packet;
  1217. BOOL fLastPacket = FALSE;
  1218. do
  1219. {
  1220. ASSERT(pReceivedPackets->TimeReceived == 0x31415926);
  1221. if (ReceiveFragmentBase != pReceivedPackets->GetFragmentNumber())
  1222. {
  1223. CORRUPTION_ASSERT(ReceiveFragmentBase == pReceivedPackets->GetFragmentNumber());
  1224. return RPC_S_PROTOCOL_ERROR;
  1225. }
  1226. if (pReceivedPackets == pLastConsecutivePacket)
  1227. {
  1228. fLastPacket = TRUE;
  1229. if (0 == (pReceivedPackets->Header.PacketFlags & DG_PF_FRAG))
  1230. {
  1231. Message->RpcFlags |= RPC_BUFFER_COMPLETE;
  1232. }
  1233. if (pReceivedPackets->Header.PacketFlags & DG_PF_LAST_FRAG)
  1234. {
  1235. Message->RpcFlags |= RPC_BUFFER_COMPLETE;
  1236. }
  1237. }
  1238. unsigned Length = pReceivedPackets->GetPacketBodyLen();
  1239. RpcpMemoryCopy(CopyBuffer, pReceivedPackets->Header.Data, Length);
  1240. #ifdef DEBUGRPC
  1241. Count += Length;
  1242. #endif
  1243. CopyBuffer += Length;
  1244. Packet = pReceivedPackets;
  1245. pReceivedPackets = pReceivedPackets->pNext;
  1246. ASSERT(!pReceivedPackets || pReceivedPackets->pPrevious == Packet);
  1247. FreePacket(Packet);
  1248. ++ReceiveFragmentBase;
  1249. }
  1250. while (!fLastPacket);
  1251. ASSERT(Count == ConsecutiveDataBytes);
  1252. ASSERT(fLastPacket || 0 == Count % 8);
  1253. pLastConsecutivePacket = 0;
  1254. ConsecutiveDataBytes = 0;
  1255. if (pReceivedPackets)
  1256. {
  1257. pReceivedPackets->pPrevious = 0;
  1258. }
  1259. return RPC_S_OK;
  1260. }
  1261. void
  1262. DG_PACKET_ENGINE::SetFragmentLengths()
  1263. {
  1264. PSECURITY_CONTEXT pSecurityContext = BaseConnection->ActiveSecurityContext;
  1265. if (0 == pSecurityContext)
  1266. {
  1267. SecurityTrailerSize = 0;
  1268. }
  1269. else switch (pSecurityContext->AuthenticationLevel)
  1270. {
  1271. case RPC_C_AUTHN_LEVEL_NONE:
  1272. {
  1273. SecurityTrailerSize = 0;
  1274. break;
  1275. }
  1276. case RPC_C_AUTHN_LEVEL_PKT:
  1277. case RPC_C_AUTHN_LEVEL_PKT_INTEGRITY:
  1278. {
  1279. SecurityTrailerSize = (unsigned short) pSecurityContext->MaximumSignatureLength();
  1280. SecurityTrailerSize += (unsigned short) Align4(sizeof(DG_SECURITY_TRAILER));
  1281. break;
  1282. }
  1283. case RPC_C_AUTHN_LEVEL_PKT_PRIVACY:
  1284. {
  1285. SecurityTrailerSize = (unsigned short) pSecurityContext->MaximumHeaderLength();
  1286. SecurityTrailerSize += (unsigned short) Align(sizeof(DG_SECURITY_TRAILER), Align4(pSecurityContext->BlockSize()));
  1287. break;
  1288. }
  1289. default:
  1290. {
  1291. ASSERT(0 && "RPC: unknown protect level");
  1292. break;
  1293. }
  1294. }
  1295. if (CurrentPduSize != BaseConnection->CurrentPduSize)
  1296. {
  1297. CurrentPduSize = (unsigned short) BaseConnection->CurrentPduSize;
  1298. SendWindowSize = (unsigned short) BaseConnection->RemoteWindowSize;
  1299. }
  1300. MaxFragmentSize = CurrentPduSize - sizeof(NCA_PACKET_HEADER);
  1301. if (SecurityTrailerSize)
  1302. {
  1303. MaxFragmentSize -= SecurityTrailerSize;
  1304. MaxFragmentSize -= MaxFragmentSize % SECURITY_HEADER_ALIGNMENT;
  1305. }
  1306. }
  1307. void
  1308. ByteSwapPacketHeader(
  1309. PDG_PACKET pPacket
  1310. )
  1311. /*++
  1312. Routine Description:
  1313. Byte swaps the packet header of the specified packet.
  1314. Arguments:
  1315. pPacket - Pointer to the packet whose header needs byte swapping.
  1316. Return Value:
  1317. <none>
  1318. --*/
  1319. {
  1320. unsigned long __RPC_FAR * VerNum = (unsigned long __RPC_FAR *) &(pPacket->Header.InterfaceVersion);
  1321. ByteSwapUuid(&(pPacket->Header.ObjectId));
  1322. ByteSwapUuid(&(pPacket->Header.InterfaceId));
  1323. ByteSwapUuid(&(pPacket->Header.ActivityId));
  1324. pPacket->Header.ServerBootTime = RpcpByteSwapLong(pPacket->Header.ServerBootTime);
  1325. *VerNum = RpcpByteSwapLong(*VerNum);
  1326. pPacket->Header.SequenceNumber = RpcpByteSwapLong(pPacket->Header.SequenceNumber);
  1327. pPacket->Header.OperationNumber = RpcpByteSwapShort(pPacket->Header.OperationNumber);
  1328. pPacket->Header.InterfaceHint = RpcpByteSwapShort(pPacket->Header.InterfaceHint);
  1329. pPacket->Header.ActivityHint = RpcpByteSwapShort(pPacket->Header.ActivityHint);
  1330. pPacket->Header.PacketBodyLen = RpcpByteSwapShort(pPacket->Header.PacketBodyLen);
  1331. pPacket->Header.FragmentNumber = RpcpByteSwapShort(pPacket->Header.FragmentNumber);
  1332. }
  1333. void
  1334. ByteSwapFackBody0(
  1335. FACK_BODY_VER_0 __RPC_FAR * pBody
  1336. )
  1337. {
  1338. pBody->WindowSize = RpcpByteSwapShort(pBody->WindowSize);
  1339. pBody->MaxDatagramSize = RpcpByteSwapLong (pBody->MaxDatagramSize);
  1340. pBody->MaxPacketSize = RpcpByteSwapLong (pBody->MaxPacketSize);
  1341. pBody->SerialNumber = RpcpByteSwapShort(pBody->SerialNumber);
  1342. pBody->AckWordCount = RpcpByteSwapShort(pBody->AckWordCount);
  1343. unsigned u;
  1344. for (u=0; u < pBody->AckWordCount; ++u)
  1345. {
  1346. pBody->Acks[u] = RpcpByteSwapLong (pBody->Acks[u]);
  1347. }
  1348. }
  1349. RPCRTAPI RPC_STATUS RPC_ENTRY
  1350. I_RpcTransDatagramAllocate(
  1351. IN DG_TRANSPORT_ENDPOINT TransportEndpoint,
  1352. OUT BUFFER *pBuffer,
  1353. OUT PUINT pBufferLength,
  1354. OUT DatagramTransportPair **pAddressPair
  1355. )
  1356. {
  1357. DG_ENDPOINT * Endpoint = DG_ENDPOINT::FromEndpoint(TransportEndpoint);
  1358. RPC_DATAGRAM_TRANSPORT * Transport = Endpoint->TransportInterface;
  1359. if ( !Endpoint->Stats.PreferredPduSize )
  1360. {
  1361. RpcpBreakPoint();
  1362. }
  1363. DG_PACKET * Packet = DG_PACKET::AllocatePacket(Endpoint->Stats.PreferredPduSize
  1364. + Transport->AddressSize
  1365. + sizeof(DatagramTransportPair));
  1366. if (!Packet)
  1367. {
  1368. return RPC_S_OUT_OF_MEMORY;
  1369. }
  1370. DG_TRANSPORT_ADDRESS Address = DG_TRANSPORT_ADDRESS(Packet->Header.Data - sizeof(NCA_PACKET_HEADER) + Endpoint->Stats.PreferredPduSize);
  1371. *pBuffer = &Packet->Header;
  1372. *pBufferLength = Endpoint->Stats.PreferredPduSize;
  1373. *pAddressPair = (DatagramTransportPair *)((char *)Address + Transport->AddressSize);
  1374. (*pAddressPair)->RemoteAddress = Address;
  1375. return RPC_S_OK;
  1376. }
  1377. RPCRTAPI RPC_STATUS RPC_ENTRY
  1378. I_RpcTransDatagramAllocate2(
  1379. IN DG_TRANSPORT_ENDPOINT TransportEndpoint,
  1380. OUT BUFFER *pBuffer,
  1381. IN OUT PUINT pBufferLength,
  1382. OUT DG_TRANSPORT_ADDRESS *pAddress
  1383. )
  1384. {
  1385. DG_ENDPOINT *pEndpoint = DG_ENDPOINT::FromEndpoint(TransportEndpoint);
  1386. RPC_DATAGRAM_TRANSPORT *pTransport = pEndpoint->TransportInterface;
  1387. DWORD dwSize = *pBufferLength;
  1388. if (dwSize < pEndpoint->Stats.PreferredPduSize)
  1389. {
  1390. dwSize = pEndpoint->Stats.PreferredPduSize;
  1391. }
  1392. DG_PACKET * Packet = DG_PACKET::AllocatePacket( dwSize + pTransport->AddressSize);
  1393. if (!Packet)
  1394. {
  1395. return RPC_S_OUT_OF_MEMORY;
  1396. }
  1397. DG_TRANSPORT_ADDRESS Address = DG_TRANSPORT_ADDRESS(Packet->Header.Data - sizeof(NCA_PACKET_HEADER) + dwSize);
  1398. *pBuffer = &Packet->Header;
  1399. *pBufferLength = dwSize;
  1400. *pAddress = Address;
  1401. return RPC_S_OK;
  1402. }
  1403. RPCRTAPI RPC_STATUS RPC_ENTRY
  1404. I_RpcTransDatagramFree(
  1405. IN RPC_TRANSPORT_ADDRESS ThisAddress,
  1406. IN BUFFER Buffer
  1407. )
  1408. {
  1409. DG_PACKET * Packet = DG_PACKET::FromPacketHeader( Buffer );
  1410. Packet->Free();
  1411. return RPC_S_OK;
  1412. }
  1413. RPC_STATUS
  1414. DG_PACKET::Initialize(
  1415. )
  1416. {
  1417. return RPC_S_OK;
  1418. }
  1419. BOOL
  1420. DG_PACKET::DeleteIdlePackets(
  1421. long CurrentTime
  1422. )
  1423. /*++
  1424. Routine Description:
  1425. This fn scans the free packet list for very old packets and deletes them.
  1426. Arguments:
  1427. none
  1428. Return Value:
  1429. none
  1430. --*/
  1431. {
  1432. return FALSE;
  1433. }
  1434. DG_COMMON_CONNECTION::DG_COMMON_CONNECTION(
  1435. RPC_DATAGRAM_TRANSPORT *a_TransportInterface,
  1436. RPC_STATUS * pStatus
  1437. ) :
  1438. Mutex (pStatus),
  1439. TimeStamp (0),
  1440. TransportInterface (a_TransportInterface),
  1441. ReferenceCount (0),
  1442. CurrentPduSize (a_TransportInterface->BasePduSize),
  1443. RemoteWindowSize (1),
  1444. RemoteDataUpdated (FALSE),
  1445. LowestActiveSequence(0),
  1446. LowestUnusedSequence(0),
  1447. ActiveSecurityContext(0)
  1448. {
  1449. }
  1450. DG_COMMON_CONNECTION::~DG_COMMON_CONNECTION()
  1451. {
  1452. delete ActiveSecurityContext;
  1453. }
  1454. RPC_STATUS
  1455. SendSecurePacket(
  1456. IN DG_ENDPOINT * SourceEndpoint,
  1457. IN DG_TRANSPORT_ADDRESS RemoteAddress,
  1458. IN UNALIGNED NCA_PACKET_HEADER *pHeader,
  1459. IN unsigned long DataOffset,
  1460. IN SECURITY_CONTEXT * SecurityContext
  1461. )
  1462. {
  1463. RPC_STATUS Status = RPC_S_OK;
  1464. unsigned TrailerLength = 0;
  1465. unsigned MaxTrailerSize = 0;
  1466. PDG_SECURITY_TRAILER pTrailer = 0;
  1467. if (SecurityContext && SecurityContext->AuthenticationLevel > RPC_C_AUTHN_LEVEL_NONE)
  1468. {
  1469. // Pad the stub data length to a multiple of 8, so the security
  1470. // trailer is properly aligned. OSF requires that the pad bytes
  1471. // be included in PacketBodyLen.
  1472. //
  1473. pHeader->SetPacketBodyLen(Align8(pHeader->GetPacketBodyLen()));
  1474. pHeader->AuthProto = (unsigned char) SecurityContext->AuthenticationService;
  1475. SECURITY_BUFFER_DESCRIPTOR BufferDescriptor;
  1476. SECURITY_BUFFER SecurityBuffers[5];
  1477. DCE_MSG_SECURITY_INFO MsgSecurityInfo;
  1478. BufferDescriptor.ulVersion = 0;
  1479. BufferDescriptor.cBuffers = 5;
  1480. BufferDescriptor.pBuffers = SecurityBuffers;
  1481. SecurityBuffers[0].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY;
  1482. SecurityBuffers[0].pvBuffer = pHeader;
  1483. SecurityBuffers[0].cbBuffer = sizeof(NCA_PACKET_HEADER);
  1484. SecurityBuffers[1].BufferType = SECBUFFER_DATA;
  1485. SecurityBuffers[1].pvBuffer = pHeader->Data + DataOffset;
  1486. SecurityBuffers[1].cbBuffer = pHeader->GetPacketBodyLen();
  1487. if (SecurityContext->AuthenticationLevel == RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
  1488. {
  1489. SecurityBuffers[2].cbBuffer = (ULONG) Align(sizeof(DG_SECURITY_TRAILER), Align4(SecurityContext->BlockSize()));
  1490. SecurityBuffers[3].cbBuffer = SecurityContext->MaximumHeaderLength();
  1491. }
  1492. else
  1493. {
  1494. SecurityBuffers[2].cbBuffer = (ULONG) Align4(sizeof(DG_SECURITY_TRAILER));
  1495. SecurityBuffers[3].cbBuffer = SecurityContext->MaximumSignatureLength();
  1496. }
  1497. pTrailer = (PDG_SECURITY_TRAILER) _alloca(SecurityBuffers[2].cbBuffer + SecurityBuffers[3].cbBuffer);
  1498. SecurityBuffers[2].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY;
  1499. SecurityBuffers[2].pvBuffer = pTrailer;
  1500. SecurityBuffers[3].BufferType = SECBUFFER_TOKEN;
  1501. SecurityBuffers[3].pvBuffer = (unsigned char *) pTrailer
  1502. + SecurityBuffers[2].cbBuffer;
  1503. SecurityBuffers[4].BufferType = SECBUFFER_PKG_PARAMS | SECBUFFER_READONLY;
  1504. SecurityBuffers[4].pvBuffer = &MsgSecurityInfo;
  1505. SecurityBuffers[4].cbBuffer = sizeof(DCE_MSG_SECURITY_INFO);
  1506. MsgSecurityInfo.SendSequenceNumber = pHeader->GetFragmentNumber();
  1507. MsgSecurityInfo.ReceiveSequenceNumber = SecurityContext->AuthContextId;
  1508. MsgSecurityInfo.PacketType = ~0;
  1509. TrailerLength = SecurityBuffers[2].cbBuffer;
  1510. pTrailer->protection_level = (unsigned char) SecurityContext->AuthenticationLevel;
  1511. pTrailer->key_vers_num = (unsigned char) SecurityContext->AuthContextId;
  1512. Status = SecurityContext->SignOrSeal (
  1513. pHeader->SequenceNumber,
  1514. SecurityContext->AuthenticationLevel != RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  1515. &BufferDescriptor );
  1516. ASSERT( SecurityBuffers[3].cbBuffer > 0 );
  1517. TrailerLength += SecurityBuffers[3].cbBuffer;
  1518. }
  1519. else
  1520. {
  1521. //
  1522. // Unsecure packet.
  1523. //
  1524. pHeader->AuthProto = 0;
  1525. }
  1526. if (RPC_S_OK == Status)
  1527. {
  1528. Status = SourceEndpoint->TransportInterface->Send(
  1529. &SourceEndpoint->TransportEndpoint,
  1530. RemoteAddress,
  1531. pHeader,
  1532. sizeof(NCA_PACKET_HEADER),
  1533. pHeader->Data + DataOffset,
  1534. pHeader->GetPacketBodyLen(),
  1535. pTrailer,
  1536. TrailerLength
  1537. );
  1538. }
  1539. return Status;
  1540. }
  1541. RPC_STATUS
  1542. VerifySecurePacket(
  1543. PDG_PACKET pPacket,
  1544. SECURITY_CONTEXT * pSecurityContext
  1545. )
  1546. {
  1547. RPC_STATUS Status = RPC_S_OK;
  1548. PDG_SECURITY_TRAILER pVerifier = (PDG_SECURITY_TRAILER)
  1549. (pPacket->Header.Data + pPacket->GetPacketBodyLen());
  1550. if (pSecurityContext->AuthenticationLevel < RPC_C_AUTHN_LEVEL_PKT)
  1551. {
  1552. return RPC_S_OK;
  1553. }
  1554. ASSERT(pVerifier->protection_level >= RPC_C_AUTHN_LEVEL_PKT);
  1555. ASSERT(pVerifier->protection_level <= RPC_C_AUTHN_LEVEL_PKT_PRIVACY);
  1556. SECURITY_BUFFER_DESCRIPTOR BufferDescriptor;
  1557. SECURITY_BUFFER SecurityBuffers[5];
  1558. DCE_MSG_SECURITY_INFO MsgSecurityInfo;
  1559. BufferDescriptor.ulVersion = 0;
  1560. BufferDescriptor.cBuffers = 5;
  1561. BufferDescriptor.pBuffers = SecurityBuffers;
  1562. SecurityBuffers[0].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY;
  1563. SecurityBuffers[0].pvBuffer = &pPacket->Header;
  1564. SecurityBuffers[0].cbBuffer = sizeof(NCA_PACKET_HEADER);
  1565. SecurityBuffers[1].BufferType = SECBUFFER_DATA;
  1566. SecurityBuffers[1].pvBuffer = pPacket->Header.Data;
  1567. SecurityBuffers[1].cbBuffer = pPacket->GetPacketBodyLen();
  1568. SecurityBuffers[2].BufferType = SECBUFFER_DATA | SECBUFFER_READONLY;
  1569. SecurityBuffers[2].pvBuffer = pVerifier;
  1570. if (pVerifier->protection_level == RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
  1571. {
  1572. unsigned Alignment = Align4(pSecurityContext->BlockSize());
  1573. SecurityBuffers[2].cbBuffer = (ULONG) Align(sizeof(DG_SECURITY_TRAILER), Alignment);
  1574. SecurityBuffers[3].pvBuffer = AlignPtr(pVerifier + 1, Alignment);
  1575. }
  1576. else
  1577. {
  1578. SecurityBuffers[2].cbBuffer = (ULONG) Align4(sizeof(DG_SECURITY_TRAILER));
  1579. SecurityBuffers[3].pvBuffer = AlignPtr4(pVerifier + 1);
  1580. }
  1581. SecurityBuffers[3].BufferType = SECBUFFER_TOKEN;
  1582. SecurityBuffers[3].cbBuffer = pPacket->DataLength
  1583. - SecurityBuffers[1].cbBuffer
  1584. - SecurityBuffers[2].cbBuffer;
  1585. SecurityBuffers[4].BufferType = SECBUFFER_PKG_PARAMS | SECBUFFER_READONLY;
  1586. SecurityBuffers[4].pvBuffer = &MsgSecurityInfo;
  1587. SecurityBuffers[4].cbBuffer = sizeof(DCE_MSG_SECURITY_INFO);
  1588. MsgSecurityInfo.SendSequenceNumber = pPacket->GetFragmentNumber();
  1589. MsgSecurityInfo.ReceiveSequenceNumber = pSecurityContext->AuthContextId;
  1590. MsgSecurityInfo.PacketType = ~0;
  1591. //
  1592. // If the packet came from a big-endian machine, we must restore
  1593. // the header to its original condition or the checksum will fail.
  1594. //
  1595. ByteSwapPacketHeaderIfNecessary(pPacket);
  1596. Status = pSecurityContext->VerifyOrUnseal(
  1597. pPacket->Header.SequenceNumber,
  1598. pVerifier->protection_level != RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
  1599. &BufferDescriptor
  1600. );
  1601. //
  1602. // Gotta re-swap the header so we can still look at its fields.
  1603. //
  1604. ByteSwapPacketHeaderIfNecessary(pPacket);
  1605. if (RPC_S_OK != Status)
  1606. {
  1607. #ifdef DEBUGRPC
  1608. DbgPrint("dg rpc: %lx: pkt %lx type %lx has bad security info (error 0x%lx)\n",
  1609. GetCurrentProcessId(), pPacket, pPacket->Header.PacketType, Status);
  1610. #endif
  1611. ASSERT(Status == RPC_S_ACCESS_DENIED ||
  1612. Status == ERROR_PASSWORD_MUST_CHANGE ||
  1613. Status == ERROR_PASSWORD_EXPIRED ||
  1614. Status == ERROR_ACCOUNT_DISABLED ||
  1615. Status == ERROR_INVALID_LOGON_HOURS ||
  1616. Status == RPC_S_OUT_OF_MEMORY);
  1617. }
  1618. return(Status);
  1619. }
  1620. BOOL
  1621. DG_PickleEEInfoIntoPacket (
  1622. IN DG_PACKET * Packet,
  1623. IN size_t PickleStartOffset
  1624. )
  1625. /*++
  1626. Function Name: PickeEEInfoIntoPacket
  1627. Parameters:
  1628. PickleStartOffset - the offset in bytes where the pickling starts
  1629. pHeader - pointer to the packet to fill
  1630. Description:
  1631. Checks for EEInfo on the thread, trims the EEInfo to Packet->MaxDataLength,
  1632. and pickles the EEInfo starting from PickleStartOffset.
  1633. Returns:
  1634. TRUE if EEInfo was pickled. FALSE if not.
  1635. --*/
  1636. {
  1637. BOOL fEEInfoPresent = FALSE;
  1638. ExtendedErrorInfo *EEInfo;
  1639. RPC_STATUS RpcStatus;
  1640. size_t CurrentPacketSize;
  1641. EEInfo = RpcpGetEEInfo();
  1642. if (EEInfo)
  1643. {
  1644. AddComputerNameToChain(EEInfo);
  1645. TrimEEInfoToLength (Packet->MaxDataLength-PickleStartOffset, &CurrentPacketSize);
  1646. if (CurrentPacketSize != 0)
  1647. {
  1648. CurrentPacketSize += PickleStartOffset;
  1649. ASSERT(IsBufferAligned(Packet->Header.Data + PickleStartOffset));
  1650. RpcpMemorySet(Packet->Header.Data, 0, CurrentPacketSize);
  1651. RpcStatus = PickleEEInfo( EEInfo,
  1652. Packet->Header.Data + PickleStartOffset,
  1653. CurrentPacketSize - PickleStartOffset
  1654. );
  1655. if (RpcStatus == RPC_S_OK)
  1656. {
  1657. fEEInfoPresent = TRUE;
  1658. Packet->SetPacketBodyLen( CurrentPacketSize );
  1659. }
  1660. }
  1661. }
  1662. return fEEInfoPresent;
  1663. }
  1664. void
  1665. InitErrorPacket(
  1666. DG_PACKET * pPacket,
  1667. unsigned char PacketType,
  1668. RPC_STATUS RpcStatus
  1669. )
  1670. /*++
  1671. Routine Description:
  1672. Maps <ProcessStatus> to an NCA error code and sends
  1673. a FAULT or REJECT packet to the client, as appropriate.
  1674. Arguments:
  1675. pSendPacket - a packet to use, or zero if this fn should allocate one
  1676. ProcessStatus - NT RPC error code
  1677. Return Value:
  1678. none
  1679. --*/
  1680. {
  1681. NCA_PACKET_HEADER * pHeader = &pPacket->Header;
  1682. CleanupPacket(pHeader);
  1683. pHeader->PacketType = PacketType;
  1684. size_t FaultSize;
  1685. BOOL fEEInfoPresent = FALSE;
  1686. //
  1687. // This mapping distinguishes client-side shutdown from server-side shutdown.
  1688. //
  1689. if (RpcStatus == ERROR_SHUTDOWN_IN_PROGRESS)
  1690. {
  1691. if (PacketType == DG_REJECT)
  1692. {
  1693. RpcStatus = RPC_S_SERVER_UNAVAILABLE;
  1694. }
  1695. else
  1696. {
  1697. RpcStatus = ERROR_SERVER_SHUTDOWN_IN_PROGRESS;
  1698. }
  1699. }
  1700. else if (RpcStatus == RPC_P_CLIENT_SHUTDOWN_IN_PROGRESS)
  1701. {
  1702. RpcStatus = ERROR_SHUTDOWN_IN_PROGRESS;
  1703. }
  1704. if (g_fSendEEInfo)
  1705. {
  1706. fEEInfoPresent = DG_PickleEEInfoIntoPacket( pPacket, FIELD_OFFSET( EXTENDED_FAULT_BODY, EeInfo) );
  1707. }
  1708. if (fEEInfoPresent)
  1709. {
  1710. //
  1711. // Packet body length already set.
  1712. //
  1713. EXTENDED_FAULT_BODY * body = (EXTENDED_FAULT_BODY *) pHeader->Data;
  1714. body->NcaStatus = MapToNcaStatusCode(RpcStatus);
  1715. body->Magic = DG_EE_MAGIC_VALUE;
  1716. body->reserved1 = 0;
  1717. body->reserved2 = 0;
  1718. }
  1719. else
  1720. {
  1721. size_t XopenFaultSize = sizeof(unsigned long);
  1722. *(unsigned long *)(pHeader->Data) = MapToNcaStatusCode(RpcStatus);
  1723. pHeader->SetPacketBodyLen(XopenFaultSize);
  1724. }
  1725. }