1 /*
2  *  Copyright 2009 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 #ifndef RTC_BASE_FAKE_NETWORK_H_
12 #define RTC_BASE_FAKE_NETWORK_H_
13 
14 #include <memory>
15 #include <string>
16 #include <utility>
17 #include <vector>
18 
19 #include "absl/memory/memory.h"
20 #include "rtc_base/checks.h"
21 #include "rtc_base/mdns_responder_interface.h"
22 #include "rtc_base/message_handler.h"
23 #include "rtc_base/network.h"
24 #include "rtc_base/socket_address.h"
25 #include "rtc_base/string_encode.h"
26 #include "rtc_base/thread.h"
27 
28 namespace rtc {
29 
30 const int kFakeIPv4NetworkPrefixLength = 24;
31 const int kFakeIPv6NetworkPrefixLength = 64;
32 
33 // Fake network manager that allows us to manually specify the IPs to use.
34 class FakeNetworkManager : public NetworkManagerBase, public MessageHandler {
35  public:
FakeNetworkManager()36   FakeNetworkManager() {}
37 
38   typedef std::vector<std::pair<SocketAddress, AdapterType>> IfaceList;
39 
AddInterface(const SocketAddress & iface)40   void AddInterface(const SocketAddress& iface) {
41     // Ensure a unique name for the interface if its name is not given.
42     AddInterface(iface, "test" + rtc::ToString(next_index_++));
43   }
44 
AddInterface(const SocketAddress & iface,const std::string & if_name)45   void AddInterface(const SocketAddress& iface, const std::string& if_name) {
46     AddInterface(iface, if_name, ADAPTER_TYPE_UNKNOWN);
47   }
48 
AddInterface(const SocketAddress & iface,const std::string & if_name,AdapterType type)49   void AddInterface(const SocketAddress& iface,
50                     const std::string& if_name,
51                     AdapterType type) {
52     SocketAddress address(if_name, 0);
53     address.SetResolvedIP(iface.ipaddr());
54     ifaces_.push_back(std::make_pair(address, type));
55     DoUpdateNetworks();
56   }
57 
RemoveInterface(const SocketAddress & iface)58   void RemoveInterface(const SocketAddress& iface) {
59     for (IfaceList::iterator it = ifaces_.begin(); it != ifaces_.end(); ++it) {
60       if (it->first.EqualIPs(iface)) {
61         ifaces_.erase(it);
62         break;
63       }
64     }
65     DoUpdateNetworks();
66   }
67 
StartUpdating()68   void StartUpdating() override {
69     ++start_count_;
70     if (start_count_ == 1) {
71       sent_first_update_ = false;
72       rtc::Thread::Current()->Post(RTC_FROM_HERE, this);
73     } else {
74       if (sent_first_update_) {
75         SignalNetworksChanged();
76       }
77     }
78   }
79 
StopUpdating()80   void StopUpdating() override { --start_count_; }
81 
82   // MessageHandler interface.
OnMessage(Message * msg)83   void OnMessage(Message* msg) override { DoUpdateNetworks(); }
84 
85   using NetworkManagerBase::set_default_local_addresses;
86   using NetworkManagerBase::set_enumeration_permission;
87 
88   // rtc::NetworkManager override.
GetMdnsResponder()89   webrtc::MdnsResponderInterface* GetMdnsResponder() const override {
90     return mdns_responder_.get();
91   }
92 
set_mdns_responder(std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder)93   void set_mdns_responder(
94       std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder) {
95     mdns_responder_ = std::move(mdns_responder);
96   }
97 
98  private:
DoUpdateNetworks()99   void DoUpdateNetworks() {
100     if (start_count_ == 0)
101       return;
102     std::vector<Network*> networks;
103     for (IfaceList::iterator it = ifaces_.begin(); it != ifaces_.end(); ++it) {
104       int prefix_length = 0;
105       if (it->first.ipaddr().family() == AF_INET) {
106         prefix_length = kFakeIPv4NetworkPrefixLength;
107       } else if (it->first.ipaddr().family() == AF_INET6) {
108         prefix_length = kFakeIPv6NetworkPrefixLength;
109       }
110       IPAddress prefix = TruncateIP(it->first.ipaddr(), prefix_length);
111       std::unique_ptr<Network> net(new Network(it->first.hostname(),
112                                                it->first.hostname(), prefix,
113                                                prefix_length, it->second));
114       net->set_default_local_address_provider(this);
115       net->AddIP(it->first.ipaddr());
116       networks.push_back(net.release());
117     }
118     bool changed;
119     MergeNetworkList(networks, &changed);
120     if (changed || !sent_first_update_) {
121       SignalNetworksChanged();
122       sent_first_update_ = true;
123     }
124   }
125 
126   IfaceList ifaces_;
127   int next_index_ = 0;
128   int start_count_ = 0;
129   bool sent_first_update_ = false;
130 
131   std::unique_ptr<webrtc::MdnsResponderInterface> mdns_responder_;
132 };
133 
134 }  // namespace rtc
135 
136 #endif  // RTC_BASE_FAKE_NETWORK_H_
137