xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/tools/devious_baton.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2023 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef QUICHE_QUIC_TOOLS_DEVIOUS_BATON_H_
6 #define QUICHE_QUIC_TOOLS_DEVIOUS_BATON_H_
7 
8 #include "quiche/common/quiche_callbacks.h"
9 #include "quiche/common/quiche_circular_deque.h"
10 #include "quiche/web_transport/web_transport.h"
11 
12 namespace quic {
13 
14 // https://www.ietf.org/id/draft-frindell-webtrans-devious-baton-00.html#name-session-error-codes
15 inline constexpr webtransport::SessionErrorCode kDeviousBatonErrorDaYamn =
16     0x01;  // Insufficient flow control credit
17 inline constexpr webtransport::SessionErrorCode kDeviousBatonErrorBruh =
18     0x02;  // Parse error
19 inline constexpr webtransport::SessionErrorCode kDeviousBatonErrorSus =
20     0x03;  // Unexpected message
21 inline constexpr webtransport::SessionErrorCode kDeviousBatonErrorBored =
22     0x04;  // Timeout
23 
24 using DeviousBatonValue = uint8_t;
25 
26 // Implementation of the Devious Baton protocol as described in
27 // https://www.ietf.org/id/draft-frindell-webtrans-devious-baton-00.html
28 class DeviousBatonSessionVisitor : public webtransport::SessionVisitor {
29  public:
DeviousBatonSessionVisitor(webtransport::Session * session,bool is_server,int initial_value,int count)30   DeviousBatonSessionVisitor(webtransport::Session* session, bool is_server,
31                              int initial_value, int count)
32       : session_(session),
33         is_server_(is_server),
34         initial_value_(initial_value),
35         count_(count) {}
36 
37   void OnSessionReady() override;
38   void OnSessionClosed(webtransport::SessionErrorCode error_code,
39                        const std::string& error_message) override;
40   void OnIncomingBidirectionalStreamAvailable() override;
41   void OnIncomingUnidirectionalStreamAvailable() override;
42   void OnDatagramReceived(absl::string_view datagram) override;
43   void OnCanCreateNewOutgoingBidirectionalStream() override;
44   void OnCanCreateNewOutgoingUnidirectionalStream() override;
45 
46  private:
47   using SendFunction = void (DeviousBatonSessionVisitor::*)(DeviousBatonValue);
SendUnidirectionalBaton(DeviousBatonValue value)48   void SendUnidirectionalBaton(DeviousBatonValue value) {
49     outgoing_unidi_batons_.push_back(value);
50     OnCanCreateNewOutgoingUnidirectionalStream();
51   }
SendBidirectionalBaton(DeviousBatonValue value)52   void SendBidirectionalBaton(DeviousBatonValue value) {
53     outgoing_bidi_batons_.push_back(value);
54     OnCanCreateNewOutgoingBidirectionalStream();
55   }
56 
57   // Creates a callback that parses an incoming baton, parses it (while
58   // potentially handling parse errors), and then passes it into the
59   // `send_function`.
60   quiche::SingleUseCallback<void(std::string)> CreateResponseCallback(
61       SendFunction send_function);
62 
63   webtransport::Session* session_;
64   bool is_server_;
65   DeviousBatonValue initial_value_;
66   int count_;
67   quiche::QuicheCircularDeque<DeviousBatonValue> outgoing_unidi_batons_;
68   quiche::QuicheCircularDeque<DeviousBatonValue> outgoing_bidi_batons_;
69 };
70 
71 }  // namespace quic
72 
73 #endif  // QUICHE_QUIC_TOOLS_DEVIOUS_BATON_H_
74