Commit 3a5e32bd authored by bengr@chromium.org's avatar bengr@chromium.org

Bypass data reduction proxy when using VPN

If the tun interface is present, disable the data reduction proxy.

BUG=357129

Review URL: https://codereview.chromium.org/373153003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283478 0039d316-1c4b-4281-b951-d872f2087c98
parent 0d0bd385
......@@ -24,6 +24,7 @@
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_network_session.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
......@@ -36,6 +37,14 @@
using base::StringPrintf;
namespace {
// Values of the UMA DataReductionProxy.NetworkChangeEvents histograms.
// This enum must remain synchronized with the enum of the same
// name in metrics/histograms/histograms.xml.
enum DataReductionProxyNetworkChangeEvent {
IP_CHANGED = 0, // The client IP address changed.
DISABLED_ON_VPN = 1, // The proxy is disabled because a VPN is running.
CHANGE_EVENT_COUNT = 2 // This must always be last.
};
// Key of the UMA DataReductionProxy.StartupState histogram.
const char kUMAProxyStartupStateHistogram[] =
......@@ -44,6 +53,13 @@ const char kUMAProxyStartupStateHistogram[] =
// Key of the UMA DataReductionProxy.ProbeURL histogram.
const char kUMAProxyProbeURL[] = "DataReductionProxy.ProbeURL";
// Record a network change event.
void RecordNetworkChangeEvent(DataReductionProxyNetworkChangeEvent event) {
UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.NetworkChangeEvents",
event,
CHANGE_EVENT_COUNT);
}
int64 GetInt64PrefValue(const base::ListValue& list_value, size_t index) {
int64 val = 0;
std::string pref_value;
......@@ -70,10 +86,10 @@ DataReductionProxySettings::DataReductionProxySettings(
DataReductionProxyParams* params)
: restricted_by_carrier_(false),
enabled_by_user_(false),
disabled_on_vpn_(false),
prefs_(NULL),
local_state_prefs_(NULL),
url_request_context_getter_(NULL),
usage_stats_(NULL) {
url_request_context_getter_(NULL) {
DCHECK(params);
params_.reset(params);
}
......@@ -312,6 +328,9 @@ void DataReductionProxySettings::OnIPAddressChanged() {
DCHECK(thread_checker_.CalledOnValidThread());
if (enabled_by_user_) {
DCHECK(params_->allowed());
RecordNetworkChangeEvent(IP_CHANGED);
if (DisableIfVPN())
return;
ProbeWhetherDataReductionProxyIsAvailable();
WarmProxyConnection();
}
......@@ -360,13 +379,13 @@ void DataReductionProxySettings::MaybeActivateDataReductionProxy(
// Configure use of the data reduction proxy if it is enabled.
enabled_by_user_= IsDataReductionProxyEnabled();
SetProxyConfigs(enabled_by_user_,
SetProxyConfigs(enabled_by_user_ && !disabled_on_vpn_,
IsDataReductionProxyAlternativeEnabled(),
restricted_by_carrier_,
at_startup);
// Check if the proxy has been restricted explicitly by the carrier.
if (enabled_by_user_) {
if (enabled_by_user_ && !disabled_on_vpn_) {
ProbeWhetherDataReductionProxyIsAvailable();
WarmProxyConnection();
}
......@@ -426,6 +445,12 @@ void DataReductionProxySettings::RecordStartupState(ProxyStartupState state) {
PROXY_STARTUP_STATE_COUNT);
}
void DataReductionProxySettings::GetNetworkList(
net::NetworkInterfaceList* interfaces,
int policy) {
net::GetNetworkList(interfaces, policy);
}
void DataReductionProxySettings::ResetParamsForTest(
DataReductionProxyParams* params) {
params_.reset(params);
......@@ -486,18 +511,6 @@ void DataReductionProxySettings::GetContentLengths(
local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate);
}
// static
base::string16 DataReductionProxySettings::AuthHashForSalt(
int64 salt,
const std::string& key) {
std::string salted_key =
base::StringPrintf("%lld%s%lld",
static_cast<long long>(salt),
key.c_str(),
static_cast<long long>(salt));
return base::UTF8ToUTF16(base::MD5String(salted_key));
}
net::URLFetcher* DataReductionProxySettings::GetBaseURLFetcher(
const GURL& gurl,
int load_flags) {
......@@ -543,4 +556,36 @@ void DataReductionProxySettings::WarmProxyConnection() {
warmup_fetcher_->Start();
}
bool DataReductionProxySettings::DisableIfVPN() {
net::NetworkInterfaceList network_interfaces;
GetNetworkList(&network_interfaces, 0);
// VPNs use a "tun" interface, so the presence of a "tun" interface indicates
// a VPN is in use.
// TODO(kundaji): Verify this works on Windows.
const std::string vpn_interface_name_prefix = "tun";
for (size_t i = 0; i < network_interfaces.size(); ++i) {
std::string interface_name = network_interfaces[i].name;
if (LowerCaseEqualsASCII(
interface_name.begin(),
interface_name.begin() + vpn_interface_name_prefix.size(),
vpn_interface_name_prefix.c_str())) {
SetProxyConfigs(false,
IsDataReductionProxyAlternativeEnabled(),
false,
false);
disabled_on_vpn_ = true;
RecordNetworkChangeEvent(DISABLED_ON_VPN);
return true;
}
}
if (disabled_on_vpn_) {
SetProxyConfigs(enabled_by_user_,
IsDataReductionProxyAlternativeEnabled(),
restricted_by_carrier_,
false);
}
disabled_on_vpn_ = false;
return false;
}
} // namespace data_reduction_proxy
......@@ -16,6 +16,7 @@
#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.h"
#include "net/base/net_util.h"
#include "net/base/network_change_notifier.h"
#include "net/url_request/url_fetcher_delegate.h"
......@@ -208,12 +209,20 @@ class DataReductionProxySettings
// customer feedback. Virtual so tests can mock it for verification.
virtual void LogProxyState(bool enabled, bool restricted, bool at_startup);
// Virtualized for mocking
// Virtualized for mocking. Records UMA containing the result of requesting
// the probe URL.
virtual void RecordProbeURLFetchResult(
data_reduction_proxy::ProbeURLFetchResult result);
// Virtualized for mocking. Records UMA specifying whether the proxy was
// enabled or disabled at startup.
virtual void RecordStartupState(
data_reduction_proxy::ProxyStartupState state);
// Virtualized for mocking. Returns the list of network interfaces in use.
virtual void GetNetworkList(net::NetworkInterfaceList* interfaces,
int policy);
DataReductionProxyConfigurator* configurator() {
return configurator_.get();
}
......@@ -273,18 +282,17 @@ class DataReductionProxySettings
// Warms the connection to the data reduction proxy.
void WarmProxyConnection();
// Disables use of the data reduction proxy on VPNs. Returns true if the
// data reduction proxy has been disabled.
bool DisableIfVPN();
// Generic method to get a URL fetcher.
net::URLFetcher* GetBaseURLFetcher(const GURL& gurl, int load_flags);
// Returns a UTF16 string that's the hash of the configured authentication
// |key| and |salt|. Returns an empty UTF16 string if no key is configured or
// the data reduction proxy feature isn't available.
static base::string16 AuthHashForSalt(int64 salt,
const std::string& key);
std::string key_;
bool restricted_by_carrier_;
bool enabled_by_user_;
bool disabled_on_vpn_;
scoped_ptr<net::URLFetcher> fetcher_;
scoped_ptr<net::URLFetcher> warmup_fetcher_;
......
......@@ -6,10 +6,12 @@
#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_TEST_UTILS_H_
#include "base/memory/scoped_ptr.h"
#include "base/prefs/testing_pref_service.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params_test_utils.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_settings.h"
#include "net/base/net_util.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
......@@ -85,6 +87,15 @@ class MockDataReductionProxySettings : public C {
EXPECT_CALL(*this, LogProxyState(enabled, restricted, at_startup)).Times(1);
C::SetProxyConfigs(enabled, alternative_enabled, restricted, at_startup);
}
virtual void GetNetworkList(net::NetworkInterfaceList* interfaces,
int policy) OVERRIDE {
if (!network_interfaces_.get())
return;
for (size_t i = 0; i < network_interfaces_->size(); ++i)
interfaces->push_back(network_interfaces_->at(i));
}
scoped_ptr<net::NetworkInterfaceList> network_interfaces_;
};
class DataReductionProxySettingsTestBase : public testing::Test {
......
......@@ -296,8 +296,39 @@ TEST_F(DataReductionProxySettingsTest, TestOnIPAddressChanged) {
true,
true,
false);
// IP address change triggers a probe that succeed. Proxy is unrestricted.
CheckProbeOnIPChange(kProbeURLWithBadResponse,
// IP address change triggers a probe that succeeds. Proxy is unrestricted.
CheckProbeOnIPChange(kProbeURLWithOKResponse,
kWarmupURLWithNoContentResponse,
"OK",
true,
false,
false);
// Simulate a VPN connection. The proxy should be disabled.
MockSettings* settings = static_cast<MockSettings*>(settings_.get());
settings->network_interfaces_.reset(new net::NetworkInterfaceList());
settings->network_interfaces_->push_back(
net::NetworkInterface("tun0", /* network interface name */
"tun0", /* network interface friendly name */
0, /* interface index */
net::NetworkChangeNotifier::CONNECTION_WIFI,
net::IPAddressNumber(), /* IP address */
0 /* network prefix */
));
settings_->OnIPAddressChanged();
base::MessageLoop::current()->RunUntilIdle();
CheckProxyConfigs(false, false, false);
// Check that the proxy is re-enabled if a non-VPN connection is later used.
settings->network_interfaces_.reset(new net::NetworkInterfaceList());
settings->network_interfaces_->push_back(
net::NetworkInterface("eth0", /* network interface name */
"eth0", /* network interface friendly name */
0, /* interface index */
net::NetworkChangeNotifier::CONNECTION_WIFI,
net::IPAddressNumber(),
0 /* network prefix */
));
CheckProbeOnIPChange(kProbeURLWithOKResponse,
kWarmupURLWithNoContentResponse,
"OK",
true,
......
......@@ -3129,6 +3129,16 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary>
</histogram>
<histogram name="DataReductionProxy.NetworkChangeEvents"
enum="DataReductionProxyNetworkChangeEvent">
<owner>bengr@chromium.org</owner>
<owner>megjablon@chromium.org</owner>
<summary>
Counts the number of times various events occur when the data reduction
proxy is enabled and the IP address of the client changes.
</summary>
</histogram>
<histogram name="DataReductionProxy.ProbeURL"
enum="DataReductionProxyProbeURLFetchResult">
<owner>bengr@chromium.org</owner>
......@@ -36371,6 +36381,11 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="10" label="Bypass due to any network error"/>
</enum>
<enum name="DataReductionProxyNetworkChangeEvent" type="int">
<int value="0" label="IP Address Change"/>
<int value="1" label="Proxy disabled on VPN"/>
</enum>
<enum name="DataReductionProxyProbeURLFetchResult" type="int">
<int value="0" label="Internet disconnected"/>
<int value="1" label="Probe failed, proxy disabled"/>
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