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 @@ ...@@ -24,6 +24,7 @@
#include "net/base/host_port_pair.h" #include "net/base/host_port_pair.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/http/http_network_session.h" #include "net/http/http_network_session.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h" #include "net/url_request/url_fetcher.h"
...@@ -36,6 +37,14 @@ ...@@ -36,6 +37,14 @@
using base::StringPrintf; using base::StringPrintf;
namespace { 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. // Key of the UMA DataReductionProxy.StartupState histogram.
const char kUMAProxyStartupStateHistogram[] = const char kUMAProxyStartupStateHistogram[] =
...@@ -44,6 +53,13 @@ const char kUMAProxyStartupStateHistogram[] = ...@@ -44,6 +53,13 @@ const char kUMAProxyStartupStateHistogram[] =
// Key of the UMA DataReductionProxy.ProbeURL histogram. // Key of the UMA DataReductionProxy.ProbeURL histogram.
const char kUMAProxyProbeURL[] = "DataReductionProxy.ProbeURL"; 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 GetInt64PrefValue(const base::ListValue& list_value, size_t index) {
int64 val = 0; int64 val = 0;
std::string pref_value; std::string pref_value;
...@@ -70,10 +86,10 @@ DataReductionProxySettings::DataReductionProxySettings( ...@@ -70,10 +86,10 @@ DataReductionProxySettings::DataReductionProxySettings(
DataReductionProxyParams* params) DataReductionProxyParams* params)
: restricted_by_carrier_(false), : restricted_by_carrier_(false),
enabled_by_user_(false), enabled_by_user_(false),
disabled_on_vpn_(false),
prefs_(NULL), prefs_(NULL),
local_state_prefs_(NULL), local_state_prefs_(NULL),
url_request_context_getter_(NULL), url_request_context_getter_(NULL) {
usage_stats_(NULL) {
DCHECK(params); DCHECK(params);
params_.reset(params); params_.reset(params);
} }
...@@ -312,6 +328,9 @@ void DataReductionProxySettings::OnIPAddressChanged() { ...@@ -312,6 +328,9 @@ void DataReductionProxySettings::OnIPAddressChanged() {
DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(thread_checker_.CalledOnValidThread());
if (enabled_by_user_) { if (enabled_by_user_) {
DCHECK(params_->allowed()); DCHECK(params_->allowed());
RecordNetworkChangeEvent(IP_CHANGED);
if (DisableIfVPN())
return;
ProbeWhetherDataReductionProxyIsAvailable(); ProbeWhetherDataReductionProxyIsAvailable();
WarmProxyConnection(); WarmProxyConnection();
} }
...@@ -360,13 +379,13 @@ void DataReductionProxySettings::MaybeActivateDataReductionProxy( ...@@ -360,13 +379,13 @@ void DataReductionProxySettings::MaybeActivateDataReductionProxy(
// Configure use of the data reduction proxy if it is enabled. // Configure use of the data reduction proxy if it is enabled.
enabled_by_user_= IsDataReductionProxyEnabled(); enabled_by_user_= IsDataReductionProxyEnabled();
SetProxyConfigs(enabled_by_user_, SetProxyConfigs(enabled_by_user_ && !disabled_on_vpn_,
IsDataReductionProxyAlternativeEnabled(), IsDataReductionProxyAlternativeEnabled(),
restricted_by_carrier_, restricted_by_carrier_,
at_startup); at_startup);
// Check if the proxy has been restricted explicitly by the carrier. // Check if the proxy has been restricted explicitly by the carrier.
if (enabled_by_user_) { if (enabled_by_user_ && !disabled_on_vpn_) {
ProbeWhetherDataReductionProxyIsAvailable(); ProbeWhetherDataReductionProxyIsAvailable();
WarmProxyConnection(); WarmProxyConnection();
} }
...@@ -426,6 +445,12 @@ void DataReductionProxySettings::RecordStartupState(ProxyStartupState state) { ...@@ -426,6 +445,12 @@ void DataReductionProxySettings::RecordStartupState(ProxyStartupState state) {
PROXY_STARTUP_STATE_COUNT); PROXY_STARTUP_STATE_COUNT);
} }
void DataReductionProxySettings::GetNetworkList(
net::NetworkInterfaceList* interfaces,
int policy) {
net::GetNetworkList(interfaces, policy);
}
void DataReductionProxySettings::ResetParamsForTest( void DataReductionProxySettings::ResetParamsForTest(
DataReductionProxyParams* params) { DataReductionProxyParams* params) {
params_.reset(params); params_.reset(params);
...@@ -486,18 +511,6 @@ void DataReductionProxySettings::GetContentLengths( ...@@ -486,18 +511,6 @@ void DataReductionProxySettings::GetContentLengths(
local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate); 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( net::URLFetcher* DataReductionProxySettings::GetBaseURLFetcher(
const GURL& gurl, const GURL& gurl,
int load_flags) { int load_flags) {
...@@ -543,4 +556,36 @@ void DataReductionProxySettings::WarmProxyConnection() { ...@@ -543,4 +556,36 @@ void DataReductionProxySettings::WarmProxyConnection() {
warmup_fetcher_->Start(); 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 } // namespace data_reduction_proxy
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h" #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_params.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_usage_stats.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/base/network_change_notifier.h"
#include "net/url_request/url_fetcher_delegate.h" #include "net/url_request/url_fetcher_delegate.h"
...@@ -208,12 +209,20 @@ class DataReductionProxySettings ...@@ -208,12 +209,20 @@ class DataReductionProxySettings
// customer feedback. Virtual so tests can mock it for verification. // customer feedback. Virtual so tests can mock it for verification.
virtual void LogProxyState(bool enabled, bool restricted, bool at_startup); 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( virtual void RecordProbeURLFetchResult(
data_reduction_proxy::ProbeURLFetchResult result); data_reduction_proxy::ProbeURLFetchResult result);
// Virtualized for mocking. Records UMA specifying whether the proxy was
// enabled or disabled at startup.
virtual void RecordStartupState( virtual void RecordStartupState(
data_reduction_proxy::ProxyStartupState state); 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() { DataReductionProxyConfigurator* configurator() {
return configurator_.get(); return configurator_.get();
} }
...@@ -273,18 +282,17 @@ class DataReductionProxySettings ...@@ -273,18 +282,17 @@ class DataReductionProxySettings
// Warms the connection to the data reduction proxy. // Warms the connection to the data reduction proxy.
void WarmProxyConnection(); 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. // Generic method to get a URL fetcher.
net::URLFetcher* GetBaseURLFetcher(const GURL& gurl, int load_flags); 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_; std::string key_;
bool restricted_by_carrier_; bool restricted_by_carrier_;
bool enabled_by_user_; bool enabled_by_user_;
bool disabled_on_vpn_;
scoped_ptr<net::URLFetcher> fetcher_; scoped_ptr<net::URLFetcher> fetcher_;
scoped_ptr<net::URLFetcher> warmup_fetcher_; scoped_ptr<net::URLFetcher> warmup_fetcher_;
......
...@@ -6,10 +6,12 @@ ...@@ -6,10 +6,12 @@
#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_TEST_UTILS_H_ #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 "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_configurator.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params_test_utils.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 "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/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
...@@ -85,6 +87,15 @@ class MockDataReductionProxySettings : public C { ...@@ -85,6 +87,15 @@ class MockDataReductionProxySettings : public C {
EXPECT_CALL(*this, LogProxyState(enabled, restricted, at_startup)).Times(1); EXPECT_CALL(*this, LogProxyState(enabled, restricted, at_startup)).Times(1);
C::SetProxyConfigs(enabled, alternative_enabled, restricted, at_startup); 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 { class DataReductionProxySettingsTestBase : public testing::Test {
......
...@@ -296,8 +296,39 @@ TEST_F(DataReductionProxySettingsTest, TestOnIPAddressChanged) { ...@@ -296,8 +296,39 @@ TEST_F(DataReductionProxySettingsTest, TestOnIPAddressChanged) {
true, true,
true, true,
false); false);
// IP address change triggers a probe that succeed. Proxy is unrestricted. // IP address change triggers a probe that succeeds. Proxy is unrestricted.
CheckProbeOnIPChange(kProbeURLWithBadResponse, 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, kWarmupURLWithNoContentResponse,
"OK", "OK",
true, true,
......
...@@ -3129,6 +3129,16 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -3129,6 +3129,16 @@ Therefore, the affected-histogram name has to have at least one dot in it.
</summary> </summary>
</histogram> </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" <histogram name="DataReductionProxy.ProbeURL"
enum="DataReductionProxyProbeURLFetchResult"> enum="DataReductionProxyProbeURLFetchResult">
<owner>bengr@chromium.org</owner> <owner>bengr@chromium.org</owner>
...@@ -36371,6 +36381,11 @@ Therefore, the affected-histogram name has to have at least one dot in it. ...@@ -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"/> <int value="10" label="Bypass due to any network error"/>
</enum> </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"> <enum name="DataReductionProxyProbeURLFetchResult" type="int">
<int value="0" label="Internet disconnected"/> <int value="0" label="Internet disconnected"/>
<int value="1" label="Probe failed, proxy disabled"/> <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