|  | /* | 
|  | *  Copyright 2009 The WebRTC Project Authors. All rights reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #ifndef WEBRTC_BASE_FAKENETWORK_H_ | 
|  | #define WEBRTC_BASE_FAKENETWORK_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <utility> | 
|  | #include <vector> | 
|  |  | 
|  | #include "webrtc/base/network.h" | 
|  | #include "webrtc/base/messagehandler.h" | 
|  | #include "webrtc/base/socketaddress.h" | 
|  | #include "webrtc/base/stringencode.h" | 
|  | #include "webrtc/base/thread.h" | 
|  |  | 
|  | namespace rtc { | 
|  |  | 
|  | const int kFakeIPv4NetworkPrefixLength = 24; | 
|  | const int kFakeIPv6NetworkPrefixLength = 64; | 
|  |  | 
|  | // Fake network manager that allows us to manually specify the IPs to use. | 
|  | class FakeNetworkManager : public NetworkManagerBase, | 
|  | public MessageHandler { | 
|  | public: | 
|  | FakeNetworkManager() : thread_(Thread::Current()) {} | 
|  |  | 
|  | typedef std::vector<std::pair<SocketAddress, AdapterType>> IfaceList; | 
|  |  | 
|  | void AddInterface(const SocketAddress& iface) { | 
|  | // Ensure a unique name for the interface if its name is not given. | 
|  | AddInterface(iface, "test" + rtc::ToString(next_index_++)); | 
|  | } | 
|  |  | 
|  | void AddInterface(const SocketAddress& iface, const std::string& if_name) { | 
|  | AddInterface(iface, if_name, ADAPTER_TYPE_UNKNOWN); | 
|  | } | 
|  |  | 
|  | void AddInterface(const SocketAddress& iface, | 
|  | const std::string& if_name, | 
|  | AdapterType type) { | 
|  | SocketAddress address(if_name, 0); | 
|  | address.SetResolvedIP(iface.ipaddr()); | 
|  | ifaces_.push_back(std::make_pair(address, type)); | 
|  | DoUpdateNetworks(); | 
|  | } | 
|  |  | 
|  | void RemoveInterface(const SocketAddress& iface) { | 
|  | for (IfaceList::iterator it = ifaces_.begin(); | 
|  | it != ifaces_.end(); ++it) { | 
|  | if (it->first.EqualIPs(iface)) { | 
|  | ifaces_.erase(it); | 
|  | break; | 
|  | } | 
|  | } | 
|  | DoUpdateNetworks(); | 
|  | } | 
|  |  | 
|  | virtual void StartUpdating() { | 
|  | ++start_count_; | 
|  | if (start_count_ == 1) { | 
|  | sent_first_update_ = false; | 
|  | thread_->Post(RTC_FROM_HERE, this); | 
|  | } else { | 
|  | if (sent_first_update_) { | 
|  | SignalNetworksChanged(); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | virtual void StopUpdating() { --start_count_; } | 
|  |  | 
|  | // MessageHandler interface. | 
|  | virtual void OnMessage(Message* msg) { | 
|  | DoUpdateNetworks(); | 
|  | } | 
|  |  | 
|  | using NetworkManagerBase::set_enumeration_permission; | 
|  | using NetworkManagerBase::set_default_local_addresses; | 
|  |  | 
|  | private: | 
|  | void DoUpdateNetworks() { | 
|  | if (start_count_ == 0) | 
|  | return; | 
|  | std::vector<Network*> networks; | 
|  | for (IfaceList::iterator it = ifaces_.begin(); | 
|  | it != ifaces_.end(); ++it) { | 
|  | int prefix_length = 0; | 
|  | if (it->first.ipaddr().family() == AF_INET) { | 
|  | prefix_length = kFakeIPv4NetworkPrefixLength; | 
|  | } else if (it->first.ipaddr().family() == AF_INET6) { | 
|  | prefix_length = kFakeIPv6NetworkPrefixLength; | 
|  | } | 
|  | IPAddress prefix = TruncateIP(it->first.ipaddr(), prefix_length); | 
|  | std::unique_ptr<Network> net(new Network(it->first.hostname(), | 
|  | it->first.hostname(), prefix, | 
|  | prefix_length, it->second)); | 
|  | net->set_default_local_address_provider(this); | 
|  | net->AddIP(it->first.ipaddr()); | 
|  | networks.push_back(net.release()); | 
|  | } | 
|  | bool changed; | 
|  | MergeNetworkList(networks, &changed); | 
|  | if (changed || !sent_first_update_) { | 
|  | SignalNetworksChanged(); | 
|  | sent_first_update_ = true; | 
|  | } | 
|  | } | 
|  |  | 
|  | Thread* thread_; | 
|  | IfaceList ifaces_; | 
|  | int next_index_ = 0; | 
|  | int start_count_ = 0; | 
|  | bool sent_first_update_ = false; | 
|  |  | 
|  | IPAddress default_local_ipv4_address_; | 
|  | IPAddress default_local_ipv6_address_; | 
|  | }; | 
|  |  | 
|  | }  // namespace rtc | 
|  |  | 
|  | #endif  // WEBRTC_BASE_FAKENETWORK_H_ |