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