Commit 3b9e4292 authored by Kartik Hegde's avatar Kartik Hegde Committed by Commit Bot

network_diagnostics: Add HttpFirewall Routine

Tests whether a firewall is blocking HTTP port 80.

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

Change-Id: I9e847e433417dd2f2cca551041d7bf4ab5ad032e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2303464
Commit-Queue: Kartik Hegde <khegde@chromium.org>
Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799403}
parent acc03fa7
......@@ -69,6 +69,7 @@ source_set("chromeos") {
"//ash/public/cpp",
"//ash/public/cpp/external_arc",
"//ash/public/mojom",
"//base/util/ranges:ranges",
"//base/util/timer",
"//build:branding_buildflags",
"//chrome/app:command_ids",
......@@ -1858,6 +1859,8 @@ source_set("chromeos") {
"net/network_diagnostics/gateway_can_be_pinged_routine.h",
"net/network_diagnostics/has_secure_wifi_connection_routine.cc",
"net/network_diagnostics/has_secure_wifi_connection_routine.h",
"net/network_diagnostics/http_firewall_routine.cc",
"net/network_diagnostics/http_firewall_routine.h",
"net/network_diagnostics/lan_connectivity_routine.cc",
"net/network_diagnostics/lan_connectivity_routine.h",
"net/network_diagnostics/network_diagnostics.cc",
......@@ -3310,6 +3313,7 @@ source_set("unit_tests") {
"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/http_firewall_routine_unittest.cc",
"net/network_diagnostics/lan_connectivity_routine_unittest.cc",
"net/network_diagnostics/network_diagnostics_routine_unittest.cc",
"net/network_diagnostics/network_diagnostics_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.
#ifndef CHROME_BROWSER_CHROMEOS_NET_NETWORK_DIAGNOSTICS_HTTP_FIREWALL_ROUTINE_H_
#define CHROME_BROWSER_CHROMEOS_NET_NETWORK_DIAGNOSTICS_HTTP_FIREWALL_ROUTINE_H_
#include <memory>
#include <vector>
#include "base/callback.h"
#include "base/optional.h"
#include "chrome/browser/chromeos/net/network_diagnostics/network_diagnostics_routine.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/address_list.h"
#include "net/log/net_log_with_source.h"
#include "services/network/public/cpp/resolve_host_client_base.h"
#include "services/network/public/mojom/host_resolver.mojom.h"
class Profile;
namespace net {
class ClientSocketFactory;
class TransportClientSocket;
} // namespace net
namespace network {
namespace mojom {
class NetworkContext;
}
} // namespace network
namespace chromeos {
namespace network_diagnostics {
// Tests whether a firewall is blocking HTTP port 80.
class HttpFirewallRoutine : public NetworkDiagnosticsRoutine {
public:
class HostResolver;
using HttpFirewallRoutineCallback =
mojom::NetworkDiagnosticsRoutines::HttpFirewallCallback;
HttpFirewallRoutine();
HttpFirewallRoutine(const HttpFirewallRoutine&) = delete;
HttpFirewallRoutine& operator=(const HttpFirewallRoutine&) = delete;
~HttpFirewallRoutine() override;
// NetworkDiagnosticsRoutine:
void AnalyzeResultsAndExecuteCallback() override;
// Run the core logic of this routine. Set |callback| to
// |routine_completed_callback_|, which is to be executed in
// AnalyzeResultsAndExecuteCallback().
void RunRoutine(HttpFirewallRoutineCallback callback);
// Processes the results of the DNS resolution done by |host_resolver_|.
void OnHostResolutionComplete(
int result,
const net::ResolveErrorInfo& resolve_error_info,
const base::Optional<net::AddressList>& resolved_addresses);
void SetNetworkContextForTesting(
network::mojom::NetworkContext* network_context);
void SetProfileForTesting(Profile* profile);
void set_client_socket_factory_for_testing(
net::ClientSocketFactory* client_socket_factory) {
client_socket_factory_ = client_socket_factory;
}
net::ClientSocketFactory* client_socket_factory() {
return client_socket_factory_;
}
private:
void AttemptNextResolution();
void AttemptSocketConnections();
void Connect(int socket_index);
void OnSocketConnected(int result, int socket_index);
// Unowned
net::ClientSocketFactory* client_socket_factory_ = nullptr;
int num_hostnames_to_query_;
std::vector<std::string> hostnames_to_query_;
static constexpr int kTotalNumRetries = 3;
int num_retries_ = kTotalNumRetries;
int socket_connection_failures_ = 0;
int num_tcp_connections_attempted_ = 0;
net::NetLogWithSource net_log_;
std::vector<std::unique_ptr<net::TransportClientSocket>> sockets_;
std::vector<net::AddressList> resolved_addresses_;
std::vector<mojom::HttpFirewallProblem> problems_;
std::unique_ptr<HostResolver> host_resolver_;
HttpFirewallRoutineCallback routine_completed_callback_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace network_diagnostics
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_NET_NETWORK_DIAGNOSTICS_HTTP_FIREWALL_ROUTINE_H_
......@@ -14,6 +14,7 @@
#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/http_firewall_routine.h"
#include "chrome/browser/chromeos/net/network_diagnostics/lan_connectivity_routine.h"
#include "chrome/browser/chromeos/net/network_diagnostics/signal_strength_routine.h"
#include "chromeos/dbus/debug_daemon/debug_daemon_client.h"
......@@ -153,5 +154,19 @@ void NetworkDiagnostics::CaptivePortal(CaptivePortalCallback callback) {
std::move(routine), std::move(callback)));
}
void NetworkDiagnostics::HttpFirewall(HttpFirewallCallback callback) {
auto routine = std::make_unique<HttpFirewallRoutine>();
// RunRoutine() takes a lambda callback that takes ownership of the routine.
// This ensures that the routine stays alive when it makes asynchronous mojo
// calls. The routine will be destroyed when the lambda exits.
routine->RunRoutine(base::BindOnce(
[](std::unique_ptr<HttpFirewallRoutine> routine,
HttpFirewallCallback callback, mojom::RoutineVerdict verdict,
const std::vector<mojom::HttpFirewallProblem>& problems) {
std::move(callback).Run(verdict, std::move(problems));
},
std::move(routine), std::move(callback)));
}
} // namespace network_diagnostics
} // namespace chromeos
......@@ -30,6 +30,7 @@ class NetworkDiagnostics : public mojom::NetworkDiagnosticsRoutines {
void LanConnectivity(LanConnectivityCallback callback) override;
void SignalStrength(SignalStrengthCallback callback) override;
void GatewayCanBePinged(GatewayCanBePingedCallback callback) override;
void HttpFirewall(HttpFirewallCallback callback) override;
void HasSecureWiFiConnection(
HasSecureWiFiConnectionCallback callback) override;
void DnsResolverPresent(DnsResolverPresentCallback callback) override;
......
......@@ -205,6 +205,10 @@ class MockNetworkDiagnosticsRoutines : public NetworkDiagnosticsRoutines {
CaptivePortal,
(NetworkDiagnosticsRoutines::CaptivePortalCallback),
(override));
MOCK_METHOD(void,
HttpFirewall,
(NetworkDiagnosticsRoutines::HttpFirewallCallback),
(override));
mojo::PendingRemote<NetworkDiagnosticsRoutines> pending_remote() {
if (receiver_.is_bound()) {
......
......@@ -88,6 +88,17 @@ enum CaptivePortalProblem {
kCaptivePortalState,
};
// Problems related to the HttpFirewall routine.
[Extensible]
enum HttpFirewallProblem {
// DNS resolution failures above threshold.
kDnsResolutionFailuresAboveThreshold,
// Firewall detected.
kFirewallDetected,
// A firewall may potentially exist.
kPotentialFirewall,
};
// 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
......@@ -127,4 +138,8 @@ interface NetworkDiagnosticsRoutines {
// Tests whether the internet connection is behind a captive portal.
CaptivePortal() => (RoutineVerdict verdict,
array<CaptivePortalProblem> problems);
// Tests whether a firewall is blocking HTTP port 80.
HttpFirewall() => (RoutineVerdict verdict,
array<HttpFirewallProblem> problems);
};
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