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