Commit 2367ac92 authored by Kartik Hegde's avatar Kartik Hegde Committed by Commit Bot

network_diagnostics: Add ResolverPresentRoutine

Add a routine to determine whether the current network has nameservers
available for DNS resolution.

BUG=chromium:956783
TEST=unit_tests --gtest_filter=ResolverPresentRoutineTest.*

Change-Id: Ic9055f2bdce2df0e5bd8c3e147a635cd0e6a31c8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2151676Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Kartik Hegde <khegde@chromium.org>
Cr-Commit-Position: refs/heads/master@{#770840}
parent ba82f691
......@@ -1745,6 +1745,8 @@ source_set("chromeos") {
"net/delay_network_call.h",
"net/dhcp_wpad_url_client.cc",
"net/dhcp_wpad_url_client.h",
"net/network_diagnostics/dns_resolver_present_routine.cc",
"net/network_diagnostics/dns_resolver_present_routine.h",
"net/network_diagnostics/gateway_can_be_pinged_routine.cc",
"net/network_diagnostics/gateway_can_be_pinged_routine.h",
"net/network_diagnostics/has_secure_wifi_connection_routine.cc",
......@@ -3079,6 +3081,7 @@ source_set("unit_tests") {
"login/version_updater/version_updater_unittest.cc",
"mobile/mobile_activator_unittest.cc",
"net/client_cert_store_chromeos_unittest.cc",
"net/network_diagnostics/dns_resolver_present_routine_unittest.cc",
"net/network_diagnostics/gateway_can_be_pinged_routine_unittest.cc",
"net/network_diagnostics/has_secure_wifi_connection_routine_unittest.cc",
"net/network_diagnostics/lan_connectivity_routine_unittest.cc",
......
// Copyright 2020 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/chromeos/net/network_diagnostics/dns_resolver_present_routine.h"
#include <string>
#include <utility>
#include <vector>
#include "base/bind.h"
#include "base/optional.h"
#include "chromeos/services/network_config/in_process_instance.h"
#include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace chromeos {
namespace network_diagnostics {
namespace {
bool NameServersAreWellFormed(const std::vector<std::string>& name_servers) {
for (const auto& name_server : name_servers) {
if (name_server == "0.0.0.0" || name_server == "::/0") {
return false;
}
}
return true;
}
bool NameServersAreNonEmpty(const std::vector<std::string>& name_servers) {
for (const auto& name_server : name_servers) {
if (name_server.empty()) {
return false;
}
}
return true;
}
} // namespace
DnsResolverPresentRoutine::DnsResolverPresentRoutine() {
set_verdict(mojom::RoutineVerdict::kNotRun);
network_config::BindToInProcessInstance(
remote_cros_network_config_.BindNewPipeAndPassReceiver());
}
DnsResolverPresentRoutine::~DnsResolverPresentRoutine() = default;
bool DnsResolverPresentRoutine::CanRun() {
DCHECK(remote_cros_network_config_);
return true;
}
void DnsResolverPresentRoutine::RunTest(
mojom::NetworkDiagnosticsRoutines::DnsResolverPresentCallback callback) {
if (!CanRun()) {
std::move(callback).Run(verdict(), std::move(problems_));
return;
}
routine_completed_callback_ = std::move(callback);
FetchActiveNetworks();
}
void DnsResolverPresentRoutine::AnalyzeResultsAndExecuteCallback() {
if (!name_servers_found_) {
set_verdict(mojom::RoutineVerdict::kProblem);
problems_.emplace_back(
mojom::DnsResolverPresentProblem::kNoNameServersFound);
} else if (!non_empty_name_servers_) {
set_verdict(mojom::RoutineVerdict::kProblem);
problems_.emplace_back(mojom::DnsResolverPresentProblem::kEmptyNameServers);
} else if (!well_formed_name_servers_) {
set_verdict(mojom::RoutineVerdict::kProblem);
problems_.emplace_back(
mojom::DnsResolverPresentProblem::kMalformedNameServers);
} else {
// The availability of non-empty, well-formed nameservers ensures that DNS
// resolution should be possible.
set_verdict(mojom::RoutineVerdict::kNoProblem);
}
std::move(routine_completed_callback_).Run(verdict(), std::move(problems_));
}
void DnsResolverPresentRoutine::FetchActiveNetworks() {
DCHECK(remote_cros_network_config_);
remote_cros_network_config_->GetNetworkStateList(
network_config::mojom::NetworkFilter::New(
network_config::mojom::FilterType::kActive,
network_config::mojom::NetworkType::kAll,
network_config::mojom::kNoLimit),
base::BindOnce(&DnsResolverPresentRoutine::OnNetworkStateListReceived,
base::Unretained(this)));
}
void DnsResolverPresentRoutine::FetchManagedProperties(
const std::string& guid) {
remote_cros_network_config_->GetManagedProperties(
guid,
base::BindOnce(&DnsResolverPresentRoutine::OnManagedPropertiesReceived,
base::Unretained(this)));
}
void DnsResolverPresentRoutine::OnManagedPropertiesReceived(
network_config::mojom::ManagedPropertiesPtr managed_properties) {
if (!managed_properties || !managed_properties->ip_configs.has_value()) {
AnalyzeResultsAndExecuteCallback();
return;
}
for (const auto& ip_config : managed_properties->ip_configs.value()) {
if (ip_config->name_servers.has_value() &&
ip_config->name_servers->size() != 0) {
name_servers_found_ = true;
if (NameServersAreNonEmpty(ip_config->name_servers.value())) {
non_empty_name_servers_ = true;
}
if (NameServersAreWellFormed(ip_config->name_servers.value())) {
well_formed_name_servers_ = true;
break;
}
}
}
AnalyzeResultsAndExecuteCallback();
}
// Process the network interface information.
void DnsResolverPresentRoutine::OnNetworkStateListReceived(
std::vector<network_config::mojom::NetworkStatePropertiesPtr> networks) {
std::string default_guid;
for (const auto& network : networks) {
if (network_config::StateIsConnected(network->connection_state)) {
default_guid = network->guid;
break;
}
}
// Since we are not connected, proceed to analyzing the results and executing
// the completion callback.
if (default_guid.empty()) {
AnalyzeResultsAndExecuteCallback();
} else {
FetchManagedProperties(default_guid);
}
}
} // namespace network_diagnostics
} // namespace chromeos
// Copyright 2020 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 CHROME_BROWSER_CHROMEOS_NET_NETWORK_DIAGNOSTICS_DNS_RESOLVER_PRESENT_ROUTINE_H_
#define CHROME_BROWSER_CHROMEOS_NET_NETWORK_DIAGNOSTICS_DNS_RESOLVER_PRESENT_ROUTINE_H_
#include <vector>
#include "base/callback.h"
#include "chrome/browser/chromeos/net/network_diagnostics/network_diagnostics_routine.h"
#include "chromeos/services/network_config/public/mojom/cros_network_config.mojom.h"
#include "mojo/public/cpp/bindings/remote.h"
namespace chromeos {
namespace network_diagnostics {
// Tests whether the current network is set up correctly for performing DNS
// resolution.
class DnsResolverPresentRoutine : public NetworkDiagnosticsRoutine {
public:
DnsResolverPresentRoutine();
~DnsResolverPresentRoutine() override;
// NetworkDiagnosticsRoutine:
bool CanRun() override;
void AnalyzeResultsAndExecuteCallback() override;
// Run the core logic of this routine. Set |callback| to
// |routine_completed_callback_|, which is to be executed in
// AnalyzeResultsAndExecuteCallback().
void RunTest(
mojom::NetworkDiagnosticsRoutines::DnsResolverPresentCallback callback);
private:
void FetchActiveNetworks();
void FetchManagedProperties(const std::string& guid);
void OnManagedPropertiesReceived(
chromeos::network_config::mojom::ManagedPropertiesPtr managed_properties);
void OnNetworkStateListReceived(
std::vector<chromeos::network_config::mojom::NetworkStatePropertiesPtr>
networks);
bool name_servers_found_ = false;
bool non_empty_name_servers_ = false;
bool well_formed_name_servers_ = false;
std::vector<mojom::DnsResolverPresentProblem> problems_;
mojo::Remote<chromeos::network_config::mojom::CrosNetworkConfig>
remote_cros_network_config_;
mojom::NetworkDiagnosticsRoutines::DnsResolverPresentCallback
routine_completed_callback_;
DISALLOW_COPY_AND_ASSIGN(DnsResolverPresentRoutine);
};
} // namespace network_diagnostics
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_DIAGNOSTICS_DNS_RESOLVER_PRESENT_ROUTINE_H_
......@@ -46,6 +46,14 @@ enum HasSecureWiFiConnectionProblem {
kUnknownSecurityType,
};
// Messages related to the DnsResolverPresent routine.
[Extensible]
enum DnsResolverPresentProblem {
kNoNameServersFound,
kMalformedNameServers,
kEmptyNameServers,
};
// This interface is to be used by any clients that need to run specific
// network-related diagnostics. Expected clients of this interface are
// NetworkHealth, cros_healthd, and a connectivity diagnostics Web UI (to name
......@@ -69,4 +77,8 @@ interface NetworkDiagnosticsRoutines {
// connected, the routine will result in a |kNotRun| verdict.
HasSecureWiFiConnection() => (RoutineVerdict verdict,
array<HasSecureWiFiConnectionProblem> problems);
// Tests whether a DNS resolver is available to the browser.
DnsResolverPresent() => (RoutineVerdict verdict,
array<DnsResolverPresentProblem> problems);
};
......@@ -6,6 +6,7 @@
#include <memory>
#include "chrome/browser/chromeos/net/network_diagnostics/dns_resolver_present_routine.h"
#include "chrome/browser/chromeos/net/network_diagnostics/gateway_can_be_pinged_routine.h"
#include "chrome/browser/chromeos/net/network_diagnostics/has_secure_wifi_connection_routine.h"
#include "chrome/browser/chromeos/net/network_diagnostics/lan_connectivity_routine.h"
......@@ -51,5 +52,11 @@ void NetworkDiagnosticsImpl::HasSecureWiFiConnection(
has_secure_wifi_connection_routine.RunTest(std::move(callback));
}
void NetworkDiagnosticsImpl::DnsResolverPresent(
DnsResolverPresentCallback callback) {
DnsResolverPresentRoutine dns_resolver_present_routine;
dns_resolver_present_routine.RunTest(std::move(callback));
}
} // namespace network_diagnostics
} // namespace chromeos
......@@ -30,6 +30,7 @@ class NetworkDiagnosticsImpl : public mojom::NetworkDiagnosticsRoutines {
void GatewayCanBePinged(GatewayCanBePingedCallback callback) override;
void HasSecureWiFiConnection(
HasSecureWiFiConnectionCallback callback) override;
void DnsResolverPresent(DnsResolverPresentCallback callback) override;
private:
mojo::ReceiverSet<mojom::NetworkDiagnosticsRoutines> receivers_;
......
......@@ -39,6 +39,7 @@ NetworkStateTestHelper::NetworkStateTestHelper(
profile_test_ = ShillProfileClient::Get()->GetTestInterface();
device_test_ = ShillDeviceClient::Get()->GetTestInterface();
service_test_ = ShillServiceClient::Get()->GetTestInterface();
ip_config_test_ = ShillIPConfigClient::Get()->GetTestInterface();
profile_test_->AddProfile(NetworkProfileHandler::GetSharedProfilePath(),
std::string() /* shared profile */);
......
......@@ -10,6 +10,7 @@
#include "base/memory/weak_ptr.h"
#include "chromeos/dbus/shill/shill_device_client.h"
#include "chromeos/dbus/shill/shill_ipconfig_client.h"
#include "chromeos/dbus/shill/shill_manager_client.h"
#include "chromeos/dbus/shill/shill_profile_client.h"
#include "chromeos/dbus/shill/shill_service_client.h"
......@@ -87,6 +88,9 @@ class NetworkStateTestHelper {
ShillProfileClient::TestInterface* profile_test() { return profile_test_; }
ShillDeviceClient::TestInterface* device_test() { return device_test_; }
ShillServiceClient::TestInterface* service_test() { return service_test_; }
ShillIPConfigClient::TestInterface* ip_config_test() {
return ip_config_test_;
}
private:
void ConfigureCallback(const dbus::ObjectPath& result);
......@@ -98,6 +102,7 @@ class NetworkStateTestHelper {
ShillProfileClient::TestInterface* profile_test_;
ShillDeviceClient::TestInterface* device_test_;
ShillServiceClient::TestInterface* service_test_;
ShillIPConfigClient::TestInterface* ip_config_test_;
std::unique_ptr<NetworkStateHandler> network_state_handler_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment