1 /*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "test/network/traffic_route.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <utility>
16
17 #include "absl/types/optional.h"
18 #include "rtc_base/logging.h"
19 #include "rtc_base/numerics/safe_minmax.h"
20
21 namespace webrtc {
22 namespace test {
23 namespace {
24
25 class NullReceiver : public EmulatedNetworkReceiverInterface {
26 public:
OnPacketReceived(EmulatedIpPacket packet)27 void OnPacketReceived(EmulatedIpPacket packet) override {}
28 };
29
30 class ActionReceiver : public EmulatedNetworkReceiverInterface {
31 public:
ActionReceiver(std::function<void ()> action,EmulatedEndpoint * endpoint)32 ActionReceiver(std::function<void()> action, EmulatedEndpoint* endpoint)
33 : action_(action), endpoint_(endpoint) {}
34 ~ActionReceiver() override = default;
35
OnPacketReceived(EmulatedIpPacket packet)36 void OnPacketReceived(EmulatedIpPacket packet) override {
37 RTC_DCHECK(port_);
38 action_();
39 endpoint_->UnbindReceiver(port_.value());
40 }
41
42 // We can't set port in constructor, because port will be provided by
43 // endpoint, when this receiver will be binded to that endpoint.
SetPort(uint16_t port)44 void SetPort(uint16_t port) { port_ = port; }
45
46 private:
47 std::function<void()> action_;
48 // Endpoint and port will be used to free port in the endpoint after action
49 // will be done.
50 EmulatedEndpoint* endpoint_;
51 absl::optional<uint16_t> port_ = absl::nullopt;
52 };
53
54 } // namespace
55
TrafficRoute(Clock * clock,EmulatedNetworkReceiverInterface * receiver,EmulatedEndpoint * endpoint)56 TrafficRoute::TrafficRoute(Clock* clock,
57 EmulatedNetworkReceiverInterface* receiver,
58 EmulatedEndpoint* endpoint)
59 : clock_(clock), receiver_(receiver), endpoint_(endpoint) {
60 null_receiver_ = std::make_unique<NullReceiver>();
61 absl::optional<uint16_t> port =
62 endpoint_->BindReceiver(0, null_receiver_.get());
63 RTC_DCHECK(port);
64 null_receiver_port_ = port.value();
65 }
66 TrafficRoute::~TrafficRoute() = default;
67
TriggerPacketBurst(size_t num_packets,size_t packet_size)68 void TrafficRoute::TriggerPacketBurst(size_t num_packets, size_t packet_size) {
69 for (size_t i = 0; i < num_packets; ++i) {
70 SendPacket(packet_size);
71 }
72 }
73
NetworkDelayedAction(size_t packet_size,std::function<void ()> action)74 void TrafficRoute::NetworkDelayedAction(size_t packet_size,
75 std::function<void()> action) {
76 auto action_receiver = std::make_unique<ActionReceiver>(action, endpoint_);
77 absl::optional<uint16_t> port =
78 endpoint_->BindReceiver(0, action_receiver.get());
79 RTC_DCHECK(port);
80 action_receiver->SetPort(port.value());
81 actions_.push_back(std::move(action_receiver));
82 SendPacket(packet_size, port.value());
83 }
84
SendPacket(size_t packet_size)85 void TrafficRoute::SendPacket(size_t packet_size) {
86 SendPacket(packet_size, null_receiver_port_);
87 }
88
SendPacket(size_t packet_size,uint16_t dest_port)89 void TrafficRoute::SendPacket(size_t packet_size, uint16_t dest_port) {
90 rtc::CopyOnWriteBuffer data(packet_size);
91 std::fill_n(data.data<uint8_t>(), data.size(), 0);
92 receiver_->OnPacketReceived(EmulatedIpPacket(
93 /*from=*/rtc::SocketAddress(),
94 rtc::SocketAddress(endpoint_->GetPeerLocalAddress(), dest_port), data,
95 clock_->CurrentTime()));
96 }
97
98 } // namespace test
99 } // namespace webrtc
100