1 // Copyright 2018 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // A library that assigns a global numbering to the events in the trace. 16 17 #ifndef THIRD_PARTY_QUIC_TRACE_LIB_ANALYSIS_TRACE_NUMBERING_H_ 18 #define THIRD_PARTY_QUIC_TRACE_LIB_ANALYSIS_TRACE_NUMBERING_H_ 19 20 #include <cstdint> 21 #include <unordered_map> 22 23 #include "absl/container/flat_hash_map.h" 24 #include "absl/log/log.h" 25 #include "quic_trace/quic_trace.pb.h" 26 27 namespace quic_trace { 28 29 // Trace offset of a packet in the connection trace. 30 using TraceOffset = uint64_t; 31 32 struct Interval { 33 TraceOffset offset; 34 size_t size; 35 }; 36 37 // Assigns a new connection offset to every sent packet, regardless of whether 38 // it's a retransmission or not. 39 // 40 // TODO(vasilvv): port QuicTcpLikeTraceConverter from QUIC for retransmission 41 // support. 42 class NumberingWithoutRetransmissions { 43 public: AssignTraceNumbering(const Event & event)44 Interval AssignTraceNumbering(const Event& event) { 45 size_t size = 0; 46 for (const Frame& frame : event.frames()) { 47 if (frame.has_stream_frame_info()) { 48 size += frame.stream_frame_info().length(); 49 } 50 if (frame.has_crypto_frame_info()) { 51 size += frame.crypto_frame_info().length(); 52 } 53 } 54 TraceOffset offset = current_offset_; 55 current_offset_ += size; 56 GetOffsets(event.encryption_level()) 57 ->emplace(event.packet_number(), Interval{offset, size}); 58 return {offset, size}; 59 } 60 GetTraceNumbering(uint64_t packet_number,EncryptionLevel enc_level)61 Interval GetTraceNumbering(uint64_t packet_number, 62 EncryptionLevel enc_level) { 63 auto offsets = GetOffsets(enc_level); 64 auto it = offsets->find(packet_number); 65 return it != offsets->end() ? it->second : Interval{0, 0}; 66 } 67 68 private: GetOffsets(EncryptionLevel enc_level)69 absl::flat_hash_map<uint64_t, Interval>* GetOffsets( 70 EncryptionLevel enc_level) { 71 switch (enc_level) { 72 case ENCRYPTION_INITIAL: 73 return &offsets_initial_; 74 case ENCRYPTION_HANDSHAKE: 75 return &offsets_handshake_; 76 case ENCRYPTION_0RTT: 77 case ENCRYPTION_1RTT: 78 return &offsets_1rtt_; 79 default: 80 LOG(FATAL) << "Unknown encryption level."; 81 } 82 } 83 84 TraceOffset current_offset_ = 0; 85 absl::flat_hash_map<uint64_t, Interval> offsets_initial_; 86 absl::flat_hash_map<uint64_t, Interval> offsets_handshake_; 87 absl::flat_hash_map<uint64_t, Interval> offsets_1rtt_; 88 }; 89 90 } // namespace quic_trace 91 92 #endif // THIRD_PARTY_QUIC_TRACE_LIB_ANALYSIS_TRACE_NUMBERING_H_ 93