Skip to content

Commit

Permalink
[Remoting Host] Enable RFC 7050 IP synthesis on hosts
Browse files Browse the repository at this point in the history
This CL enables DNS64/NAT64 prefix discovery and IP synthesis on the
host. This allows hosts on DNS64/NAT64 network to connect to our
IPv4-only relay servers using Chromotocol. Connections via WebRTC are
not affected because they have IPv6 relay endpoints. As stated in
CL 1392286, this does not fix direct/STUN connection between IPv4-only
and DNS64/NAT64 peers.

Non-NaCl platforms support NetworkChangeNotifier so the host will
refresh the prefix only when the network interface has been changed,
rather than refreshing it every time we are about to make the
connection.

Bug: 914617
Change-Id: I458156fa1221d8755e84e62b8409b1cb15d1f024
Reviewed-on: https://chromium-review.googlesource.com/c/1392360
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Reviewed-by: Joe Downing <joedow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#621399}
  • Loading branch information
ywh233 authored and Commit Bot committed Jan 10, 2019
1 parent 6e94be6 commit 1132c58
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 3 deletions.
3 changes: 3 additions & 0 deletions remoting/host/chromoting_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "remoting/protocol/host_stub.h"
#include "remoting/protocol/ice_connection_to_client.h"
#include "remoting/protocol/input_stub.h"
#include "remoting/protocol/native_ip_synthesizer.h"
#include "remoting/protocol/transport_context.h"
#include "remoting/protocol/webrtc_connection_to_client.h"

Expand Down Expand Up @@ -110,6 +111,8 @@ void ChromotingHost::Start(const std::string& host_owner_email) {
for (auto& observer : status_monitor_->observers())
observer.OnStart(host_owner_email);

protocol::InitializeNativeIpSynthesizer();

session_manager_->AcceptIncoming(
base::Bind(&ChromotingHost::OnIncomingSession, base::Unretained(this)));
}
Expand Down
12 changes: 9 additions & 3 deletions remoting/host/chromoting_host_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "net/base/network_change_notifier.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/host/audio_capturer.h"
#include "remoting/host/chromoting_host_context.h"
Expand Down Expand Up @@ -62,11 +65,13 @@ class ChromotingHostTest : public testing::Test {
ChromotingHostTest() = default;

void SetUp() override {
task_runner_ = new AutoThreadTaskRunner(message_loop_.task_runner(),
network_change_notifier_.reset(net::NetworkChangeNotifier::Create());

task_runner_ = new AutoThreadTaskRunner(base::ThreadTaskRunnerHandle::Get(),
base::DoNothing());

desktop_environment_factory_.reset(
new FakeDesktopEnvironmentFactory(message_loop_.task_runner()));
new FakeDesktopEnvironmentFactory(base::ThreadTaskRunnerHandle::Get()));
session_manager_ = new protocol::MockSessionManager();

host_.reset(new ChromotingHost(
Expand Down Expand Up @@ -205,7 +210,8 @@ class ChromotingHostTest : public testing::Test {
}

protected:
base::MessageLoop message_loop_;
base::test::ScopedTaskEnvironment scoped_task_environment_;
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
scoped_refptr<AutoThreadTaskRunner> task_runner_;
MockConnectionToClientEventHandler handler_;
std::unique_ptr<FakeDesktopEnvironmentFactory> desktop_environment_factory_;
Expand Down
5 changes: 5 additions & 0 deletions remoting/host/it2me/it2me_host_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/policy/policy_constants.h"
#include "net/base/network_change_notifier.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/host/chromoting_host.h"
#include "remoting/host/chromoting_host_context.h"
Expand Down Expand Up @@ -191,6 +192,8 @@ class It2MeHostTest : public testing::Test, public It2MeHost::Observer {
std::unique_ptr<base::RunLoop> run_loop_;
std::unique_ptr<FakeSignalStrategy> fake_bot_signal_strategy_;

std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;

std::unique_ptr<ChromotingHostContext> host_context_;
scoped_refptr<AutoThreadTaskRunner> network_task_runner_;
scoped_refptr<AutoThreadTaskRunner> ui_task_runner_;
Expand All @@ -211,6 +214,8 @@ void It2MeHostTest::SetUp() {
#endif
run_loop_.reset(new base::RunLoop());

network_change_notifier_.reset(net::NetworkChangeNotifier::Create());

host_context_ = ChromotingHostContext::Create(new AutoThreadTaskRunner(
base::ThreadTaskRunnerHandle::Get(), run_loop_->QuitClosure()));
network_task_runner_ = host_context_->network_task_runner();
Expand Down
5 changes: 5 additions & 0 deletions remoting/host/it2me/it2me_native_messaging_host_main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "base/task/task_scheduler/task_scheduler.h"
#include "build/build_config.h"
#include "mojo/core/embedder/embedder.h"
#include "net/base/network_change_notifier.h"
#include "remoting/base/auto_thread_task_runner.h"
#include "remoting/base/breakpad.h"
#include "remoting/host/chromoting_host_context.h"
Expand Down Expand Up @@ -201,6 +202,10 @@ int It2MeNativeMessagingHostMain(int argc, char** argv) {
base::MessageLoopForUI message_loop;
base::RunLoop run_loop;

// NetworkChangeNotifier must be initialized after MessageLoop.
std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier(
net::NetworkChangeNotifier::Create());

std::unique_ptr<It2MeHostFactory> factory(new It2MeHostFactory());

std::unique_ptr<NativeMessagingPipe> native_messaging_pipe(
Expand Down
2 changes: 2 additions & 0 deletions remoting/protocol/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ static_library("protocol") {
"chromium_port_allocator_factory.h",
"chromium_socket_factory.cc",
"chromium_socket_factory.h",
"rfc7050_prefix_refresher.cc",
"rfc7050_prefix_refresher.h",
"webrtc_audio_module.cc",
"webrtc_audio_module.h",
"webrtc_audio_sink_adapter.cc",
Expand Down
5 changes: 5 additions & 0 deletions remoting/protocol/native_ip_synthesizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "base/no_destructor.h"
#include "net/base/sys_addrinfo.h"
#include "remoting/protocol/rfc7050_ip_synthesizer.h"
#include "remoting/protocol/rfc7050_prefix_refresher.h"
#include "third_party/webrtc/rtc_base/ipaddress.h"
#include "third_party/webrtc/rtc_base/socketaddress.h"

Expand Down Expand Up @@ -60,6 +61,10 @@ rtc::SocketAddress ToNativeSocket(const rtc::SocketAddress& original_socket) {
void RefreshNativeIpSynthesizer(base::OnceClosure on_done) {
Rfc7050IpSynthesizer::GetInstance()->UpdateDns64Prefix(std::move(on_done));
}
#elif !defined(OS_ANDROID) && !defined(OS_IOS)
void InitializeNativeIpSynthesizer() {
static base::NoDestructor<Rfc7050PrefixRefresher> refresher;
}
#endif

} // namespace protocol
Expand Down
9 changes: 9 additions & 0 deletions remoting/protocol/native_ip_synthesizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,16 @@ rtc::SocketAddress ToNativeSocket(const rtc::SocketAddress& original_socket);
// NetworkChangeNotifier, so caller must manually refresh to make sure the
// synthesizer is up to date.
void RefreshNativeIpSynthesizer(base::OnceClosure on_done);
#elif !defined(OS_ANDROID) && !defined(OS_IOS)
// Call this to setup the native IP synthesizer. Does nothing if the synthesizer
// is already initialized.
//
// This will cause the IP synthesizer to refresh itself when this function is
// first called, and every time the network conditions are changed.
void InitializeNativeIpSynthesizer();
#endif
// Android and iOS have built-in IPv6 synthesizing logic so refreshing IP
// synthesizer is not needed.

} // namespace protocol
} // namespace remoting
Expand Down
72 changes: 72 additions & 0 deletions remoting/protocol/rfc7050_prefix_refresher.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright 2019 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 "remoting/protocol/rfc7050_prefix_refresher.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "remoting/protocol/rfc7050_ip_synthesizer.h"

namespace {
// Network changes will fire multiple notifications in a short period of time.
// This delay reduces the number of DNS queries being sent out.
constexpr base::TimeDelta kRefreshDelay =
base::TimeDelta::FromMilliseconds(500);
} // namespace

namespace remoting {
namespace protocol {

Rfc7050PrefixRefresher::Rfc7050PrefixRefresher()
: ip_synthesizer_(Rfc7050IpSynthesizer::GetInstance()),
task_runner_(base::ThreadTaskRunnerHandle::Get()),
weak_factory_(this) {
DCHECK(net::NetworkChangeNotifier::HasNetworkChangeNotifier());

// The first update should be run immediately so that the IP synthesizer is
// ready to use right after the constructor is run.
OnUpdateDns64Prefix();

net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
net::NetworkChangeNotifier::AddDNSObserver(this);
}

Rfc7050PrefixRefresher::~Rfc7050PrefixRefresher() {
net::NetworkChangeNotifier::RemoveDNSObserver(this);
net::NetworkChangeNotifier::RemoveNetworkChangeObserver(this);
}

void Rfc7050PrefixRefresher::OnDNSChanged() {
ScheduleUpdateDns64Prefix();
}

void Rfc7050PrefixRefresher::OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) {
ScheduleUpdateDns64Prefix();
}

void Rfc7050PrefixRefresher::ScheduleUpdateDns64Prefix() {
DCHECK(task_runner_->BelongsToCurrentThread());
if (update_dns64_prefix_scheduled_) {
return;
}
update_dns64_prefix_scheduled_ = true;
task_runner_->PostDelayedTask(
FROM_HERE,
base::BindOnce(&Rfc7050PrefixRefresher::OnUpdateDns64Prefix,
weak_factory_.GetWeakPtr()),
kRefreshDelay);
}

void Rfc7050PrefixRefresher::OnUpdateDns64Prefix() {
DCHECK(task_runner_->BelongsToCurrentThread());
update_dns64_prefix_scheduled_ = false;
ip_synthesizer_->UpdateDns64Prefix(base::DoNothing());
}

} // namespace protocol
} // namespace remoting
49 changes: 49 additions & 0 deletions remoting/protocol/rfc7050_prefix_refresher.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2019 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.

#ifndef REMOTING_PROTOCOL_RFC7050_PREFIX_REFRESHER_H_
#define REMOTING_PROTOCOL_RFC7050_PREFIX_REFRESHER_H_

#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "net/base/network_change_notifier.h"

namespace remoting {
namespace protocol {

class Rfc7050IpSynthesizer;

// Helper class to observe network changes and update Rfc7050IpSynthesizer's
// DNS64 prefix when the network is changed.
class Rfc7050PrefixRefresher
: public net::NetworkChangeNotifier::DNSObserver,
public net::NetworkChangeNotifier::NetworkChangeObserver {
public:
Rfc7050PrefixRefresher();
~Rfc7050PrefixRefresher() override;

private:
// DNSObserver override.
void OnDNSChanged() override;

// NetworkChangeObserver override.
void OnNetworkChanged(
net::NetworkChangeNotifier::ConnectionType type) override;

void ScheduleUpdateDns64Prefix();
void OnUpdateDns64Prefix();

bool update_dns64_prefix_scheduled_ = false;
Rfc7050IpSynthesizer* ip_synthesizer_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtrFactory<Rfc7050PrefixRefresher> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(Rfc7050PrefixRefresher);
};

} // namespace protocol
} // namespace remoting

#endif // REMOTING_PROTOCOL_RFC7050_PREFIX_REFRESHER_H_

0 comments on commit 1132c58

Please sign in to comment.