| Index: net/quic/test_tools/simulator/traffic_policer.cc
|
| diff --git a/net/quic/test_tools/simulator/traffic_policer.cc b/net/quic/test_tools/simulator/traffic_policer.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..84ea4db0f24389cb3c2d7fad94bd6cbcd67b02ca
|
| --- /dev/null
|
| +++ b/net/quic/test_tools/simulator/traffic_policer.cc
|
| @@ -0,0 +1,86 @@
|
| +// Copyright (c) 2016 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/quic/test_tools/simulator/traffic_policer.h"
|
| +
|
| +#include <algorithm>
|
| +
|
| +namespace net {
|
| +namespace simulator {
|
| +
|
| +TrafficPolicer::TrafficPolicer(Simulator* simulator,
|
| + std::string name,
|
| + QuicByteCount initial_bucket_size,
|
| + QuicByteCount max_bucket_size,
|
| + QuicBandwidth target_bandwidth,
|
| + Endpoint* input)
|
| + : Actor(simulator, name),
|
| + initial_bucket_size_(initial_bucket_size),
|
| + max_bucket_size_(max_bucket_size),
|
| + target_bandwidth_(target_bandwidth),
|
| + last_refill_time_(clock_->Now()),
|
| + input_(input),
|
| + output_(this) {
|
| + input_->SetTxPort(this);
|
| +}
|
| +
|
| +TrafficPolicer::~TrafficPolicer() {}
|
| +
|
| +void TrafficPolicer::Act() {}
|
| +
|
| +void TrafficPolicer::Refill() {
|
| + QuicTime::Delta time_passed = clock_->Now() - last_refill_time_;
|
| + QuicByteCount refill_size = time_passed * target_bandwidth_;
|
| +
|
| + for (auto& bucket : token_buckets_) {
|
| + bucket.second = std::min(bucket.second + refill_size, max_bucket_size_);
|
| + }
|
| +
|
| + last_refill_time_ = clock_->Now();
|
| +}
|
| +
|
| +void TrafficPolicer::AcceptPacket(std::unique_ptr<Packet> packet) {
|
| + // Refill existing buckets.
|
| + Refill();
|
| +
|
| + // Create a new bucket if one does not exist.
|
| + if (token_buckets_.count(packet->destination) == 0) {
|
| + token_buckets_.insert(
|
| + std::make_pair(packet->destination, initial_bucket_size_));
|
| + }
|
| +
|
| + auto bucket = token_buckets_.find(packet->destination);
|
| + DCHECK(bucket != token_buckets_.end());
|
| +
|
| + // Silently drop the packet on the floor if out of tokens
|
| + if (bucket->second < packet->size) {
|
| + return;
|
| + }
|
| +
|
| + bucket->second -= packet->size;
|
| + output_tx_port_->AcceptPacket(std::move(packet));
|
| +}
|
| +
|
| +QuicTime::Delta TrafficPolicer::TimeUntilAvailable() {
|
| + return output_tx_port_->TimeUntilAvailable();
|
| +}
|
| +
|
| +TrafficPolicer::Output::Output(TrafficPolicer* policer)
|
| + : Endpoint(policer->simulator(), policer->name() + " (output port)"),
|
| + policer_(policer) {}
|
| +
|
| +TrafficPolicer::Output::~Output() {}
|
| +
|
| +UnconstrainedPortInterface* TrafficPolicer::Output::GetRxPort() {
|
| + return policer_->input_->GetRxPort();
|
| +}
|
| +
|
| +void TrafficPolicer::Output::SetTxPort(ConstrainedPortInterface* port) {
|
| + policer_->output_tx_port_ = port;
|
| +}
|
| +
|
| +void TrafficPolicer::Output::Act() {}
|
| +
|
| +} // namespace simulator
|
| +} // namespace net
|
|
|