| Index: chrome/browser/local_discovery/privet_traffic_detector.cc
|
| diff --git a/chrome/browser/local_discovery/privet_traffic_detector.cc b/chrome/browser/local_discovery/privet_traffic_detector.cc
|
| deleted file mode 100644
|
| index 687b6f1d56685411283e6b0e9b42a270ac69ecce..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/local_discovery/privet_traffic_detector.cc
|
| +++ /dev/null
|
| @@ -1,203 +0,0 @@
|
| -// Copyright 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "chrome/browser/local_discovery/privet_traffic_detector.h"
|
| -
|
| -#include <stddef.h>
|
| -
|
| -#include "base/location.h"
|
| -#include "base/macros.h"
|
| -#include "base/metrics/histogram.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/sys_byteorder.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/network_interfaces.h"
|
| -#include "net/dns/dns_protocol.h"
|
| -#include "net/dns/dns_response.h"
|
| -#include "net/dns/mdns_client.h"
|
| -#include "net/log/net_log.h"
|
| -#include "net/udp/datagram_server_socket.h"
|
| -#include "net/udp/udp_server_socket.h"
|
| -
|
| -namespace {
|
| -
|
| -const int kMaxRestartAttempts = 10;
|
| -const char kPrivetDeviceTypeDnsString[] = "\x07_privet";
|
| -
|
| -void GetNetworkListOnFileThread(
|
| - const base::Callback<void(const net::NetworkInterfaceList&)> callback) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
|
| - net::NetworkInterfaceList networks;
|
| - if (!GetNetworkList(&networks, net::INCLUDE_HOST_SCOPE_VIRTUAL_INTERFACES))
|
| - return;
|
| -
|
| - net::NetworkInterfaceList ip4_networks;
|
| - for (size_t i = 0; i < networks.size(); ++i) {
|
| - net::AddressFamily address_family =
|
| - net::GetAddressFamily(networks[i].address);
|
| - if (address_family == net::ADDRESS_FAMILY_IPV4 &&
|
| - networks[i].prefix_length >= 24) {
|
| - ip4_networks.push_back(networks[i]);
|
| - }
|
| - }
|
| -
|
| - net::IPAddressNumber localhost_prefix(4, 0);
|
| - localhost_prefix[0] = 127;
|
| - ip4_networks.push_back(
|
| - net::NetworkInterface("lo",
|
| - "lo",
|
| - 0,
|
| - net::NetworkChangeNotifier::CONNECTION_UNKNOWN,
|
| - localhost_prefix,
|
| - 8,
|
| - net::IP_ADDRESS_ATTRIBUTE_NONE));
|
| - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
|
| - base::Bind(callback, ip4_networks));
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -namespace local_discovery {
|
| -
|
| -PrivetTrafficDetector::PrivetTrafficDetector(
|
| - net::AddressFamily address_family,
|
| - const base::Closure& on_traffic_detected)
|
| - : on_traffic_detected_(on_traffic_detected),
|
| - callback_runner_(base::MessageLoop::current()->task_runner()),
|
| - address_family_(address_family),
|
| - io_buffer_(
|
| - new net::IOBufferWithSize(net::dns_protocol::kMaxMulticastSize)),
|
| - restart_attempts_(kMaxRestartAttempts),
|
| - weak_ptr_factory_(this) {
|
| -}
|
| -
|
| -void PrivetTrafficDetector::Start() {
|
| - content::BrowserThread::PostTask(
|
| - content::BrowserThread::IO,
|
| - FROM_HERE,
|
| - base::Bind(&PrivetTrafficDetector::StartOnIOThread,
|
| - weak_ptr_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -PrivetTrafficDetector::~PrivetTrafficDetector() {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
|
| -}
|
| -
|
| -void PrivetTrafficDetector::StartOnIOThread() {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
|
| - ScheduleRestart();
|
| -}
|
| -
|
| -void PrivetTrafficDetector::OnNetworkChanged(
|
| - net::NetworkChangeNotifier::ConnectionType type) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - restart_attempts_ = kMaxRestartAttempts;
|
| - if (type != net::NetworkChangeNotifier::CONNECTION_NONE)
|
| - ScheduleRestart();
|
| -}
|
| -
|
| -void PrivetTrafficDetector::ScheduleRestart() {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - socket_.reset();
|
| - weak_ptr_factory_.InvalidateWeakPtrs();
|
| - content::BrowserThread::PostDelayedTask(
|
| - content::BrowserThread::FILE,
|
| - FROM_HERE,
|
| - base::Bind(&GetNetworkListOnFileThread,
|
| - base::Bind(&PrivetTrafficDetector::Restart,
|
| - weak_ptr_factory_.GetWeakPtr())),
|
| - base::TimeDelta::FromSeconds(3));
|
| -}
|
| -
|
| -void PrivetTrafficDetector::Restart(const net::NetworkInterfaceList& networks) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - networks_ = networks;
|
| - if (Bind() < net::OK || DoLoop(0) < net::OK) {
|
| - if ((restart_attempts_--) > 0)
|
| - ScheduleRestart();
|
| - } else {
|
| - // Reset on success.
|
| - restart_attempts_ = kMaxRestartAttempts;
|
| - }
|
| -}
|
| -
|
| -int PrivetTrafficDetector::Bind() {
|
| - if (!start_time_.is_null()) {
|
| - base::TimeDelta time_delta = base::Time::Now() - start_time_;
|
| - UMA_HISTOGRAM_LONG_TIMES("LocalDiscovery.DetectorRestartTime", time_delta);
|
| - }
|
| - start_time_ = base::Time::Now();
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - socket_.reset(new net::UDPServerSocket(NULL, net::NetLog::Source()));
|
| - net::IPEndPoint multicast_addr = net::GetMDnsIPEndPoint(address_family_);
|
| - net::IPAddressNumber address_any(multicast_addr.address().size());
|
| - net::IPEndPoint bind_endpoint(address_any, multicast_addr.port());
|
| - socket_->AllowAddressReuse();
|
| - int rv = socket_->Listen(bind_endpoint);
|
| - if (rv < net::OK)
|
| - return rv;
|
| - socket_->SetMulticastLoopbackMode(false);
|
| - return socket_->JoinGroup(multicast_addr.address());
|
| -}
|
| -
|
| -bool PrivetTrafficDetector::IsSourceAcceptable() const {
|
| - for (size_t i = 0; i < networks_.size(); ++i) {
|
| - if (net::IPNumberMatchesPrefix(recv_addr_.address(), networks_[i].address,
|
| - networks_[i].prefix_length)) {
|
| - return true;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool PrivetTrafficDetector::IsPrivetPacket(int rv) const {
|
| - if (rv <= static_cast<int>(sizeof(net::dns_protocol::Header)) ||
|
| - !IsSourceAcceptable()) {
|
| - return false;
|
| - }
|
| -
|
| - const char* buffer_begin = io_buffer_->data();
|
| - const char* buffer_end = buffer_begin + rv;
|
| - const net::dns_protocol::Header* header =
|
| - reinterpret_cast<const net::dns_protocol::Header*>(buffer_begin);
|
| - // Check if response packet.
|
| - if (!(header->flags & base::HostToNet16(net::dns_protocol::kFlagResponse)))
|
| - return false;
|
| - const char* substring_begin = kPrivetDeviceTypeDnsString;
|
| - const char* substring_end = substring_begin +
|
| - arraysize(kPrivetDeviceTypeDnsString) - 1;
|
| - // Check for expected substring, any Privet device must include this.
|
| - return std::search(buffer_begin, buffer_end, substring_begin,
|
| - substring_end) != buffer_end;
|
| -}
|
| -
|
| -int PrivetTrafficDetector::DoLoop(int rv) {
|
| - DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
|
| - do {
|
| - if (IsPrivetPacket(rv)) {
|
| - socket_.reset();
|
| - callback_runner_->PostTask(FROM_HERE, on_traffic_detected_);
|
| - base::TimeDelta time_delta = base::Time::Now() - start_time_;
|
| - UMA_HISTOGRAM_LONG_TIMES("LocalDiscovery.DetectorTriggerTime",
|
| - time_delta);
|
| - return net::OK;
|
| - }
|
| -
|
| - rv = socket_->RecvFrom(
|
| - io_buffer_.get(),
|
| - io_buffer_->size(),
|
| - &recv_addr_,
|
| - base::Bind(base::IgnoreResult(&PrivetTrafficDetector::DoLoop),
|
| - base::Unretained(this)));
|
| - } while (rv > 0);
|
| -
|
| - if (rv != net::ERR_IO_PENDING)
|
| - return rv;
|
| -
|
| - return net::OK;
|
| -}
|
| -
|
| -} // namespace local_discovery
|
|
|