blob: 6152293340f7e7b01fe3a3bd0bedcec3262fef6f [file] [log] [blame]
[email protected]78b9fcd32013-02-20 17:10:241// Copyright (c) 2013 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_connection_logger.h"
6
7#include "base/bind.h"
8#include "base/callback.h"
[email protected]160f5e272013-07-02 20:26:269#include "base/metrics/histogram.h"
[email protected]5eddf042013-10-18 20:34:5410#include "base/metrics/sparse_histogram.h"
[email protected]fc9be5802013-06-11 10:56:5111#include "base/strings/string_number_conversions.h"
[email protected]78b9fcd32013-02-20 17:10:2412#include "base/values.h"
13#include "net/base/net_log.h"
[email protected]54f5f932013-08-14 19:47:2014#include "net/quic/crypto/crypto_handshake.h"
[email protected]78b9fcd32013-02-20 17:10:2415
[email protected]24e5bc52013-09-18 15:36:5816using std::string;
17
[email protected]78b9fcd32013-02-20 17:10:2418namespace net {
19
20namespace {
21
[email protected]ea5ef4c2013-06-13 22:50:2722base::Value* NetLogQuicPacketCallback(const IPEndPoint* self_address,
23 const IPEndPoint* peer_address,
24 size_t packet_size,
25 NetLog::LogLevel /* log_level */) {
26 base::DictionaryValue* dict = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:2427 dict->SetString("self_address", self_address->ToString());
28 dict->SetString("peer_address", peer_address->ToString());
29 dict->SetInteger("size", packet_size);
30 return dict;
31}
32
[email protected]e1c2acb2013-06-22 22:34:1333base::Value* NetLogQuicPacketSentCallback(
34 QuicPacketSequenceNumber sequence_number,
35 EncryptionLevel level,
36 size_t packet_size,
[email protected]752fbe52013-10-14 08:35:3237 WriteResult result,
[email protected]e1c2acb2013-06-22 22:34:1338 NetLog::LogLevel /* log_level */) {
39 base::DictionaryValue* dict = new base::DictionaryValue();
40 dict->SetInteger("encryption_level", level);
41 dict->SetString("packet_sequence_number",
42 base::Uint64ToString(sequence_number));
43 dict->SetInteger("size", packet_size);
[email protected]752fbe52013-10-14 08:35:3244 if (result.status != WRITE_STATUS_OK) {
45 dict->SetInteger("net_error", result.error_code);
[email protected]e1c2acb2013-06-22 22:34:1346 }
47 return dict;
48}
49
[email protected]63074912013-08-14 01:55:1250base::Value* NetLogQuicPacketRetransmittedCallback(
51 QuicPacketSequenceNumber old_sequence_number,
52 QuicPacketSequenceNumber new_sequence_number,
53 NetLog::LogLevel /* log_level */) {
54 base::DictionaryValue* dict = new base::DictionaryValue();
55 dict->SetString("old_packet_sequence_number",
56 base::Uint64ToString(old_sequence_number));
57 dict->SetString("new_packet_sequence_number",
58 base::Uint64ToString(new_sequence_number));
59 return dict;
60}
61
[email protected]ea5ef4c2013-06-13 22:50:2762base::Value* NetLogQuicPacketHeaderCallback(const QuicPacketHeader* header,
63 NetLog::LogLevel /* log_level */) {
64 base::DictionaryValue* dict = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:2465 dict->SetString("guid",
66 base::Uint64ToString(header->public_header.guid));
[email protected]9db443912013-02-25 05:27:0367 dict->SetInteger("reset_flag", header->public_header.reset_flag);
68 dict->SetInteger("version_flag", header->public_header.version_flag);
[email protected]78b9fcd32013-02-20 17:10:2469 dict->SetString("packet_sequence_number",
70 base::Uint64ToString(header->packet_sequence_number));
[email protected]9db443912013-02-25 05:27:0371 dict->SetInteger("entropy_flag", header->entropy_flag);
72 dict->SetInteger("fec_flag", header->fec_flag);
[email protected]78b9fcd32013-02-20 17:10:2473 dict->SetInteger("fec_group", header->fec_group);
74 return dict;
75}
76
[email protected]ea5ef4c2013-06-13 22:50:2777base::Value* NetLogQuicStreamFrameCallback(const QuicStreamFrame* frame,
78 NetLog::LogLevel /* log_level */) {
79 base::DictionaryValue* dict = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:2480 dict->SetInteger("stream_id", frame->stream_id);
81 dict->SetBoolean("fin", frame->fin);
82 dict->SetString("offset", base::Uint64ToString(frame->offset));
83 dict->SetInteger("length", frame->data.length());
84 return dict;
85}
86
[email protected]ea5ef4c2013-06-13 22:50:2787base::Value* NetLogQuicAckFrameCallback(const QuicAckFrame* frame,
88 NetLog::LogLevel /* log_level */) {
89 base::DictionaryValue* dict = new base::DictionaryValue();
90 base::DictionaryValue* sent_info = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:2491 dict->Set("sent_info", sent_info);
92 sent_info->SetString("least_unacked",
93 base::Uint64ToString(frame->sent_info.least_unacked));
[email protected]ea5ef4c2013-06-13 22:50:2794 base::DictionaryValue* received_info = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:2495 dict->Set("received_info", received_info);
96 received_info->SetString(
97 "largest_observed",
98 base::Uint64ToString(frame->received_info.largest_observed));
[email protected]ea5ef4c2013-06-13 22:50:2799 base::ListValue* missing = new base::ListValue();
[email protected]78b9fcd32013-02-20 17:10:24100 received_info->Set("missing_packets", missing);
[email protected]9db443912013-02-25 05:27:03101 const SequenceNumberSet& missing_packets =
102 frame->received_info.missing_packets;
103 for (SequenceNumberSet::const_iterator it = missing_packets.begin();
[email protected]78b9fcd32013-02-20 17:10:24104 it != missing_packets.end(); ++it) {
[email protected]63074912013-08-14 01:55:12105 missing->AppendString(base::Uint64ToString(*it));
[email protected]78b9fcd32013-02-20 17:10:24106 }
107 return dict;
108}
109
[email protected]ea5ef4c2013-06-13 22:50:27110base::Value* NetLogQuicCongestionFeedbackFrameCallback(
[email protected]78b9fcd32013-02-20 17:10:24111 const QuicCongestionFeedbackFrame* frame,
112 NetLog::LogLevel /* log_level */) {
[email protected]ea5ef4c2013-06-13 22:50:27113 base::DictionaryValue* dict = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:24114 switch (frame->type) {
115 case kInterArrival: {
116 dict->SetString("type", "InterArrival");
117 dict->SetInteger("accumulated_number_of_lost_packets",
118 frame->inter_arrival.accumulated_number_of_lost_packets);
[email protected]ea5ef4c2013-06-13 22:50:27119 base::ListValue* received = new base::ListValue();
[email protected]78b9fcd32013-02-20 17:10:24120 dict->Set("received_packets", received);
121 for (TimeMap::const_iterator it =
122 frame->inter_arrival.received_packet_times.begin();
123 it != frame->inter_arrival.received_packet_times.end(); ++it) {
124 std::string value = base::Uint64ToString(it->first) + "@" +
[email protected]74bda142013-03-31 02:49:11125 base::Uint64ToString(it->second.ToDebuggingValue());
[email protected]63074912013-08-14 01:55:12126 received->AppendString(value);
[email protected]78b9fcd32013-02-20 17:10:24127 }
128 break;
129 }
130 case kFixRate:
131 dict->SetString("type", "FixRate");
132 dict->SetInteger("bitrate_in_bytes_per_second",
133 frame->fix_rate.bitrate.ToBytesPerSecond());
134 break;
135 case kTCP:
136 dict->SetString("type", "TCP");
137 dict->SetInteger("accumulated_number_of_lost_packets",
138 frame->tcp.accumulated_number_of_lost_packets);
139 dict->SetInteger("receive_window", frame->tcp.receive_window);
140 break;
141 }
142
143 return dict;
144}
145
[email protected]ea5ef4c2013-06-13 22:50:27146base::Value* NetLogQuicRstStreamFrameCallback(
147 const QuicRstStreamFrame* frame,
148 NetLog::LogLevel /* log_level */) {
149 base::DictionaryValue* dict = new base::DictionaryValue();
[email protected]78b9fcd32013-02-20 17:10:24150 dict->SetInteger("stream_id", frame->stream_id);
[email protected]d6846d12013-06-21 09:52:03151 dict->SetInteger("quic_rst_stream_error", frame->error_code);
[email protected]78b9fcd32013-02-20 17:10:24152 dict->SetString("details", frame->error_details);
153 return dict;
154}
155
[email protected]ea5ef4c2013-06-13 22:50:27156base::Value* NetLogQuicConnectionCloseFrameCallback(
[email protected]78b9fcd32013-02-20 17:10:24157 const QuicConnectionCloseFrame* frame,
158 NetLog::LogLevel /* log_level */) {
[email protected]ea5ef4c2013-06-13 22:50:27159 base::DictionaryValue* dict = new base::DictionaryValue();
[email protected]d6846d12013-06-21 09:52:03160 dict->SetInteger("quic_error", frame->error_code);
[email protected]78b9fcd32013-02-20 17:10:24161 dict->SetString("details", frame->error_details);
162 return dict;
163}
164
[email protected]63074912013-08-14 01:55:12165base::Value* NetLogQuicVersionNegotiationPacketCallback(
166 const QuicVersionNegotiationPacket* packet,
167 NetLog::LogLevel /* log_level */) {
168 base::DictionaryValue* dict = new base::DictionaryValue();
169 base::ListValue* versions = new base::ListValue();
170 dict->Set("versions", versions);
171 for (QuicVersionVector::const_iterator it = packet->versions.begin();
172 it != packet->versions.end(); ++it) {
173 versions->AppendString(QuicVersionToString(*it));
174 }
175 return dict;
176}
177
[email protected]54f5f932013-08-14 19:47:20178base::Value* NetLogQuicCryptoHandshakeMessageCallback(
179 const CryptoHandshakeMessage* message,
180 NetLog::LogLevel /* log_level */) {
181 base::DictionaryValue* dict = new base::DictionaryValue();
182 dict->SetString("quic_crypto_handshake_message", message->DebugString());
183 return dict;
184}
185
[email protected]2042aa12013-08-15 01:36:30186base::Value* NetLogQuicConnectionClosedCallback(
187 QuicErrorCode error,
188 bool from_peer,
189 NetLog::LogLevel /* log_level */) {
190 base::DictionaryValue* dict = new base::DictionaryValue();
191 dict->SetInteger("quic_error", error);
192 dict->SetBoolean("from_peer", from_peer);
193 return dict;
194}
195
[email protected]160f5e272013-07-02 20:26:26196void UpdatePacketGapSentHistogram(size_t num_consecutive_missing_packets) {
197 UMA_HISTOGRAM_COUNTS("Net.QuicSession.PacketGapSent",
198 num_consecutive_missing_packets);
199}
200
[email protected]78b9fcd32013-02-20 17:10:24201} // namespace
202
203QuicConnectionLogger::QuicConnectionLogger(const BoundNetLog& net_log)
[email protected]160f5e272013-07-02 20:26:26204 : net_log_(net_log),
205 last_received_packet_sequence_number_(0),
206 largest_received_packet_sequence_number_(0),
207 largest_received_missing_packet_sequence_number_(0),
208 out_of_order_recieved_packet_count_(0) {
[email protected]78b9fcd32013-02-20 17:10:24209}
210
211QuicConnectionLogger::~QuicConnectionLogger() {
[email protected]160f5e272013-07-02 20:26:26212 UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderPacketsReceived",
213 out_of_order_recieved_packet_count_);
[email protected]78b9fcd32013-02-20 17:10:24214}
215
[email protected]e1c2acb2013-06-22 22:34:13216void QuicConnectionLogger::OnFrameAddedToPacket(const QuicFrame& frame) {
217 switch (frame.type) {
218 case PADDING_FRAME:
219 break;
220 case STREAM_FRAME:
221 net_log_.AddEvent(
222 NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_SENT,
223 base::Bind(&NetLogQuicStreamFrameCallback, frame.stream_frame));
224 break;
225 case ACK_FRAME:
226 net_log_.AddEvent(
227 NetLog::TYPE_QUIC_SESSION_ACK_FRAME_SENT,
228 base::Bind(&NetLogQuicAckFrameCallback, frame.ack_frame));
229 break;
230 case CONGESTION_FEEDBACK_FRAME:
231 net_log_.AddEvent(
232 NetLog::TYPE_QUIC_SESSION_CONGESTION_FEEDBACK_FRAME_SENT,
233 base::Bind(&NetLogQuicCongestionFeedbackFrameCallback,
234 frame.congestion_feedback_frame));
235 break;
236 case RST_STREAM_FRAME:
[email protected]5eddf042013-10-18 20:34:54237 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeClient",
238 frame.rst_stream_frame->error_code);
[email protected]e1c2acb2013-06-22 22:34:13239 net_log_.AddEvent(
240 NetLog::TYPE_QUIC_SESSION_RST_STREAM_FRAME_SENT,
241 base::Bind(&NetLogQuicRstStreamFrameCallback,
242 frame.rst_stream_frame));
243 break;
244 case CONNECTION_CLOSE_FRAME:
245 net_log_.AddEvent(
246 NetLog::TYPE_QUIC_SESSION_CONNECTION_CLOSE_FRAME_SENT,
247 base::Bind(&NetLogQuicConnectionCloseFrameCallback,
248 frame.connection_close_frame));
249 break;
250 case GOAWAY_FRAME:
251 break;
252 default:
253 DCHECK(false) << "Illegal frame type: " << frame.type;
254 }
255}
256
257void QuicConnectionLogger::OnPacketSent(
258 QuicPacketSequenceNumber sequence_number,
259 EncryptionLevel level,
260 const QuicEncryptedPacket& packet,
[email protected]752fbe52013-10-14 08:35:32261 WriteResult result) {
[email protected]e1c2acb2013-06-22 22:34:13262 net_log_.AddEvent(
263 NetLog::TYPE_QUIC_SESSION_PACKET_SENT,
264 base::Bind(&NetLogQuicPacketSentCallback, sequence_number, level,
[email protected]752fbe52013-10-14 08:35:32265 packet.length(), result));
[email protected]e1c2acb2013-06-22 22:34:13266}
267
[email protected]63074912013-08-14 01:55:12268void QuicConnectionLogger:: OnPacketRetransmitted(
269 QuicPacketSequenceNumber old_sequence_number,
270 QuicPacketSequenceNumber new_sequence_number) {
271 net_log_.AddEvent(
272 NetLog::TYPE_QUIC_SESSION_PACKET_RETRANSMITTED,
273 base::Bind(&NetLogQuicPacketRetransmittedCallback,
274 old_sequence_number, new_sequence_number));
275}
276
[email protected]78b9fcd32013-02-20 17:10:24277void QuicConnectionLogger::OnPacketReceived(const IPEndPoint& self_address,
278 const IPEndPoint& peer_address,
279 const QuicEncryptedPacket& packet) {
280 net_log_.AddEvent(
281 NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
282 base::Bind(&NetLogQuicPacketCallback, &self_address, &peer_address,
283 packet.length()));
284}
285
[email protected]48878092013-07-26 14:51:56286void QuicConnectionLogger::OnProtocolVersionMismatch(
287 QuicVersion received_version) {
[email protected]14e8106c2013-03-14 16:25:33288 // TODO(rtenneti): Add logging.
289}
290
[email protected]78b9fcd32013-02-20 17:10:24291void QuicConnectionLogger::OnPacketHeader(const QuicPacketHeader& header) {
292 net_log_.AddEvent(
293 NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
294 base::Bind(&NetLogQuicPacketHeaderCallback, &header));
[email protected]160f5e272013-07-02 20:26:26295 if (largest_received_packet_sequence_number_ <
296 header.packet_sequence_number) {
297 QuicPacketSequenceNumber delta = header.packet_sequence_number -
298 largest_received_packet_sequence_number_;
299 if (delta > 1) {
300 // There is a gap between the largest packet previously received and
301 // the current packet. This indicates either loss, or out-of-order
302 // delivery.
303 UMA_HISTOGRAM_COUNTS("Net.QuicSession.PacketGapReceived", delta - 1);
304 }
305 largest_received_packet_sequence_number_ = header.packet_sequence_number;
306 }
307 if (header.packet_sequence_number < last_received_packet_sequence_number_) {
308 ++out_of_order_recieved_packet_count_;
[email protected]e068e222013-09-08 23:34:00309 UMA_HISTOGRAM_COUNTS("Net.QuicSession.OutOfOrderGapReceived",
310 last_received_packet_sequence_number_ -
311 header.packet_sequence_number);
[email protected]160f5e272013-07-02 20:26:26312 }
313 last_received_packet_sequence_number_ = header.packet_sequence_number;
[email protected]78b9fcd32013-02-20 17:10:24314}
315
316void QuicConnectionLogger::OnStreamFrame(const QuicStreamFrame& frame) {
317 net_log_.AddEvent(
318 NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
319 base::Bind(&NetLogQuicStreamFrameCallback, &frame));
320}
321
322void QuicConnectionLogger::OnAckFrame(const QuicAckFrame& frame) {
323 net_log_.AddEvent(
324 NetLog::TYPE_QUIC_SESSION_ACK_FRAME_RECEIVED,
325 base::Bind(&NetLogQuicAckFrameCallback, &frame));
[email protected]160f5e272013-07-02 20:26:26326
327 if (frame.received_info.missing_packets.empty())
328 return;
329
330 SequenceNumberSet missing_packets = frame.received_info.missing_packets;
331 SequenceNumberSet::const_iterator it = missing_packets.lower_bound(
332 largest_received_missing_packet_sequence_number_);
333 if (it == missing_packets.end())
334 return;
335
336 if (*it == largest_received_missing_packet_sequence_number_) {
337 ++it;
[email protected]4b06e7d2013-07-03 01:33:09338 if (it == missing_packets.end())
339 return;
[email protected]160f5e272013-07-02 20:26:26340 }
341 // Scan through the list and log consecutive ranges of missing packets.
342 size_t num_consecutive_missing_packets = 0;
343 QuicPacketSequenceNumber previous_missing_packet = *it - 1;
344 while (it != missing_packets.end()) {
345 if (previous_missing_packet == *it - 1) {
346 ++num_consecutive_missing_packets;
347 } else {
348 DCHECK_NE(0u, num_consecutive_missing_packets);
349 UpdatePacketGapSentHistogram(num_consecutive_missing_packets);
350 // Make sure this packet it included in the count.
351 num_consecutive_missing_packets = 1;
352 }
353 previous_missing_packet = *it;
354 ++it;
355 }
356 if (num_consecutive_missing_packets != 0) {
357 UpdatePacketGapSentHistogram(num_consecutive_missing_packets);
358 }
359 largest_received_missing_packet_sequence_number_ =
360 *missing_packets.rbegin();
[email protected]78b9fcd32013-02-20 17:10:24361}
362
363void QuicConnectionLogger::OnCongestionFeedbackFrame(
364 const QuicCongestionFeedbackFrame& frame) {
365 net_log_.AddEvent(
366 NetLog::TYPE_QUIC_SESSION_CONGESTION_FEEDBACK_FRAME_RECEIVED,
367 base::Bind(&NetLogQuicCongestionFeedbackFrameCallback, &frame));
368}
369
370void QuicConnectionLogger::OnRstStreamFrame(const QuicRstStreamFrame& frame) {
[email protected]5eddf042013-10-18 20:34:54371 UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicSession.RstStreamErrorCodeServer",
372 frame.error_code);
[email protected]78b9fcd32013-02-20 17:10:24373 net_log_.AddEvent(
374 NetLog::TYPE_QUIC_SESSION_RST_STREAM_FRAME_RECEIVED,
375 base::Bind(&NetLogQuicRstStreamFrameCallback, &frame));
376}
377
378void QuicConnectionLogger::OnConnectionCloseFrame(
379 const QuicConnectionCloseFrame& frame) {
380 net_log_.AddEvent(
381 NetLog::TYPE_QUIC_SESSION_CONNECTION_CLOSE_FRAME_RECEIVED,
382 base::Bind(&NetLogQuicConnectionCloseFrameCallback, &frame));
383}
384
385void QuicConnectionLogger::OnPublicResetPacket(
386 const QuicPublicResetPacket& packet) {
[email protected]63074912013-08-14 01:55:12387 net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_PUBLIC_RESET_PACKET_RECEIVED);
[email protected]78b9fcd32013-02-20 17:10:24388}
389
[email protected]14e8106c2013-03-14 16:25:33390void QuicConnectionLogger::OnVersionNegotiationPacket(
391 const QuicVersionNegotiationPacket& packet) {
[email protected]63074912013-08-14 01:55:12392 net_log_.AddEvent(
393 NetLog::TYPE_QUIC_SESSION_VERSION_NEGOTIATION_PACKET_RECEIVED,
394 base::Bind(&NetLogQuicVersionNegotiationPacketCallback, &packet));
[email protected]14e8106c2013-03-14 16:25:33395}
396
[email protected]78b9fcd32013-02-20 17:10:24397void QuicConnectionLogger::OnRevivedPacket(
398 const QuicPacketHeader& revived_header,
399 base::StringPiece payload) {
[email protected]63074912013-08-14 01:55:12400 net_log_.AddEvent(
401 NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_REVIVED,
402 base::Bind(&NetLogQuicPacketHeaderCallback, &revived_header));
[email protected]78b9fcd32013-02-20 17:10:24403}
404
[email protected]54f5f932013-08-14 19:47:20405void QuicConnectionLogger::OnCryptoHandshakeMessageReceived(
406 const CryptoHandshakeMessage& message) {
407 net_log_.AddEvent(
408 NetLog::TYPE_QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_RECEIVED,
409 base::Bind(&NetLogQuicCryptoHandshakeMessageCallback, &message));
410}
411
412void QuicConnectionLogger::OnCryptoHandshakeMessageSent(
413 const CryptoHandshakeMessage& message) {
414 net_log_.AddEvent(
415 NetLog::TYPE_QUIC_SESSION_CRYPTO_HANDSHAKE_MESSAGE_SENT,
416 base::Bind(&NetLogQuicCryptoHandshakeMessageCallback, &message));
417}
418
[email protected]2042aa12013-08-15 01:36:30419void QuicConnectionLogger::OnConnectionClose(QuicErrorCode error,
420 bool from_peer) {
421 net_log_.AddEvent(
422 NetLog::TYPE_QUIC_SESSION_CLOSED,
423 base::Bind(&NetLogQuicConnectionClosedCallback, error, from_peer));
424}
425
[email protected]24e5bc52013-09-18 15:36:58426void QuicConnectionLogger::OnSuccessfulVersionNegotiation(
427 const QuicVersion& version) {
428 string quic_version = QuicVersionToString(version);
429 net_log_.AddEvent(NetLog::TYPE_QUIC_SESSION_VERSION_NEGOTIATED,
430 NetLog::StringCallback("version", &quic_version));
431}
432
[email protected]78b9fcd32013-02-20 17:10:24433} // namespace net