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