Commit a0cb4a2c authored by Renjie's avatar Renjie Committed by Commit Bot

Add experiment of racing stale dns on connection.

In QuicStreamFactory::Job, chances are host resolution won't return synchronously. While waiting for the host resolution callback, the stale host resolver will be queried, and a connection from the stale host result will be established but not confirmed. After host resolution returns, the two IP addresses will be compared. If they match, the connection will be confirmed. Otherwise the connection from stale host will be closed and connection from the fresh resolution will be established.

Bug: 787942
Change-Id: I7a5f78ec42e97778d7c7d200f4d8ac894611fd19
Reviewed-on: https://chromium-review.googlesource.com/1186112
Commit-Queue: Renjie Tang <renjietang@chromium.org>
Reviewed-by: default avatarRyan Hamilton <rch@chromium.org>
Cr-Commit-Position: refs/heads/master@{#594522}
parent ecd3faa9
......@@ -330,6 +330,13 @@ bool ShouldQuicGoawayOnPathDegrading(
"true");
}
bool ShouldQuicRaceStaleDNSOnConnection(
const VariationParameters& quic_trial_params) {
return base::LowerCaseEqualsASCII(
GetVariationParam(quic_trial_params, "race_stale_dns_on_connection"),
"true");
}
int GetQuicMaxTimeOnNonDefaultNetworkSeconds(
const VariationParameters& quic_trial_params) {
int value;
......@@ -473,6 +480,8 @@ void ConfigureQuicParams(base::StringPiece quic_trial_group,
ShouldQuicRetryOnAlternateNetworkBeforeHandshake(quic_trial_params);
params->quic_go_away_on_path_degrading =
ShouldQuicGoawayOnPathDegrading(quic_trial_params);
params->quic_race_stale_dns_on_connection =
ShouldQuicRaceStaleDNSOnConnection(quic_trial_params);
int max_time_on_non_default_network_seconds =
GetQuicMaxTimeOnNonDefaultNetworkSeconds(quic_trial_params);
if (max_time_on_non_default_network_seconds > 0) {
......
......@@ -118,6 +118,7 @@ TEST_F(NetworkSessionConfiguratorTest, EnableQuicFromFieldTrialGroup) {
EXPECT_FALSE(params_.quic_estimate_initial_rtt);
EXPECT_FALSE(params_.quic_migrate_sessions_on_network_change_v2);
EXPECT_FALSE(params_.quic_migrate_sessions_early_v2);
EXPECT_FALSE(params_.quic_race_stale_dns_on_connection);
EXPECT_FALSE(params_.quic_retry_on_alternate_network_before_handshake);
EXPECT_FALSE(params_.quic_go_away_on_path_degrading);
EXPECT_FALSE(params_.quic_allow_server_migration);
......@@ -360,6 +361,18 @@ TEST_F(NetworkSessionConfiguratorTest,
EXPECT_TRUE(params_.quic_retry_on_alternate_network_before_handshake);
}
TEST_F(NetworkSessionConfiguratorTest,
QuicRaceStaleDNSOnCOnnectionFromFieldTrialParams) {
std::map<std::string, std::string> field_trial_params;
field_trial_params["race_stale_dns_on_connection"] = "true";
variations::AssociateVariationParams("QUIC", "Enabled", field_trial_params);
base::FieldTrialList::CreateFieldTrial("QUIC", "Enabled");
ParseFieldTrials();
EXPECT_TRUE(params_.quic_race_stale_dns_on_connection);
}
TEST_F(NetworkSessionConfiguratorTest,
QuicGoawayOnPathDegradingFromFieldTrialParams) {
std::map<std::string, std::string> field_trial_params;
......
......@@ -284,7 +284,8 @@ int MockHostResolverBase::ResolveStaleFromCache(
next_request_id_++;
int rv = ResolveFromIPLiteralOrCache(
info.host_port_pair(), info.address_family(), info.host_resolver_flags(),
HostResolverSource::ANY, info.allow_cached_response(), addresses);
HostResolverSource::ANY, info.allow_cached_response(), addresses,
stale_info);
return rv;
}
......
......@@ -128,6 +128,7 @@ HttpNetworkSession::Params::Params()
quic_migrate_sessions_on_network_change_v2(false),
quic_migrate_sessions_early_v2(false),
quic_retry_on_alternate_network_before_handshake(false),
quic_race_stale_dns_on_connection(false),
quic_go_away_on_path_degrading(false),
quic_max_time_on_non_default_network(
base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs)),
......@@ -220,6 +221,7 @@ HttpNetworkSession::HttpNetworkSession(const Params& params,
params.quic_migrate_sessions_on_network_change_v2,
params.quic_migrate_sessions_early_v2,
params.quic_retry_on_alternate_network_before_handshake,
params.quic_race_stale_dns_on_connection,
params.quic_go_away_on_path_degrading,
params.quic_max_time_on_non_default_network,
params.quic_max_migrations_to_non_default_network_on_write_error,
......@@ -383,6 +385,8 @@ std::unique_ptr<base::Value> HttpNetworkSession::QuicInfoToValue() const {
params_.quic_migrate_sessions_early_v2);
dict->SetBoolean("retry_on_alternate_network_before_handshake",
params_.quic_retry_on_alternate_network_before_handshake);
dict->SetBoolean("race_stale_dns_on_connection",
params_.quic_race_stale_dns_on_connection);
dict->SetBoolean("go_away_on_path_degrading",
params_.quic_go_away_on_path_degrading);
dict->SetInteger("max_time_on_non_default_network_seconds",
......
......@@ -191,6 +191,9 @@ class NET_EXPORT HttpNetworkSession {
// If true, a new connection may be kicked off on an alternate network when
// a connection fails on the default network before handshake is confirmed.
bool quic_retry_on_alternate_network_before_handshake;
// If true, the quic stream factory may race connection from stale dns
// result with the original dns resolution
bool quic_race_stale_dns_on_connection;
// If true, the quic session may mark itself as GOAWAY on path degrading.
bool quic_go_away_on_path_degrading;
// Maximum time the session could be on the non-default network before
......
......@@ -137,6 +137,7 @@ class HttpProxyClientSocketWrapperTest
/*migrate_sessions_on_network_change_v2=*/false,
/*migrate_sessions_early_v2=*/false,
/*retry_on_alternate_network_before_handshake=*/false,
/*race_stale_dns_on_connection=*/false,
/*go_away_on_path_degrading=*/false,
base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
kMaxMigrationsToNonDefaultNetworkOnWriteError,
......
......@@ -1673,6 +1673,12 @@ EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_CONNECT)
// will be attempted soon.
EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_RETRY_ON_ALTERNATE_NETWORK)
// This event indicates that the stale host resolution has failed.
EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_FAILED)
// This event indicates that the stale host doesn't match with fresh host.
EVENT_TYPE(QUIC_STREAM_FACTORY_JOB_STALE_HOST_RESOLUTION_NO_MATCH)
// ------------------------------------------------------------------------
// quic::QuicSession
// ------------------------------------------------------------------------
......
This diff is collapsed.
......@@ -250,6 +250,7 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
bool migrate_sessions_on_network_change_v2,
bool migrate_sessions_early_v2,
bool retry_on_alternate_network_before_handshake,
bool race_stale_dns_on_connection,
bool go_away_on_path_degrading,
base::TimeDelta max_time_on_non_default_network,
int max_migrations_to_non_default_network_on_write_error,
......@@ -548,6 +549,10 @@ class NET_EXPORT_PRIVATE QuicStreamFactory
// connection fails on the default network before handshake is confirmed.
const bool retry_on_alternate_network_before_handshake_;
// Set if stale DNS result may be speculatively used to connect and then
// compared with the original DNS result.
const bool race_stale_dns_on_connection_;
// Set if client should mark the session as GOAWAY when the connection
// experiences poor connectivity
const bool go_away_on_path_degrading_;
......
......@@ -104,6 +104,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
bool enable_token_binding = data_provider.ConsumeBool();
bool enable_channel_id = data_provider.ConsumeBool();
bool enable_socket_recv_optimization = data_provider.ConsumeBool();
bool race_stale_dns_on_connection = data_provider.ConsumeBool();
env->crypto_client_stream_factory.AddProofVerifyDetails(&env->verify_details);
......@@ -143,7 +144,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
quic::kMaxTimeForCryptoHandshakeSecs, quic::kInitialIdleTimeoutSecs,
migrate_sessions_on_network_change_v2, migrate_sessions_early_v2,
retry_on_alternate_network_before_handshake,
go_away_on_path_degrading,
race_stale_dns_on_connection, go_away_on_path_degrading,
base::TimeDelta::FromSeconds(kMaxTimeOnNonDefaultNetworkSecs),
kMaxMigrationsToNonDefaultNetworkOnWriteError,
kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
......
......@@ -70,6 +70,22 @@ QuicChromiumClientSession* QuicStreamFactoryPeer::GetActiveSession(
return factory->active_sessions_[session_key];
}
bool QuicStreamFactoryPeer::HasLiveSession(
QuicStreamFactory* factory,
const HostPortPair& destination,
const quic::QuicServerId& server_id) {
QuicSessionKey session_key = QuicSessionKey(server_id, SocketTag());
QuicStreamFactory::QuicSessionAliasKey alias_key =
QuicStreamFactory::QuicSessionAliasKey(destination, session_key);
for (QuicStreamFactory::SessionIdMap::iterator it =
factory->all_sessions_.begin();
it != factory->all_sessions_.end(); ++it) {
if (it->second == alias_key)
return true;
}
return false;
}
bool QuicStreamFactoryPeer::IsLiveSession(QuicStreamFactory* factory,
QuicChromiumClientSession* session) {
for (QuicStreamFactory::SessionIdMap::iterator it =
......
......@@ -56,6 +56,10 @@ class QuicStreamFactoryPeer {
QuicStreamFactory* factory,
const quic::QuicServerId& server_id);
static bool HasLiveSession(QuicStreamFactory* factory,
const HostPortPair& destination,
const quic::QuicServerId& server_id);
static bool IsLiveSession(QuicStreamFactory* factory,
QuicChromiumClientSession* session);
......
This diff is collapsed.
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