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