• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/quic/quic_test_packet_printer.h"
6 #include "base/memory/raw_ptr.h"
7 
8 #include <ostream>
9 
10 #include "base/strings/string_number_conversions.h"
11 #include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
12 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
13 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_flags.h"
14 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
15 
16 namespace quic {
17 
18 class QuicPacketPrinter : public QuicFramerVisitorInterface {
19  public:
QuicPacketPrinter(QuicFramer * framer,std::ostream * output)20   explicit QuicPacketPrinter(QuicFramer* framer, std::ostream* output)
21       : framer_(framer), output_(output) {}
22 
23   // QuicFramerVisitorInterface implementation.
OnError(QuicFramer * framer)24   void OnError(QuicFramer* framer) override {
25     *output_ << "OnError: " << QuicErrorCodeToString(framer->error())
26              << " detail: " << framer->detailed_error() << "\n";
27   }
OnProtocolVersionMismatch(ParsedQuicVersion received_version)28   bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
29     framer_->set_version(received_version);
30     *output_ << "OnProtocolVersionMismatch: "
31              << ParsedQuicVersionToString(received_version) << "\n";
32     return true;
33   }
OnPacket()34   void OnPacket() override { *output_ << "OnPacket\n"; }
OnVersionNegotiationPacket(const QuicVersionNegotiationPacket & packet)35   void OnVersionNegotiationPacket(
36       const QuicVersionNegotiationPacket& packet) override {
37     *output_ << "OnVersionNegotiationPacket\n";
38   }
OnRetryPacket(QuicConnectionId original_connection_id,QuicConnectionId new_connection_id,std::string_view retry_token,std::string_view retry_integrity_tag,std::string_view retry_without_tag)39   void OnRetryPacket(QuicConnectionId original_connection_id,
40                      QuicConnectionId new_connection_id,
41                      std::string_view retry_token,
42                      std::string_view retry_integrity_tag,
43                      std::string_view retry_without_tag) override {
44     *output_ << "OnRetryPacket\n";
45   }
OnUnauthenticatedPublicHeader(const QuicPacketHeader & header)46   bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
47     *output_ << "OnUnauthenticatedPublicHeader: " << header << "\n";
48     return true;
49   }
OnUnauthenticatedHeader(const QuicPacketHeader & header)50   bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
51     *output_ << "OnUnauthenticatedHeader: " << header;
52     return true;
53   }
OnDecryptedPacket(size_t length,EncryptionLevel level)54   void OnDecryptedPacket(size_t length, EncryptionLevel level) override {
55     *output_ << "OnDecryptedPacket\n";
56   }
OnPacketHeader(const QuicPacketHeader & header)57   bool OnPacketHeader(const QuicPacketHeader& header) override {
58     *output_ << "OnPacketHeader\n";
59     return true;
60   }
OnCoalescedPacket(const QuicEncryptedPacket & packet)61   void OnCoalescedPacket(const QuicEncryptedPacket& packet) override {
62     *output_ << "OnCoalescedPacket\n";
63   }
OnUndecryptablePacket(const QuicEncryptedPacket & packet,EncryptionLevel decryption_level,bool has_decryption_key)64   void OnUndecryptablePacket(const QuicEncryptedPacket& packet,
65                              EncryptionLevel decryption_level,
66                              bool has_decryption_key) override {
67     *output_ << "OnUndecryptablePacket, decryption_level: " << decryption_level
68              << "\n";
69   }
OnStreamFrame(const QuicStreamFrame & frame)70   bool OnStreamFrame(const QuicStreamFrame& frame) override {
71     *output_ << "OnStreamFrame: " << frame;
72     *output_ << "         data: { "
73              << base::HexEncode(frame.data_buffer, frame.data_length) << " }\n";
74     return true;
75   }
OnCryptoFrame(const QuicCryptoFrame & frame)76   bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
77     *output_ << "OnCryptoFrame: " << frame;
78     *output_ << "         data: { "
79              << base::HexEncode(frame.data_buffer, frame.data_length) << " }\n";
80     return true;
81   }
OnAckFrameStart(QuicPacketNumber largest_acked,QuicTime::Delta)82   bool OnAckFrameStart(QuicPacketNumber largest_acked,
83                        QuicTime::Delta /*ack_delay_time*/) override {
84     *output_ << "OnAckFrameStart, largest_acked: " << largest_acked << "\n";
85     return true;
86   }
OnAckRange(QuicPacketNumber start,QuicPacketNumber end)87   bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
88     *output_ << "OnAckRange: [" << start << ", " << end << ")\n";
89     return true;
90   }
OnAckTimestamp(QuicPacketNumber packet_number,QuicTime timestamp)91   bool OnAckTimestamp(QuicPacketNumber packet_number,
92                       QuicTime timestamp) override {
93     *output_ << "OnAckTimestamp: [" << packet_number << ", "
94              << timestamp.ToDebuggingValue() << ")\n";
95     return true;
96   }
OnAckFrameEnd(QuicPacketNumber start,const absl::optional<QuicEcnCounts> & ecn_counts)97   bool OnAckFrameEnd(QuicPacketNumber start,
98                      const absl::optional<QuicEcnCounts>& ecn_counts) override {
99     *output_ << "OnAckFrameEnd, start: " << start << ", "
100              << ecn_counts.value_or(QuicEcnCounts()).ToString() << "\n";
101     return true;
102   }
OnStopWaitingFrame(const QuicStopWaitingFrame & frame)103   bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
104     *output_ << "OnStopWaitingFrame: " << frame;
105     return true;
106   }
OnPaddingFrame(const QuicPaddingFrame & frame)107   bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
108     *output_ << "OnPaddingFrame: " << frame;
109     return true;
110   }
OnPingFrame(const QuicPingFrame & frame)111   bool OnPingFrame(const QuicPingFrame& frame) override {
112     *output_ << "OnPingFrame\n";
113     return true;
114   }
OnRstStreamFrame(const QuicRstStreamFrame & frame)115   bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
116     *output_ << "OnRstStreamFrame: " << frame;
117     return true;
118   }
OnConnectionCloseFrame(const QuicConnectionCloseFrame & frame)119   bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
120     // The frame printout will indicate whether it's a Google QUIC
121     // CONNECTION_CLOSE, IETF QUIC CONNECTION_CLOSE/Transport, or IETF QUIC
122     // CONNECTION_CLOSE/Application frame.
123     *output_ << "OnConnectionCloseFrame: " << frame;
124     return true;
125   }
OnNewConnectionIdFrame(const QuicNewConnectionIdFrame & frame)126   bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
127     *output_ << "OnNewConnectionIdFrame: " << frame;
128     return true;
129   }
OnRetireConnectionIdFrame(const QuicRetireConnectionIdFrame & frame)130   bool OnRetireConnectionIdFrame(
131       const QuicRetireConnectionIdFrame& frame) override {
132     *output_ << "OnRetireConnectionIdFrame: " << frame;
133     return true;
134   }
OnNewTokenFrame(const QuicNewTokenFrame & frame)135   bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
136     *output_ << "OnNewTokenFrame: " << frame;
137     return true;
138   }
OnStopSendingFrame(const QuicStopSendingFrame & frame)139   bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
140     *output_ << "OnStopSendingFrame: " << frame;
141     return true;
142   }
OnPathChallengeFrame(const QuicPathChallengeFrame & frame)143   bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
144     *output_ << "OnPathChallengeFrame: " << frame;
145     return true;
146   }
OnPathResponseFrame(const QuicPathResponseFrame & frame)147   bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
148     *output_ << "OnPathResponseFrame: " << frame;
149     return true;
150   }
OnGoAwayFrame(const QuicGoAwayFrame & frame)151   bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
152     *output_ << "OnGoAwayFrame: " << frame;
153     return true;
154   }
OnMaxStreamsFrame(const QuicMaxStreamsFrame & frame)155   bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
156     *output_ << "OnMaxStreamsFrame: " << frame;
157     return true;
158   }
OnStreamsBlockedFrame(const QuicStreamsBlockedFrame & frame)159   bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
160     *output_ << "OnStreamsBlockedFrame: " << frame;
161     return true;
162   }
OnKeyUpdate(KeyUpdateReason reason)163   void OnKeyUpdate(KeyUpdateReason reason) override {
164     *output_ << "OnKeyUpdate: " << reason << "\n";
165   }
OnDecryptedFirstPacketInKeyPhase()166   void OnDecryptedFirstPacketInKeyPhase() override {
167     *output_ << "OnDecryptedFirstPacketInKeyPhase\n";
168   }
AdvanceKeysAndCreateCurrentOneRttDecrypter()169   std::unique_ptr<QuicDecrypter> AdvanceKeysAndCreateCurrentOneRttDecrypter()
170       override {
171     *output_ << "AdvanceKeysAndCreateCurrentOneRttDecrypter\n";
172     return nullptr;
173   }
CreateCurrentOneRttEncrypter()174   std::unique_ptr<QuicEncrypter> CreateCurrentOneRttEncrypter() override {
175     *output_ << "CreateCurrentOneRttEncrypter\n";
176     return nullptr;
177   }
OnWindowUpdateFrame(const QuicWindowUpdateFrame & frame)178   bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
179     *output_ << "OnWindowUpdateFrame: " << frame;
180     return true;
181   }
OnBlockedFrame(const QuicBlockedFrame & frame)182   bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
183     *output_ << "OnBlockedFrame: " << frame;
184     return true;
185   }
OnMessageFrame(const QuicMessageFrame & frame)186   bool OnMessageFrame(const QuicMessageFrame& frame) override {
187     *output_ << "OnMessageFrame: " << frame;
188     return true;
189   }
OnHandshakeDoneFrame(const QuicHandshakeDoneFrame & frame)190   bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
191     *output_ << "OnHandshakeDoneFrame: " << frame;
192     return true;
193   }
OnAckFrequencyFrame(const QuicAckFrequencyFrame & frame)194   bool OnAckFrequencyFrame(const QuicAckFrequencyFrame& frame) override {
195     *output_ << "OnAckFrequencyFrame: " << frame;
196     return true;
197   }
OnPacketComplete()198   void OnPacketComplete() override { *output_ << "OnPacketComplete\n"; }
IsValidStatelessResetToken(const StatelessResetToken & token) const199   bool IsValidStatelessResetToken(
200       const StatelessResetToken& token) const override {
201     *output_ << "IsValidStatelessResetToken\n";
202     return false;
203   }
OnAuthenticatedIetfStatelessResetPacket(const QuicIetfStatelessResetPacket & packet)204   void OnAuthenticatedIetfStatelessResetPacket(
205       const QuicIetfStatelessResetPacket& packet) override {
206     *output_ << "OnAuthenticatedIetfStatelessResetPacket\n";
207   }
208 
209  private:
210   raw_ptr<QuicFramer> framer_;  // Unowned.
211   mutable raw_ptr<std::ostream> output_;
212 };
213 
214 }  // namespace quic
215 
216 namespace net {
217 
PrintWrite(const std::string & data)218 std::string QuicPacketPrinter::PrintWrite(const std::string& data) {
219   quic::ParsedQuicVersionVector versions = {version_};
220   // Fake a time since we're not actually generating acks.
221   quic::QuicTime start(quic::QuicTime::Zero());
222   // Construct a server framer as this will be processing packets from
223   // the client.
224   quic::QuicFramer framer(versions, start, quic::Perspective::IS_SERVER,
225                           quic::kQuicDefaultConnectionIdLength);
226   std::ostringstream stream;
227   quic::QuicPacketPrinter visitor(&framer, &stream);
228   framer.set_visitor(&visitor);
229 
230   if (version_.KnowsWhichDecrypterToUse()) {
231     framer.InstallDecrypter(
232         quic::ENCRYPTION_FORWARD_SECURE,
233         std::make_unique<quic::test::TaggingDecrypter>());  // IN-TEST
234   } else {
235     framer.SetDecrypter(
236         quic::ENCRYPTION_FORWARD_SECURE,
237         std::make_unique<quic::test::TaggingDecrypter>());  // IN-TEST
238   }
239 
240   quic::QuicEncryptedPacket encrypted(data.c_str(), data.length());
241   framer.ProcessPacket(encrypted);
242   return stream.str() + "\n\n";
243 }
244 
245 }  // namespace net
246