1 // Copyright 2013 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_connection_logger.h"
6
7 #include <algorithm>
8 #include <limits>
9 #include <memory>
10 #include <utility>
11 #include <vector>
12
13 #include "base/metrics/histogram_base.h"
14 #include "base/metrics/histogram_functions.h"
15 #include "base/metrics/histogram_macros.h"
16 #include "base/values.h"
17 #include "net/base/ip_address.h"
18 #include "net/cert/x509_certificate.h"
19 #include "net/quic/address_utils.h"
20 #include "net/quic/quic_address_mismatch.h"
21 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake_message.h"
22 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_protocol.h"
23 #include "net/third_party/quiche/src/quiche/quic/core/quic_connection_id.h"
24 #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
25 #include "net/third_party/quiche/src/quiche/quic/core/quic_socket_address_coder.h"
26 #include "net/third_party/quiche/src/quiche/quic/core/quic_time.h"
27 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
28
29 using quic::kMaxOutgoingPacketSize;
30 using std::string;
31
32 namespace net {
33
34 namespace {
35
36 // If |address| is an IPv4-mapped IPv6 address, returns ADDRESS_FAMILY_IPV4
37 // instead of ADDRESS_FAMILY_IPV6. Othewise, behaves like GetAddressFamily().
GetRealAddressFamily(const IPAddress & address)38 AddressFamily GetRealAddressFamily(const IPAddress& address) {
39 return address.IsIPv4MappedIPv6() ? ADDRESS_FAMILY_IPV4
40 : GetAddressFamily(address);
41 }
42
43 } // namespace
44
QuicConnectionLogger(quic::QuicSession * session,const char * const connection_description,std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,const NetLogWithSource & net_log)45 QuicConnectionLogger::QuicConnectionLogger(
46 quic::QuicSession* session,
47 const char* const connection_description,
48 std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher,
49 const NetLogWithSource& net_log)
50 : session_(session),
51 connection_description_(connection_description),
52 socket_performance_watcher_(std::move(socket_performance_watcher)),
53 event_logger_(session, net_log) {}
54
~QuicConnectionLogger()55 QuicConnectionLogger::~QuicConnectionLogger() {
56 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.OutOfOrderPacketsReceived",
57 num_out_of_order_received_packets_);
58 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.OutOfOrderLargePacketsReceived",
59 num_out_of_order_large_received_packets_);
60 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.IncorrectConnectionIDsReceived",
61 num_incorrect_connection_ids_);
62 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.UndecryptablePacketsReceived",
63 num_undecryptable_packets_);
64 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.DuplicatePacketsReceived",
65 num_duplicate_packets_);
66 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.BlockedFrames.Received",
67 num_blocked_frames_received_);
68 UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.BlockedFrames.Sent",
69 num_blocked_frames_sent_);
70
71 const quic::QuicConnectionStats& stats = session_->connection()->GetStats();
72 UMA_HISTOGRAM_TIMES("Net.QuicSession.MinRTT",
73 base::Microseconds(stats.min_rtt_us));
74 UMA_HISTOGRAM_TIMES("Net.QuicSession.SmoothedRTT",
75 base::Microseconds(stats.srtt_us));
76
77 if (num_frames_received_ > 0) {
78 int duplicate_stream_frame_per_thousand =
79 num_duplicate_frames_received_ * 1000 / num_frames_received_;
80 if (num_packets_received_ < 100) {
81 UMA_HISTOGRAM_CUSTOM_COUNTS(
82 "Net.QuicSession.StreamFrameDuplicatedShortConnection",
83 duplicate_stream_frame_per_thousand, 1, 1000, 75);
84 } else {
85 UMA_HISTOGRAM_CUSTOM_COUNTS(
86 "Net.QuicSession.StreamFrameDuplicatedLongConnection",
87 duplicate_stream_frame_per_thousand, 1, 1000, 75);
88 }
89 }
90
91 RecordAggregatePacketLossRate();
92 }
93
OnFrameAddedToPacket(const quic::QuicFrame & frame)94 void QuicConnectionLogger::OnFrameAddedToPacket(const quic::QuicFrame& frame) {
95 switch (frame.type) {
96 case quic::PADDING_FRAME:
97 break;
98 case quic::STREAM_FRAME:
99 break;
100 case quic::ACK_FRAME: {
101 break;
102 }
103 case quic::RST_STREAM_FRAME:
104 base::UmaHistogramSparse("Net.QuicSession.RstStreamErrorCodeClient",
105 frame.rst_stream_frame->error_code);
106 break;
107 case quic::CONNECTION_CLOSE_FRAME:
108 break;
109 case quic::GOAWAY_FRAME:
110 break;
111 case quic::WINDOW_UPDATE_FRAME:
112 break;
113 case quic::BLOCKED_FRAME:
114 ++num_blocked_frames_sent_;
115 break;
116 case quic::STOP_WAITING_FRAME:
117 break;
118 case quic::PING_FRAME:
119 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.ConnectionFlowControlBlocked",
120 session_->IsConnectionFlowControlBlocked());
121 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.StreamFlowControlBlocked",
122 session_->IsStreamFlowControlBlocked());
123 break;
124 case quic::MTU_DISCOVERY_FRAME:
125 break;
126 case quic::NEW_CONNECTION_ID_FRAME:
127 break;
128 case quic::MAX_STREAMS_FRAME:
129 break;
130 case quic::STREAMS_BLOCKED_FRAME:
131 break;
132 case quic::PATH_RESPONSE_FRAME:
133 break;
134 case quic::PATH_CHALLENGE_FRAME:
135 break;
136 case quic::STOP_SENDING_FRAME:
137 base::UmaHistogramSparse("Net.QuicSession.StopSendingErrorCodeClient",
138 frame.stop_sending_frame.error_code);
139 break;
140 case quic::MESSAGE_FRAME:
141 break;
142 case quic::CRYPTO_FRAME:
143 break;
144 case quic::NEW_TOKEN_FRAME:
145 break;
146 case quic::RETIRE_CONNECTION_ID_FRAME:
147 break;
148 default:
149 DCHECK(false) << "Illegal frame type: " << frame.type;
150 }
151 event_logger_.OnFrameAddedToPacket(frame);
152 }
153
OnStreamFrameCoalesced(const quic::QuicStreamFrame & frame)154 void QuicConnectionLogger::OnStreamFrameCoalesced(
155 const quic::QuicStreamFrame& frame) {
156 event_logger_.OnStreamFrameCoalesced(frame);
157 }
158
OnPacketSent(quic::QuicPacketNumber packet_number,quic::QuicPacketLength packet_length,bool has_crypto_handshake,quic::TransmissionType transmission_type,quic::EncryptionLevel encryption_level,const quic::QuicFrames & retransmittable_frames,const quic::QuicFrames & nonretransmittable_frames,quic::QuicTime sent_time,uint32_t batch_id)159 void QuicConnectionLogger::OnPacketSent(
160 quic::QuicPacketNumber packet_number,
161 quic::QuicPacketLength packet_length,
162 bool has_crypto_handshake,
163 quic::TransmissionType transmission_type,
164 quic::EncryptionLevel encryption_level,
165 const quic::QuicFrames& retransmittable_frames,
166 const quic::QuicFrames& nonretransmittable_frames,
167 quic::QuicTime sent_time,
168 uint32_t batch_id) {
169 // 4.4.1.4. Minimum Packet Size
170 // The payload of a UDP datagram carrying the Initial packet MUST be
171 // expanded to at least 1200 octets
172 const quic::QuicPacketLength kMinClientInitialPacketLength = 1200;
173 switch (encryption_level) {
174 case quic::ENCRYPTION_INITIAL:
175 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.SendPacketSize.Initial",
176 packet_length, 1, kMaxOutgoingPacketSize, 50);
177 if (packet_length < kMinClientInitialPacketLength) {
178 UMA_HISTOGRAM_CUSTOM_COUNTS(
179 "Net.QuicSession.TooSmallInitialSentPacket",
180 kMinClientInitialPacketLength - packet_length, 1,
181 kMinClientInitialPacketLength, 50);
182 }
183 break;
184 case quic::ENCRYPTION_HANDSHAKE:
185 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.SendPacketSize.Handshake",
186 packet_length, 1, kMaxOutgoingPacketSize, 50);
187 break;
188 case quic::ENCRYPTION_ZERO_RTT:
189 UMA_HISTOGRAM_CUSTOM_COUNTS("Net.QuicSession.SendPacketSize.0RTT",
190 packet_length, 1, kMaxOutgoingPacketSize, 50);
191 break;
192 case quic::ENCRYPTION_FORWARD_SECURE:
193 UMA_HISTOGRAM_CUSTOM_COUNTS(
194 "Net.QuicSession.SendPacketSize.ForwardSecure", packet_length, 1,
195 kMaxOutgoingPacketSize, 50);
196 break;
197 case quic::NUM_ENCRYPTION_LEVELS:
198 NOTREACHED();
199 }
200
201 event_logger_.OnPacketSent(packet_number, packet_length, has_crypto_handshake,
202 transmission_type, encryption_level,
203 retransmittable_frames, nonretransmittable_frames,
204 sent_time, batch_id);
205 }
206
OnPacketLoss(quic::QuicPacketNumber lost_packet_number,quic::EncryptionLevel encryption_level,quic::TransmissionType transmission_type,quic::QuicTime detection_time)207 void QuicConnectionLogger::OnPacketLoss(
208 quic::QuicPacketNumber lost_packet_number,
209 quic::EncryptionLevel encryption_level,
210 quic::TransmissionType transmission_type,
211 quic::QuicTime detection_time) {
212 event_logger_.OnPacketLoss(lost_packet_number, encryption_level,
213 transmission_type, detection_time);
214 }
215
OnConfigProcessed(const quic::QuicSentPacketManager::DebugDelegate::SendParameters & parameters)216 void QuicConnectionLogger::OnConfigProcessed(
217 const quic::QuicSentPacketManager::DebugDelegate::SendParameters&
218 parameters) {
219 event_logger_.OnConfigProcessed(parameters);
220 }
221
OnPingSent()222 void QuicConnectionLogger::OnPingSent() {
223 no_packet_received_after_ping_ = true;
224 }
225
OnPacketReceived(const quic::QuicSocketAddress & self_address,const quic::QuicSocketAddress & peer_address,const quic::QuicEncryptedPacket & packet)226 void QuicConnectionLogger::OnPacketReceived(
227 const quic::QuicSocketAddress& self_address,
228 const quic::QuicSocketAddress& peer_address,
229 const quic::QuicEncryptedPacket& packet) {
230 if (local_address_from_self_.GetFamily() == ADDRESS_FAMILY_UNSPECIFIED) {
231 local_address_from_self_ = ToIPEndPoint(self_address);
232 UMA_HISTOGRAM_ENUMERATION(
233 "Net.QuicSession.ConnectionTypeFromSelf",
234 GetRealAddressFamily(ToIPEndPoint(self_address).address()),
235 ADDRESS_FAMILY_LAST);
236 }
237
238 previous_received_packet_size_ = last_received_packet_size_;
239 last_received_packet_size_ = packet.length();
240 event_logger_.OnPacketReceived(self_address, peer_address, packet);
241 }
242
OnUnauthenticatedHeader(const quic::QuicPacketHeader & header)243 void QuicConnectionLogger::OnUnauthenticatedHeader(
244 const quic::QuicPacketHeader& header) {
245 event_logger_.OnUnauthenticatedHeader(header);
246 }
247
OnIncorrectConnectionId(quic::QuicConnectionId connection_id)248 void QuicConnectionLogger::OnIncorrectConnectionId(
249 quic::QuicConnectionId connection_id) {
250 ++num_incorrect_connection_ids_;
251 }
252
OnUndecryptablePacket(quic::EncryptionLevel decryption_level,bool dropped)253 void QuicConnectionLogger::OnUndecryptablePacket(
254 quic::EncryptionLevel decryption_level,
255 bool dropped) {
256 ++num_undecryptable_packets_;
257 event_logger_.OnUndecryptablePacket(decryption_level, dropped);
258 }
259
OnAttemptingToProcessUndecryptablePacket(quic::EncryptionLevel decryption_level)260 void QuicConnectionLogger::OnAttemptingToProcessUndecryptablePacket(
261 quic::EncryptionLevel decryption_level) {
262 event_logger_.OnAttemptingToProcessUndecryptablePacket(decryption_level);
263 }
264
OnDuplicatePacket(quic::QuicPacketNumber packet_number)265 void QuicConnectionLogger::OnDuplicatePacket(
266 quic::QuicPacketNumber packet_number) {
267 ++num_duplicate_packets_;
268 event_logger_.OnDuplicatePacket(packet_number);
269 }
270
OnProtocolVersionMismatch(quic::ParsedQuicVersion received_version)271 void QuicConnectionLogger::OnProtocolVersionMismatch(
272 quic::ParsedQuicVersion received_version) {
273 // TODO(rtenneti): Add logging.
274 }
275
OnPacketHeader(const quic::QuicPacketHeader & header,quic::QuicTime receive_time,quic::EncryptionLevel level)276 void QuicConnectionLogger::OnPacketHeader(const quic::QuicPacketHeader& header,
277 quic::QuicTime receive_time,
278 quic::EncryptionLevel level) {
279 if (!first_received_packet_number_.IsInitialized()) {
280 first_received_packet_number_ = header.packet_number;
281 } else if (header.packet_number < first_received_packet_number_) {
282 // Ignore packets with packet numbers less than
283 // first_received_packet_number_.
284 return;
285 }
286 ++num_packets_received_;
287 if (!largest_received_packet_number_.IsInitialized()) {
288 largest_received_packet_number_ = header.packet_number;
289 } else if (largest_received_packet_number_ < header.packet_number) {
290 uint64_t delta = header.packet_number - largest_received_packet_number_;
291 if (delta > 1) {
292 // There is a gap between the largest packet previously received and
293 // the current packet. This indicates either loss, or out-of-order
294 // delivery.
295 UMA_HISTOGRAM_COUNTS_1M(
296 "Net.QuicSession.PacketGapReceived",
297 static_cast<base::HistogramBase::Sample>(delta - 1));
298 }
299 largest_received_packet_number_ = header.packet_number;
300 }
301 if (header.packet_number - first_received_packet_number_ <
302 received_packets_.size()) {
303 received_packets_[header.packet_number - first_received_packet_number_] =
304 true;
305 }
306 if (last_received_packet_number_.IsInitialized() &&
307 header.packet_number < last_received_packet_number_) {
308 ++num_out_of_order_received_packets_;
309 if (previous_received_packet_size_ < last_received_packet_size_)
310 ++num_out_of_order_large_received_packets_;
311 UMA_HISTOGRAM_COUNTS_1M(
312 "Net.QuicSession.OutOfOrderGapReceived",
313 static_cast<base::HistogramBase::Sample>(last_received_packet_number_ -
314 header.packet_number));
315 } else if (no_packet_received_after_ping_) {
316 if (last_received_packet_number_.IsInitialized()) {
317 UMA_HISTOGRAM_COUNTS_1M(
318 "Net.QuicSession.PacketGapReceivedNearPing",
319 static_cast<base::HistogramBase::Sample>(
320 header.packet_number - last_received_packet_number_));
321 }
322 no_packet_received_after_ping_ = false;
323 }
324 last_received_packet_number_ = header.packet_number;
325 event_logger_.OnPacketHeader(header, receive_time, level);
326 }
327
OnStreamFrame(const quic::QuicStreamFrame & frame)328 void QuicConnectionLogger::OnStreamFrame(const quic::QuicStreamFrame& frame) {
329 event_logger_.OnStreamFrame(frame);
330 }
331
OnPathChallengeFrame(const quic::QuicPathChallengeFrame & frame)332 void QuicConnectionLogger::OnPathChallengeFrame(
333 const quic::QuicPathChallengeFrame& frame) {
334 event_logger_.OnPathChallengeFrame(frame);
335 }
336
OnPathResponseFrame(const quic::QuicPathResponseFrame & frame)337 void QuicConnectionLogger::OnPathResponseFrame(
338 const quic::QuicPathResponseFrame& frame) {
339 event_logger_.OnPathResponseFrame(frame);
340 }
341
OnCryptoFrame(const quic::QuicCryptoFrame & frame)342 void QuicConnectionLogger::OnCryptoFrame(const quic::QuicCryptoFrame& frame) {
343 event_logger_.OnCryptoFrame(frame);
344 }
345
OnStopSendingFrame(const quic::QuicStopSendingFrame & frame)346 void QuicConnectionLogger::OnStopSendingFrame(
347 const quic::QuicStopSendingFrame& frame) {
348 base::UmaHistogramSparse("Net.QuicSession.StopSendingErrorCodeServer",
349 frame.error_code);
350 event_logger_.OnStopSendingFrame(frame);
351 }
352
OnStreamsBlockedFrame(const quic::QuicStreamsBlockedFrame & frame)353 void QuicConnectionLogger::OnStreamsBlockedFrame(
354 const quic::QuicStreamsBlockedFrame& frame) {
355 event_logger_.OnStreamsBlockedFrame(frame);
356 }
357
OnMaxStreamsFrame(const quic::QuicMaxStreamsFrame & frame)358 void QuicConnectionLogger::OnMaxStreamsFrame(
359 const quic::QuicMaxStreamsFrame& frame) {
360 event_logger_.OnMaxStreamsFrame(frame);
361 }
362
OnIncomingAck(quic::QuicPacketNumber ack_packet_number,quic::EncryptionLevel ack_decrypted_level,const quic::QuicAckFrame & frame,quic::QuicTime ack_receive_time,quic::QuicPacketNumber largest_observed,bool rtt_updated,quic::QuicPacketNumber least_unacked_sent_packet)363 void QuicConnectionLogger::OnIncomingAck(
364 quic::QuicPacketNumber ack_packet_number,
365 quic::EncryptionLevel ack_decrypted_level,
366 const quic::QuicAckFrame& frame,
367 quic::QuicTime ack_receive_time,
368 quic::QuicPacketNumber largest_observed,
369 bool rtt_updated,
370 quic::QuicPacketNumber least_unacked_sent_packet) {
371 const size_t kApproximateLargestSoloAckBytes = 100;
372 if (last_received_packet_number_ - first_received_packet_number_ <
373 received_acks_.size() &&
374 last_received_packet_size_ < kApproximateLargestSoloAckBytes) {
375 received_acks_[last_received_packet_number_ -
376 first_received_packet_number_] = true;
377 }
378
379 event_logger_.OnIncomingAck(ack_packet_number, ack_decrypted_level, frame,
380 ack_receive_time, largest_observed, rtt_updated,
381 least_unacked_sent_packet);
382 }
383
OnRstStreamFrame(const quic::QuicRstStreamFrame & frame)384 void QuicConnectionLogger::OnRstStreamFrame(
385 const quic::QuicRstStreamFrame& frame) {
386 base::UmaHistogramSparse("Net.QuicSession.RstStreamErrorCodeServer",
387 frame.error_code);
388 event_logger_.OnRstStreamFrame(frame);
389 }
390
OnConnectionCloseFrame(const quic::QuicConnectionCloseFrame & frame)391 void QuicConnectionLogger::OnConnectionCloseFrame(
392 const quic::QuicConnectionCloseFrame& frame) {
393 event_logger_.OnConnectionCloseFrame(frame);
394 }
395
OnWindowUpdateFrame(const quic::QuicWindowUpdateFrame & frame,const quic::QuicTime & receive_time)396 void QuicConnectionLogger::OnWindowUpdateFrame(
397 const quic::QuicWindowUpdateFrame& frame,
398 const quic::QuicTime& receive_time) {
399 event_logger_.OnWindowUpdateFrame(frame, receive_time);
400 }
401
OnBlockedFrame(const quic::QuicBlockedFrame & frame)402 void QuicConnectionLogger::OnBlockedFrame(const quic::QuicBlockedFrame& frame) {
403 ++num_blocked_frames_received_;
404 event_logger_.OnBlockedFrame(frame);
405 }
406
OnGoAwayFrame(const quic::QuicGoAwayFrame & frame)407 void QuicConnectionLogger::OnGoAwayFrame(const quic::QuicGoAwayFrame& frame) {
408 UMA_HISTOGRAM_BOOLEAN("Net.QuicSession.GoAwayReceivedForConnectionMigration",
409 frame.error_code == quic::QUIC_ERROR_MIGRATING_PORT);
410
411 event_logger_.OnGoAwayFrame(frame);
412 }
413
OnPingFrame(const quic::QuicPingFrame & frame,quic::QuicTime::Delta ping_received_delay)414 void QuicConnectionLogger::OnPingFrame(
415 const quic::QuicPingFrame& frame,
416 quic::QuicTime::Delta ping_received_delay) {
417 event_logger_.OnPingFrame(frame, ping_received_delay);
418 }
419
OnPaddingFrame(const quic::QuicPaddingFrame & frame)420 void QuicConnectionLogger::OnPaddingFrame(const quic::QuicPaddingFrame& frame) {
421 event_logger_.OnPaddingFrame(frame);
422 }
423
OnNewConnectionIdFrame(const quic::QuicNewConnectionIdFrame & frame)424 void QuicConnectionLogger::OnNewConnectionIdFrame(
425 const quic::QuicNewConnectionIdFrame& frame) {
426 event_logger_.OnNewConnectionIdFrame(frame);
427 }
428
OnNewTokenFrame(const quic::QuicNewTokenFrame & frame)429 void QuicConnectionLogger::OnNewTokenFrame(
430 const quic::QuicNewTokenFrame& frame) {
431 event_logger_.OnNewTokenFrame(frame);
432 }
433
OnRetireConnectionIdFrame(const quic::QuicRetireConnectionIdFrame & frame)434 void QuicConnectionLogger::OnRetireConnectionIdFrame(
435 const quic::QuicRetireConnectionIdFrame& frame) {
436 event_logger_.OnRetireConnectionIdFrame(frame);
437 }
438
OnMessageFrame(const quic::QuicMessageFrame & frame)439 void QuicConnectionLogger::OnMessageFrame(const quic::QuicMessageFrame& frame) {
440 event_logger_.OnMessageFrame(frame);
441 }
442
OnHandshakeDoneFrame(const quic::QuicHandshakeDoneFrame & frame)443 void QuicConnectionLogger::OnHandshakeDoneFrame(
444 const quic::QuicHandshakeDoneFrame& frame) {
445 event_logger_.OnHandshakeDoneFrame(frame);
446 }
447
OnCoalescedPacketSent(const quic::QuicCoalescedPacket & coalesced_packet,size_t length)448 void QuicConnectionLogger::OnCoalescedPacketSent(
449 const quic::QuicCoalescedPacket& coalesced_packet,
450 size_t length) {
451 event_logger_.OnCoalescedPacketSent(coalesced_packet, length);
452 }
453
OnVersionNegotiationPacket(const quic::QuicVersionNegotiationPacket & packet)454 void QuicConnectionLogger::OnVersionNegotiationPacket(
455 const quic::QuicVersionNegotiationPacket& packet) {
456 event_logger_.OnVersionNegotiationPacket(packet);
457 }
458
OnCryptoHandshakeMessageReceived(const quic::CryptoHandshakeMessage & message)459 void QuicConnectionLogger::OnCryptoHandshakeMessageReceived(
460 const quic::CryptoHandshakeMessage& message) {
461 if (message.tag() == quic::kSHLO) {
462 std::string_view address;
463 quic::QuicSocketAddressCoder decoder;
464 if (message.GetStringPiece(quic::kCADR, &address) &&
465 decoder.Decode(address.data(), address.size())) {
466 local_address_from_shlo_ =
467 IPEndPoint(ToIPAddress(decoder.ip()), decoder.port());
468 UMA_HISTOGRAM_ENUMERATION(
469 "Net.QuicSession.ConnectionTypeFromPeer",
470 GetRealAddressFamily(local_address_from_shlo_.address()),
471 ADDRESS_FAMILY_LAST);
472
473 int sample = GetAddressMismatch(local_address_from_shlo_,
474 local_address_from_self_);
475 // If `sample` is negative, we are seemingly talking to an older server
476 // that does not support the feature, so we can't report the results in
477 // the histogram.
478 if (sample >= 0) {
479 UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.SelfShloAddressMismatch",
480 static_cast<QuicAddressMismatch>(sample),
481 QUIC_ADDRESS_MISMATCH_MAX);
482 }
483 }
484 }
485 event_logger_.OnCryptoHandshakeMessageReceived(message);
486 }
487
OnCryptoHandshakeMessageSent(const quic::CryptoHandshakeMessage & message)488 void QuicConnectionLogger::OnCryptoHandshakeMessageSent(
489 const quic::CryptoHandshakeMessage& message) {
490 event_logger_.OnCryptoHandshakeMessageSent(message);
491 }
492
OnConnectionClosed(const quic::QuicConnectionCloseFrame & frame,quic::ConnectionCloseSource source)493 void QuicConnectionLogger::OnConnectionClosed(
494 const quic::QuicConnectionCloseFrame& frame,
495 quic::ConnectionCloseSource source) {
496 event_logger_.OnConnectionClosed(frame, source);
497 }
498
OnSuccessfulVersionNegotiation(const quic::ParsedQuicVersion & version)499 void QuicConnectionLogger::OnSuccessfulVersionNegotiation(
500 const quic::ParsedQuicVersion& version) {
501 event_logger_.OnSuccessfulVersionNegotiation(version);
502 }
503
UpdateReceivedFrameCounts(quic::QuicStreamId stream_id,int num_frames_received,int num_duplicate_frames_received)504 void QuicConnectionLogger::UpdateReceivedFrameCounts(
505 quic::QuicStreamId stream_id,
506 int num_frames_received,
507 int num_duplicate_frames_received) {
508 if (!quic::QuicUtils::IsCryptoStreamId(session_->transport_version(),
509 stream_id)) {
510 num_frames_received_ += num_frames_received;
511 num_duplicate_frames_received_ += num_duplicate_frames_received;
512 }
513 }
514
OnCertificateVerified(const CertVerifyResult & result)515 void QuicConnectionLogger::OnCertificateVerified(
516 const CertVerifyResult& result) {
517 event_logger_.OnCertificateVerified(result);
518 }
519
ReceivedPacketLossRate() const520 float QuicConnectionLogger::ReceivedPacketLossRate() const {
521 if (!largest_received_packet_number_.IsInitialized())
522 return 0.0f;
523 float num_packets =
524 largest_received_packet_number_ - first_received_packet_number_ + 1;
525 float num_missing = num_packets - num_packets_received_;
526 return num_missing / num_packets;
527 }
528
OnRttChanged(quic::QuicTime::Delta rtt) const529 void QuicConnectionLogger::OnRttChanged(quic::QuicTime::Delta rtt) const {
530 // Notify socket performance watcher of the updated RTT value.
531 if (!socket_performance_watcher_)
532 return;
533
534 int64_t microseconds = rtt.ToMicroseconds();
535 if (microseconds != 0 &&
536 socket_performance_watcher_->ShouldNotifyUpdatedRTT()) {
537 socket_performance_watcher_->OnUpdatedRTTAvailable(
538 base::Microseconds(rtt.ToMicroseconds()));
539 }
540 }
541
OnTransportParametersSent(const quic::TransportParameters & transport_parameters)542 void QuicConnectionLogger::OnTransportParametersSent(
543 const quic::TransportParameters& transport_parameters) {
544 event_logger_.OnTransportParametersSent(transport_parameters);
545 }
546
OnTransportParametersReceived(const quic::TransportParameters & transport_parameters)547 void QuicConnectionLogger::OnTransportParametersReceived(
548 const quic::TransportParameters& transport_parameters) {
549 event_logger_.OnTransportParametersReceived(transport_parameters);
550 }
551
OnTransportParametersResumed(const quic::TransportParameters & transport_parameters)552 void QuicConnectionLogger::OnTransportParametersResumed(
553 const quic::TransportParameters& transport_parameters) {
554 event_logger_.OnTransportParametersResumed(transport_parameters);
555 }
556
OnZeroRttRejected(int reason)557 void QuicConnectionLogger::OnZeroRttRejected(int reason) {
558 event_logger_.OnZeroRttRejected(reason);
559 }
560
OnEncryptedClientHelloSent(std::string_view client_hello)561 void QuicConnectionLogger::OnEncryptedClientHelloSent(
562 std::string_view client_hello) {
563 event_logger_.OnEncryptedClientHelloSent(client_hello);
564 }
565
RecordAggregatePacketLossRate() const566 void QuicConnectionLogger::RecordAggregatePacketLossRate() const {
567 // We don't report packet loss rates for short connections under 22 packets in
568 // length to avoid tremendously anomalous contributions to our histogram.
569 // (e.g., if we only got 5 packets, but lost 1, we'd otherwise
570 // record a 20% loss in this histogram!). We may still get some strange data
571 // (1 loss in 22 is still high :-/).
572 if (!largest_received_packet_number_.IsInitialized() ||
573 largest_received_packet_number_ - first_received_packet_number_ < 22) {
574 return;
575 }
576
577 string prefix("Net.QuicSession.PacketLossRate_");
578 base::HistogramBase* histogram = base::Histogram::FactoryGet(
579 prefix + connection_description_, 1, 1000, 75,
580 base::HistogramBase::kUmaTargetedHistogramFlag);
581 histogram->Add(static_cast<base::HistogramBase::Sample>(
582 ReceivedPacketLossRate() * 1000));
583 }
584
585 } // namespace net
586