xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/quic_packet_number.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2019 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 #ifndef QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
6 #define QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
7 
8 #include <limits>
9 #include <ostream>
10 #include <string>
11 
12 #include "quiche/quic/platform/api/quic_export.h"
13 #include "quiche/quic/platform/api/quic_logging.h"
14 
15 namespace quic {
16 
17 // QuicPacketNumber can either initialized or uninitialized. An initialized
18 // packet number is simply an ordinal number. A sentinel value is used to
19 // represent an uninitialized packet number.
20 class QUICHE_EXPORT QuicPacketNumber {
21  public:
22   // Construct an uninitialized packet number.
QuicPacketNumber()23   constexpr QuicPacketNumber() : packet_number_(UninitializedPacketNumber()) {}
24 
25   // Construct a packet number from uint64_t. |packet_number| cannot equal the
26   // sentinel value.
QuicPacketNumber(uint64_t packet_number)27   explicit constexpr QuicPacketNumber(uint64_t packet_number)
28       : packet_number_(packet_number) {
29     QUICHE_DCHECK_NE(UninitializedPacketNumber(), packet_number)
30         << "Use default constructor for uninitialized packet number";
31   }
32 
33   // The sentinel value representing an uninitialized packet number.
UninitializedPacketNumber()34   static constexpr uint64_t UninitializedPacketNumber() {
35     return std::numeric_limits<uint64_t>::max();
36   }
37 
38   // Packet number becomes uninitialized after calling this function.
39   void Clear();
40 
41   // Updates this packet number to be |new_value| if it is greater than current
42   // value.
43   void UpdateMax(QuicPacketNumber new_value);
44 
45   // REQUIRES: IsInitialized() == true.
46   uint64_t Hash() const;
47 
48   // Converts packet number to uint64_t.
49   // REQUIRES: IsInitialized() == true.
50   uint64_t ToUint64() const;
51 
52   // Returns true if packet number is considered initialized.
53   bool IsInitialized() const;
54 
55   // REQUIRES: IsInitialized() == true && ToUint64() <
56   // numeric_limits<uint64_t>::max() - 1.
57   QuicPacketNumber& operator++();
58   QuicPacketNumber operator++(int);
59   // REQUIRES: IsInitialized() == true && ToUint64() >= 1.
60   QuicPacketNumber& operator--();
61   QuicPacketNumber operator--(int);
62 
63   // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
64   // ToUint64() > |delta|.
65   QuicPacketNumber& operator+=(uint64_t delta);
66   // REQUIRES: IsInitialized() == true && ToUint64() >= |delta|.
67   QuicPacketNumber& operator-=(uint64_t delta);
68 
69   // Human-readable representation suitable for logging.
70   std::string ToString() const;
71 
72   QUICHE_EXPORT friend std::ostream& operator<<(std::ostream& os,
73                                                 const QuicPacketNumber& p);
74 
75  private:
76   // All following operators REQUIRE operands.Initialized() == true.
77   friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
78   friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
79   friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
80   friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
81   friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
82   friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
83 
84   // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() > |delta|.
85   friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
86                                            uint64_t delta);
87   // REQUIRES: lhs.ToUint64() >= |delta|.
88   friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
89                                            uint64_t delta);
90   // REQUIRES: lhs >= rhs.
91   friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
92 
93   uint64_t packet_number_;
94 };
95 
96 class QUICHE_EXPORT QuicPacketNumberHash {
97  public:
operator()98   uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
99     return packet_number.Hash();
100   }
101 };
102 
103 inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
104   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
105       << lhs << " vs. " << rhs;
106   return lhs.packet_number_ == rhs.packet_number_;
107 }
108 
109 inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
110   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
111       << lhs << " vs. " << rhs;
112   return lhs.packet_number_ != rhs.packet_number_;
113 }
114 
115 inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
116   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
117       << lhs << " vs. " << rhs;
118   return lhs.packet_number_ < rhs.packet_number_;
119 }
120 
121 inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
122   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
123       << lhs << " vs. " << rhs;
124   return lhs.packet_number_ <= rhs.packet_number_;
125 }
126 
127 inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
128   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
129       << lhs << " vs. " << rhs;
130   return lhs.packet_number_ > rhs.packet_number_;
131 }
132 
133 inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
134   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized())
135       << lhs << " vs. " << rhs;
136   return lhs.packet_number_ >= rhs.packet_number_;
137 }
138 
139 inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
140 #ifndef NDEBUG
141   QUICHE_DCHECK(lhs.IsInitialized());
142   QUICHE_DCHECK_GT(std::numeric_limits<uint64_t>::max() - lhs.ToUint64(),
143                    delta);
144 #endif
145   return QuicPacketNumber(lhs.packet_number_ + delta);
146 }
147 
148 inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
149 #ifndef NDEBUG
150   QUICHE_DCHECK(lhs.IsInitialized());
151   QUICHE_DCHECK_GE(lhs.ToUint64(), delta);
152 #endif
153   return QuicPacketNumber(lhs.packet_number_ - delta);
154 }
155 
156 inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
157   QUICHE_DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
158       << lhs << " vs. " << rhs;
159   return lhs.packet_number_ - rhs.packet_number_;
160 }
161 
162 }  // namespace quic
163 
164 #endif  // QUICHE_QUIC_CORE_QUIC_PACKET_NUMBER_H_
165