summaryrefslogtreecommitdiffstats
path: root/net/quic/quic_connection_logger.h
blob: 9e687f2a62d88af76b74baab70db93330c22473f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_QUIC_QUIC_CONNECTION_LOGGER_H_
#define NET_QUIC_QUIC_CONNECTION_LOGGER_H_

#include <bitset>

#include "net/base/ip_endpoint.h"
#include "net/base/network_change_notifier.h"
#include "net/base/socket_performance_watcher.h"
#include "net/log/net_log.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_protocol.h"
#include "net/quic/quic_spdy_session.h"

namespace net {
namespace test {
class QuicConnectionLoggerPeer;
}  // namespace test

class CryptoHandshakeMessage;
class CertVerifyResult;

// This class is a debug visitor of a QuicConnection which logs
// events to |net_log|.
class NET_EXPORT_PRIVATE QuicConnectionLogger
    : public QuicConnectionDebugVisitor {
 public:
  QuicConnectionLogger(
      QuicSpdySession* session,
      const char* const connection_description,
      scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher,
      const BoundNetLog& net_log);

  ~QuicConnectionLogger() override;

  // QuicPacketGenerator::DebugDelegateInterface
  void OnFrameAddedToPacket(const QuicFrame& frame) override;

  // QuicConnectionDebugVisitorInterface
  void OnPacketSent(const SerializedPacket& serialized_packet,
                    QuicPacketNumber original_packet_number,
                    EncryptionLevel level,
                    TransmissionType transmission_type,
                    const QuicEncryptedPacket& packet,
                    QuicTime sent_time) override;
  void OnPacketReceived(const IPEndPoint& self_address,
                        const IPEndPoint& peer_address,
                        const QuicEncryptedPacket& packet) override;
  void OnUnauthenticatedHeader(const QuicPacketHeader& header) override;
  void OnIncorrectConnectionId(QuicConnectionId connection_id) override;
  void OnUndecryptablePacket() override;
  void OnDuplicatePacket(QuicPacketNumber packet_number) override;
  void OnProtocolVersionMismatch(QuicVersion version) override;
  void OnPacketHeader(const QuicPacketHeader& header) override;
  void OnStreamFrame(const QuicStreamFrame& frame) override;
  void OnAckFrame(const QuicAckFrame& frame) override;
  void OnStopWaitingFrame(const QuicStopWaitingFrame& frame) override;
  void OnRstStreamFrame(const QuicRstStreamFrame& frame) override;
  void OnConnectionCloseFrame(const QuicConnectionCloseFrame& frame) override;
  void OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) override;
  void OnBlockedFrame(const QuicBlockedFrame& frame) override;
  void OnGoAwayFrame(const QuicGoAwayFrame& frame) override;
  void OnPingFrame(const QuicPingFrame& frame) override;
  void OnPublicResetPacket(const QuicPublicResetPacket& packet) override;
  void OnVersionNegotiationPacket(
      const QuicVersionNegotiationPacket& packet) override;
  void OnRevivedPacket(const QuicPacketHeader& revived_header,
                       base::StringPiece payload) override;
  void OnConnectionClosed(QuicErrorCode error, bool from_peer) override;
  void OnSuccessfulVersionNegotiation(const QuicVersion& version) override;
  void OnRttChanged(QuicTime::Delta rtt) const override;

  void OnCryptoHandshakeMessageReceived(
      const CryptoHandshakeMessage& message);
  void OnCryptoHandshakeMessageSent(
      const CryptoHandshakeMessage& message);
  void UpdateReceivedFrameCounts(QuicStreamId stream_id,
                                 int num_frames_received,
                                 int num_duplicate_frames_received);
  void OnCertificateVerified(const CertVerifyResult& result);

  // Returns connection's overall packet loss rate in fraction.
  float ReceivedPacketLossRate() const;

 private:
  friend class test::QuicConnectionLoggerPeer;

  // Do a factory get for a histogram for recording data, about individual
  // packet numbers, that was gathered in the vectors
  // received_packets_ and received_acks_. |statistic_name| identifies which
  // element of data is recorded, and is used to form the histogram name.
  base::HistogramBase* GetPacketNumberHistogram(
      const char* statistic_name) const;
  // Do a factory get for a histogram to record a 6-packet loss-sequence as a
  // sample. The histogram will record the 64 distinct possible combinations.
  // |which_6| is used to adjust the name of the histogram to distinguish the
  // first 6 packets in a connection, vs. some later 6 packets.
  base::HistogramBase* Get6PacketHistogram(const char* which_6) const;
  // Do a factory get for a histogram to record cumulative stats across a 21
  // packet sequence.  |which_21| is used to adjust the name of the histogram
  // to distinguish the first 21 packets' loss data, vs. some later 21 packet
  // sequences' loss data.
  base::HistogramBase* Get21CumulativeHistogram(const char* which_21) const;
  // Add samples associated with a |bit_mask_of_packets| to the given histogram
  // that was provided by Get21CumulativeHistogram().  The LSB of that mask
  // corresponds to the oldest packet number in the series of packets,
  // and the bit in the 2^20 position corresponds to the most recently received
  // packet.  Of the maximum of 21 bits that are valid (correspond to packets),
  // only the most significant |valid_bits_in_mask| are processed.
  // A bit value of 0 indicates that a packet was never received, and a 1
  // indicates the packet was received.
  static void AddTo21CumulativeHistogram(base::HistogramBase* histogram,
                                         int bit_mask_of_packets,
                                         int valid_bits_in_mask);
  // For connections longer than 21 received packets, this call will calculate
  // the overall packet loss rate, and record it into a histogram.
  void RecordAggregatePacketLossRate() const;
  // At destruction time, this records results of |pacaket_received_| into
  // histograms for specific connection types.
  void RecordLossHistograms() const;

  BoundNetLog net_log_;
  QuicSpdySession* session_;  // Unowned.
  // The last packet number received.
  QuicPacketNumber last_received_packet_number_;
  // The size of the most recently received packet.
  size_t last_received_packet_size_;
  // The size of the previously received packet.
  size_t previous_received_packet_size_;
  // The timestamp of last packet sent.
  QuicTime last_packet_sent_time_;
  // The largest packet number received.  In the case where a packet is
  // received late (out of order), this value will not be updated.
  QuicPacketNumber largest_received_packet_number_;
  // The largest packet number which the peer has failed to
  // receive, according to the missing packet set in their ack frames.
  QuicPacketNumber largest_received_missing_packet_number_;
  // Number of times that the current received packet number is
  // smaller than the last received packet number.
  size_t num_out_of_order_received_packets_;
  // Number of times that the current received packet number is
  // smaller than the last received packet number and where the
  // size of the current packet is larger than the size of the previous
  // packet.
  size_t num_out_of_order_large_received_packets_;
  // The number of times that OnPacketHeader was called.
  // If the network replicates packets, then this number may be slightly
  // different from the real number of distinct packets received.
  QuicPacketCount num_packets_received_;
  // Number of times a truncated ACK frame was sent.
  size_t num_truncated_acks_sent_;
  // Number of times a truncated ACK frame was received.
  size_t num_truncated_acks_received_;
  // The kCADR value provided by the server in ServerHello.
  IPEndPoint local_address_from_shlo_;
  // The first local address from which a packet was received.
  IPEndPoint local_address_from_self_;
  // Count of the number of frames received.
  int num_frames_received_;
  // Count of the number of duplicate frames received.
  int num_duplicate_frames_received_;
  // Count of the number of packets received with incorrect connection IDs.
  int num_incorrect_connection_ids_;
  // Count of the number of undecryptable packets received.
  int num_undecryptable_packets_;
  // Count of the number of duplicate packets received.
  int num_duplicate_packets_;
  // Count of the number of BLOCKED frames received.
  int num_blocked_frames_received_;
  // Count of the number of BLOCKED frames sent.
  int num_blocked_frames_sent_;
  // Vector of inital packets status' indexed by packet numbers, where
  // false means never received.  Zero is not a valid packet number, so
  // that offset is never used, and we'll track 150 packets.
  std::bitset<151> received_packets_;
  // Vector to indicate which of the initial 150 received packets turned out to
  // contain solo ACK frames.  An element is true iff an ACK frame was in the
  // corresponding packet, and there was very little else.
  std::bitset<151> received_acks_;
  // The available type of connection (WiFi, 3G, etc.) when connection was first
  // used.
  const char* const connection_description_;
  // Receives notifications regarding the performance of the underlying socket
  // for the QUIC connection. May be null.
  const scoped_ptr<SocketPerformanceWatcher> socket_performance_watcher_;

  DISALLOW_COPY_AND_ASSIGN(QuicConnectionLogger);
};

}  // namespace net

#endif  // NET_QUIC_QUIC_CONNECTION_LOGGER_H_