| // Copyright (c) 2019 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. | 
 |  | 
 | #include "net/third_party/quiche/src/quic/quartc/test/random_delay_link.h" | 
 |  | 
 | #include <cmath> | 
 | #include <cstdint> | 
 |  | 
 | #include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" | 
 | #include "net/third_party/quiche/src/quic/test_tools/simulator/link.h" | 
 | #include "net/third_party/quiche/src/quic/test_tools/simulator/port.h" | 
 | #include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h" | 
 |  | 
 | namespace quic { | 
 | namespace simulator { | 
 | namespace { | 
 |  | 
 | // Number of buckets used to define an exponential distribution. | 
 | constexpr int64_t kNumBuckets = 2l << 32; | 
 |  | 
 | }  // namespace | 
 |  | 
 | RandomDelayLink::RandomDelayLink(Simulator* simulator, | 
 |                                  std::string name, | 
 |                                  UnconstrainedPortInterface* sink, | 
 |                                  QuicBandwidth bandwidth, | 
 |                                  QuicTime::Delta propagation_delay) | 
 |     : OneWayLink(simulator, name, sink, bandwidth, propagation_delay), | 
 |       median_random_delay_(QuicTime::Delta::Zero()) {} | 
 |  | 
 | RandomDelayLink::~RandomDelayLink() {} | 
 |  | 
 | QuicTime::Delta RandomDelayLink::GetRandomDelay(QuicTime::Delta transfer_time) { | 
 |   // Computes a random delay following an exponential distribution, with median | 
 |   // value |median_random_delay_|.  Choose a uniform random value between 1 and | 
 |   // kNumBuckets, convert this to an exponential, then scale it such that a | 
 |   // random value from the middle of the distribution (0.5) corresponds to | 
 |   // |median_random_delay_|. | 
 |   return std::log( | 
 |              static_cast<double>( | 
 |                  simulator_->GetRandomGenerator()->RandUint64() % kNumBuckets + | 
 |                  1) / | 
 |              kNumBuckets) / | 
 |          std::log(0.5) * median_random_delay_; | 
 | } | 
 |  | 
 | SymmetricRandomDelayLink::SymmetricRandomDelayLink( | 
 |     Simulator* simulator, | 
 |     std::string name, | 
 |     UnconstrainedPortInterface* sink_a, | 
 |     UnconstrainedPortInterface* sink_b, | 
 |     QuicBandwidth bandwidth, | 
 |     QuicTime::Delta propagation_delay) | 
 |     : a_to_b_link_(simulator, | 
 |                    QuicStringPrintf("%s (A-to-B)", name.c_str()), | 
 |                    sink_b, | 
 |                    bandwidth, | 
 |                    propagation_delay), | 
 |       b_to_a_link_(simulator, | 
 |                    QuicStringPrintf("%s (B-to-A)", name.c_str()), | 
 |                    sink_a, | 
 |                    bandwidth, | 
 |                    propagation_delay) {} | 
 |  | 
 | SymmetricRandomDelayLink::SymmetricRandomDelayLink( | 
 |     Endpoint* endpoint_a, | 
 |     Endpoint* endpoint_b, | 
 |     QuicBandwidth bandwidth, | 
 |     QuicTime::Delta propagation_delay) | 
 |     : SymmetricRandomDelayLink(endpoint_a->simulator(), | 
 |                                QuicStringPrintf("Link [%s]<->[%s]", | 
 |                                                 endpoint_a->name().c_str(), | 
 |                                                 endpoint_b->name().c_str()), | 
 |                                endpoint_a->GetRxPort(), | 
 |                                endpoint_b->GetRxPort(), | 
 |                                bandwidth, | 
 |                                propagation_delay) { | 
 |   endpoint_a->SetTxPort(&a_to_b_link_); | 
 |   endpoint_b->SetTxPort(&b_to_a_link_); | 
 | } | 
 |  | 
 | }  // namespace simulator | 
 | }  // namespace quic |