// 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 "base/metrics/histogram.h"
#include "base/sys_byteorder.h"
#include "net/base/dns_util.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/dns/dns_protocol.h"
#include "net/dns/dns_response.h"
#include "net/dns/mdns_client.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(content::BrowserThread::CurrentlyOn(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].network_prefix >= 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()->message_loop_proxy()),
      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(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}

void PrivetTrafficDetector::StartOnIOThread() {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
  ScheduleRestart();
}

void PrivetTrafficDetector::OnNetworkChanged(
    net::NetworkChangeNotifier::ConnectionType type) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
  restart_attempts_ = kMaxRestartAttempts;
  if (type != net::NetworkChangeNotifier::CONNECTION_NONE)
    ScheduleRestart();
}

void PrivetTrafficDetector::ScheduleRestart() {
  DCHECK(content::BrowserThread::CurrentlyOn(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(content::BrowserThread::CurrentlyOn(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(content::BrowserThread::CurrentlyOn(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].network_prefix)) {
      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(content::BrowserThread::CurrentlyOn(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
