Hybrid ICN (hICN) plugin  v21.06-rc0-4-g18fa668
rtc_state.h
1 /*
2  * Copyright (c) 2017-2021 Cisco and/or its affiliates.
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  * http://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 
16 #pragma once
17 #include <hicn/transport/config.h>
18 #include <hicn/transport/core/asio_wrapper.h>
19 #include <hicn/transport/core/content_object.h>
20 #include <hicn/transport/core/name.h>
21 #include <protocols/indexer.h>
22 #include <protocols/rtc/probe_handler.h>
23 #include <protocols/rtc/rtc_data_path.h>
24 
25 #include <map>
26 #include <set>
27 
28 namespace transport {
29 
30 namespace protocol {
31 
32 namespace rtc {
33 
34 enum class PacketState : uint8_t { RECEIVED, LOST, UNKNOWN };
35 
36 class RTCState : std::enable_shared_from_this<RTCState> {
37  public:
38  using DiscoveredRttCallback = std::function<void()>;
39 
40  public:
41  RTCState(Indexer *indexer,
42  ProbeHandler::SendProbeCallback &&rtt_probes_callback,
43  DiscoveredRttCallback &&discovered_rtt_callback,
44  asio::io_service &io_service);
45 
46  ~RTCState();
47 
48  // packet events
49  void onSendNewInterest(const core::Name *interest_name);
50  void onTimeout(uint32_t seq, bool lost);
51  void onLossDetected(uint32_t seq);
52  void onRetransmission(uint32_t seq);
53  void onDataPacketReceived(const core::ContentObject &content_object,
54  bool compute_stats);
55  void onFecPacketReceived(const core::ContentObject &content_object);
56  void onNackPacketReceived(const core::ContentObject &nack,
57  bool compute_stats);
58  void onPacketLost(uint32_t seq);
59  void onPacketRecoveredRtx(uint32_t seq);
60  void onPacketRecoveredFec(uint32_t seq);
61  bool onProbePacketReceived(const core::ContentObject &probe);
62 
63  // protocol state
64  void onNewRound(double round_len, bool in_sync);
65 
66  // main path
67  uint32_t getProducerPath() const {
68  if (mainPathIsValid()) return main_path_->getPathId();
69  return 0;
70  }
71 
72  // delay metrics
73  bool isRttDiscovered() const { return init_rtt_; }
74 
75  uint64_t getRTT() const {
76  if (mainPathIsValid()) return main_path_->getMinRtt();
77  return 0;
78  }
79  void resetRttStats() {
80  if (mainPathIsValid()) main_path_->clearRtt();
81  }
82 
83  double getQueuing() const {
84  if (mainPathIsValid()) return main_path_->getQueuingDealy();
85  return 0.0;
86  }
87  double getIAT() const {
88  if (mainPathIsValid()) return main_path_->getInterArrivalGap();
89  return 0.0;
90  }
91 
92  double getJitter() const {
93  if (mainPathIsValid()) return main_path_->getJitter();
94  return 0.0;
95  }
96 
97  // pending interests
98  uint64_t getInterestSentTime(uint32_t seq) {
99  auto it = pending_interests_.find(seq);
100  if (it != pending_interests_.end()) return it->second;
101  return 0;
102  }
103 
104  bool isPending(uint32_t seq) {
105  if (pending_interests_.find(seq) != pending_interests_.end()) return true;
106  return false;
107  }
108 
109  uint32_t getPendingInterestNumber() const {
110  return pending_interests_.size();
111  }
112 
113  PacketState isReceivedOrLost(uint32_t seq) {
114  auto it = received_or_lost_packets_.find(seq);
115  if (it != received_or_lost_packets_.end()) return it->second;
116  return PacketState::UNKNOWN;
117  }
118 
119  // loss rate
120  double getLossRate() const { return loss_rate_; }
121  double getAvgLossRate() const { return avg_loss_rate_; }
122  double getMaxLossRate() const { return max_loss_rate_; }
123  double getLastRoundLossRate() const { return last_round_loss_rate_; }
124  double getResidualLossRate() const { return residual_loss_rate_; }
125 
126  uint32_t getLostData() const { return packets_lost_; };
127  uint32_t getRecoveredLosses() const { return losses_recovered_; }
128 
129  uint32_t getDefinitelyLostPackets() const { return definitely_lost_pkt_; }
130 
131  uint32_t getHighestSeqReceived() const { return highest_seq_received_; }
132 
133  uint32_t getHighestSeqReceivedInOrder() const {
134  return highest_seq_received_in_order_;
135  }
136 
137  // fec packets
138  uint32_t getReceivedFecPackets() const { return received_fec_pkt_; }
139  uint32_t getPendingFecPackets() const { return pending_fec_pkt_; }
140 
141  // generic stats
142  uint32_t getReceivedBytesInRound() const { return received_bytes_; }
143  uint32_t getReceivedNacksInRound() const {
144  return received_nacks_last_round_;
145  }
146  uint32_t getSentInterestInRound() const { return sent_interests_last_round_; }
147  uint32_t getSentRtxInRound() const { return sent_rtx_last_round_; }
148 
149  // bandwidth/production metrics
150  double getAvailableBw() const { return 0.0; }; // TODO
151  double getProducerRate() const { return production_rate_; }
152  double getReceivedRate() const { return received_rate_; }
153  double getAveragePacketSize() const { return avg_packet_size_; }
154 
155  // nacks
156  uint32_t getRoundsWithoutNacks() const { return rounds_without_nacks_; }
157  uint32_t getLastSeqNacked() const { return last_seq_nacked_; }
158 
159  // producer state
160  bool isProducerActive() const { return producer_is_active_; }
161 
162  // packets from cache
163  double getPacketFromCacheRatio() const { return data_from_cache_rate_; }
164 
165  std::map<uint32_t, uint64_t>::iterator getPendingInterestsMapBegin() {
166  return pending_interests_.begin();
167  }
168  std::map<uint32_t, uint64_t>::iterator getPendingInterestsMapEnd() {
169  return pending_interests_.end();
170  }
171 
172  private:
173  void initParams();
174 
175  // update stats
176  void updateState();
177  void updateReceivedBytes(const core::ContentObject &content_object);
178  void updatePacketSize(const core::ContentObject &content_object);
179  void updatePathStats(const core::ContentObject &content_object, bool is_nack);
180  void updateLossRate();
181 
182  void addRecvOrLost(uint32_t seq, PacketState state);
183 
184  void setInitRttTimer(uint32_t wait);
185  void checkInitRttTimer();
186 
187  bool mainPathIsValid() const {
188  if (main_path_ != nullptr)
189  return true;
190  else
191  return false;
192  }
193 
194  // packets counters (total)
195  uint32_t sent_interests_;
196  uint32_t sent_rtx_;
197  uint32_t received_data_;
198  uint32_t received_nacks_;
199  uint32_t received_timeouts_;
200  uint32_t received_probes_;
201 
202  // loss counters
203  int32_t packets_lost_;
204  int32_t losses_recovered_;
205  uint32_t definitely_lost_pkt_;
206  uint32_t first_seq_in_round_;
207  uint32_t highest_seq_received_;
208  uint32_t highest_seq_received_in_order_;
209  uint32_t last_seq_nacked_; // segment for which we got an oldNack
210  double loss_rate_;
211  double avg_loss_rate_;
212  double max_loss_rate_;
213  double last_round_loss_rate_;
214  double residual_loss_rate_;
215 
216  // bw counters
217  uint32_t received_bytes_;
218  double avg_packet_size_;
219  double production_rate_; // rate communicated by the producer using nacks
220  double received_rate_; // rate recevied by the consumer
221 
222  // nack counter
223  // the bool takes tracks only about the valid nacks (no rtx) and it is used to
224  // switch between the states. Instead received_nacks_last_round_ logs all the
225  // nacks for statistics
226  bool nack_on_last_round_;
227  uint32_t received_nacks_last_round_;
228 
229  // packets counter
230  uint32_t received_packets_last_round_;
231  uint32_t received_data_last_round_;
232  uint32_t received_data_from_cache_;
233  double data_from_cache_rate_;
234  uint32_t sent_interests_last_round_;
235  uint32_t sent_rtx_last_round_;
236 
237  // fec counter
238  uint32_t received_fec_pkt_;
239  uint32_t pending_fec_pkt_;
240 
241  // round conunters
242  uint32_t rounds_;
243  uint32_t rounds_without_nacks_;
244  uint32_t rounds_without_packets_;
245 
246  // init rtt
247  uint64_t first_interest_sent_time_;
248  uint32_t first_interest_sent_seq_;
249 
250  // producer state
251  bool
252  producer_is_active_; // the prodcuer is active if we receive some packets
253  uint32_t
254  last_production_seq_; // last production seq received by the producer
255  uint64_t last_prod_update_; // timestamp of the last packets used to update
256  // stats from the producer
257 
258  // paths stats
259  std::unordered_map<uint32_t, std::shared_ptr<RTCDataPath>> path_table_;
260  std::shared_ptr<RTCDataPath> main_path_;
261 
262  // packet received
263  // cache where to store info about the last MAX_CACHED_PACKETS
264  std::map<uint32_t, PacketState> received_or_lost_packets_;
265 
266  // pending interests
267  std::map<uint32_t, uint64_t> pending_interests_;
268 
269  // indexer
270  Indexer *indexer_;
271 
272  // skipped interests
273  uint32_t last_interest_sent_;
274  std::unordered_set<uint32_t> skipped_interests_;
275 
276  // probes
277  std::shared_ptr<ProbeHandler> rtt_probes_;
278  bool init_rtt_;
279  std::unique_ptr<asio::steady_timer> init_rtt_timer_;
280 
281  // callbacks
282  DiscoveredRttCallback discovered_rtt_callback_;
283 };
284 
285 } // namespace rtc
286 
287 } // namespace protocol
288 
289 } // namespace transport
transport::core::Name
Definition: name.h:45
transport::core::ContentObject
Definition: content_object.h:29
transport::protocol::rtc::RTCState
Definition: rtc_state.h:36
transport
Definition: forwarder_config.h:32
transport::protocol::Indexer
Definition: indexer.h:35