1 // Copyright 2019 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 #include "net/quic/quic_test_packet_printer.h"
6 
7 #include <ostream>
8 
9 #include "net/third_party/quiche/src/common/platform/api/quiche_text_utils.h"
10 #include "net/third_party/quiche/src/quic/core/crypto/null_decrypter.h"
11 #include "net/third_party/quiche/src/quic/core/quic_framer.h"
12 #include "net/third_party/quiche/src/quic/core/quic_utils.h"
13 #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
14 
15 namespace quic {
16 
17 class QuicPacketPrinter : public QuicFramerVisitorInterface {
18  public:
QuicPacketPrinter(QuicFramer * framer,std::ostream * output)19   explicit QuicPacketPrinter(QuicFramer* framer, std::ostream* output)
20       : framer_(framer), output_(output) {}
21 
22   // QuicFramerVisitorInterface implementation.
OnError(QuicFramer * framer)23   void OnError(QuicFramer* framer) override {
24     *output_ << "OnError: " << QuicErrorCodeToString(framer->error())
25              << " detail: " << framer->detailed_error() << "\n";
26   }
OnProtocolVersionMismatch(ParsedQuicVersion received_version)27   bool OnProtocolVersionMismatch(ParsedQuicVersion received_version) override {
28     framer_->set_version(received_version);
29     *output_ << "OnProtocolVersionMismatch: "
30              << ParsedQuicVersionToString(received_version) << "\n";
31     return true;
32   }
OnPacket()33   void OnPacket() override { *output_ << "OnPacket\n"; }
OnPublicResetPacket(const QuicPublicResetPacket & packet)34   void OnPublicResetPacket(const QuicPublicResetPacket& packet) override {
35     *output_ << "OnPublicResetPacket\n";
36   }
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,quiche::QuicheStringPiece retry_token,quiche::QuicheStringPiece retry_integrity_tag,quiche::QuicheStringPiece retry_without_tag)41   void OnRetryPacket(QuicConnectionId original_connection_id,
42                      QuicConnectionId new_connection_id,
43                      quiche::QuicheStringPiece retry_token,
44                      quiche::QuicheStringPiece retry_integrity_tag,
45                      quiche::QuicheStringPiece retry_without_tag) override {
46     *output_ << "OnRetryPacket\n";
47   }
OnUnauthenticatedPublicHeader(const QuicPacketHeader & header)48   bool OnUnauthenticatedPublicHeader(const QuicPacketHeader& header) override {
49     *output_ << "OnUnauthenticatedPublicHeader: " << header << "\n";
50     return true;
51   }
OnUnauthenticatedHeader(const QuicPacketHeader & header)52   bool OnUnauthenticatedHeader(const QuicPacketHeader& header) override {
53     *output_ << "OnUnauthenticatedHeader: " << header;
54     return true;
55   }
OnDecryptedPacket(EncryptionLevel level)56   void OnDecryptedPacket(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              << quiche::QuicheTextUtils::HexEncode(frame.data_buffer,
76                                                    frame.data_length)
77              << " }\n";
78     return true;
79   }
OnCryptoFrame(const QuicCryptoFrame & frame)80   bool OnCryptoFrame(const QuicCryptoFrame& frame) override {
81     *output_ << "OnCryptoFrame: " << frame;
82     *output_ << "         data: { "
83              << quiche::QuicheTextUtils::HexEncode(frame.data_buffer,
84                                                    frame.data_length)
85              << " }\n";
86     return true;
87   }
OnAckFrameStart(QuicPacketNumber largest_acked,QuicTime::Delta)88   bool OnAckFrameStart(QuicPacketNumber largest_acked,
89                        QuicTime::Delta /*ack_delay_time*/) override {
90     *output_ << "OnAckFrameStart, largest_acked: " << largest_acked << "\n";
91     return true;
92   }
OnAckRange(QuicPacketNumber start,QuicPacketNumber end)93   bool OnAckRange(QuicPacketNumber start, QuicPacketNumber end) override {
94     *output_ << "OnAckRange: [" << start << ", " << end << ")\n";
95     return true;
96   }
OnAckTimestamp(QuicPacketNumber packet_number,QuicTime timestamp)97   bool OnAckTimestamp(QuicPacketNumber packet_number,
98                       QuicTime timestamp) override {
99     *output_ << "OnAckTimestamp: [" << packet_number << ", "
100              << timestamp.ToDebuggingValue() << ")\n";
101     return true;
102   }
OnAckFrameEnd(QuicPacketNumber start)103   bool OnAckFrameEnd(QuicPacketNumber start) override {
104     *output_ << "OnAckFrameEnd, start: " << start << "\n";
105     return true;
106   }
OnStopWaitingFrame(const QuicStopWaitingFrame & frame)107   bool OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override {
108     *output_ << "OnStopWaitingFrame: " << frame;
109     return true;
110   }
OnPaddingFrame(const QuicPaddingFrame & frame)111   bool OnPaddingFrame(const QuicPaddingFrame& frame) override {
112     *output_ << "OnPaddingFrame: " << frame;
113     return true;
114   }
OnPingFrame(const QuicPingFrame & frame)115   bool OnPingFrame(const QuicPingFrame& frame) override {
116     *output_ << "OnPingFrame\n";
117     return true;
118   }
OnRstStreamFrame(const QuicRstStreamFrame & frame)119   bool OnRstStreamFrame(const QuicRstStreamFrame& frame) override {
120     *output_ << "OnRstStreamFrame: " << frame;
121     return true;
122   }
OnConnectionCloseFrame(const QuicConnectionCloseFrame & frame)123   bool OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override {
124     // The frame printout will indicate whether it's a Google QUIC
125     // CONNECTION_CLOSE, IETF QUIC CONNECTION_CLOSE/Transport, or IETF QUIC
126     // CONNECTION_CLOSE/Application frame.
127     *output_ << "OnConnectionCloseFrame: " << frame;
128     return true;
129   }
OnNewConnectionIdFrame(const QuicNewConnectionIdFrame & frame)130   bool OnNewConnectionIdFrame(const QuicNewConnectionIdFrame& frame) override {
131     *output_ << "OnNewConnectionIdFrame: " << frame;
132     return true;
133   }
OnRetireConnectionIdFrame(const QuicRetireConnectionIdFrame & frame)134   bool OnRetireConnectionIdFrame(
135       const QuicRetireConnectionIdFrame& frame) override {
136     *output_ << "OnRetireConnectionIdFrame: " << frame;
137     return true;
138   }
OnNewTokenFrame(const QuicNewTokenFrame & frame)139   bool OnNewTokenFrame(const QuicNewTokenFrame& frame) override {
140     *output_ << "OnNewTokenFrame: " << frame;
141     return true;
142   }
OnStopSendingFrame(const QuicStopSendingFrame & frame)143   bool OnStopSendingFrame(const QuicStopSendingFrame& frame) override {
144     *output_ << "OnStopSendingFrame: " << frame;
145     return true;
146   }
OnPathChallengeFrame(const QuicPathChallengeFrame & frame)147   bool OnPathChallengeFrame(const QuicPathChallengeFrame& frame) override {
148     *output_ << "OnPathChallengeFrame: " << frame;
149     return true;
150   }
OnPathResponseFrame(const QuicPathResponseFrame & frame)151   bool OnPathResponseFrame(const QuicPathResponseFrame& frame) override {
152     *output_ << "OnPathResponseFrame: " << frame;
153     return true;
154   }
OnGoAwayFrame(const QuicGoAwayFrame & frame)155   bool OnGoAwayFrame(const QuicGoAwayFrame& frame) override {
156     *output_ << "OnGoAwayFrame: " << frame;
157     return true;
158   }
OnMaxStreamsFrame(const QuicMaxStreamsFrame & frame)159   bool OnMaxStreamsFrame(const QuicMaxStreamsFrame& frame) override {
160     *output_ << "OnMaxStreamsFrame: " << frame;
161     return true;
162   }
OnStreamsBlockedFrame(const QuicStreamsBlockedFrame & frame)163   bool OnStreamsBlockedFrame(const QuicStreamsBlockedFrame& frame) override {
164     *output_ << "OnStreamsBlockedFrame: " << frame;
165     return true;
166   }
OnWindowUpdateFrame(const QuicWindowUpdateFrame & frame)167   bool OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override {
168     *output_ << "OnWindowUpdateFrame: " << frame;
169     return true;
170   }
OnBlockedFrame(const QuicBlockedFrame & frame)171   bool OnBlockedFrame(const QuicBlockedFrame& frame) override {
172     *output_ << "OnBlockedFrame: " << frame;
173     return true;
174   }
OnMessageFrame(const QuicMessageFrame & frame)175   bool OnMessageFrame(const QuicMessageFrame& frame) override {
176     *output_ << "OnMessageFrame: " << frame;
177     return true;
178   }
OnHandshakeDoneFrame(const QuicHandshakeDoneFrame & frame)179   bool OnHandshakeDoneFrame(const QuicHandshakeDoneFrame& frame) override {
180     *output_ << "OnHandshakeDoneFrame: " << frame;
181     return true;
182   }
OnPacketComplete()183   void OnPacketComplete() override { *output_ << "OnPacketComplete\n"; }
IsValidStatelessResetToken(QuicUint128 token) const184   bool IsValidStatelessResetToken(QuicUint128 token) const override {
185     *output_ << "IsValidStatelessResetToken\n";
186     return false;
187   }
OnAuthenticatedIetfStatelessResetPacket(const QuicIetfStatelessResetPacket & packet)188   void OnAuthenticatedIetfStatelessResetPacket(
189       const QuicIetfStatelessResetPacket& packet) override {
190     *output_ << "OnAuthenticatedIetfStatelessResetPacket\n";
191   }
192 
193  private:
194   QuicFramer* framer_;  // Unowned.
195   mutable std::ostream* output_;
196 };
197 
198 }  // namespace quic
199 
200 namespace net {
201 
PrintWrite(const std::string & data)202 std::string QuicPacketPrinter::PrintWrite(const std::string& data) {
203   quic::ParsedQuicVersionVector versions = {version_};
204   // Fake a time since we're not actually generating acks.
205   quic::QuicTime start(quic::QuicTime::Zero());
206   // Construct a server framer as this will be processing packets from
207   // the client.
208   quic::QuicFramer framer(versions, start, quic::Perspective::IS_SERVER,
209                           quic::kQuicDefaultConnectionIdLength);
210   std::ostringstream stream;
211   quic::QuicPacketPrinter visitor(&framer, &stream);
212   framer.set_visitor(&visitor);
213 
214   if (version_.KnowsWhichDecrypterToUse()) {
215     framer.InstallDecrypter(
216         quic::ENCRYPTION_FORWARD_SECURE,
217         std::make_unique<quic::NullDecrypter>(quic::Perspective::IS_SERVER));
218   } else {
219     framer.SetDecrypter(
220         quic::ENCRYPTION_FORWARD_SECURE,
221         std::make_unique<quic::NullDecrypter>(quic::Perspective::IS_SERVER));
222   }
223 
224   quic::QuicEncryptedPacket encrypted(data.c_str(), data.length());
225   framer.ProcessPacket(encrypted);
226   return stream.str() + "\n\n";
227 }
228 
229 }  // namespace net
230