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.

5118 lines
128 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 2001
  3. Module Name:
  4. HttpRTS.cxx
  5. Abstract:
  6. HTTP2 RTS packets support functions.
  7. Author:
  8. KamenM 09-07-01 Created
  9. Revision History:
  10. --*/
  11. #include <precomp.hxx>
  12. #include <HttpRTS.hxx>
  13. const int TunnelSettingsCommandTypeSizes[LAST_RTS_COMMAND + 1] =
  14. {
  15. sizeof(ULONG), // tsctReceiveWindowSize
  16. sizeof(FlowControlAck), // tsctFlowControlAck
  17. sizeof(ULONG), // tsctConnectionTimeout
  18. sizeof(ChannelSettingCookie), // tsctCookie
  19. sizeof(ULONG), // tsctChannelLifetime
  20. sizeof(ULONG), // tsctClientKeepalive
  21. sizeof(ULONG), // tsctVersion
  22. 0, // tsctEmpty
  23. sizeof(ULONG), // tsctPadding - size is variable. This is only for the conformance count
  24. 0, // tsctNANCE - no operands
  25. 0, // tsctANCE - no operands
  26. sizeof(ChannelSettingClientAddress), // tsctClientAddress
  27. sizeof(ChannelSettingCookie), // tsctAssociationGroupId
  28. sizeof(ULONG), // tsctDestination
  29. sizeof(ULONG) // tsctPingTrafficSentNotify
  30. };
  31. const int ClientAddressSizes[] =
  32. {
  33. FIELD_OFFSET(ChannelSettingClientAddress, u) + sizeof(SOCKADDR_IN),
  34. FIELD_OFFSET(ChannelSettingClientAddress, u) + sizeof(SOCKADDR_IN6)
  35. };
  36. BYTE *ValidateRTSPacketCommon (
  37. IN BYTE *Packet,
  38. IN ULONG PacketLength
  39. )
  40. /*++
  41. Routine Description:
  42. Validates the common portions of an RTS packet.
  43. Arguments:
  44. Packet - the packet to be validated.
  45. PacketLength - the length of the packet.
  46. Return Value:
  47. A pointer to the location after the common part if successful.
  48. NULL is validation failed.
  49. --*/
  50. {
  51. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  52. if (PacketLength < BaseRTSSizeAndPadding)
  53. {
  54. ASSERT(0);
  55. return NULL;
  56. }
  57. if (RTS->common.frag_length != (unsigned short) PacketLength)
  58. {
  59. ASSERT(0);
  60. return NULL;
  61. }
  62. if ( (RTS->common.rpc_vers != OSF_RPC_V20_VERS)
  63. || (RTS->common.rpc_vers_minor > OSF_RPC_V20_VERS_MINOR))
  64. {
  65. ASSERT(0);
  66. return NULL;
  67. }
  68. if (RTS->common.pfc_flags != (PFC_FIRST_FRAG | PFC_LAST_FRAG))
  69. {
  70. ASSERT(0);
  71. return NULL;
  72. }
  73. if (RTS->common.drep[0] != NDR_LITTLE_ENDIAN)
  74. {
  75. ASSERT(0);
  76. return NULL;
  77. }
  78. if ((RTS->common.auth_length != 0)
  79. || (RTS->common.call_id != 0))
  80. {
  81. ASSERT(0);
  82. return NULL;
  83. }
  84. return (Packet + BaseRTSSizeAndPadding);
  85. }
  86. RPC_STATUS CheckPacketForForwarding (
  87. IN BYTE *Packet,
  88. IN ULONG PacketLength,
  89. IN ForwardDestinations CurrentLocation
  90. )
  91. /*++
  92. Routine Description:
  93. Checks whether a packet needs forwarding, and if yes,
  94. patches up the protocol version if it is present.
  95. Arguments:
  96. Packet - the packet to be validated.
  97. PacketLength - the length of the packet.
  98. CurrentLocation - the current location we're in. This is how
  99. this routine knows whether to forward.
  100. Return Value:
  101. RPC_S_OK for success (means the packet is for us)
  102. RPC_P_PACKET_NEEDS_FORWARDING - success, but packet is not for us
  103. RPC_S_PROTOCOL_ERROR - packet is garbled and cannot be processed
  104. --*/
  105. {
  106. BYTE *CurrentPosition;
  107. ULONG CurrentLength;
  108. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  109. TunnelSettingsCommand *CurrentCommand;
  110. int i;
  111. BOOL ForwardingNeeded;
  112. ULONG *ProtocolPosition;
  113. CurrentPosition = ValidateRTSPacketCommon(Packet,
  114. PacketLength);
  115. if (CurrentPosition == NULL)
  116. return RPC_S_PROTOCOL_ERROR;
  117. ForwardingNeeded = FALSE;
  118. ProtocolPosition = NULL;
  119. CurrentLength = CurrentPosition - Packet;
  120. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  121. for (i = 0; i < RTS->NumberOfSettingCommands; i ++)
  122. {
  123. // check if there is enough to read the command after this
  124. CurrentLength += BaseRTSCommandSize;
  125. if (CurrentLength > PacketLength)
  126. return RPC_S_PROTOCOL_ERROR;
  127. if (CurrentCommand->CommandType == tsctDestination)
  128. {
  129. CurrentLength += SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination);
  130. if (CurrentLength > PacketLength)
  131. return RPC_S_PROTOCOL_ERROR;
  132. if (CurrentCommand->u.Destination == CurrentLocation)
  133. return RPC_S_OK;
  134. ForwardingNeeded = TRUE;
  135. // if we have found the protocol as well, we're done - break
  136. // out of here
  137. if (ProtocolPosition)
  138. break;
  139. }
  140. else if (CurrentCommand->CommandType == tsctVersion)
  141. {
  142. CurrentLength += SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion);
  143. if (CurrentLength > PacketLength)
  144. return RPC_S_PROTOCOL_ERROR;
  145. ProtocolPosition = &CurrentCommand->u.Version;
  146. // if we have already found the destination as well, we're done -
  147. // get out of here
  148. if (ForwardingNeeded)
  149. break;
  150. }
  151. else
  152. {
  153. if (CurrentCommand->CommandType > LAST_RTS_COMMAND)
  154. return RPC_S_PROTOCOL_ERROR;
  155. CurrentLength += SIZE_OF_RTS_CMD_AND_PADDING(CurrentCommand->CommandType);
  156. }
  157. CurrentCommand = (TunnelSettingsCommand *)(Packet + CurrentLength);
  158. }
  159. if (ForwardingNeeded)
  160. {
  161. if (ProtocolPosition)
  162. *ProtocolPosition = HTTP2ProtocolVersion;
  163. return RPC_P_PACKET_NEEDS_FORWARDING;
  164. }
  165. return RPC_S_OK;
  166. }
  167. BOOL UntrustedIsPingPacket (
  168. IN BYTE *Packet,
  169. IN ULONG PacketLength
  170. )
  171. /*++
  172. Routine Description:
  173. Checks if a packet coming from an untrusted source is a
  174. ping packet.
  175. Arguments:
  176. Packet - the packet to be validated.
  177. PacketLength - the length of the packet.
  178. Return Value:
  179. non-zero if it is a valid ping packet.
  180. zero if it is a valid non-ping packet or if it is an
  181. invalid packet.
  182. --*/
  183. {
  184. BYTE *CurrentPosition;
  185. rpcconn_tunnel_settings *RTS;
  186. CurrentPosition = ValidateRTSPacketCommon(Packet,
  187. PacketLength);
  188. if (CurrentPosition == NULL)
  189. return FALSE;
  190. RTS = (rpcconn_tunnel_settings *)Packet;
  191. return (RTS->Flags & RTS_FLAG_PING);
  192. }
  193. BOOL IsEchoPacket (
  194. IN BYTE *Packet,
  195. IN ULONG PacketLength
  196. )
  197. /*++
  198. Routine Description:
  199. Checks if a packet is an echo packet.
  200. Arguments:
  201. Packet - the packet to be validated.
  202. PacketLength - the length of the packet.
  203. Return Value:
  204. non-zero if it is a valid echo packet.
  205. zero if it is a valid non-echo packet or if it is an
  206. invalid packet.
  207. --*/
  208. {
  209. BYTE *CurrentPosition;
  210. rpcconn_tunnel_settings *RTS;
  211. CurrentPosition = ValidateRTSPacketCommon(Packet,
  212. PacketLength);
  213. if (CurrentPosition == NULL)
  214. return FALSE;
  215. RTS = (rpcconn_tunnel_settings *)Packet;
  216. return (RTS->Flags & RTS_FLAG_ECHO);
  217. }
  218. BOOL IsOtherCmdPacket (
  219. IN BYTE *Packet,
  220. IN ULONG PacketLength
  221. )
  222. /*++
  223. Routine Description:
  224. Checks if a packet coming from an untrusted source is a
  225. other cmd packet.
  226. Arguments:
  227. Packet - the packet to be validated.
  228. PacketLength - the length of the packet.
  229. Return Value:
  230. non-zero if it is a valid other cmd packet.
  231. zero if it is not a valid other cmd packet.
  232. --*/
  233. {
  234. BYTE *CurrentPosition;
  235. rpcconn_tunnel_settings *RTS;
  236. CurrentPosition = ValidateRTSPacketCommon(Packet,
  237. PacketLength);
  238. if (CurrentPosition == NULL)
  239. return FALSE;
  240. RTS = (rpcconn_tunnel_settings *)Packet;
  241. return (RTS->Flags & RTS_FLAG_OTHER_CMD);
  242. }
  243. HTTP2SendContext *AllocateAndInitializePingPacket (
  244. void
  245. )
  246. /*++
  247. Routine Description:
  248. Allocates and initializes an RTS ping packet
  249. Arguments:
  250. Return Value:
  251. The allocated send context or NULL for out-of-memory
  252. --*/
  253. {
  254. HTTP2SendContext *SendContext;
  255. TunnelSettingsCommand *CurrentCommand;
  256. rpcconn_tunnel_settings *RTS;
  257. SendContext = AllocateAndInitializeRTSPacket(
  258. 0
  259. );
  260. if (SendContext)
  261. {
  262. RTS = GetRTSPacketFromSendContext(SendContext);
  263. RTS->Flags = RTS_FLAG_PING;
  264. RTS->NumberOfSettingCommands = 0;
  265. }
  266. return SendContext;
  267. }
  268. HTTP2SendContext *AllocateAndInitializePingPacketWithSize (
  269. IN ULONG TotalPacketSize
  270. )
  271. /*++
  272. Routine Description:
  273. Allocates and initializes an RTS ping packet padding
  274. the packet until a certain size.
  275. Arguments:
  276. TotalPacketSize - the total desired size of the packet.
  277. Return Value:
  278. The allocated send context or NULL for out-of-memory
  279. --*/
  280. {
  281. HTTP2SendContext *SendContext;
  282. TunnelSettingsCommand *CurrentCommand;
  283. rpcconn_tunnel_settings *RTS;
  284. BOOL UseEmpty;
  285. ULONG ExtraSize;
  286. // the size of empty must be 0 for the calculation below to work
  287. ASSERT(SIZE_OF_RTS_CMD_AND_PADDING(tsctEmpty) == 0);
  288. ASSERT(TotalPacketSize >= BaseRTSSizeAndPadding
  289. + BaseRTSCommandSize * 1
  290. + SIZE_OF_RTS_CMD_AND_PADDING(tsctEmpty));
  291. // reduce the TotalPacketSize to the size of the actual padding
  292. // We subtract the base packet size + the padding command itself
  293. TotalPacketSize -= BaseRTSCommandSize * 1
  294. + BaseRTSSizeAndPadding;
  295. SendContext = AllocateAndInitializeRTSPacket(
  296. BaseRTSCommandSize * 1
  297. + TotalPacketSize
  298. );
  299. if (SendContext)
  300. {
  301. // if we were required to use larger size, we'll use the padding.
  302. // if it was smaller, we'll use the empty command
  303. if (TotalPacketSize >= SIZE_OF_RTS_CMD_AND_PADDING(tsctPadding))
  304. {
  305. TotalPacketSize -= SIZE_OF_RTS_CMD_AND_PADDING(tsctPadding);
  306. UseEmpty = FALSE;
  307. }
  308. else
  309. {
  310. TotalPacketSize -= SIZE_OF_RTS_CMD_AND_PADDING(tsctEmpty);
  311. UseEmpty = TRUE;
  312. }
  313. RTS = GetRTSPacketFromSendContext(SendContext);
  314. RTS->Flags = RTS_FLAG_PING;
  315. RTS->NumberOfSettingCommands = 1;
  316. CurrentCommand = RTS->Cmd;
  317. if (UseEmpty)
  318. {
  319. // set empty command
  320. CurrentCommand->CommandType = tsctEmpty;
  321. }
  322. else
  323. {
  324. // set padding command
  325. CurrentCommand->CommandType = tsctPadding;
  326. CurrentCommand->u.ConformanceCount = TotalPacketSize;
  327. CurrentCommand = SkipCommand(CurrentCommand, tsctPadding);
  328. // clean out the padding bytes
  329. RpcpMemorySet(CurrentCommand, 0, TotalPacketSize);
  330. }
  331. }
  332. return SendContext;
  333. }
  334. RPC_STATUS ParseAndFreePingPacket (
  335. IN BYTE *Packet,
  336. IN ULONG PacketLength
  337. )
  338. /*++
  339. Routine Description:
  340. Parses and frees a ping packet.
  341. N.B.: UntrustedIsPingPacket must have
  342. already been called and returned non-zero
  343. for this function to be used.
  344. Arguments:
  345. Packet - the packet to be validated.
  346. PacketLength - the length of the packet.
  347. Return Value:
  348. RPC_S_OK for success
  349. RPC_S_PROTOCOL_ERROR for garbled packet
  350. --*/
  351. {
  352. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  353. RPC_STATUS RpcStatus;
  354. if (RTS->NumberOfSettingCommands != 0)
  355. goto AbortAndExit;
  356. if (RTS->Flags != RTS_FLAG_PING)
  357. goto AbortAndExit;
  358. RpcStatus = RPC_S_OK;
  359. goto CleanupAndExit;
  360. AbortAndExit:
  361. RpcStatus = RPC_S_PROTOCOL_ERROR;
  362. CleanupAndExit:
  363. RpcFreeBuffer(Packet);
  364. return RpcStatus;
  365. }
  366. ULONG GetD1_A1TotalLength (
  367. void
  368. )
  369. /*++
  370. Routine Description:
  371. Calculates the length of a D1/A1 RTS packet
  372. Arguments:
  373. Return Value:
  374. The length of the D1/A1 RTS packet.
  375. --*/
  376. {
  377. return (BaseRTSSizeAndPadding
  378. + BaseRTSCommandSize * 4
  379. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  380. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  381. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  382. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  383. );
  384. }
  385. HTTP2SendContext *AllocateAndInitializeEmptyRTS (
  386. void
  387. )
  388. /*++
  389. Routine Description:
  390. Allocates and initializes an empty RTS packet
  391. Arguments:
  392. Return Value:
  393. The allocated send context or NULL for out-of-memory
  394. --*/
  395. {
  396. HTTP2SendContext *SendContext;
  397. TunnelSettingsCommand *CurrentCommand;
  398. rpcconn_tunnel_settings *RTS;
  399. SendContext = AllocateAndInitializeRTSPacket(
  400. BaseRTSCommandSize * 1
  401. );
  402. if (SendContext)
  403. {
  404. RTS = GetRTSPacketFromSendContext(SendContext);
  405. RTS->Flags = 0;
  406. RTS->NumberOfSettingCommands = 1;
  407. CurrentCommand = RTS->Cmd;
  408. // set empty command
  409. CurrentCommand->CommandType = tsctEmpty;
  410. }
  411. return SendContext;
  412. }
  413. RPC_STATUS ParseEmptyRTS (
  414. IN BYTE *Packet,
  415. IN ULONG PacketLength
  416. )
  417. /*++
  418. Routine Description:
  419. Parses an empty RTS packet
  420. Arguments:
  421. Packet - the packet received.
  422. PacketLength - the length of the packet
  423. Return Value:
  424. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  425. otherwise.
  426. --*/
  427. {
  428. ULONG MemorySize;
  429. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  430. BYTE *CurrentPosition;
  431. TunnelSettingsCommand *CurrentCommand;
  432. RPC_STATUS RpcStatus;
  433. MemorySize = BaseRTSSizeAndPadding
  434. + BaseRTSCommandSize * 1
  435. ;
  436. if (PacketLength < MemorySize)
  437. goto AbortAndExit;
  438. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  439. if (CurrentPosition == NULL)
  440. goto AbortAndExit;
  441. if (RTS->NumberOfSettingCommands != 1)
  442. goto AbortAndExit;
  443. if (RTS->Flags != 0)
  444. goto AbortAndExit;
  445. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  446. // verify empty
  447. if (CurrentCommand->CommandType != tsctEmpty)
  448. goto AbortAndExit;
  449. RpcStatus = RPC_S_OK;
  450. goto CleanupAndExit;
  451. AbortAndExit:
  452. RpcStatus = RPC_S_PROTOCOL_ERROR;
  453. CleanupAndExit:
  454. return RpcStatus;
  455. }
  456. RPC_STATUS ParseAndFreeEmptyRTS (
  457. IN BYTE *Packet,
  458. IN ULONG PacketLength
  459. )
  460. /*++
  461. Routine Description:
  462. Parses and frees an empty RTS packet
  463. Arguments:
  464. Packet - the packet received.
  465. PacketLength - the length of the packet
  466. Return Value:
  467. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  468. otherwise.
  469. --*/
  470. {
  471. RPC_STATUS RpcStatus;
  472. RpcStatus = ParseEmptyRTS(Packet,
  473. PacketLength
  474. );
  475. RpcFreeBuffer(Packet);
  476. return RpcStatus;
  477. }
  478. HTTP2SendContext *AllocateAndInitializeEmptyRTSWithDestination (
  479. IN ForwardDestinations Destination
  480. )
  481. /*++
  482. Routine Description:
  483. Allocates and initializes an empty RTS packet
  484. Arguments:
  485. Destination - where to forward this to.
  486. Return Value:
  487. The allocated send context or NULL for out-of-memory
  488. --*/
  489. {
  490. HTTP2SendContext *SendContext;
  491. TunnelSettingsCommand *CurrentCommand;
  492. rpcconn_tunnel_settings *RTS;
  493. SendContext = AllocateAndInitializeRTSPacket(
  494. BaseRTSCommandSize * 1
  495. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  496. );
  497. if (SendContext)
  498. {
  499. RTS = GetRTSPacketFromSendContext(SendContext);
  500. RTS->Flags = 0;
  501. RTS->NumberOfSettingCommands = 1;
  502. CurrentCommand = RTS->Cmd;
  503. // set destination
  504. CurrentCommand->CommandType = tsctDestination;
  505. CurrentCommand->u.Destination = Destination;
  506. }
  507. return SendContext;
  508. }
  509. RPC_STATUS ParseEmptyRTSWithDestination (
  510. IN BYTE *Packet,
  511. IN ULONG PacketLength,
  512. IN ForwardDestinations ExpectedDestination
  513. )
  514. /*++
  515. Routine Description:
  516. Parses an empty RTS packet with destination
  517. Arguments:
  518. Packet - the packet received.
  519. PacketLength - the length of the packet
  520. ExpectedDestination - the destination code for this location (client)
  521. Return Value:
  522. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  523. otherwise.
  524. --*/
  525. {
  526. ULONG MemorySize;
  527. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  528. BYTE *CurrentPosition;
  529. TunnelSettingsCommand *CurrentCommand;
  530. RPC_STATUS RpcStatus;
  531. MemorySize = BaseRTSSizeAndPadding
  532. + BaseRTSCommandSize * 1
  533. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  534. ;
  535. if (PacketLength < MemorySize)
  536. goto AbortAndExit;
  537. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  538. if (CurrentPosition == NULL)
  539. goto AbortAndExit;
  540. if (RTS->NumberOfSettingCommands != 1)
  541. goto AbortAndExit;
  542. if (RTS->Flags != 0)
  543. goto AbortAndExit;
  544. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  545. // verify destination
  546. if (CurrentCommand->CommandType != tsctDestination)
  547. goto AbortAndExit;
  548. if (ExpectedDestination != CurrentCommand->u.Destination)
  549. goto AbortAndExit;
  550. RpcStatus = RPC_S_OK;
  551. goto CleanupAndExit;
  552. AbortAndExit:
  553. RpcStatus = RPC_S_PROTOCOL_ERROR;
  554. CleanupAndExit:
  555. return RpcStatus;
  556. }
  557. RPC_STATUS ParseAndFreeEmptyRTSWithDestination (
  558. IN BYTE *Packet,
  559. IN ULONG PacketLength,
  560. IN ForwardDestinations ExpectedDestination
  561. )
  562. /*++
  563. Routine Description:
  564. Parses and frees an empty RTS packet with destination
  565. Arguments:
  566. Packet - the packet received.
  567. PacketLength - the length of the packet
  568. ExpectedDestination - the destination code for this location (client)
  569. Return Value:
  570. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  571. otherwise.
  572. --*/
  573. {
  574. RPC_STATUS RpcStatus;
  575. RpcStatus = ParseEmptyRTSWithDestination (Packet,
  576. PacketLength,
  577. ExpectedDestination
  578. );
  579. RpcFreeBuffer(Packet);
  580. return RpcStatus;
  581. }
  582. HTTP2SendContext *AllocateAndInitializeD1_A1 (
  583. IN ULONG ProtocolVersion,
  584. IN HTTP2Cookie *ConnectionCookie,
  585. IN HTTP2Cookie *ChannelCookie,
  586. IN ULONG ClientReceiveWindow
  587. )
  588. /*++
  589. Routine Description:
  590. Allocates and initializes a D1/A1 RTS packet
  591. Arguments:
  592. ProtocolVersion - the version of the HTTP tunnelling protocol
  593. ConnectionCookie - the connection cookie
  594. ChannelCookie - the channel cookie
  595. ClientReceiveWindow - the client receive window
  596. Return Value:
  597. The allocated send context or NULL for out-of-memory
  598. --*/
  599. {
  600. HTTP2SendContext *SendContext;
  601. TunnelSettingsCommand *CurrentCommand;
  602. rpcconn_tunnel_settings *RTS;
  603. SendContext = AllocateAndInitializeRTSPacket(
  604. BaseRTSCommandSize * 4
  605. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  606. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  607. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  608. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  609. );
  610. if (SendContext)
  611. {
  612. RTS = GetRTSPacketFromSendContext(SendContext);
  613. RTS->Flags = 0;
  614. RTS->NumberOfSettingCommands = 4;
  615. CurrentCommand = RTS->Cmd;
  616. // set version
  617. CurrentCommand->CommandType = tsctVersion;
  618. CurrentCommand->u.Version = ProtocolVersion;
  619. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  620. // set connection cookie
  621. CurrentCommand->CommandType = tsctCookie;
  622. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  623. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  624. // set channel cookie
  625. CurrentCommand->CommandType = tsctCookie;
  626. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  627. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  628. // set client receive window
  629. CurrentCommand->CommandType = tsctReceiveWindowSize;
  630. CurrentCommand->u.ReceiveWindowSize = ClientReceiveWindow;
  631. }
  632. return SendContext;
  633. }
  634. RPC_STATUS ParseAndFreeD1_A1 (
  635. IN BYTE *Packet,
  636. IN ULONG PacketLength,
  637. OUT ULONG *ProtocolVersion,
  638. OUT HTTP2Cookie *ConnectionCookie,
  639. OUT HTTP2Cookie *ChannelCookie,
  640. OUT ULONG *ClientReceiveWindow
  641. )
  642. /*++
  643. Routine Description:
  644. Parses and frees a D1/A1 RTS packet
  645. Arguments:
  646. Packet - the packet received.
  647. PacketLength - the length of the packet
  648. ProtocolVersion - the version of the HTTP tunnelling protocol
  649. ConnectionCookie - the connection cookie
  650. ChannelCookie - the channel cookie
  651. ClientReceiveWindow - the client receive window
  652. Return Value:
  653. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  654. otherwise.
  655. --*/
  656. {
  657. ULONG MemorySize;
  658. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  659. BYTE *CurrentPosition;
  660. TunnelSettingsCommand *CurrentCommand;
  661. RPC_STATUS RpcStatus;
  662. MemorySize = BaseRTSSizeAndPadding
  663. + BaseRTSCommandSize * 4
  664. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  665. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  666. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  667. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize);
  668. if (PacketLength < MemorySize)
  669. goto AbortAndExit;
  670. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  671. if (CurrentPosition == NULL)
  672. goto AbortAndExit;
  673. if (RTS->NumberOfSettingCommands != 4)
  674. goto AbortAndExit;
  675. if (RTS->Flags != 0)
  676. goto AbortAndExit;
  677. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  678. // get version
  679. if (CurrentCommand->CommandType != tsctVersion)
  680. goto AbortAndExit;
  681. *ProtocolVersion = CurrentCommand->u.Version;
  682. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  683. // get connection cookie
  684. if (CurrentCommand->CommandType != tsctCookie)
  685. goto AbortAndExit;
  686. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  687. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  688. // get channel cookie
  689. if (CurrentCommand->CommandType != tsctCookie)
  690. goto AbortAndExit;
  691. ChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  692. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  693. // get client receive window
  694. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  695. goto AbortAndExit;
  696. *ClientReceiveWindow = CurrentCommand->u.ReceiveWindowSize;
  697. RpcStatus = RPC_S_OK;
  698. goto CleanupAndExit;
  699. AbortAndExit:
  700. RpcStatus = RPC_S_PROTOCOL_ERROR;
  701. CleanupAndExit:
  702. RpcFreeBuffer(Packet);
  703. return RpcStatus;
  704. }
  705. HTTP2SendContext *AllocateAndInitializeD1_A2 (
  706. IN ULONG ProtocolVersion,
  707. IN HTTP2Cookie *ConnectionCookie,
  708. IN HTTP2Cookie *ChannelCookie,
  709. IN ULONG ChannelLifetime,
  710. IN ULONG ProxyReceiveWindow
  711. )
  712. /*++
  713. Routine Description:
  714. Allocates and initializes a D1/A2 RTS packet
  715. Arguments:
  716. ProtocolVersion - the version of the HTTP tunnelling protocol
  717. ConnectionCookie - the connection cookie
  718. ChannelCookie - the channel cookie
  719. ChannelLifetime - the lifetime of the channel
  720. ProxyReceiveWindow - the proxy receive window
  721. Return Value:
  722. The allocated send context or NULL for out-of-memory
  723. --*/
  724. {
  725. HTTP2SendContext *SendContext;
  726. TunnelSettingsCommand *CurrentCommand;
  727. rpcconn_tunnel_settings *RTS;
  728. SendContext = AllocateAndInitializeRTSPacket(
  729. BaseRTSCommandSize * 5
  730. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  731. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  732. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  733. + SIZE_OF_RTS_CMD_AND_PADDING(tsctChannelLifetime)
  734. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  735. );
  736. if (SendContext)
  737. {
  738. RTS = GetRTSPacketFromSendContext(SendContext);
  739. RTS->Flags = RTS_FLAG_OUT_CHANNEL;
  740. RTS->NumberOfSettingCommands = 5;
  741. CurrentCommand = RTS->Cmd;
  742. // set version
  743. CurrentCommand->CommandType = tsctVersion;
  744. CurrentCommand->u.Version = ProtocolVersion;
  745. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  746. // set connection cookie
  747. CurrentCommand->CommandType = tsctCookie;
  748. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  749. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  750. // set channel cookie
  751. CurrentCommand->CommandType = tsctCookie;
  752. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  753. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  754. // set channel lifetime
  755. CurrentCommand->CommandType = tsctChannelLifetime;
  756. CurrentCommand->u.ChannelLifetime = ChannelLifetime;
  757. CurrentCommand = SkipCommand(CurrentCommand, tsctChannelLifetime);
  758. // set proxy receive window
  759. CurrentCommand->CommandType = tsctReceiveWindowSize;
  760. CurrentCommand->u.ReceiveWindowSize = ProxyReceiveWindow;
  761. }
  762. return SendContext;
  763. }
  764. RPC_STATUS ParseD1_A2 (
  765. IN BYTE *Packet,
  766. IN ULONG PacketLength,
  767. OUT ULONG *ProtocolVersion,
  768. OUT HTTP2Cookie *ConnectionCookie,
  769. OUT HTTP2Cookie *ChannelCookie,
  770. OUT ULONG *ChannelLifetime,
  771. OUT ULONG *ProxyReceiveWindow
  772. )
  773. /*++
  774. Routine Description:
  775. Parses D1/A2 RTS packet
  776. Arguments:
  777. Packet - the packet received.
  778. PacketLength - the length of the packet
  779. ProtocolVersion - the version of the HTTP tunnelling protocol
  780. ConnectionCookie - the connection cookie
  781. ChannelCookie - the channel cookie
  782. ChannelLifetime - the lifetime of the channel
  783. ProxyReceiveWindow - the proxy receive window
  784. Return Value:
  785. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  786. otherwise.
  787. --*/
  788. {
  789. ULONG MemorySize;
  790. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  791. BYTE *CurrentPosition;
  792. TunnelSettingsCommand *CurrentCommand;
  793. RPC_STATUS RpcStatus;
  794. MemorySize = BaseRTSSizeAndPadding
  795. + BaseRTSCommandSize * 5
  796. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  797. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  798. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  799. + SIZE_OF_RTS_CMD_AND_PADDING(tsctChannelLifetime)
  800. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize);
  801. if (PacketLength < MemorySize)
  802. goto AbortAndExit;
  803. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  804. if (CurrentPosition == NULL)
  805. goto AbortAndExit;
  806. if (RTS->NumberOfSettingCommands != 5)
  807. goto AbortAndExit;
  808. if (RTS->Flags != RTS_FLAG_OUT_CHANNEL)
  809. goto AbortAndExit;
  810. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  811. // get version
  812. if (CurrentCommand->CommandType != tsctVersion)
  813. goto AbortAndExit;
  814. *ProtocolVersion = CurrentCommand->u.Version;
  815. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  816. // get connection cookie
  817. if (CurrentCommand->CommandType != tsctCookie)
  818. goto AbortAndExit;
  819. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  820. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  821. // get channel cookie
  822. if (CurrentCommand->CommandType != tsctCookie)
  823. goto AbortAndExit;
  824. ChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  825. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  826. // get channel lifetime
  827. if (CurrentCommand->CommandType != tsctChannelLifetime)
  828. goto AbortAndExit;
  829. *ChannelLifetime = CurrentCommand->u.ChannelLifetime;
  830. CurrentCommand = SkipCommand(CurrentCommand, tsctChannelLifetime);
  831. // get proxy receive window
  832. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  833. goto AbortAndExit;
  834. *ProxyReceiveWindow = CurrentCommand->u.ReceiveWindowSize;
  835. RpcStatus = RPC_S_OK;
  836. goto CleanupAndExit;
  837. AbortAndExit:
  838. RpcStatus = RPC_S_PROTOCOL_ERROR;
  839. CleanupAndExit:
  840. return RpcStatus;
  841. }
  842. HTTP2SendContext *AllocateAndInitializeD1_B1 (
  843. IN ULONG ProtocolVersion,
  844. IN HTTP2Cookie *ConnectionCookie,
  845. IN HTTP2Cookie *ChannelCookie,
  846. IN ULONG ChannelLifetime,
  847. IN ULONG ClientKeepAliveInterval,
  848. IN HTTP2Cookie *AssociationGroupId
  849. )
  850. /*++
  851. Routine Description:
  852. Allocates and initializes a D1/B1 RTS packet
  853. Arguments:
  854. ProtocolVersion - the version of the HTTP tunnelling protocol
  855. ConnectionCookie - the connection cookie
  856. ChannelCookie - the channel cookie
  857. ChannelLifetime - the lifetime of the channel
  858. ClientKeepAliveInterval - the client receive window
  859. AssociationGroupId - the association group id
  860. Return Value:
  861. The allocated send context or NULL for out-of-memory
  862. --*/
  863. {
  864. HTTP2SendContext *SendContext;
  865. TunnelSettingsCommand *CurrentCommand;
  866. rpcconn_tunnel_settings *RTS;
  867. SendContext = AllocateAndInitializeRTSPacket(
  868. BaseRTSCommandSize * 6
  869. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  870. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  871. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  872. + SIZE_OF_RTS_CMD_AND_PADDING(tsctChannelLifetime)
  873. + SIZE_OF_RTS_CMD_AND_PADDING(tsctClientKeepalive)
  874. + SIZE_OF_RTS_CMD_AND_PADDING(tsctAssociationGroupId)
  875. );
  876. if (SendContext)
  877. {
  878. RTS = GetRTSPacketFromSendContext(SendContext);
  879. RTS->Flags = 0;
  880. RTS->NumberOfSettingCommands = 6;
  881. CurrentCommand = RTS->Cmd;
  882. // set version
  883. CurrentCommand->CommandType = tsctVersion;
  884. CurrentCommand->u.Version = ProtocolVersion;
  885. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  886. // set connection cookie
  887. CurrentCommand->CommandType = tsctCookie;
  888. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  889. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  890. // set channel cookie
  891. CurrentCommand->CommandType = tsctCookie;
  892. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  893. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  894. // set channel lifetime
  895. CurrentCommand->CommandType = tsctChannelLifetime;
  896. CurrentCommand->u.ChannelLifetime = ChannelLifetime;
  897. CurrentCommand = SkipCommand(CurrentCommand, tsctChannelLifetime);
  898. // set client receive window
  899. CurrentCommand->CommandType = tsctClientKeepalive;
  900. CurrentCommand->u.ClientKeepalive = ClientKeepAliveInterval;
  901. CurrentCommand = SkipCommand(CurrentCommand, tsctClientKeepalive);
  902. // set association group id
  903. CurrentCommand->CommandType = tsctAssociationGroupId;
  904. RpcpMemoryCopy(CurrentCommand->u.AssociationGroupId.Cookie, AssociationGroupId->GetCookie(), COOKIE_SIZE_IN_BYTES);
  905. }
  906. return SendContext;
  907. }
  908. RPC_STATUS ParseAndFreeD1_B1 (
  909. IN BYTE *Packet,
  910. IN ULONG PacketLength,
  911. OUT ULONG *ProtocolVersion,
  912. OUT HTTP2Cookie *ConnectionCookie,
  913. OUT HTTP2Cookie *ChannelCookie,
  914. OUT ULONG *ChannelLifetime,
  915. OUT HTTP2Cookie *AssociationGroupId,
  916. OUT ULONG *ClientKeepAliveInterval
  917. )
  918. /*++
  919. Routine Description:
  920. Parses and frees a D1/B1 RTS packet
  921. Arguments:
  922. Packet - the packet received.
  923. PacketLength - the length of the packet
  924. ProtocolVersion - on output, the version of the HTTP tunnelling protocol
  925. Success only.
  926. ConnectionCookie - on output, the connection cookie. Success only.
  927. ChannelCookie - on output, the channel cookie. Success only.
  928. ChannelLifetime - on output, the lifetime of the channel. Success only.
  929. AssociationGroupId - on output, the client association group id.
  930. Success only.
  931. ClientKeepAliveInterval - on output, the client receive window.
  932. Success only.
  933. Return Value:
  934. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  935. otherwise.
  936. --*/
  937. {
  938. ULONG MemorySize;
  939. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  940. BYTE *CurrentPosition;
  941. TunnelSettingsCommand *CurrentCommand;
  942. RPC_STATUS RpcStatus;
  943. MemorySize = BaseRTSSizeAndPadding
  944. + BaseRTSCommandSize * 6
  945. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  946. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  947. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  948. + SIZE_OF_RTS_CMD_AND_PADDING(tsctChannelLifetime)
  949. + SIZE_OF_RTS_CMD_AND_PADDING(tsctClientKeepalive)
  950. + SIZE_OF_RTS_CMD_AND_PADDING(tsctAssociationGroupId)
  951. ;
  952. if (PacketLength < MemorySize)
  953. goto AbortAndExit;
  954. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  955. if (CurrentPosition == NULL)
  956. goto AbortAndExit;
  957. if (RTS->NumberOfSettingCommands != 6)
  958. goto AbortAndExit;
  959. if (RTS->Flags != 0)
  960. goto AbortAndExit;
  961. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  962. // get version
  963. if (CurrentCommand->CommandType != tsctVersion)
  964. goto AbortAndExit;
  965. *ProtocolVersion = CurrentCommand->u.Version;
  966. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  967. // get connection cookie
  968. if (CurrentCommand->CommandType != tsctCookie)
  969. goto AbortAndExit;
  970. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  971. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  972. // get channel cookie
  973. if (CurrentCommand->CommandType != tsctCookie)
  974. goto AbortAndExit;
  975. ChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  976. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  977. // get channel lifetime
  978. if (CurrentCommand->CommandType != tsctChannelLifetime)
  979. goto AbortAndExit;
  980. *ChannelLifetime = CurrentCommand->u.ChannelLifetime;
  981. CurrentCommand = SkipCommand(CurrentCommand, tsctChannelLifetime);
  982. // get client keep alive
  983. if (CurrentCommand->CommandType != tsctClientKeepalive)
  984. goto AbortAndExit;
  985. *ClientKeepAliveInterval = CurrentCommand->u.ClientKeepalive;
  986. CurrentCommand = SkipCommand(CurrentCommand, tsctClientKeepalive);
  987. // get association group id
  988. if (CurrentCommand->CommandType != tsctAssociationGroupId)
  989. goto AbortAndExit;
  990. AssociationGroupId->SetCookie((BYTE *)CurrentCommand->u.AssociationGroupId.Cookie);
  991. RpcStatus = RPC_S_OK;
  992. goto CleanupAndExit;
  993. AbortAndExit:
  994. RpcStatus = RPC_S_PROTOCOL_ERROR;
  995. CleanupAndExit:
  996. RpcFreeBuffer(Packet);
  997. return RpcStatus;
  998. }
  999. HTTP2SendContext *AllocateAndInitializeD1_B2 (
  1000. IN ULONG ProtocolVersion,
  1001. IN HTTP2Cookie *ConnectionCookie,
  1002. IN HTTP2Cookie *ChannelCookie,
  1003. IN ULONG ReceiveWindowSize,
  1004. IN ULONG ConnectionTimeout,
  1005. IN HTTP2Cookie *AssociationGroupId,
  1006. IN ChannelSettingClientAddress *ClientAddress
  1007. )
  1008. /*++
  1009. Routine Description:
  1010. Allocates and initializes a D1/B2 RTS packet
  1011. Arguments:
  1012. ProtocolVersion - the version of the HTTP tunnelling protocol
  1013. ConnectionCookie - the connection cookie
  1014. ChannelCookie - the channel cookie
  1015. ReceiveWindowSize - the receive window size of the in proxy
  1016. ConnectionTimeout - connection timeout of the in proxy
  1017. ClientAddress - client address of the client as seen by the in proxy
  1018. AssociationGroupId - the association group id
  1019. Return Value:
  1020. The allocated send context or NULL for out-of-memory
  1021. --*/
  1022. {
  1023. HTTP2SendContext *SendContext;
  1024. TunnelSettingsCommand *CurrentCommand;
  1025. rpcconn_tunnel_settings *RTS;
  1026. SendContext = AllocateAndInitializeRTSPacket(
  1027. BaseRTSCommandSize * 7
  1028. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1029. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1030. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1031. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1032. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  1033. + SIZE_OF_RTS_CMD_AND_PADDING(tsctAssociationGroupId)
  1034. + ClientAddressSizes[ClientAddress->AddressType]
  1035. );
  1036. if (SendContext)
  1037. {
  1038. RTS = GetRTSPacketFromSendContext(SendContext);
  1039. RTS->Flags = RTS_FLAG_IN_CHANNEL;
  1040. RTS->NumberOfSettingCommands = 7;
  1041. CurrentCommand = RTS->Cmd;
  1042. // set version
  1043. CurrentCommand->CommandType = tsctVersion;
  1044. CurrentCommand->u.Version = ProtocolVersion;
  1045. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1046. // set connection cookie
  1047. CurrentCommand->CommandType = tsctCookie;
  1048. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1049. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1050. // set channel cookie
  1051. CurrentCommand->CommandType = tsctCookie;
  1052. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1053. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1054. // set receive window size
  1055. CurrentCommand->CommandType = tsctReceiveWindowSize;
  1056. CurrentCommand->u.ReceiveWindowSize = ReceiveWindowSize;
  1057. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1058. // set connection timeout
  1059. CurrentCommand->CommandType = tsctConnectionTimeout;
  1060. CurrentCommand->u.ConnectionTimeout = ConnectionTimeout;
  1061. CurrentCommand = SkipCommand(CurrentCommand, tsctConnectionTimeout);
  1062. // set association group id
  1063. CurrentCommand->CommandType = tsctAssociationGroupId;
  1064. RpcpMemoryCopy(CurrentCommand->u.AssociationGroupId.Cookie, AssociationGroupId->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1065. CurrentCommand = SkipCommand(CurrentCommand, tsctAssociationGroupId);
  1066. // set client address.
  1067. CurrentCommand->CommandType = tsctClientAddress;
  1068. CurrentCommand->u.ClientAddress.AddressType = ClientAddress->AddressType;
  1069. RpcpMemorySet(&CurrentCommand->u, 0, ClientAddressSizes[ClientAddress->AddressType]);
  1070. if (ClientAddress->AddressType == catIPv4)
  1071. {
  1072. RpcpCopyIPv4Address((SOCKADDR_IN *)ClientAddress->u.IPv4Address,
  1073. (SOCKADDR_IN *) CurrentCommand->u.ClientAddress.u.IPv4Address);
  1074. }
  1075. else
  1076. {
  1077. RpcpCopyIPv6Address((SOCKADDR_IN6 *)ClientAddress->u.IPv4Address,
  1078. (SOCKADDR_IN6 *) CurrentCommand->u.ClientAddress.u.IPv4Address);
  1079. }
  1080. }
  1081. return SendContext;
  1082. }
  1083. RPC_STATUS ParseD1_B2 (
  1084. IN BYTE *Packet,
  1085. IN ULONG PacketLength,
  1086. OUT ULONG *ProtocolVersion,
  1087. OUT HTTP2Cookie *ConnectionCookie,
  1088. OUT HTTP2Cookie *ChannelCookie,
  1089. OUT ULONG *ReceiveWindowSize,
  1090. OUT ULONG *ConnectionTimeout,
  1091. OUT HTTP2Cookie *AssociationGroupId,
  1092. OUT ChannelSettingClientAddress *ClientAddress
  1093. )
  1094. /*++
  1095. Routine Description:
  1096. Parses a D1/B2 RTS packet
  1097. Arguments:
  1098. Packet - the packet received.
  1099. PacketLength - the length of the packet
  1100. ProtocolVersion - the version of the HTTP tunnelling protocol
  1101. ConnectionCookie - the connection cookie
  1102. ChannelCookie - the channel cookie
  1103. ReceiveWindowSize - the receive window size of the in proxy
  1104. ConnectionTimeout - connection timeout of the in proxy
  1105. AssociationGroupId - the association group id
  1106. ClientAddress - client address of the client as seen by the in proxy
  1107. Return Value:
  1108. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1109. otherwise.
  1110. --*/
  1111. {
  1112. ULONG MemorySize;
  1113. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  1114. BYTE *CurrentPosition;
  1115. TunnelSettingsCommand *CurrentCommand;
  1116. RPC_STATUS RpcStatus;
  1117. MemorySize = BaseRTSSizeAndPadding
  1118. + BaseRTSCommandSize * 7
  1119. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1120. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1121. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1122. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1123. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  1124. + FIELD_OFFSET(ChannelSettingClientAddress, u) // check for enough space to read the
  1125. // address type
  1126. ;
  1127. if (PacketLength < MemorySize)
  1128. goto AbortAndExit;
  1129. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  1130. if (CurrentPosition == NULL)
  1131. goto AbortAndExit;
  1132. if (RTS->NumberOfSettingCommands != 7)
  1133. goto AbortAndExit;
  1134. if (RTS->Flags != RTS_FLAG_IN_CHANNEL)
  1135. goto AbortAndExit;
  1136. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  1137. // get version
  1138. if (CurrentCommand->CommandType != tsctVersion)
  1139. goto AbortAndExit;
  1140. *ProtocolVersion = CurrentCommand->u.Version;
  1141. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1142. // get connection cookie
  1143. if (CurrentCommand->CommandType != tsctCookie)
  1144. goto AbortAndExit;
  1145. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  1146. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1147. // get channel cookie
  1148. if (CurrentCommand->CommandType != tsctCookie)
  1149. goto AbortAndExit;
  1150. ChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  1151. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1152. // get receive window size
  1153. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  1154. goto AbortAndExit;
  1155. *ReceiveWindowSize = CurrentCommand->u.ReceiveWindowSize;
  1156. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1157. // get connection timeout
  1158. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  1159. goto AbortAndExit;
  1160. *ConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  1161. CurrentCommand = SkipCommand(CurrentCommand, tsctConnectionTimeout);
  1162. if (CurrentCommand->CommandType != tsctAssociationGroupId)
  1163. goto AbortAndExit;
  1164. AssociationGroupId->SetCookie((BYTE *)CurrentCommand->u.AssociationGroupId.Cookie);
  1165. CurrentCommand = SkipCommand(CurrentCommand, tsctAssociationGroupId);
  1166. // get client address. Note that we have checked the length only up to
  1167. // the address type. Everything after that must be validated separately
  1168. if (CurrentCommand->CommandType != tsctClientAddress)
  1169. goto AbortAndExit;
  1170. ClientAddress->AddressType = CurrentCommand->u.ClientAddress.AddressType;
  1171. // We have already calculated the size of the AddressType field. Add the
  1172. // size for the body of the client address
  1173. MemorySize +=
  1174. ClientAddressSizes[ClientAddress->AddressType]
  1175. - FIELD_OFFSET(ChannelSettingClientAddress, u);
  1176. if (PacketLength < MemorySize)
  1177. goto AbortAndExit;
  1178. if (ClientAddress->AddressType == catIPv4)
  1179. {
  1180. RpcpCopyIPv4Address((SOCKADDR_IN *)CurrentCommand->u.ClientAddress.u.IPv4Address,
  1181. (SOCKADDR_IN *)ClientAddress->u.IPv4Address);
  1182. }
  1183. else
  1184. {
  1185. RpcpCopyIPv6Address((SOCKADDR_IN6 *)CurrentCommand->u.ClientAddress.u.IPv4Address,
  1186. (SOCKADDR_IN6 *)ClientAddress->u.IPv4Address);
  1187. }
  1188. RpcStatus = RPC_S_OK;
  1189. goto CleanupAndExit;
  1190. AbortAndExit:
  1191. RpcStatus = RPC_S_PROTOCOL_ERROR;
  1192. CleanupAndExit:
  1193. return RpcStatus;
  1194. }
  1195. RPC_STATUS GetFirstServerPacketType (
  1196. IN BYTE *Packet,
  1197. IN ULONG PacketLength,
  1198. OUT HTTP2FirstServerPacketType *PacketType
  1199. )
  1200. /*++
  1201. Routine Description:
  1202. Determines the type of the first server packet.
  1203. Arguments:
  1204. Packet - the packet received.
  1205. PacketLength - the length of the packet
  1206. PacketType - one of the members of the enumeration
  1207. Return Value:
  1208. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1209. otherwise.
  1210. --*/
  1211. {
  1212. rpcconn_tunnel_settings *RTS;
  1213. if (PacketLength < BaseRTSSizeAndPadding)
  1214. return RPC_S_PROTOCOL_ERROR;
  1215. RTS = (rpcconn_tunnel_settings *)Packet;
  1216. if (RTS->Flags & RTS_FLAG_OUT_CHANNEL)
  1217. {
  1218. if (RTS->Flags & RTS_FLAG_RECYCLE_CHANNEL)
  1219. *PacketType = http2fsptD4_A4;
  1220. else
  1221. *PacketType = http2fsptD1_A2;
  1222. return RPC_S_OK;
  1223. }
  1224. else if (RTS->Flags & RTS_FLAG_IN_CHANNEL)
  1225. {
  1226. if (RTS->Flags & RTS_FLAG_RECYCLE_CHANNEL)
  1227. *PacketType = http2fsptD2_A2;
  1228. else
  1229. *PacketType = http2fsptD1_B2;
  1230. return RPC_S_OK;
  1231. }
  1232. else
  1233. return RPC_S_PROTOCOL_ERROR;
  1234. }
  1235. RPC_STATUS GetClientOpenedPacketType (
  1236. IN BYTE *Packet,
  1237. IN ULONG PacketLength,
  1238. OUT HTTP2ClientOpenedPacketType *PacketType
  1239. )
  1240. /*++
  1241. Routine Description:
  1242. Determines the type of the packet in client opened (or one of
  1243. the opened states)
  1244. Arguments:
  1245. Packet - the packet received.
  1246. PacketLength - the length of the packet
  1247. PacketType - one of the members of the enumeration
  1248. Return Value:
  1249. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1250. otherwise.
  1251. --*/
  1252. {
  1253. rpcconn_tunnel_settings *RTS;
  1254. if (PacketLength < BaseRTSSizeAndPadding)
  1255. return RPC_S_PROTOCOL_ERROR;
  1256. RTS = (rpcconn_tunnel_settings *)Packet;
  1257. // here we expect D2/A4, D3/A4, D4/A2, D4/A6, D5/A6
  1258. // and D5/B3
  1259. if (RTS->Flags & RTS_FLAG_RECYCLE_CHANNEL)
  1260. {
  1261. *PacketType = http2coptD4_A2;
  1262. }
  1263. else if (RTS->Flags & RTS_FLAG_OUT_CHANNEL)
  1264. {
  1265. *PacketType = http2coptD4_A6;
  1266. }
  1267. else if (RTS->Flags & RTS_FLAG_EOF)
  1268. {
  1269. // D5/B3 has the EOF flag
  1270. *PacketType = http2coptD5_B3;
  1271. }
  1272. else if (IsD4_A10(Packet, PacketLength))
  1273. {
  1274. // D4/A10 is an ANCE packet.
  1275. *PacketType = http2coptD4_A10;
  1276. }
  1277. else if (IsD5_A6(Packet, PacketLength, fdClient))
  1278. {
  1279. // D5/A6 is an ANCE packet with forward destination.
  1280. *PacketType = http2coptD5_A6;
  1281. }
  1282. else if (IsD2_A4OrD3_A4(Packet, PacketLength))
  1283. {
  1284. *PacketType = http2coptD2_A4;
  1285. }
  1286. else
  1287. {
  1288. *PacketType = http2coptD3_A4;
  1289. }
  1290. return RPC_S_OK;
  1291. }
  1292. RPC_STATUS GetServerOpenedPacketType (
  1293. IN BYTE *Packet,
  1294. IN ULONG PacketLength,
  1295. OUT HTTP2ServerOpenedPacketType *PacketType
  1296. )
  1297. /*++
  1298. Routine Description:
  1299. Determines the type of the packet in server opened (or one of
  1300. the opened states)
  1301. Arguments:
  1302. Packet - the packet received.
  1303. PacketLength - the length of the packet
  1304. PacketType - one of the members of the enumeration
  1305. Return Value:
  1306. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1307. otherwise.
  1308. --*/
  1309. {
  1310. rpcconn_tunnel_settings *RTS;
  1311. if (PacketLength < BaseRTSSizeAndPadding)
  1312. return RPC_S_PROTOCOL_ERROR;
  1313. RTS = (rpcconn_tunnel_settings *)Packet;
  1314. // here we expect D2/A6, D2/B1, D3/A2, D4/A8 and D5/A8
  1315. if (RTS->Flags & RTS_FLAG_OUT_CHANNEL)
  1316. {
  1317. // D4/A8 and D5/A8 are differentiated by state only
  1318. *PacketType = http2soptD4_A8orD5_A8;
  1319. }
  1320. else if (IsEmptyRTS (Packet, PacketLength))
  1321. {
  1322. *PacketType = http2soptD2_B1;
  1323. }
  1324. else
  1325. {
  1326. *PacketType = http2soptD2_A6orD3_A2;
  1327. }
  1328. return RPC_S_OK;
  1329. }
  1330. RPC_STATUS GetOtherCmdPacketType (
  1331. IN BYTE *Packet,
  1332. IN ULONG PacketLength,
  1333. OUT HTTP2OtherCmdPacketType *PacketType
  1334. )
  1335. /*++
  1336. Routine Description:
  1337. Determines the type of a packet containing other cmd flag
  1338. Arguments:
  1339. Packet - the packet received.
  1340. PacketLength - the length of the packet
  1341. PacketType - one of the members of the enumeration
  1342. Return Value:
  1343. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1344. otherwise.
  1345. --*/
  1346. {
  1347. rpcconn_tunnel_settings *RTS;
  1348. if (PacketLength < BaseRTSSizeAndPadding)
  1349. return RPC_S_PROTOCOL_ERROR;
  1350. RTS = (rpcconn_tunnel_settings *)Packet;
  1351. // right now we only expect KeepAliveChange
  1352. *PacketType = http2ocptKeepAliveChange;
  1353. return RPC_S_OK;
  1354. }
  1355. RPC_STATUS GetServerOutChannelOtherCmdPacketType (
  1356. IN BYTE *Packet,
  1357. IN ULONG PacketLength,
  1358. OUT HTTP2ServerOutChannelOtherCmdPacketType *PacketType
  1359. )
  1360. /*++
  1361. Routine Description:
  1362. Determines the type of a packet containing other cmd flag
  1363. Arguments:
  1364. Packet - the packet received.
  1365. PacketLength - the length of the packet
  1366. PacketType - one of the members of the enumeration
  1367. Return Value:
  1368. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1369. otherwise.
  1370. --*/
  1371. {
  1372. ULONG MemorySize;
  1373. // tsctPingTrafficSentNotify is shorter than tsctFlowControlAck
  1374. // This is how we differentiate them
  1375. ASSERT(SIZE_OF_RTS_CMD_AND_PADDING(tsctFlowControlAck)
  1376. > SIZE_OF_RTS_CMD_AND_PADDING(tsctPingTrafficSentNotify));
  1377. MemorySize = BaseRTSSizeAndPadding
  1378. + BaseRTSCommandSize * 1
  1379. + SIZE_OF_RTS_CMD_AND_PADDING(tsctFlowControlAck)
  1380. ;
  1381. if (PacketLength < MemorySize)
  1382. *PacketType = http2sococptPingTrafficSentNotify;
  1383. else
  1384. *PacketType = http2sococptFlowControl;
  1385. return RPC_S_OK;
  1386. }
  1387. const char *ResponseHeaderFragment1 = "HTTP/1.1 200 Success\r\nContent-Type:application/rpc\r\nContent-Length:";
  1388. const int ResponseHeaderFragment1Length = 67; // length of "HTTP/1.1 200 Success\r\nContent-Type:application/rpc\r\nContent-Length:"
  1389. const char *ResponseHeaderFragment2 = "\r\n\r\n";
  1390. const int ResponseHeaderFragment2Length = 4; // length of "\r\n\r\n"
  1391. HTTP2SendContext *AllocateAndInitializeResponseHeader (
  1392. void
  1393. )
  1394. /*++
  1395. Routine Description:
  1396. Allocates and initializes the out channel response header.
  1397. Arguments:
  1398. Return Value:
  1399. The allocated and initialized send context on success. NULL on
  1400. failure.
  1401. --*/
  1402. {
  1403. ULONG MemorySize;
  1404. char *Buffer;
  1405. char *OriginalBuffer;
  1406. HTTP2SendContext *SendContext;
  1407. MemorySize = ResponseHeaderFragment1Length
  1408. + DefaultChannelLifetimeStringLength
  1409. + ResponseHeaderFragment2Length
  1410. ;
  1411. Buffer = (char *)RpcAllocateBuffer(HTTPSendContextSizeAndPadding + MemorySize);
  1412. if (Buffer == NULL)
  1413. return NULL;
  1414. OriginalBuffer = Buffer;
  1415. SendContext = (HTTP2SendContext *)Buffer;
  1416. Buffer += HTTPSendContextSizeAndPadding;
  1417. #if DBG
  1418. SendContext->ListEntryUsed = FALSE;
  1419. #endif
  1420. SendContext->maxWriteBuffer = MemorySize;
  1421. SendContext->pWriteBuffer = (BUFFER)Buffer;
  1422. SendContext->TrafficType = http2ttRaw;
  1423. SendContext->u.SyncEvent = NULL;
  1424. SendContext->Flags = 0;
  1425. SendContext->UserData = 0;
  1426. RpcpMemoryCopy(Buffer, ResponseHeaderFragment1, ResponseHeaderFragment1Length);
  1427. Buffer += ResponseHeaderFragment1Length;
  1428. RpcpMemoryCopy(Buffer, DefaultChannelLifetimeString, DefaultChannelLifetimeStringLength);
  1429. Buffer += DefaultChannelLifetimeStringLength;
  1430. RpcpMemoryCopy(Buffer, ResponseHeaderFragment2, ResponseHeaderFragment2Length);
  1431. return (HTTP2SendContext *)OriginalBuffer;
  1432. }
  1433. HTTP2SendContext *AllocateAndInitializeD1_A3 (
  1434. IN ULONG ProxyConnectionTimeout
  1435. )
  1436. /*++
  1437. Routine Description:
  1438. Allocates and initializes an D1_A3 packet.
  1439. Arguments:
  1440. ProxyConnectionTimeout - the proxy connection timeout.
  1441. Return Value:
  1442. The allocated and initialized send context on success. NULL on
  1443. failure.
  1444. --*/
  1445. {
  1446. HTTP2SendContext *SendContext;
  1447. TunnelSettingsCommand *CurrentCommand;
  1448. rpcconn_tunnel_settings *RTS;
  1449. SendContext = AllocateAndInitializeRTSPacket(
  1450. BaseRTSCommandSize * 1
  1451. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1452. );
  1453. if (SendContext)
  1454. {
  1455. RTS = GetRTSPacketFromSendContext(SendContext);
  1456. RTS->NumberOfSettingCommands = 1;
  1457. CurrentCommand = RTS->Cmd;
  1458. // set connection timeout
  1459. CurrentCommand->CommandType = tsctConnectionTimeout;
  1460. CurrentCommand->u.ConnectionTimeout = ProxyConnectionTimeout;
  1461. }
  1462. return SendContext;
  1463. }
  1464. RPC_STATUS ParseAndFreeD1_A3 (
  1465. IN BYTE *Packet,
  1466. IN ULONG PacketLength,
  1467. OUT ULONG *ProxyConnectionTimeout
  1468. )
  1469. /*++
  1470. Routine Description:
  1471. Parses and frees a D1/A3 RTS packet
  1472. Arguments:
  1473. Packet - the packet received.
  1474. PacketLength - the length of the packet
  1475. ProxyConnectionTimeout - the proxy connection timeout is returned
  1476. here (success only).
  1477. Return Value:
  1478. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1479. otherwise.
  1480. --*/
  1481. {
  1482. ULONG MemorySize;
  1483. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  1484. BYTE *CurrentPosition;
  1485. TunnelSettingsCommand *CurrentCommand;
  1486. RPC_STATUS RpcStatus;
  1487. MemorySize = BaseRTSSizeAndPadding
  1488. + BaseRTSCommandSize * 1
  1489. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout);
  1490. if (PacketLength < MemorySize)
  1491. goto AbortAndExit;
  1492. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  1493. if (CurrentPosition == NULL)
  1494. goto AbortAndExit;
  1495. if (RTS->NumberOfSettingCommands != 1)
  1496. goto AbortAndExit;
  1497. if (RTS->Flags != 0)
  1498. goto AbortAndExit;
  1499. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  1500. // get connection timeout
  1501. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  1502. goto AbortAndExit;
  1503. *ProxyConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  1504. RpcStatus = RPC_S_OK;
  1505. goto CleanupAndExit;
  1506. AbortAndExit:
  1507. RpcStatus = RPC_S_PROTOCOL_ERROR;
  1508. CleanupAndExit:
  1509. RpcFreeBuffer(Packet);
  1510. return RpcStatus;
  1511. }
  1512. HTTP2SendContext *AllocateAndInitializeD1_B3 (
  1513. IN ULONG ReceiveWindowSize,
  1514. IN ULONG UpdatedProtocolVersion
  1515. )
  1516. /*++
  1517. Routine Description:
  1518. Allocates and initializes an D1_B3 packet.
  1519. Arguments:
  1520. ReceiveWindowSize - the server receive window size.
  1521. UpdatedProtocolVersion - the updated protocol version.
  1522. Return Value:
  1523. The allocated and initialized send context on success. NULL on
  1524. failure.
  1525. --*/
  1526. {
  1527. HTTP2SendContext *SendContext;
  1528. TunnelSettingsCommand *CurrentCommand;
  1529. rpcconn_tunnel_settings *RTS;
  1530. SendContext = AllocateAndInitializeRTSPacket(
  1531. BaseRTSCommandSize * 2
  1532. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1533. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1534. );
  1535. if (SendContext)
  1536. {
  1537. RTS = GetRTSPacketFromSendContext(SendContext);
  1538. RTS->NumberOfSettingCommands = 2;
  1539. CurrentCommand = RTS->Cmd;
  1540. // set receive window
  1541. CurrentCommand->CommandType = tsctReceiveWindowSize;
  1542. CurrentCommand->u.ConnectionTimeout = ReceiveWindowSize;
  1543. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1544. // set version
  1545. CurrentCommand->CommandType = tsctVersion;
  1546. CurrentCommand->u.Version = UpdatedProtocolVersion;
  1547. }
  1548. return SendContext;
  1549. }
  1550. RPC_STATUS ParseAndFreeD1_B3 (
  1551. IN BYTE *Packet,
  1552. IN ULONG PacketLength,
  1553. OUT ULONG *ReceiveWindowSize,
  1554. OUT ULONG *UpdatedProtocolVersion
  1555. )
  1556. /*++
  1557. Routine Description:
  1558. Parses and frees a D1/A3 RTS packet
  1559. Arguments:
  1560. Packet - the packet received.
  1561. PacketLength - the length of the packet
  1562. ReceiveWindowSize - the receive window size is returned
  1563. here (success only).
  1564. UpdatedProtocolVersion - the updated protocol version from the
  1565. server (success only)
  1566. Return Value:
  1567. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1568. otherwise.
  1569. --*/
  1570. {
  1571. ULONG MemorySize;
  1572. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  1573. BYTE *CurrentPosition;
  1574. TunnelSettingsCommand *CurrentCommand;
  1575. RPC_STATUS RpcStatus;
  1576. MemorySize = BaseRTSSizeAndPadding
  1577. + BaseRTSCommandSize * 2
  1578. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1579. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1580. ;
  1581. if (PacketLength < MemorySize)
  1582. goto AbortAndExit;
  1583. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  1584. if (CurrentPosition == NULL)
  1585. goto AbortAndExit;
  1586. if (RTS->NumberOfSettingCommands != 2)
  1587. goto AbortAndExit;
  1588. if (RTS->Flags != 0)
  1589. goto AbortAndExit;
  1590. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  1591. // get receive window
  1592. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  1593. goto AbortAndExit;
  1594. *ReceiveWindowSize = CurrentCommand->u.ConnectionTimeout;
  1595. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1596. // get version
  1597. if (CurrentCommand->CommandType != tsctVersion)
  1598. goto AbortAndExit;
  1599. *UpdatedProtocolVersion = CurrentCommand->u.Version;
  1600. RpcStatus = RPC_S_OK;
  1601. goto CleanupAndExit;
  1602. AbortAndExit:
  1603. RpcStatus = RPC_S_PROTOCOL_ERROR;
  1604. CleanupAndExit:
  1605. RpcFreeBuffer(Packet);
  1606. return RpcStatus;
  1607. }
  1608. HTTP2SendContext *AllocateAndInitializeD1_C1 (
  1609. IN ULONG UpdatedProtocolVersion,
  1610. IN ULONG InProxyReceiveWindowSize,
  1611. IN ULONG InProxyConnectionTimeout
  1612. )
  1613. /*++
  1614. Routine Description:
  1615. Allocates and initializes a D1_C1 packet.
  1616. Arguments:
  1617. UpdatedProtocolVersion - the updated protocol version.
  1618. InProxyReceiveWindowSize - the in proxy receive window size.
  1619. InProxyConnectionTimeout - the in proxy connection timeout
  1620. Return Value:
  1621. The allocated and initialized send context on success. NULL on
  1622. failure.
  1623. --*/
  1624. {
  1625. HTTP2SendContext *SendContext;
  1626. TunnelSettingsCommand *CurrentCommand;
  1627. rpcconn_tunnel_settings *RTS;
  1628. SendContext = AllocateAndInitializeRTSPacket(
  1629. BaseRTSCommandSize * 3
  1630. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1631. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1632. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  1633. );
  1634. if (SendContext)
  1635. {
  1636. RTS = GetRTSPacketFromSendContext(SendContext);
  1637. RTS->NumberOfSettingCommands = 3;
  1638. CurrentCommand = RTS->Cmd;
  1639. // set version
  1640. CurrentCommand->CommandType = tsctVersion;
  1641. CurrentCommand->u.Version = UpdatedProtocolVersion;
  1642. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1643. // set receive window
  1644. CurrentCommand->CommandType = tsctReceiveWindowSize;
  1645. CurrentCommand->u.ReceiveWindowSize = InProxyReceiveWindowSize;
  1646. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1647. // set connection timeout
  1648. CurrentCommand->CommandType = tsctConnectionTimeout;
  1649. CurrentCommand->u.ConnectionTimeout = InProxyConnectionTimeout;
  1650. }
  1651. return SendContext;
  1652. }
  1653. RPC_STATUS ParseD1_C1 (
  1654. IN BYTE *Packet,
  1655. IN ULONG PacketLength,
  1656. OUT ULONG *UpdatedProtocolVersion,
  1657. OUT ULONG *InProxyReceiveWindowSize,
  1658. OUT ULONG *InProxyConnectionTimeout
  1659. )
  1660. /*++
  1661. Routine Description:
  1662. Parses a D1_C1 packet.
  1663. Arguments:
  1664. Packet - the packet received.
  1665. PacketLength - the length of the packet
  1666. UpdatedProtocolVersion - the updated protocol version.
  1667. InProxyReceiveWindowSize - the in proxy receive window size.
  1668. InProxyConnectionTimeout - the in proxy connection timeout
  1669. Return Value:
  1670. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1671. otherwise.
  1672. --*/
  1673. {
  1674. ULONG MemorySize;
  1675. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  1676. BYTE *CurrentPosition;
  1677. TunnelSettingsCommand *CurrentCommand;
  1678. RPC_STATUS RpcStatus;
  1679. MemorySize = BaseRTSSizeAndPadding
  1680. + BaseRTSCommandSize * 3
  1681. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1682. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1683. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  1684. ;
  1685. if (PacketLength < MemorySize)
  1686. goto AbortAndExit;
  1687. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  1688. if (CurrentPosition == NULL)
  1689. goto AbortAndExit;
  1690. if (RTS->NumberOfSettingCommands != 3)
  1691. goto AbortAndExit;
  1692. if (RTS->Flags != 0)
  1693. goto AbortAndExit;
  1694. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  1695. // get version
  1696. if (CurrentCommand->CommandType != tsctVersion)
  1697. goto AbortAndExit;
  1698. *UpdatedProtocolVersion = CurrentCommand->u.Version;
  1699. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1700. // get receive window
  1701. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  1702. goto AbortAndExit;
  1703. *InProxyReceiveWindowSize = CurrentCommand->u.ReceiveWindowSize;
  1704. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1705. // get connection timeout
  1706. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  1707. goto AbortAndExit;
  1708. *InProxyConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  1709. RpcStatus = RPC_S_OK;
  1710. goto CleanupAndExit;
  1711. AbortAndExit:
  1712. RpcStatus = RPC_S_PROTOCOL_ERROR;
  1713. CleanupAndExit:
  1714. return RpcStatus;
  1715. }
  1716. RPC_STATUS ParseAndFreeD1_C2 (
  1717. IN BYTE *Packet,
  1718. IN ULONG PacketLength,
  1719. OUT ULONG *UpdatedProtocolVersion,
  1720. OUT ULONG *InProxyReceiveWindowSize,
  1721. OUT ULONG *InProxyConnectionTimeout
  1722. )
  1723. /*++
  1724. Routine Description:
  1725. Parses and frees a D1_C2 packet.
  1726. Arguments:
  1727. Packet - the packet received.
  1728. PacketLength - the length of the packet
  1729. UpdatedProtocolVersion - the updated protocol version.
  1730. InProxyReceiveWindowSize - the in proxy receive window size.
  1731. InProxyConnectionTimeout - the in proxy connection timeout
  1732. Return Value:
  1733. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1734. otherwise.
  1735. --*/
  1736. {
  1737. RPC_STATUS RpcStatus;
  1738. // D1/C1 has the same format as D1/C2
  1739. RpcStatus = ParseD1_C1(Packet,
  1740. PacketLength,
  1741. UpdatedProtocolVersion,
  1742. InProxyReceiveWindowSize,
  1743. InProxyConnectionTimeout
  1744. );
  1745. RpcFreeBuffer(Packet);
  1746. return RpcStatus;
  1747. }
  1748. HTTP2SendContext *AllocateAndInitializeD2_A1 (
  1749. IN ULONG ProtocolVersion,
  1750. IN HTTP2Cookie *ConnectionCookie,
  1751. IN HTTP2Cookie *OldChannelCookie,
  1752. IN HTTP2Cookie *NewChannelCookie
  1753. )
  1754. /*++
  1755. Routine Description:
  1756. Allocates and initializes a D2/A1 RTS packet
  1757. Arguments:
  1758. ProtocolVersion - the version of the HTTP tunnelling protocol
  1759. ConnectionCookie - the connection cookie
  1760. OldChannelCookie - the old channel cookie
  1761. NewChannelCookie - the new channel cookie
  1762. Return Value:
  1763. The allocated send context or NULL for out-of-memory
  1764. --*/
  1765. {
  1766. HTTP2SendContext *SendContext;
  1767. TunnelSettingsCommand *CurrentCommand;
  1768. rpcconn_tunnel_settings *RTS;
  1769. SendContext = AllocateAndInitializeRTSPacket(
  1770. BaseRTSCommandSize * 4
  1771. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1772. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1773. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1774. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1775. );
  1776. if (SendContext)
  1777. {
  1778. RTS = GetRTSPacketFromSendContext(SendContext);
  1779. RTS->Flags = RTS_FLAG_RECYCLE_CHANNEL;
  1780. RTS->NumberOfSettingCommands = 4;
  1781. CurrentCommand = RTS->Cmd;
  1782. // set version
  1783. CurrentCommand->CommandType = tsctVersion;
  1784. CurrentCommand->u.Version = ProtocolVersion;
  1785. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1786. // set connection cookie
  1787. CurrentCommand->CommandType = tsctCookie;
  1788. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1789. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1790. // set old channel cookie
  1791. CurrentCommand->CommandType = tsctCookie;
  1792. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, OldChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1793. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1794. // set new channel cookie
  1795. CurrentCommand->CommandType = tsctCookie;
  1796. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, NewChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1797. }
  1798. return SendContext;
  1799. }
  1800. RPC_STATUS ParseAndFreeD2_A1 (
  1801. IN BYTE *Packet,
  1802. IN ULONG PacketLength,
  1803. OUT ULONG *ProtocolVersion,
  1804. OUT HTTP2Cookie *ConnectionCookie,
  1805. OUT HTTP2Cookie *OldChannelCookie,
  1806. OUT HTTP2Cookie *NewChannelCookie
  1807. )
  1808. /*++
  1809. Routine Description:
  1810. Parses and frees a D2/A1 RTS packet
  1811. Arguments:
  1812. Packet - the packet received.
  1813. PacketLength - the length of the packet
  1814. ProtocolVersion - on output, the version of the HTTP tunnelling protocol
  1815. Success only.
  1816. ConnectionCookie - on output, the connection cookie. Success only.
  1817. OldChannelCookie - on output, the old channel cookie. Success only.
  1818. NewChannelCookie - on output, the new channel cookie. Success only.
  1819. Return Value:
  1820. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1821. otherwise.
  1822. --*/
  1823. {
  1824. ULONG MemorySize;
  1825. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  1826. BYTE *CurrentPosition;
  1827. TunnelSettingsCommand *CurrentCommand;
  1828. RPC_STATUS RpcStatus;
  1829. MemorySize = BaseRTSSizeAndPadding
  1830. + BaseRTSCommandSize * 4
  1831. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1832. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1833. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1834. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1835. ;
  1836. if (PacketLength < MemorySize)
  1837. goto AbortAndExit;
  1838. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  1839. if (CurrentPosition == NULL)
  1840. goto AbortAndExit;
  1841. if (RTS->NumberOfSettingCommands != 4)
  1842. goto AbortAndExit;
  1843. if (RTS->Flags != RTS_FLAG_RECYCLE_CHANNEL)
  1844. goto AbortAndExit;
  1845. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  1846. // get version
  1847. if (CurrentCommand->CommandType != tsctVersion)
  1848. goto AbortAndExit;
  1849. *ProtocolVersion = CurrentCommand->u.Version;
  1850. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1851. // get connection cookie
  1852. if (CurrentCommand->CommandType != tsctCookie)
  1853. goto AbortAndExit;
  1854. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  1855. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1856. // get new channel cookie
  1857. if (CurrentCommand->CommandType != tsctCookie)
  1858. goto AbortAndExit;
  1859. OldChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  1860. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1861. // get old channel cookie
  1862. if (CurrentCommand->CommandType != tsctCookie)
  1863. goto AbortAndExit;
  1864. NewChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  1865. RpcStatus = RPC_S_OK;
  1866. goto CleanupAndExit;
  1867. AbortAndExit:
  1868. RpcStatus = RPC_S_PROTOCOL_ERROR;
  1869. CleanupAndExit:
  1870. RpcFreeBuffer(Packet);
  1871. return RpcStatus;
  1872. }
  1873. HTTP2SendContext *AllocateAndInitializeD2_A2 (
  1874. IN ULONG ProtocolVersion,
  1875. IN HTTP2Cookie *ConnectionCookie,
  1876. IN HTTP2Cookie *OldChannelCookie,
  1877. IN HTTP2Cookie *NewChannelCookie,
  1878. IN ULONG ReceiveWindowSize,
  1879. IN ULONG ConnectionTimeout
  1880. )
  1881. /*++
  1882. Routine Description:
  1883. Allocates and initializes a D2/A2 RTS packet
  1884. Arguments:
  1885. ProtocolVersion - the version of the HTTP tunnelling protocol
  1886. ConnectionCookie - the connection cookie
  1887. OldChannelCookie - the old channel cookie
  1888. NewChannelCookie - the new channel cookie
  1889. ReceiveWindowSize - the receive window size of the in proxy
  1890. ConnectionTimeout - connection timeout of the in proxy
  1891. Return Value:
  1892. The allocated send context or NULL for out-of-memory
  1893. --*/
  1894. {
  1895. HTTP2SendContext *SendContext;
  1896. TunnelSettingsCommand *CurrentCommand;
  1897. rpcconn_tunnel_settings *RTS;
  1898. SendContext = AllocateAndInitializeRTSPacket(
  1899. BaseRTSCommandSize * 6
  1900. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1901. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1902. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1903. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1904. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1905. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  1906. );
  1907. if (SendContext)
  1908. {
  1909. RTS = GetRTSPacketFromSendContext(SendContext);
  1910. RTS->Flags = RTS_FLAG_IN_CHANNEL | RTS_FLAG_RECYCLE_CHANNEL;
  1911. RTS->NumberOfSettingCommands = 6;
  1912. CurrentCommand = RTS->Cmd;
  1913. // set version
  1914. CurrentCommand->CommandType = tsctVersion;
  1915. CurrentCommand->u.Version = ProtocolVersion;
  1916. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1917. // set connection cookie
  1918. CurrentCommand->CommandType = tsctCookie;
  1919. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1920. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1921. // set old channel cookie
  1922. CurrentCommand->CommandType = tsctCookie;
  1923. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, OldChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1924. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1925. // set new channel cookie
  1926. CurrentCommand->CommandType = tsctCookie;
  1927. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, NewChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  1928. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  1929. // set receive window size
  1930. CurrentCommand->CommandType = tsctReceiveWindowSize;
  1931. CurrentCommand->u.ReceiveWindowSize = ReceiveWindowSize;
  1932. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  1933. // set connection timeout
  1934. CurrentCommand->CommandType = tsctConnectionTimeout;
  1935. CurrentCommand->u.ConnectionTimeout = ConnectionTimeout;
  1936. }
  1937. return SendContext;
  1938. }
  1939. RPC_STATUS ParseD2_A2 (
  1940. IN BYTE *Packet,
  1941. IN ULONG PacketLength,
  1942. OUT ULONG *ProtocolVersion,
  1943. OUT HTTP2Cookie *ConnectionCookie,
  1944. OUT HTTP2Cookie *OldChannelCookie,
  1945. OUT HTTP2Cookie *NewChannelCookie,
  1946. OUT ULONG *ReceiveWindowSize,
  1947. OUT ULONG *ConnectionTimeout
  1948. )
  1949. /*++
  1950. Routine Description:
  1951. Parses a D1/B2 RTS packet
  1952. Arguments:
  1953. Packet - the packet received.
  1954. PacketLength - the length of the packet
  1955. ProtocolVersion - the version of the HTTP tunnelling protocol
  1956. ConnectionCookie - the connection cookie
  1957. OldChannelCookie - the old channel cookie
  1958. NewChannelCookie - the new channel cookie
  1959. ReceiveWindowSize - the receive window size of the in proxy
  1960. ConnectionTimeout - connection timeout of the in proxy
  1961. Return Value:
  1962. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  1963. otherwise.
  1964. --*/
  1965. {
  1966. ULONG MemorySize;
  1967. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  1968. BYTE *CurrentPosition;
  1969. TunnelSettingsCommand *CurrentCommand;
  1970. RPC_STATUS RpcStatus;
  1971. MemorySize = BaseRTSSizeAndPadding
  1972. + BaseRTSCommandSize * 6
  1973. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  1974. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1975. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1976. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  1977. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  1978. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  1979. ;
  1980. if (PacketLength < MemorySize)
  1981. goto AbortAndExit;
  1982. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  1983. if (CurrentPosition == NULL)
  1984. goto AbortAndExit;
  1985. if (RTS->NumberOfSettingCommands != 6)
  1986. goto AbortAndExit;
  1987. if (RTS->Flags != (RTS_FLAG_IN_CHANNEL | RTS_FLAG_RECYCLE_CHANNEL))
  1988. goto AbortAndExit;
  1989. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  1990. // get version
  1991. if (CurrentCommand->CommandType != tsctVersion)
  1992. goto AbortAndExit;
  1993. *ProtocolVersion = CurrentCommand->u.Version;
  1994. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  1995. // get connection cookie
  1996. if (CurrentCommand->CommandType != tsctCookie)
  1997. goto AbortAndExit;
  1998. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  1999. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2000. // get old channel cookie
  2001. if (CurrentCommand->CommandType != tsctCookie)
  2002. goto AbortAndExit;
  2003. OldChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2004. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2005. // get new channel cookie
  2006. if (CurrentCommand->CommandType != tsctCookie)
  2007. goto AbortAndExit;
  2008. NewChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2009. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2010. // get receive window size
  2011. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  2012. goto AbortAndExit;
  2013. *ReceiveWindowSize = CurrentCommand->u.ReceiveWindowSize;
  2014. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  2015. // get connection timeout
  2016. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  2017. goto AbortAndExit;
  2018. *ConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  2019. CurrentCommand = SkipCommand(CurrentCommand, tsctConnectionTimeout);
  2020. RpcStatus = RPC_S_OK;
  2021. goto CleanupAndExit;
  2022. AbortAndExit:
  2023. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2024. CleanupAndExit:
  2025. return RpcStatus;
  2026. }
  2027. HTTP2SendContext *AllocateAndInitializeD2_A3 (
  2028. IN ForwardDestinations Destination,
  2029. IN ULONG ProtocolVersion,
  2030. IN ULONG ReceiveWindowSize,
  2031. IN ULONG ConnectionTimeout
  2032. )
  2033. /*++
  2034. Routine Description:
  2035. Allocates and initializes a D2/A3 RTS packet
  2036. Arguments:
  2037. Destination - where to forward this to.
  2038. ProtocolVersion - the version of the HTTP tunnelling protocol
  2039. ReceiveWindowSize - the receive window size of the in proxy
  2040. ConnectionTimeout - connection timeout of the in proxy
  2041. Return Value:
  2042. The allocated send context or NULL for out-of-memory
  2043. --*/
  2044. {
  2045. HTTP2SendContext *SendContext;
  2046. TunnelSettingsCommand *CurrentCommand;
  2047. rpcconn_tunnel_settings *RTS;
  2048. SendContext = AllocateAndInitializeRTSPacket(
  2049. BaseRTSCommandSize * 4
  2050. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2051. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2052. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2053. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  2054. );
  2055. if (SendContext)
  2056. {
  2057. RTS = GetRTSPacketFromSendContext(SendContext);
  2058. RTS->Flags = 0;
  2059. RTS->NumberOfSettingCommands = 4;
  2060. CurrentCommand = RTS->Cmd;
  2061. // set destination
  2062. CurrentCommand->CommandType = tsctDestination;
  2063. CurrentCommand->u.Destination = Destination;
  2064. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  2065. // set version
  2066. CurrentCommand->CommandType = tsctVersion;
  2067. CurrentCommand->u.Version = ProtocolVersion;
  2068. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2069. // set receive window size
  2070. CurrentCommand->CommandType = tsctReceiveWindowSize;
  2071. CurrentCommand->u.ReceiveWindowSize = ReceiveWindowSize;
  2072. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  2073. // set connection timeout
  2074. CurrentCommand->CommandType = tsctConnectionTimeout;
  2075. CurrentCommand->u.ConnectionTimeout = ConnectionTimeout;
  2076. }
  2077. return SendContext;
  2078. }
  2079. RPC_STATUS ParseAndFreeD2_A4 (
  2080. IN BYTE *Packet,
  2081. IN ULONG PacketLength,
  2082. IN ForwardDestinations ExpectedDestination,
  2083. OUT ULONG *ProtocolVersion,
  2084. OUT ULONG *ReceiveWindowSize,
  2085. OUT ULONG *ConnectionTimeout
  2086. )
  2087. /*++
  2088. Routine Description:
  2089. Parses and frees a D2/A4 RTS packet
  2090. Arguments:
  2091. Packet - the packet received.
  2092. PacketLength - the length of the packet
  2093. ExpectedDestination - the destination code for this location (client)
  2094. ProtocolVersion - the version of the HTTP tunnelling protocol
  2095. ReceiveWindowSize - the receive window size of the in proxy
  2096. ConnectionTimeout - connection timeout of the in proxy
  2097. Return Value:
  2098. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2099. otherwise.
  2100. --*/
  2101. {
  2102. ULONG MemorySize;
  2103. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2104. BYTE *CurrentPosition;
  2105. TunnelSettingsCommand *CurrentCommand;
  2106. RPC_STATUS RpcStatus;
  2107. MemorySize = BaseRTSSizeAndPadding
  2108. + BaseRTSCommandSize * 4
  2109. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2110. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2111. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2112. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  2113. ;
  2114. if (PacketLength < MemorySize)
  2115. goto AbortAndExit;
  2116. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2117. if (CurrentPosition == NULL)
  2118. goto AbortAndExit;
  2119. if (RTS->NumberOfSettingCommands != 4)
  2120. goto AbortAndExit;
  2121. if (RTS->Flags != 0)
  2122. goto AbortAndExit;
  2123. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2124. // verify destination
  2125. if (CurrentCommand->CommandType != tsctDestination)
  2126. goto AbortAndExit;
  2127. if (ExpectedDestination != CurrentCommand->u.Destination)
  2128. goto AbortAndExit;
  2129. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  2130. // get version
  2131. if (CurrentCommand->CommandType != tsctVersion)
  2132. goto AbortAndExit;
  2133. *ProtocolVersion = CurrentCommand->u.Version;
  2134. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2135. // get receive window size
  2136. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  2137. goto AbortAndExit;
  2138. *ReceiveWindowSize = CurrentCommand->u.ReceiveWindowSize;
  2139. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  2140. // get connection timeout
  2141. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  2142. goto AbortAndExit;
  2143. *ConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  2144. CurrentCommand = SkipCommand(CurrentCommand, tsctConnectionTimeout);
  2145. RpcStatus = RPC_S_OK;
  2146. goto CleanupAndExit;
  2147. AbortAndExit:
  2148. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2149. CleanupAndExit:
  2150. RpcFreeBuffer(Packet);
  2151. return RpcStatus;
  2152. }
  2153. HTTP2SendContext *AllocateAndInitializeD2_A5 (
  2154. IN HTTP2Cookie *NewChannelCookie
  2155. )
  2156. /*++
  2157. Routine Description:
  2158. Allocates and initializes a D2/A5 RTS packet
  2159. Arguments:
  2160. NewChannelCookie - the new channel cookie
  2161. Return Value:
  2162. The allocated send context or NULL for out-of-memory
  2163. --*/
  2164. {
  2165. HTTP2SendContext *SendContext;
  2166. TunnelSettingsCommand *CurrentCommand;
  2167. rpcconn_tunnel_settings *RTS;
  2168. SendContext = AllocateAndInitializeRTSPacket(
  2169. BaseRTSCommandSize * 1
  2170. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2171. );
  2172. if (SendContext)
  2173. {
  2174. RTS = GetRTSPacketFromSendContext(SendContext);
  2175. RTS->Flags = 0;
  2176. RTS->NumberOfSettingCommands = 1;
  2177. CurrentCommand = RTS->Cmd;
  2178. // set new channel cookie
  2179. CurrentCommand->CommandType = tsctCookie;
  2180. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, NewChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2181. }
  2182. return SendContext;
  2183. }
  2184. RPC_STATUS ParseD2_A5 (
  2185. IN BYTE *Packet,
  2186. IN ULONG PacketLength,
  2187. OUT HTTP2Cookie *NewChannelCookie
  2188. )
  2189. /*++
  2190. Routine Description:
  2191. Parses a D2/A5 RTS packet
  2192. Arguments:
  2193. Packet - the packet received.
  2194. PacketLength - the length of the packet
  2195. NewChannelCookie - the new channel cookie
  2196. Return Value:
  2197. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2198. otherwise.
  2199. --*/
  2200. {
  2201. ULONG MemorySize;
  2202. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2203. BYTE *CurrentPosition;
  2204. TunnelSettingsCommand *CurrentCommand;
  2205. RPC_STATUS RpcStatus;
  2206. MemorySize = BaseRTSSizeAndPadding
  2207. + BaseRTSCommandSize * 1
  2208. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2209. ;
  2210. if (PacketLength < MemorySize)
  2211. goto AbortAndExit;
  2212. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2213. if (CurrentPosition == NULL)
  2214. goto AbortAndExit;
  2215. if (RTS->NumberOfSettingCommands != 1)
  2216. goto AbortAndExit;
  2217. if (RTS->Flags != 0)
  2218. goto AbortAndExit;
  2219. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2220. // get new channel cookie
  2221. if (CurrentCommand->CommandType != tsctCookie)
  2222. goto AbortAndExit;
  2223. NewChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2224. RpcStatus = RPC_S_OK;
  2225. goto CleanupAndExit;
  2226. AbortAndExit:
  2227. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2228. CleanupAndExit:
  2229. return RpcStatus;
  2230. }
  2231. RPC_STATUS ParseAndFreeD2_A6 (
  2232. IN BYTE *Packet,
  2233. IN ULONG PacketLength,
  2234. OUT HTTP2Cookie *NewChannelCookie
  2235. )
  2236. /*++
  2237. Routine Description:
  2238. Parses and frees a D2/A6 RTS packet
  2239. Arguments:
  2240. Packet - the packet received.
  2241. PacketLength - the length of the packet
  2242. NewChannelCookie - the new channel cookie
  2243. Return Value:
  2244. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2245. otherwise.
  2246. --*/
  2247. {
  2248. RPC_STATUS RpcStatus;
  2249. // D2/A6 is the same as D2/A5
  2250. RpcStatus = ParseD2_A5(Packet,
  2251. PacketLength,
  2252. NewChannelCookie);
  2253. RpcFreeBuffer(Packet);
  2254. return RpcStatus;
  2255. }
  2256. HTTP2SendContext *AllocateAndInitializeD2_B2 (
  2257. IN ULONG ServerReceiveWindow
  2258. )
  2259. /*++
  2260. Routine Description:
  2261. Allocates and initializes a D2/B2 RTS packet
  2262. Arguments:
  2263. ServerReceiveWindow - the server receive window
  2264. Return Value:
  2265. The allocated send context or NULL for out-of-memory
  2266. --*/
  2267. {
  2268. HTTP2SendContext *SendContext;
  2269. TunnelSettingsCommand *CurrentCommand;
  2270. rpcconn_tunnel_settings *RTS;
  2271. SendContext = AllocateAndInitializeRTSPacket(
  2272. BaseRTSCommandSize * 1
  2273. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2274. );
  2275. if (SendContext)
  2276. {
  2277. RTS = GetRTSPacketFromSendContext(SendContext);
  2278. RTS->Flags = 0;
  2279. RTS->NumberOfSettingCommands = 1;
  2280. CurrentCommand = RTS->Cmd;
  2281. // set server receive window
  2282. CurrentCommand->CommandType = tsctReceiveWindowSize;
  2283. CurrentCommand->u.ReceiveWindowSize = ServerReceiveWindow;
  2284. }
  2285. return SendContext;
  2286. }
  2287. RPC_STATUS ParseAndFreeD2_B2 (
  2288. IN BYTE *Packet,
  2289. IN ULONG PacketLength,
  2290. OUT ULONG *ServerReceiveWindow
  2291. )
  2292. /*++
  2293. Routine Description:
  2294. Parses and frees a D2/B2 RTS packet
  2295. Arguments:
  2296. Packet - the packet received.
  2297. PacketLength - the length of the packet
  2298. ServerReceiveWindow - the server receive window
  2299. Return Value:
  2300. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2301. otherwise.
  2302. --*/
  2303. {
  2304. ULONG MemorySize;
  2305. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2306. BYTE *CurrentPosition;
  2307. TunnelSettingsCommand *CurrentCommand;
  2308. RPC_STATUS RpcStatus;
  2309. MemorySize = BaseRTSSizeAndPadding
  2310. + BaseRTSCommandSize * 1
  2311. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize);
  2312. if (PacketLength < MemorySize)
  2313. goto AbortAndExit;
  2314. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2315. if (CurrentPosition == NULL)
  2316. goto AbortAndExit;
  2317. if (RTS->NumberOfSettingCommands != 1)
  2318. goto AbortAndExit;
  2319. if (RTS->Flags != 0)
  2320. goto AbortAndExit;
  2321. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2322. // get server receive window
  2323. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  2324. goto AbortAndExit;
  2325. *ServerReceiveWindow = CurrentCommand->u.ReceiveWindowSize;
  2326. RpcStatus = RPC_S_OK;
  2327. goto CleanupAndExit;
  2328. AbortAndExit:
  2329. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2330. CleanupAndExit:
  2331. RpcFreeBuffer(Packet);
  2332. return RpcStatus;
  2333. }
  2334. HTTP2SendContext *AllocateAndInitializeD4_A3 (
  2335. IN ULONG ProtocolVersion,
  2336. IN HTTP2Cookie *ConnectionCookie,
  2337. IN HTTP2Cookie *OldChannelCookie,
  2338. IN HTTP2Cookie *NewChannelCookie,
  2339. IN ULONG ClientReceiveWindow
  2340. )
  2341. /*++
  2342. Routine Description:
  2343. Allocates and initializes a D4/A3 RTS packet
  2344. Arguments:
  2345. ProtocolVersion - the version of the HTTP tunnelling protocol
  2346. ConnectionCookie - the connection cookie
  2347. OldChannelCookie - the old channel cookie
  2348. NewChannelCookie - the new channel cookie
  2349. ClientReceiveWindow - the client receive window
  2350. Return Value:
  2351. The allocated send context or NULL for out-of-memory
  2352. --*/
  2353. {
  2354. HTTP2SendContext *SendContext;
  2355. TunnelSettingsCommand *CurrentCommand;
  2356. rpcconn_tunnel_settings *RTS;
  2357. SendContext = AllocateAndInitializeRTSPacket(
  2358. BaseRTSCommandSize * 5
  2359. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2360. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2361. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2362. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2363. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2364. );
  2365. if (SendContext)
  2366. {
  2367. RTS = GetRTSPacketFromSendContext(SendContext);
  2368. RTS->Flags = RTS_FLAG_RECYCLE_CHANNEL;
  2369. RTS->NumberOfSettingCommands = 5;
  2370. CurrentCommand = RTS->Cmd;
  2371. // set version
  2372. CurrentCommand->CommandType = tsctVersion;
  2373. CurrentCommand->u.Version = ProtocolVersion;
  2374. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2375. // set connection cookie
  2376. CurrentCommand->CommandType = tsctCookie;
  2377. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2378. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2379. // set old channel cookie
  2380. CurrentCommand->CommandType = tsctCookie;
  2381. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, OldChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2382. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2383. // set new channel cookie
  2384. CurrentCommand->CommandType = tsctCookie;
  2385. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, NewChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2386. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2387. // set client receive window
  2388. CurrentCommand->CommandType = tsctReceiveWindowSize;
  2389. CurrentCommand->u.ReceiveWindowSize = ClientReceiveWindow;
  2390. }
  2391. return SendContext;
  2392. }
  2393. RPC_STATUS ParseAndFreeD4_A2 (
  2394. IN BYTE *Packet,
  2395. IN ULONG PacketLength
  2396. )
  2397. /*++
  2398. Routine Description:
  2399. Parses and frees a D4/A2 packet
  2400. Arguments:
  2401. Packet - the packet received.
  2402. PacketLength - the length of the packet
  2403. Return Value:
  2404. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2405. otherwise.
  2406. --*/
  2407. {
  2408. ULONG MemorySize;
  2409. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2410. BYTE *CurrentPosition;
  2411. TunnelSettingsCommand *CurrentCommand;
  2412. RPC_STATUS RpcStatus;
  2413. MemorySize = BaseRTSSizeAndPadding
  2414. + BaseRTSCommandSize * 1
  2415. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2416. ;
  2417. if (PacketLength < MemorySize)
  2418. goto AbortAndExit;
  2419. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2420. if (CurrentPosition == NULL)
  2421. goto AbortAndExit;
  2422. if (RTS->NumberOfSettingCommands != 1)
  2423. goto AbortAndExit;
  2424. if (RTS->Flags != RTS_FLAG_RECYCLE_CHANNEL)
  2425. goto AbortAndExit;
  2426. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2427. // verify destination
  2428. if (CurrentCommand->CommandType != tsctDestination)
  2429. goto AbortAndExit;
  2430. if (fdClient != CurrentCommand->u.Destination)
  2431. goto AbortAndExit;
  2432. RpcStatus = RPC_S_OK;
  2433. goto CleanupAndExit;
  2434. AbortAndExit:
  2435. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2436. CleanupAndExit:
  2437. RpcFreeBuffer(Packet);
  2438. return RpcStatus;
  2439. }
  2440. ULONG GetD4_A3TotalLength (
  2441. void
  2442. )
  2443. /*++
  2444. Routine Description:
  2445. Calculates the length of a D1/A1 RTS packet
  2446. Arguments:
  2447. Return Value:
  2448. The length of the D1/A1 RTS packet.
  2449. --*/
  2450. {
  2451. return (BaseRTSSizeAndPadding
  2452. + BaseRTSCommandSize * 5
  2453. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2454. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2455. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2456. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2457. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2458. );
  2459. }
  2460. ULONG GetD4_A11TotalLength (
  2461. void
  2462. )
  2463. /*++
  2464. Routine Description:
  2465. Calculates the length of a D4/A11 RTS packet
  2466. Arguments:
  2467. Return Value:
  2468. The length of the D4/A11 RTS packet.
  2469. --*/
  2470. {
  2471. return (BaseRTSSizeAndPadding
  2472. + BaseRTSCommandSize * 1
  2473. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  2474. );
  2475. }
  2476. RPC_STATUS ParseD4_A3 (
  2477. IN BYTE *Packet,
  2478. IN ULONG PacketLength,
  2479. OUT ULONG *ProtocolVersion,
  2480. OUT HTTP2Cookie *ConnectionCookie,
  2481. OUT HTTP2Cookie *OldChannelCookie,
  2482. OUT HTTP2Cookie *NewChannelCookie,
  2483. OUT ULONG *ClientReceiveWindow
  2484. )
  2485. /*++
  2486. Routine Description:
  2487. Parses and frees a D1/A1 RTS packet
  2488. Arguments:
  2489. Packet - the packet received.
  2490. PacketLength - the length of the packet
  2491. ProtocolVersion - the version of the HTTP tunnelling protocol
  2492. ConnectionCookie - the connection cookie
  2493. OldChannelCookie - the old channel cookie
  2494. NewChannelCookie - the new channel cookie
  2495. ClientReceiveWindow - the client receive window
  2496. Return Value:
  2497. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2498. otherwise.
  2499. --*/
  2500. {
  2501. ULONG MemorySize;
  2502. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2503. BYTE *CurrentPosition;
  2504. TunnelSettingsCommand *CurrentCommand;
  2505. RPC_STATUS RpcStatus;
  2506. MemorySize = BaseRTSSizeAndPadding
  2507. + BaseRTSCommandSize * 5
  2508. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2509. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2510. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2511. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2512. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize);
  2513. if (PacketLength < MemorySize)
  2514. goto AbortAndExit;
  2515. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2516. if (CurrentPosition == NULL)
  2517. goto AbortAndExit;
  2518. if (RTS->NumberOfSettingCommands != 5)
  2519. goto AbortAndExit;
  2520. if (RTS->Flags != RTS_FLAG_RECYCLE_CHANNEL)
  2521. goto AbortAndExit;
  2522. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2523. // get version
  2524. if (CurrentCommand->CommandType != tsctVersion)
  2525. goto AbortAndExit;
  2526. *ProtocolVersion = CurrentCommand->u.Version;
  2527. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2528. // get connection cookie
  2529. if (CurrentCommand->CommandType != tsctCookie)
  2530. goto AbortAndExit;
  2531. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2532. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2533. // get old channel cookie
  2534. if (CurrentCommand->CommandType != tsctCookie)
  2535. goto AbortAndExit;
  2536. OldChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2537. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2538. // get new channel cookie
  2539. if (CurrentCommand->CommandType != tsctCookie)
  2540. goto AbortAndExit;
  2541. NewChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2542. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2543. // get client receive window
  2544. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  2545. goto AbortAndExit;
  2546. *ClientReceiveWindow = CurrentCommand->u.ReceiveWindowSize;
  2547. RpcStatus = RPC_S_OK;
  2548. goto CleanupAndExit;
  2549. AbortAndExit:
  2550. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2551. CleanupAndExit:
  2552. return RpcStatus;
  2553. }
  2554. RPC_STATUS ParseAndFreeD4_A3 (
  2555. IN BYTE *Packet,
  2556. IN ULONG PacketLength,
  2557. OUT ULONG *ProtocolVersion,
  2558. OUT HTTP2Cookie *ConnectionCookie,
  2559. OUT HTTP2Cookie *OldChannelCookie,
  2560. OUT HTTP2Cookie *NewChannelCookie,
  2561. OUT ULONG *ClientReceiveWindow
  2562. )
  2563. /*++
  2564. Routine Description:
  2565. Parses and frees a D1/A1 RTS packet
  2566. Arguments:
  2567. Packet - the packet received.
  2568. PacketLength - the length of the packet
  2569. ProtocolVersion - the version of the HTTP tunnelling protocol
  2570. ConnectionCookie - the connection cookie
  2571. OldChannelCookie - the old channel cookie
  2572. NewChannelCookie - the new channel cookie
  2573. ClientReceiveWindow - the client receive window
  2574. Return Value:
  2575. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2576. otherwise.
  2577. --*/
  2578. {
  2579. RPC_STATUS RpcStatus;
  2580. RpcStatus = ParseD4_A3 (Packet,
  2581. PacketLength,
  2582. ProtocolVersion,
  2583. ConnectionCookie,
  2584. OldChannelCookie,
  2585. NewChannelCookie,
  2586. ClientReceiveWindow
  2587. );
  2588. RpcFreeBuffer(Packet);
  2589. return RpcStatus;
  2590. }
  2591. HTTP2SendContext *AllocateAndInitializeD4_A4 (
  2592. IN ULONG ProtocolVersion,
  2593. IN HTTP2Cookie *ConnectionCookie,
  2594. IN HTTP2Cookie *OldChannelCookie,
  2595. IN HTTP2Cookie *NewChannelCookie,
  2596. IN ULONG ChannelLifetime,
  2597. IN ULONG ProxyReceiveWindow,
  2598. IN ULONG ProxyConnectionTimeout
  2599. )
  2600. /*++
  2601. Routine Description:
  2602. Allocates and initializes a D4/A4 RTS packet
  2603. Arguments:
  2604. ProtocolVersion - the version of the HTTP tunnelling protocol
  2605. ConnectionCookie - the connection cookie
  2606. OldChannelCookie - the old channel cookie
  2607. NewChannelCookie - the new channel cookie
  2608. ChannelLifetime - the lifetime of the channel
  2609. ProxyReceiveWindow - the proxy receive window
  2610. ProxyConnectionTimeout - the proxy connection timeout
  2611. Return Value:
  2612. The allocated send context or NULL for out-of-memory
  2613. --*/
  2614. {
  2615. HTTP2SendContext *SendContext;
  2616. TunnelSettingsCommand *CurrentCommand;
  2617. rpcconn_tunnel_settings *RTS;
  2618. SendContext = AllocateAndInitializeRTSPacket(
  2619. BaseRTSCommandSize * 7
  2620. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2621. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2622. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2623. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2624. + SIZE_OF_RTS_CMD_AND_PADDING(tsctChannelLifetime)
  2625. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2626. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  2627. );
  2628. if (SendContext)
  2629. {
  2630. RTS = GetRTSPacketFromSendContext(SendContext);
  2631. RTS->Flags = RTS_FLAG_RECYCLE_CHANNEL | RTS_FLAG_OUT_CHANNEL;
  2632. RTS->NumberOfSettingCommands = 7;
  2633. CurrentCommand = RTS->Cmd;
  2634. // set version
  2635. CurrentCommand->CommandType = tsctVersion;
  2636. CurrentCommand->u.Version = ProtocolVersion;
  2637. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2638. // set connection cookie
  2639. CurrentCommand->CommandType = tsctCookie;
  2640. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, ConnectionCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2641. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2642. // set old channel cookie
  2643. CurrentCommand->CommandType = tsctCookie;
  2644. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, OldChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2645. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2646. // set new channel cookie
  2647. CurrentCommand->CommandType = tsctCookie;
  2648. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, NewChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2649. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2650. // set channel lifetime
  2651. CurrentCommand->CommandType = tsctChannelLifetime;
  2652. CurrentCommand->u.ChannelLifetime = ChannelLifetime;
  2653. CurrentCommand = SkipCommand(CurrentCommand, tsctChannelLifetime);
  2654. // set proxy receive window
  2655. CurrentCommand->CommandType = tsctReceiveWindowSize;
  2656. CurrentCommand->u.ReceiveWindowSize = ProxyReceiveWindow;
  2657. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  2658. // set proxy connection timeout
  2659. CurrentCommand->CommandType = tsctConnectionTimeout;
  2660. CurrentCommand->u.ConnectionTimeout = ProxyConnectionTimeout;
  2661. }
  2662. return SendContext;
  2663. }
  2664. RPC_STATUS ParseD4_A4 (
  2665. IN BYTE *Packet,
  2666. IN ULONG PacketLength,
  2667. OUT ULONG *ProtocolVersion,
  2668. OUT HTTP2Cookie *ConnectionCookie,
  2669. OUT HTTP2Cookie *OldChannelCookie,
  2670. OUT HTTP2Cookie *NewChannelCookie,
  2671. OUT ULONG *ChannelLifetime,
  2672. OUT ULONG *ProxyReceiveWindow,
  2673. OUT ULONG *ProxyConnectionTimeout
  2674. )
  2675. /*++
  2676. Routine Description:
  2677. Parses and frees a D1/A1 RTS packet
  2678. Arguments:
  2679. Packet - the packet received.
  2680. PacketLength - the length of the packet
  2681. ProtocolVersion - the version of the HTTP tunnelling protocol
  2682. ConnectionCookie - the connection cookie
  2683. OldChannelCookie - the old channel cookie
  2684. NewChannelCookie - the new channel cookie
  2685. ChannelLifetime - the lifetime of the channel
  2686. ProxyReceiveWindow - the proxy receive window
  2687. ProxyConnectionTimeout - the proxy connection timeout
  2688. Return Value:
  2689. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2690. otherwise.
  2691. --*/
  2692. {
  2693. ULONG MemorySize;
  2694. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2695. BYTE *CurrentPosition;
  2696. TunnelSettingsCommand *CurrentCommand;
  2697. RPC_STATUS RpcStatus;
  2698. MemorySize = BaseRTSSizeAndPadding
  2699. + BaseRTSCommandSize * 7
  2700. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2701. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2702. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2703. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2704. + SIZE_OF_RTS_CMD_AND_PADDING(tsctChannelLifetime)
  2705. + SIZE_OF_RTS_CMD_AND_PADDING(tsctReceiveWindowSize)
  2706. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  2707. ;
  2708. if (PacketLength < MemorySize)
  2709. goto AbortAndExit;
  2710. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2711. if (CurrentPosition == NULL)
  2712. goto AbortAndExit;
  2713. if (RTS->NumberOfSettingCommands != 7)
  2714. goto AbortAndExit;
  2715. if (RTS->Flags != (RTS_FLAG_RECYCLE_CHANNEL | RTS_FLAG_OUT_CHANNEL))
  2716. goto AbortAndExit;
  2717. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2718. // get version
  2719. if (CurrentCommand->CommandType != tsctVersion)
  2720. goto AbortAndExit;
  2721. *ProtocolVersion = CurrentCommand->u.Version;
  2722. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2723. // get connection cookie
  2724. if (CurrentCommand->CommandType != tsctCookie)
  2725. goto AbortAndExit;
  2726. ConnectionCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2727. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2728. // get old channel cookie
  2729. if (CurrentCommand->CommandType != tsctCookie)
  2730. goto AbortAndExit;
  2731. OldChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2732. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2733. // get new channel cookie
  2734. if (CurrentCommand->CommandType != tsctCookie)
  2735. goto AbortAndExit;
  2736. NewChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2737. CurrentCommand = SkipCommand(CurrentCommand, tsctCookie);
  2738. // get channel lifetime
  2739. if (CurrentCommand->CommandType != tsctChannelLifetime)
  2740. goto AbortAndExit;
  2741. *ChannelLifetime = CurrentCommand->u.ChannelLifetime;
  2742. CurrentCommand = SkipCommand(CurrentCommand, tsctChannelLifetime);
  2743. // get proxy receive window
  2744. if (CurrentCommand->CommandType != tsctReceiveWindowSize)
  2745. goto AbortAndExit;
  2746. *ProxyReceiveWindow = CurrentCommand->u.ReceiveWindowSize;
  2747. CurrentCommand = SkipCommand(CurrentCommand, tsctReceiveWindowSize);
  2748. // get proxy connection timeout
  2749. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  2750. goto AbortAndExit;
  2751. *ProxyConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  2752. RpcStatus = RPC_S_OK;
  2753. goto CleanupAndExit;
  2754. AbortAndExit:
  2755. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2756. CleanupAndExit:
  2757. return RpcStatus;
  2758. }
  2759. HTTP2SendContext *AllocateAndInitializeD4_A5 (
  2760. IN ForwardDestinations Destination,
  2761. IN ULONG ProtocolVersion,
  2762. IN ULONG ConnectionTimeout
  2763. )
  2764. /*++
  2765. Routine Description:
  2766. Allocates and initializes a D4/A5 RTS packet
  2767. Arguments:
  2768. Destination - where to forward this to.
  2769. ProtocolVersion - the version of the HTTP tunnelling protocol
  2770. ConnectionTimeout - connection timeout of the out proxy
  2771. Return Value:
  2772. The allocated send context or NULL for out-of-memory
  2773. --*/
  2774. {
  2775. HTTP2SendContext *SendContext;
  2776. TunnelSettingsCommand *CurrentCommand;
  2777. rpcconn_tunnel_settings *RTS;
  2778. SendContext = AllocateAndInitializeRTSPacket(
  2779. BaseRTSCommandSize * 3
  2780. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2781. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2782. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  2783. );
  2784. if (SendContext)
  2785. {
  2786. RTS = GetRTSPacketFromSendContext(SendContext);
  2787. RTS->Flags = RTS_FLAG_OUT_CHANNEL;
  2788. RTS->NumberOfSettingCommands = 3;
  2789. CurrentCommand = RTS->Cmd;
  2790. // set destination
  2791. CurrentCommand->CommandType = tsctDestination;
  2792. CurrentCommand->u.Destination = Destination;
  2793. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  2794. // set version
  2795. CurrentCommand->CommandType = tsctVersion;
  2796. CurrentCommand->u.Version = ProtocolVersion;
  2797. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2798. // set connection timeout
  2799. CurrentCommand->CommandType = tsctConnectionTimeout;
  2800. CurrentCommand->u.ConnectionTimeout = ConnectionTimeout;
  2801. }
  2802. return SendContext;
  2803. }
  2804. RPC_STATUS ParseAndFreeD4_A6 (
  2805. IN BYTE *Packet,
  2806. IN ULONG PacketLength,
  2807. IN ForwardDestinations ExpectedDestination,
  2808. OUT ULONG *ProtocolVersion,
  2809. OUT ULONG *ConnectionTimeout
  2810. )
  2811. /*++
  2812. Routine Description:
  2813. Parses and frees a D4/A6 RTS packet
  2814. Arguments:
  2815. Packet - the packet received.
  2816. PacketLength - the length of the packet
  2817. ExpectedDestination - the destination code for this location (client)
  2818. ProtocolVersion - the version of the HTTP tunnelling protocol
  2819. ConnectionTimeout - connection timeout of the out proxy
  2820. Return Value:
  2821. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2822. otherwise.
  2823. --*/
  2824. {
  2825. ULONG MemorySize;
  2826. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2827. BYTE *CurrentPosition;
  2828. TunnelSettingsCommand *CurrentCommand;
  2829. RPC_STATUS RpcStatus;
  2830. MemorySize = BaseRTSSizeAndPadding
  2831. + BaseRTSCommandSize * 3
  2832. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2833. + SIZE_OF_RTS_CMD_AND_PADDING(tsctVersion)
  2834. + SIZE_OF_RTS_CMD_AND_PADDING(tsctConnectionTimeout)
  2835. ;
  2836. if (PacketLength < MemorySize)
  2837. goto AbortAndExit;
  2838. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2839. if (CurrentPosition == NULL)
  2840. goto AbortAndExit;
  2841. if (RTS->NumberOfSettingCommands != 3)
  2842. goto AbortAndExit;
  2843. if (RTS->Flags != RTS_FLAG_OUT_CHANNEL)
  2844. goto AbortAndExit;
  2845. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2846. // verify destination
  2847. if (CurrentCommand->CommandType != tsctDestination)
  2848. goto AbortAndExit;
  2849. if (ExpectedDestination != CurrentCommand->u.Destination)
  2850. goto AbortAndExit;
  2851. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2852. // get version
  2853. if (CurrentCommand->CommandType != tsctVersion)
  2854. goto AbortAndExit;
  2855. *ProtocolVersion = CurrentCommand->u.Version;
  2856. CurrentCommand = SkipCommand(CurrentCommand, tsctVersion);
  2857. // get connection timeout
  2858. if (CurrentCommand->CommandType != tsctConnectionTimeout)
  2859. goto AbortAndExit;
  2860. *ConnectionTimeout = CurrentCommand->u.ConnectionTimeout;
  2861. CurrentCommand = SkipCommand(CurrentCommand, tsctConnectionTimeout);
  2862. RpcStatus = RPC_S_OK;
  2863. goto CleanupAndExit;
  2864. AbortAndExit:
  2865. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2866. CleanupAndExit:
  2867. RpcFreeBuffer(Packet);
  2868. return RpcStatus;
  2869. }
  2870. HTTP2SendContext *AllocateAndInitializeD4_A7 (
  2871. IN ForwardDestinations Destination,
  2872. IN HTTP2Cookie *NewChannelCookie
  2873. )
  2874. /*++
  2875. Routine Description:
  2876. Allocates and initializes a D4/A7 RTS packet
  2877. Arguments:
  2878. Destination - the destination for the packet.
  2879. NewChannelCookie - the new channel cookie
  2880. Return Value:
  2881. The allocated send context or NULL for out-of-memory
  2882. --*/
  2883. {
  2884. HTTP2SendContext *SendContext;
  2885. TunnelSettingsCommand *CurrentCommand;
  2886. rpcconn_tunnel_settings *RTS;
  2887. SendContext = AllocateAndInitializeRTSPacket(
  2888. BaseRTSCommandSize * 2
  2889. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2890. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2891. );
  2892. if (SendContext)
  2893. {
  2894. RTS = GetRTSPacketFromSendContext(SendContext);
  2895. RTS->Flags = RTS_FLAG_OUT_CHANNEL;
  2896. RTS->NumberOfSettingCommands = 2;
  2897. CurrentCommand = RTS->Cmd;
  2898. // set destination
  2899. CurrentCommand->CommandType = tsctDestination;
  2900. CurrentCommand->u.Destination = Destination;
  2901. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  2902. // set new channel cookie
  2903. CurrentCommand->CommandType = tsctCookie;
  2904. RpcpMemoryCopy(CurrentCommand->u.Cookie.Cookie, NewChannelCookie->GetCookie(), COOKIE_SIZE_IN_BYTES);
  2905. }
  2906. return SendContext;
  2907. }
  2908. RPC_STATUS ParseAndFreeD4_A8 (
  2909. IN BYTE *Packet,
  2910. IN ULONG PacketLength,
  2911. IN ForwardDestinations ExpectedDestination,
  2912. OUT HTTP2Cookie *NewChannelCookie
  2913. )
  2914. /*++
  2915. Routine Description:
  2916. Parses a D2/A5 RTS packet
  2917. Arguments:
  2918. Packet - the packet received.
  2919. PacketLength - the length of the packet
  2920. NewChannelCookie - the new channel cookie
  2921. Return Value:
  2922. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  2923. otherwise.
  2924. --*/
  2925. {
  2926. ULONG MemorySize;
  2927. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  2928. BYTE *CurrentPosition;
  2929. TunnelSettingsCommand *CurrentCommand;
  2930. RPC_STATUS RpcStatus;
  2931. MemorySize = BaseRTSSizeAndPadding
  2932. + BaseRTSCommandSize * 2
  2933. + SIZE_OF_RTS_CMD_AND_PADDING(tsctCookie)
  2934. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  2935. ;
  2936. if (PacketLength < MemorySize)
  2937. goto AbortAndExit;
  2938. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  2939. if (CurrentPosition == NULL)
  2940. goto AbortAndExit;
  2941. if (RTS->NumberOfSettingCommands != 2)
  2942. goto AbortAndExit;
  2943. if (RTS->Flags != RTS_FLAG_OUT_CHANNEL)
  2944. goto AbortAndExit;
  2945. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  2946. // verify destination
  2947. if (CurrentCommand->CommandType != tsctDestination)
  2948. goto AbortAndExit;
  2949. if (ExpectedDestination != CurrentCommand->u.Destination)
  2950. goto AbortAndExit;
  2951. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  2952. // get new channel cookie
  2953. if (CurrentCommand->CommandType != tsctCookie)
  2954. goto AbortAndExit;
  2955. NewChannelCookie->SetCookie((BYTE *)CurrentCommand->u.Cookie.Cookie);
  2956. RpcStatus = RPC_S_OK;
  2957. goto CleanupAndExit;
  2958. AbortAndExit:
  2959. RpcStatus = RPC_S_PROTOCOL_ERROR;
  2960. CleanupAndExit:
  2961. RpcFreeBuffer(Packet);
  2962. return RpcStatus;
  2963. }
  2964. HTTP2SendContext *AllocateAndInitializeD4_A9 (
  2965. void
  2966. )
  2967. /*++
  2968. Routine Description:
  2969. Allocates and initializes a D4/A9 RTS packet
  2970. Arguments:
  2971. Return Value:
  2972. The allocated send context or NULL for out-of-memory
  2973. --*/
  2974. {
  2975. HTTP2SendContext *SendContext;
  2976. TunnelSettingsCommand *CurrentCommand;
  2977. rpcconn_tunnel_settings *RTS;
  2978. SendContext = AllocateAndInitializeRTSPacket(
  2979. BaseRTSCommandSize * 1
  2980. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  2981. );
  2982. if (SendContext)
  2983. {
  2984. RTS = GetRTSPacketFromSendContext(SendContext);
  2985. RTS->Flags = 0;
  2986. RTS->NumberOfSettingCommands = 1;
  2987. CurrentCommand = RTS->Cmd;
  2988. // set ANCE command
  2989. CurrentCommand->CommandType = tsctANCE;
  2990. }
  2991. return SendContext;
  2992. }
  2993. RPC_STATUS ParseD4_A9 (
  2994. IN BYTE *Packet,
  2995. IN ULONG PacketLength
  2996. )
  2997. /*++
  2998. Routine Description:
  2999. Parses a D4/A10 RTS packet
  3000. Arguments:
  3001. Packet - the packet received.
  3002. PacketLength - the length of the packet
  3003. Return Value:
  3004. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3005. otherwise.
  3006. --*/
  3007. {
  3008. ULONG MemorySize;
  3009. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3010. BYTE *CurrentPosition;
  3011. TunnelSettingsCommand *CurrentCommand;
  3012. RPC_STATUS RpcStatus;
  3013. MemorySize = BaseRTSSizeAndPadding
  3014. + BaseRTSCommandSize * 1
  3015. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  3016. ;
  3017. if (PacketLength < MemorySize)
  3018. goto AbortAndExit;
  3019. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3020. if (CurrentPosition == NULL)
  3021. goto AbortAndExit;
  3022. if (RTS->NumberOfSettingCommands != 1)
  3023. goto AbortAndExit;
  3024. if (RTS->Flags != 0)
  3025. goto AbortAndExit;
  3026. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3027. // verify ANCE
  3028. if (CurrentCommand->CommandType != tsctANCE)
  3029. goto AbortAndExit;
  3030. RpcStatus = RPC_S_OK;
  3031. goto CleanupAndExit;
  3032. AbortAndExit:
  3033. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3034. CleanupAndExit:
  3035. return RpcStatus;
  3036. }
  3037. RPC_STATUS ParseAndFreeD4_A9 (
  3038. IN BYTE *Packet,
  3039. IN ULONG PacketLength
  3040. )
  3041. /*++
  3042. Routine Description:
  3043. Parses and frees a D4/A10 RTS packet
  3044. Arguments:
  3045. Packet - the packet received.
  3046. PacketLength - the length of the packet
  3047. Return Value:
  3048. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3049. otherwise.
  3050. --*/
  3051. {
  3052. RPC_STATUS RpcStatus;
  3053. RpcStatus = ParseD4_A10(Packet,
  3054. PacketLength
  3055. );
  3056. RpcFreeBuffer(Packet);
  3057. return RpcStatus;
  3058. }
  3059. HTTP2SendContext *AllocateAndInitializeD5_A5 (
  3060. IN ForwardDestinations Destination
  3061. )
  3062. /*++
  3063. Routine Description:
  3064. Allocates and initializes a D4/A9 RTS packet
  3065. Arguments:
  3066. Destination - destination for forwarding
  3067. Return Value:
  3068. The allocated send context or NULL for out-of-memory
  3069. --*/
  3070. {
  3071. HTTP2SendContext *SendContext;
  3072. TunnelSettingsCommand *CurrentCommand;
  3073. rpcconn_tunnel_settings *RTS;
  3074. SendContext = AllocateAndInitializeRTSPacket(
  3075. BaseRTSCommandSize * 2
  3076. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  3077. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  3078. );
  3079. if (SendContext)
  3080. {
  3081. RTS = GetRTSPacketFromSendContext(SendContext);
  3082. RTS->Flags = 0;
  3083. RTS->NumberOfSettingCommands = 2;
  3084. CurrentCommand = RTS->Cmd;
  3085. // set destination
  3086. CurrentCommand->CommandType = tsctDestination;
  3087. CurrentCommand->u.Destination = Destination;
  3088. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  3089. // set empty command
  3090. CurrentCommand->CommandType = tsctANCE;
  3091. }
  3092. return SendContext;
  3093. }
  3094. RPC_STATUS ParseD5_A6 (
  3095. IN BYTE *Packet,
  3096. IN ULONG PacketLength,
  3097. IN ForwardDestinations ExpectedDestination
  3098. )
  3099. /*++
  3100. Routine Description:
  3101. Parses a D5/A6 RTS packet
  3102. Arguments:
  3103. Packet - the packet received.
  3104. PacketLength - the length of the packet
  3105. ExpectedDestination - the destination code for the target location (client)
  3106. Return Value:
  3107. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3108. otherwise.
  3109. --*/
  3110. {
  3111. ULONG MemorySize;
  3112. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3113. BYTE *CurrentPosition;
  3114. TunnelSettingsCommand *CurrentCommand;
  3115. RPC_STATUS RpcStatus;
  3116. MemorySize = BaseRTSSizeAndPadding
  3117. + BaseRTSCommandSize * 2
  3118. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  3119. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  3120. ;
  3121. if (PacketLength < MemorySize)
  3122. goto AbortAndExit;
  3123. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3124. if (CurrentPosition == NULL)
  3125. goto AbortAndExit;
  3126. if (RTS->NumberOfSettingCommands != 2)
  3127. goto AbortAndExit;
  3128. if (RTS->Flags != 0)
  3129. goto AbortAndExit;
  3130. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3131. // verify destination
  3132. if (CurrentCommand->CommandType != tsctDestination)
  3133. goto AbortAndExit;
  3134. if (ExpectedDestination != CurrentCommand->u.Destination)
  3135. goto AbortAndExit;
  3136. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  3137. // verify ANCE
  3138. if (CurrentCommand->CommandType != tsctANCE)
  3139. goto AbortAndExit;
  3140. RpcStatus = RPC_S_OK;
  3141. goto CleanupAndExit;
  3142. AbortAndExit:
  3143. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3144. CleanupAndExit:
  3145. return RpcStatus;
  3146. }
  3147. RPC_STATUS ParseAndFreeD5_A6 (
  3148. IN BYTE *Packet,
  3149. IN ULONG PacketLength,
  3150. IN ForwardDestinations ExpectedDestination
  3151. )
  3152. /*++
  3153. Routine Description:
  3154. Parses and frees a D5/A5 RTS packet
  3155. Arguments:
  3156. Packet - the packet received.
  3157. PacketLength - the length of the packet
  3158. ExpectedDestination - the destination code for this location (client)
  3159. Return Value:
  3160. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3161. otherwise.
  3162. --*/
  3163. {
  3164. RPC_STATUS RpcStatus;
  3165. RpcStatus = ParseD5_A6(Packet,
  3166. PacketLength,
  3167. ExpectedDestination
  3168. );
  3169. RpcFreeBuffer(Packet);
  3170. return RpcStatus;
  3171. }
  3172. HTTP2SendContext *AllocateAndInitializeD5_B1orB2 (
  3173. IN BOOL IsAckOrNak
  3174. )
  3175. /*++
  3176. Routine Description:
  3177. Allocates and initializes a D5/B1 or D5/B2 RTS packet
  3178. Arguments:
  3179. IsAckOrNack - non-zero if this is an ACK and D5/B1 needs
  3180. to go out. If 0, this is a NACK and D5/B2 will go out.
  3181. Return Value:
  3182. The allocated send context or NULL for out-of-memory
  3183. --*/
  3184. {
  3185. HTTP2SendContext *SendContext;
  3186. TunnelSettingsCommand *CurrentCommand;
  3187. rpcconn_tunnel_settings *RTS;
  3188. ASSERT(SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE) == SIZE_OF_RTS_CMD_AND_PADDING(tsctNANCE));
  3189. SendContext = AllocateAndInitializeRTSPacket(
  3190. BaseRTSCommandSize * 1
  3191. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  3192. );
  3193. if (SendContext)
  3194. {
  3195. RTS = GetRTSPacketFromSendContext(SendContext);
  3196. RTS->Flags = 0;
  3197. RTS->NumberOfSettingCommands = 1;
  3198. CurrentCommand = RTS->Cmd;
  3199. // set ANCE or NANCE command
  3200. if (IsAckOrNak)
  3201. CurrentCommand->CommandType = tsctANCE;
  3202. else
  3203. CurrentCommand->CommandType = tsctNANCE;
  3204. }
  3205. return SendContext;
  3206. }
  3207. RPC_STATUS ParseAndFreeD5_B1orB2 (
  3208. IN BYTE *Packet,
  3209. IN ULONG PacketLength,
  3210. OUT BOOL *IsAckOrNak
  3211. )
  3212. /*++
  3213. Routine Description:
  3214. Parses and frees a D5/B1 or D2/B2 RTS packet
  3215. Arguments:
  3216. Packet - the packet received.
  3217. PacketLength - the length of the packet
  3218. IsAckOrNak - if success, on output it will contain
  3219. non-zero if the packet was ACK (ANCE or D5/B1)
  3220. or zero if the packet was NACK (NANCE or D5/B2)
  3221. Return Value:
  3222. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3223. otherwise.
  3224. --*/
  3225. {
  3226. ULONG MemorySize;
  3227. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3228. BYTE *CurrentPosition;
  3229. TunnelSettingsCommand *CurrentCommand;
  3230. RPC_STATUS RpcStatus;
  3231. MemorySize = BaseRTSSizeAndPadding
  3232. + BaseRTSCommandSize * 1
  3233. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  3234. ;
  3235. if (PacketLength < MemorySize)
  3236. goto AbortAndExit;
  3237. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3238. if (CurrentPosition == NULL)
  3239. goto AbortAndExit;
  3240. if (RTS->NumberOfSettingCommands != 1)
  3241. goto AbortAndExit;
  3242. if (RTS->Flags != 0)
  3243. goto AbortAndExit;
  3244. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3245. // verify ANCE
  3246. if (CurrentCommand->CommandType == tsctANCE)
  3247. *IsAckOrNak = TRUE;
  3248. else if (CurrentCommand->CommandType == tsctNANCE)
  3249. *IsAckOrNak = FALSE;
  3250. else
  3251. goto AbortAndExit;
  3252. RpcStatus = RPC_S_OK;
  3253. goto CleanupAndExit;
  3254. AbortAndExit:
  3255. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3256. CleanupAndExit:
  3257. RpcFreeBuffer(Packet);
  3258. return RpcStatus;
  3259. }
  3260. RPC_STATUS ParseAndFreeD5_B3 (
  3261. IN BYTE *Packet,
  3262. IN ULONG PacketLength
  3263. )
  3264. /*++
  3265. Routine Description:
  3266. Parses and frees a D5/B3 RTS packet
  3267. Arguments:
  3268. Packet - the packet received.
  3269. PacketLength - the length of the packet
  3270. Return Value:
  3271. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3272. otherwise.
  3273. --*/
  3274. {
  3275. ULONG MemorySize;
  3276. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3277. BYTE *CurrentPosition;
  3278. TunnelSettingsCommand *CurrentCommand;
  3279. RPC_STATUS RpcStatus;
  3280. MemorySize = BaseRTSSizeAndPadding
  3281. + BaseRTSCommandSize * 1
  3282. + SIZE_OF_RTS_CMD_AND_PADDING(tsctANCE)
  3283. ;
  3284. if (PacketLength < MemorySize)
  3285. goto AbortAndExit;
  3286. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3287. if (CurrentPosition == NULL)
  3288. goto AbortAndExit;
  3289. if (RTS->NumberOfSettingCommands != 1)
  3290. goto AbortAndExit;
  3291. if (RTS->Flags != RTS_FLAG_EOF)
  3292. goto AbortAndExit;
  3293. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3294. // verify ANCE
  3295. if (CurrentCommand->CommandType != tsctANCE)
  3296. goto AbortAndExit;
  3297. RpcStatus = RPC_S_OK;
  3298. goto CleanupAndExit;
  3299. AbortAndExit:
  3300. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3301. CleanupAndExit:
  3302. RpcFreeBuffer(Packet);
  3303. return RpcStatus;
  3304. }
  3305. HTTP2SendContext *AllocateAndInitializeKeepAliveChangePacket (
  3306. IN ULONG NewKeepAliveInterval
  3307. )
  3308. /*++
  3309. Routine Description:
  3310. Allocates and initializes a keep alive change packet.
  3311. Arguments:
  3312. NewKeepAliveInterval - the new keep alive interval in
  3313. milliseconds
  3314. Return Value:
  3315. The allocated send context or NULL for out-of-memory
  3316. --*/
  3317. {
  3318. HTTP2SendContext *SendContext;
  3319. TunnelSettingsCommand *CurrentCommand;
  3320. rpcconn_tunnel_settings *RTS;
  3321. SendContext = AllocateAndInitializeRTSPacket(
  3322. BaseRTSCommandSize * 1
  3323. + SIZE_OF_RTS_CMD_AND_PADDING(tsctClientKeepalive)
  3324. );
  3325. if (SendContext)
  3326. {
  3327. RTS = GetRTSPacketFromSendContext(SendContext);
  3328. RTS->Flags = RTS_FLAG_OTHER_CMD;
  3329. RTS->NumberOfSettingCommands = 1;
  3330. CurrentCommand = RTS->Cmd;
  3331. // set destination
  3332. CurrentCommand->CommandType = tsctClientKeepalive;
  3333. CurrentCommand->u.ClientKeepalive = NewKeepAliveInterval;
  3334. }
  3335. return SendContext;
  3336. }
  3337. RPC_STATUS ParseAndFreeKeepAliveChangePacket (
  3338. IN BYTE *Packet,
  3339. IN ULONG PacketLength,
  3340. OUT ULONG *NewKeepAliveInterval
  3341. )
  3342. /*++
  3343. Routine Description:
  3344. Parses and frees a keep alive change packet
  3345. Arguments:
  3346. Packet - the packet received.
  3347. PacketLength - the length of the packet
  3348. NewKeepAliveInterval - the new keep alive interval
  3349. Return Value:
  3350. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3351. otherwise.
  3352. --*/
  3353. {
  3354. ULONG MemorySize;
  3355. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3356. BYTE *CurrentPosition;
  3357. TunnelSettingsCommand *CurrentCommand;
  3358. RPC_STATUS RpcStatus;
  3359. MemorySize = BaseRTSSizeAndPadding
  3360. + BaseRTSCommandSize * 1
  3361. + SIZE_OF_RTS_CMD_AND_PADDING(tsctClientKeepalive)
  3362. ;
  3363. if (PacketLength < MemorySize)
  3364. goto AbortAndExit;
  3365. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3366. if (CurrentPosition == NULL)
  3367. goto AbortAndExit;
  3368. if (RTS->NumberOfSettingCommands != 1)
  3369. goto AbortAndExit;
  3370. if (RTS->Flags != RTS_FLAG_OTHER_CMD)
  3371. goto AbortAndExit;
  3372. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3373. // get new client keep alive
  3374. if (CurrentCommand->CommandType != tsctClientKeepalive)
  3375. goto AbortAndExit;
  3376. *NewKeepAliveInterval = CurrentCommand->u.ClientKeepalive;
  3377. if ((*NewKeepAliveInterval < MinimumClientNewKeepAliveInterval)
  3378. && (*NewKeepAliveInterval != 0))
  3379. goto AbortAndExit;
  3380. RpcStatus = RPC_S_OK;
  3381. goto CleanupAndExit;
  3382. AbortAndExit:
  3383. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3384. CleanupAndExit:
  3385. RpcFreeBuffer(Packet);
  3386. return RpcStatus;
  3387. }
  3388. HTTP2SendContext *AllocateAndInitializeFlowControlAckPacket (
  3389. IN ULONG BytesReceivedForAck,
  3390. IN ULONG WindowForAck,
  3391. IN HTTP2Cookie *CookieForChannel
  3392. )
  3393. /*++
  3394. Routine Description:
  3395. Allocates and initializes a flow control ack packet
  3396. Arguments:
  3397. BytesReceivedForAck - the bytes received at the time the
  3398. ack was issued.
  3399. WindowForAck - the available window at the time the ack was
  3400. issued.
  3401. CookieForChannel - the cookie of the channel we ack to.
  3402. Return Value:
  3403. The allocated send context or NULL for out-of-memory
  3404. --*/
  3405. {
  3406. HTTP2SendContext *SendContext;
  3407. TunnelSettingsCommand *CurrentCommand;
  3408. rpcconn_tunnel_settings *RTS;
  3409. SendContext = AllocateAndInitializeRTSPacket(
  3410. BaseRTSCommandSize * 1
  3411. + SIZE_OF_RTS_CMD_AND_PADDING(tsctFlowControlAck)
  3412. );
  3413. if (SendContext)
  3414. {
  3415. RTS = GetRTSPacketFromSendContext(SendContext);
  3416. RTS->Flags = RTS_FLAG_OTHER_CMD;
  3417. RTS->NumberOfSettingCommands = 1;
  3418. CurrentCommand = RTS->Cmd;
  3419. // set ack command
  3420. CurrentCommand->CommandType = tsctFlowControlAck;
  3421. CurrentCommand->u.Ack.BytesReceived = BytesReceivedForAck;
  3422. CurrentCommand->u.Ack.AvailableWindow = WindowForAck;
  3423. RpcpMemoryCopy(CurrentCommand->u.Ack.ChannelCookie.Cookie, CookieForChannel->GetCookie(), COOKIE_SIZE_IN_BYTES);
  3424. }
  3425. return SendContext;
  3426. }
  3427. HTTP2SendContext *AllocateAndInitializeFlowControlAckPacketWithDestination (
  3428. IN ForwardDestinations Destination,
  3429. IN ULONG BytesReceivedForAck,
  3430. IN ULONG WindowForAck,
  3431. IN HTTP2Cookie *CookieForChannel
  3432. )
  3433. /*++
  3434. Routine Description:
  3435. Allocates and initializes a flow control ack packet with a forward
  3436. destination
  3437. Arguments:
  3438. Destination - the destination to which to forward the packet
  3439. BytesReceivedForAck - the bytes received at the time the
  3440. ack was issued.
  3441. WindowForAck - the available window at the time the ack was
  3442. issued.
  3443. CookieForChannel - the cookie of the channel we ack to.
  3444. Return Value:
  3445. The allocated send context or NULL for out-of-memory
  3446. --*/
  3447. {
  3448. HTTP2SendContext *SendContext;
  3449. TunnelSettingsCommand *CurrentCommand;
  3450. rpcconn_tunnel_settings *RTS;
  3451. SendContext = AllocateAndInitializeRTSPacket(
  3452. BaseRTSCommandSize * 2
  3453. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  3454. + SIZE_OF_RTS_CMD_AND_PADDING(tsctFlowControlAck)
  3455. );
  3456. if (SendContext)
  3457. {
  3458. RTS = GetRTSPacketFromSendContext(SendContext);
  3459. RTS->Flags = RTS_FLAG_OTHER_CMD;
  3460. RTS->NumberOfSettingCommands = 2;
  3461. CurrentCommand = RTS->Cmd;
  3462. // set destination
  3463. CurrentCommand->CommandType = tsctDestination;
  3464. CurrentCommand->u.Destination = Destination;
  3465. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  3466. // set ack command
  3467. CurrentCommand->CommandType = tsctFlowControlAck;
  3468. CurrentCommand->u.Ack.BytesReceived = BytesReceivedForAck;
  3469. CurrentCommand->u.Ack.AvailableWindow = WindowForAck;
  3470. RpcpMemoryCopy(CurrentCommand->u.Ack.ChannelCookie.Cookie, CookieForChannel->GetCookie(), COOKIE_SIZE_IN_BYTES);
  3471. }
  3472. return SendContext;
  3473. }
  3474. RPC_STATUS ParseAndFreeFlowControlAckPacket (
  3475. IN BYTE *Packet,
  3476. IN ULONG PacketLength,
  3477. OUT ULONG *BytesReceivedForAck,
  3478. OUT ULONG *WindowForAck,
  3479. OUT HTTP2Cookie *CookieForChannel
  3480. )
  3481. /*++
  3482. Routine Description:
  3483. Parses and frees a flow control ack packet
  3484. Arguments:
  3485. Packet - the packet received.
  3486. PacketLength - the length of the packet
  3487. BytesReceivedForAck - the bytes received at the time the
  3488. ack was issued.
  3489. WindowForAck - the available window at the time the ack was
  3490. issued.
  3491. CookieForChannel - the cookie of the channel we received ack for.
  3492. Return Value:
  3493. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3494. otherwise.
  3495. --*/
  3496. {
  3497. ULONG MemorySize;
  3498. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3499. BYTE *CurrentPosition;
  3500. TunnelSettingsCommand *CurrentCommand;
  3501. RPC_STATUS RpcStatus;
  3502. MemorySize = BaseRTSSizeAndPadding
  3503. + BaseRTSCommandSize * 1
  3504. + SIZE_OF_RTS_CMD_AND_PADDING(tsctFlowControlAck)
  3505. ;
  3506. if (PacketLength < MemorySize)
  3507. goto AbortAndExit;
  3508. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3509. if (CurrentPosition == NULL)
  3510. goto AbortAndExit;
  3511. if (RTS->NumberOfSettingCommands != 1)
  3512. goto AbortAndExit;
  3513. if (RTS->Flags != RTS_FLAG_OTHER_CMD)
  3514. goto AbortAndExit;
  3515. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3516. // get ack values
  3517. if (CurrentCommand->CommandType != tsctFlowControlAck)
  3518. goto AbortAndExit;
  3519. *BytesReceivedForAck = CurrentCommand->u.Ack.BytesReceived;
  3520. *WindowForAck = CurrentCommand->u.Ack.AvailableWindow;
  3521. CookieForChannel->SetCookie((BYTE *)CurrentCommand->u.Ack.ChannelCookie.Cookie);
  3522. RpcStatus = RPC_S_OK;
  3523. goto CleanupAndExit;
  3524. AbortAndExit:
  3525. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3526. CleanupAndExit:
  3527. RpcFreeBuffer(Packet);
  3528. return RpcStatus;
  3529. }
  3530. RPC_STATUS ParseAndFreeFlowControlAckPacketWithDestination (
  3531. IN BYTE *Packet,
  3532. IN ULONG PacketLength,
  3533. IN ForwardDestinations ExpectedDestination,
  3534. OUT ULONG *BytesReceivedForAck,
  3535. OUT ULONG *WindowForAck,
  3536. OUT HTTP2Cookie *CookieForChannel
  3537. )
  3538. /*++
  3539. Routine Description:
  3540. Parses and frees a flow control ack packet
  3541. Arguments:
  3542. Packet - the packet received.
  3543. PacketLength - the length of the packet
  3544. Destination - the expected destination
  3545. BytesReceivedForAck - the bytes received at the time the
  3546. ack was issued.
  3547. WindowForAck - the available window at the time the ack was
  3548. issued.
  3549. CookieForChannel - the cookie of the channel we received ack for.
  3550. Return Value:
  3551. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3552. otherwise.
  3553. --*/
  3554. {
  3555. RPC_STATUS RpcStatus;
  3556. RpcStatus = ParseFlowControlAckPacketWithDestination (
  3557. Packet,
  3558. PacketLength,
  3559. ExpectedDestination,
  3560. BytesReceivedForAck,
  3561. WindowForAck,
  3562. CookieForChannel
  3563. );
  3564. RpcFreeBuffer(Packet);
  3565. return RpcStatus;
  3566. }
  3567. RPC_STATUS ParseFlowControlAckPacketWithDestination (
  3568. IN BYTE *Packet,
  3569. IN ULONG PacketLength,
  3570. IN ForwardDestinations ExpectedDestination,
  3571. OUT ULONG *BytesReceivedForAck,
  3572. OUT ULONG *WindowForAck,
  3573. OUT HTTP2Cookie *CookieForChannel
  3574. )
  3575. /*++
  3576. Routine Description:
  3577. Parses a flow control ack packet
  3578. Arguments:
  3579. Packet - the packet received.
  3580. PacketLength - the length of the packet
  3581. Destination - the expected destination
  3582. BytesReceivedForAck - the bytes received at the time the
  3583. ack was issued.
  3584. WindowForAck - the available window at the time the ack was
  3585. issued.
  3586. CookieForChannel - the cookie of the channel we received ack for.
  3587. Return Value:
  3588. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3589. otherwise.
  3590. --*/
  3591. {
  3592. ULONG MemorySize;
  3593. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3594. BYTE *CurrentPosition;
  3595. TunnelSettingsCommand *CurrentCommand;
  3596. RPC_STATUS RpcStatus;
  3597. MemorySize = BaseRTSSizeAndPadding
  3598. + BaseRTSCommandSize * 2
  3599. + SIZE_OF_RTS_CMD_AND_PADDING(tsctDestination)
  3600. + SIZE_OF_RTS_CMD_AND_PADDING(tsctFlowControlAck)
  3601. ;
  3602. if (PacketLength < MemorySize)
  3603. goto AbortAndExit;
  3604. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3605. if (CurrentPosition == NULL)
  3606. goto AbortAndExit;
  3607. if (RTS->NumberOfSettingCommands != 2)
  3608. goto AbortAndExit;
  3609. if (RTS->Flags != RTS_FLAG_OTHER_CMD)
  3610. goto AbortAndExit;
  3611. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3612. // verify destination
  3613. if (CurrentCommand->CommandType != tsctDestination)
  3614. goto AbortAndExit;
  3615. if (ExpectedDestination != CurrentCommand->u.Destination)
  3616. goto AbortAndExit;
  3617. CurrentCommand = SkipCommand(CurrentCommand, tsctDestination);
  3618. // get ack values
  3619. if (CurrentCommand->CommandType != tsctFlowControlAck)
  3620. goto AbortAndExit;
  3621. *BytesReceivedForAck = CurrentCommand->u.Ack.BytesReceived;
  3622. *WindowForAck = CurrentCommand->u.Ack.AvailableWindow;
  3623. CookieForChannel->SetCookie((BYTE *)CurrentCommand->u.Ack.ChannelCookie.Cookie);
  3624. RpcStatus = RPC_S_OK;
  3625. goto CleanupAndExit;
  3626. AbortAndExit:
  3627. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3628. CleanupAndExit:
  3629. return RpcStatus;
  3630. }
  3631. HTTP2SendContext *AllocateAndInitializePingTrafficSentNotifyPacket (
  3632. IN ULONG PingTrafficSentBytes
  3633. )
  3634. /*++
  3635. Routine Description:
  3636. Allocates and initializes a ping traffic sent packet
  3637. Arguments:
  3638. PingTrafficSentBytes - the number of bytes sent in ping traffic
  3639. Return Value:
  3640. The allocated send context or NULL for out-of-memory
  3641. --*/
  3642. {
  3643. HTTP2SendContext *SendContext;
  3644. TunnelSettingsCommand *CurrentCommand;
  3645. rpcconn_tunnel_settings *RTS;
  3646. SendContext = AllocateAndInitializeRTSPacket(
  3647. BaseRTSCommandSize * 1
  3648. + SIZE_OF_RTS_CMD_AND_PADDING(tsctPingTrafficSentNotify)
  3649. );
  3650. if (SendContext)
  3651. {
  3652. RTS = GetRTSPacketFromSendContext(SendContext);
  3653. RTS->Flags = RTS_FLAG_OTHER_CMD;
  3654. RTS->NumberOfSettingCommands = 1;
  3655. CurrentCommand = RTS->Cmd;
  3656. // set ping traffic sent
  3657. CurrentCommand->CommandType = tsctPingTrafficSentNotify;
  3658. CurrentCommand->u.PingTrafficSent = PingTrafficSentBytes;
  3659. }
  3660. return SendContext;
  3661. }
  3662. RPC_STATUS ParseAndFreePingTrafficSentNotifyPacket (
  3663. IN BYTE *Packet,
  3664. IN ULONG PacketLength,
  3665. OUT ULONG *PingTrafficSentBytes
  3666. )
  3667. /*++
  3668. Routine Description:
  3669. Parses a ping traffic sent packet
  3670. Arguments:
  3671. Packet - the packet received.
  3672. PacketLength - the length of the packet
  3673. PingTrafficSentBytes - the number of bytes sent in ping traffic
  3674. Return Value:
  3675. RPC_S_OK if the packet was successfully parsed and RPC_S_PROTOCOL_ERROR
  3676. otherwise.
  3677. --*/
  3678. {
  3679. ULONG MemorySize;
  3680. rpcconn_tunnel_settings *RTS = (rpcconn_tunnel_settings *)Packet;
  3681. BYTE *CurrentPosition;
  3682. TunnelSettingsCommand *CurrentCommand;
  3683. RPC_STATUS RpcStatus;
  3684. MemorySize = BaseRTSSizeAndPadding
  3685. + BaseRTSCommandSize * 1
  3686. + SIZE_OF_RTS_CMD_AND_PADDING(tsctPingTrafficSentNotify)
  3687. ;
  3688. if (PacketLength < MemorySize)
  3689. goto AbortAndExit;
  3690. CurrentPosition = ValidateRTSPacketCommon(Packet, PacketLength);
  3691. if (CurrentPosition == NULL)
  3692. goto AbortAndExit;
  3693. if (RTS->NumberOfSettingCommands != 1)
  3694. goto AbortAndExit;
  3695. if (RTS->Flags != RTS_FLAG_OTHER_CMD)
  3696. goto AbortAndExit;
  3697. CurrentCommand = (TunnelSettingsCommand *)CurrentPosition;
  3698. // get ping traffic sent values
  3699. if (CurrentCommand->CommandType != tsctPingTrafficSentNotify)
  3700. goto AbortAndExit;
  3701. *PingTrafficSentBytes = CurrentCommand->u.PingTrafficSent;
  3702. RpcStatus = RPC_S_OK;
  3703. goto CleanupAndExit;
  3704. AbortAndExit:
  3705. RpcStatus = RPC_S_PROTOCOL_ERROR;
  3706. CleanupAndExit:
  3707. RpcFreeBuffer(Packet);
  3708. return RpcStatus;
  3709. }