• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/renderer/p2p/ipc_network_manager.h"
6 
7 #include "base/bind.h"
8 #include "base/sys_byteorder.h"
9 #include "net/base/net_util.h"
10 
11 namespace content {
12 
IpcNetworkManager(P2PSocketDispatcher * socket_dispatcher)13 IpcNetworkManager::IpcNetworkManager(P2PSocketDispatcher* socket_dispatcher)
14     : socket_dispatcher_(socket_dispatcher),
15       start_count_(0),
16       network_list_received_(false),
17       weak_factory_(this) {
18   socket_dispatcher_->AddNetworkListObserver(this);
19 }
20 
~IpcNetworkManager()21 IpcNetworkManager::~IpcNetworkManager() {
22   DCHECK(!start_count_);
23   socket_dispatcher_->RemoveNetworkListObserver(this);
24 }
25 
StartUpdating()26 void IpcNetworkManager::StartUpdating() {
27   if (network_list_received_) {
28     // Post a task to avoid reentrancy.
29     base::MessageLoop::current()->PostTask(
30         FROM_HERE,
31         base::Bind(&IpcNetworkManager::SendNetworksChangedSignal,
32                    weak_factory_.GetWeakPtr()));
33   }
34   ++start_count_;
35 }
36 
StopUpdating()37 void IpcNetworkManager::StopUpdating() {
38   DCHECK_GT(start_count_, 0);
39   --start_count_;
40 }
41 
OnNetworkListChanged(const net::NetworkInterfaceList & list)42 void IpcNetworkManager::OnNetworkListChanged(
43     const net::NetworkInterfaceList& list) {
44 
45   // Update flag if network list received for the first time.
46   if (!network_list_received_)
47     network_list_received_ = true;
48 
49   // Note: 32 and 64 are the arbitrary(kind of) prefix length used to
50   // differentiate IPv4 and IPv6 addresses.
51   // talk_base::Network uses these prefix_length to compare network
52   // interfaces discovered.
53   std::vector<talk_base::Network*> networks;
54   for (net::NetworkInterfaceList::const_iterator it = list.begin();
55        it != list.end(); it++) {
56     if (it->address.size() == net::kIPv4AddressSize) {
57       uint32 address;
58       memcpy(&address, &it->address[0], sizeof(uint32));
59       address = talk_base::NetworkToHost32(address);
60       talk_base::Network* network = new talk_base::Network(
61           it->name, it->name, talk_base::IPAddress(address), 32);
62       network->AddIP(talk_base::IPAddress(address));
63       networks.push_back(network);
64     } else if (it->address.size() == net::kIPv6AddressSize) {
65       in6_addr address;
66       memcpy(&address, &it->address[0], sizeof(in6_addr));
67       talk_base::IPAddress ip6_addr(address);
68       if (!talk_base::IPIsPrivate(ip6_addr)) {
69         talk_base::Network* network = new talk_base::Network(
70             it->name, it->name, ip6_addr, 64);
71         network->AddIP(ip6_addr);
72         networks.push_back(network);
73       }
74     }
75   }
76 
77   bool changed = false;
78   MergeNetworkList(networks, &changed);
79   if (changed)
80     SignalNetworksChanged();
81 }
82 
SendNetworksChangedSignal()83 void IpcNetworkManager::SendNetworksChangedSignal() {
84   SignalNetworksChanged();
85 }
86 
87 }  // namespace content
88