Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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