Skip to content

Commit

Permalink
Add protocolfilter setting to set overriding protocols for an origin.
Browse files Browse the repository at this point in the history
b/205134049
  • Loading branch information
aee-google committed Aug 29, 2024
1 parent 5ec2b75 commit 0634e60
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 3 deletions.
16 changes: 16 additions & 0 deletions cobalt/h5vcc/h5vcc_settings.cc
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,15 @@ bool H5vccSettings::Set(const std::string& name, SetValueType value) const {
}
}

if (name.compare(network::kProtocolFilterKey) == 0 &&
value.IsType<std::string>() && value.AsType<std::string>().size() < 512) {
std::string rawJson = value.AsType<std::string>();
persistent_settings_->Set(network::kProtocolFilterKey,
base::Value(rawJson));
network_module_->SetProtocolFilterFromPersistentSettings();
return true;
}

if (name.compare("cpu_usage_tracker_intervals") == 0 &&
value.IsType<std::string>() && value.AsType<std::string>().size() < 512) {
absl::optional<base::Value> config =
Expand Down Expand Up @@ -193,6 +202,13 @@ std::string H5vccSettings::GetPersistentSettingAsString(
absl::optional<std::string> json = base::WriteJson(value);
return json.value_or(std::string());
}

if (key.compare(network::kProtocolFilterKey) == 0) {
base::Value value;
persistent_settings_->Get(network::kProtocolFilterKey, &value);
if (!value.is_string()) return std::string();
return value.GetString();
}
return std::string();
}

Expand Down
64 changes: 64 additions & 0 deletions cobalt/network/network_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "base/bind.h"
#include "base/command_line.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
Expand Down Expand Up @@ -160,6 +161,68 @@ void NetworkModule::SetEnableHttp3FromPersistentSettings() {
}
}

void NetworkModule::SetProtocolFilterFromPersistentSettings() {
if (!options_.persistent_settings) return;

base::Value value;
options_.persistent_settings->Get(kProtocolFilterKey, &value);
if (!value.is_string()) return;

if (value.GetString().empty()) {
task_runner()->PostTask(FROM_HERE,
base::Bind(
[](URLRequestContext* url_request_context) {
url_request_context->url_request_context()
->quic_context()
->params()
->protocol_filter = absl::nullopt;
},
base::Unretained(url_request_context_.get())));
return;
}

absl::optional<base::Value> config =
base::JSONReader::Read(value.GetString());
if (!config.has_value() || !config->is_list()) return;

net::ProtocolFilter protocol_filter;
for (auto& filter_value : config->GetList()) {
if (!filter_value.is_dict()) return;
const auto& dict = filter_value.GetDict();
const base::Value* origin = dict.Find("origin");
const base::Value* alt_svc = dict.Find("altSvc");
if (!origin || !alt_svc) continue;
if (!origin->is_string() || !alt_svc->is_string()) continue;
net::ProtocolFilterEntry entry;
entry.origin = origin->GetString();
if (base::StartsWith(alt_svc->GetString(), "h3")) {
entry.alt_svc.protocol = net::kProtoQUIC;
if (base::StartsWith(alt_svc->GetString(), "h3-Q046")) {
entry.alt_svc.quic_version =
net::ProtocolFilterEntry::QuicVersion::Q046;
} else {
entry.alt_svc.quic_version =
net::ProtocolFilterEntry::QuicVersion::RFC_V1;
}
} else {
entry.alt_svc.protocol = net::kProtoUnknown;
}
protocol_filter.push_back(std::move(entry));
}

task_runner()->PostTask(
FROM_HERE, base::Bind(
[](URLRequestContext* url_request_context,
net::ProtocolFilter protocol_filter) {
url_request_context->url_request_context()
->quic_context()
->params()
->protocol_filter = std::move(protocol_filter);
},
base::Unretained(url_request_context_.get()),
std::move(protocol_filter)));
}

void NetworkModule::EnsureStorageManagerStarted() {
DCHECK(storage_manager_);
storage_manager_->EnsureStarted();
Expand Down Expand Up @@ -249,6 +312,7 @@ void NetworkModule::Initialize(const std::string& user_agent_string,
SetEnableQuicFromPersistentSettings();
SetEnableHttp2FromPersistentSettings();
SetEnableHttp3FromPersistentSettings();
SetProtocolFilterFromPersistentSettings();
}

void NetworkModule::OnCreate(
Expand Down
2 changes: 2 additions & 0 deletions cobalt/network/network_module.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ constexpr int32_t kEnabledClientHintHeaders = (kCallTypeLoader | kCallTypeXHR);
const char kQuicEnabledPersistentSettingsKey[] = "QUICEnabled";
const char kHttp2EnabledPersistentSettingsKey[] = "HTTP2Enabled";
const char kHttp3EnabledPersistentSettingsKey[] = "HTTP3Enabled";
const char kProtocolFilterKey[] = "protocolfilter";

class NetworkSystem;
// NetworkModule wraps various networking-related components such as
Expand Down Expand Up @@ -133,6 +134,7 @@ class NetworkModule : public base::CurrentThread::DestructionObserver {
void SetEnableQuicFromPersistentSettings();
void SetEnableHttp2FromPersistentSettings();
void SetEnableHttp3FromPersistentSettings();
void SetProtocolFilterFromPersistentSettings();

// Adds the Client Hint Headers to the provided URLFetcher if enabled.
void AddClientHintHeaders(net::URLFetcher& url_fetcher,
Expand Down
38 changes: 35 additions & 3 deletions net/http/http_stream_factory_job_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#if defined(STARBOARD)
#include "base/strings/pattern.h"
#endif // defined(STARBOARD)
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
Expand Down Expand Up @@ -1203,6 +1206,35 @@ HttpStreamFactory::JobController::GetAlternativeServiceInfoInternal(
url::SchemeHostPort(original_url),
request_info.network_anonymization_key);
#if defined(STARBOARD)
if (session_->context().quic_context->params()->protocol_filter.has_value()) {
url::SchemeHostPort origin(original_url);
const ProtocolFilter& protocol_filter = *(session_->context().quic_context->params()->protocol_filter);
for (const ProtocolFilterEntry& entry : protocol_filter) {
if (!base::MatchPattern(origin.host(), entry.origin)) continue;

if (entry.alt_svc.protocol != kProtoQUIC) {
return AlternativeServiceInfo();
}

quic::ParsedQuicVersionVector versions;
if (entry.alt_svc.quic_version == ProtocolFilterEntry::QuicVersion::Q046) {
versions.push_back(quic::ParsedQuicVersion::Q046());
} else {
versions.push_back(quic::ParsedQuicVersion::RFCv1());
}

// If version not supported, skip.
if (SelectQuicVersion(versions) == quic::ParsedQuicVersion::Unsupported()) {
continue;
}

return AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
AlternativeService(net::kProtoQUIC, origin.host(),
origin.port()),
base::Time::Max(), versions);
}
}

// This block of code suggests QUIC connection for initial requests to a
// new host. This method is proven to provide performance benefit while still
// enabling Cobalt network module to fall back on TCP connection when QUIC
Expand All @@ -1213,21 +1245,21 @@ HttpStreamFactory::JobController::GetAlternativeServiceInfoInternal(
// Leave the port restriction only in production builds to simplify testing
#if defined(COBALT_BUILD_TYPE_GOLD)
if (origin.port() == kDefaultQUICServerPort) {
#endif
#endif // defined(COBALT_BUILD_TYPE_GOLD)
quic::ParsedQuicVersionVector versions = quic::AllSupportedVersions();
return AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
AlternativeService(net::kProtoQUIC, origin.host(),
origin.port()),
base::Time::Max(), versions);
#if defined(COBALT_BUILD_TYPE_GOLD)
}
#endif
#endif // defined(COBALT_BUILD_TYPE_GOLD)
return AlternativeServiceInfo();
}
#else
if (alternative_service_info_vector.empty())
return AlternativeServiceInfo();
#endif
#endif // defined(STARBOARD)

bool quic_advertised = false;
bool quic_all_broken = true;
Expand Down
26 changes: 26 additions & 0 deletions net/quic/quic_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,32 @@
#include "base/time/time.h"
#include "net/base/features.h"
#include "net/base/host_port_pair.h"
#if defined(STARBOARD)
#include "net/socket/next_proto.h"
#endif // defined(STARBOARD)
#include "net/third_party/quiche/src/quiche/quic/core/quic_connection.h"

namespace net {

#if defined(STARBOARD)
struct ProtocolFilterEntry {

enum QuicVersion {
Q046,
RFC_V1
};

struct AltSvc {
NextProto protocol;
QuicVersion quic_version;
};

std::string origin;
AltSvc alt_svc;
};
using ProtocolFilter = std::vector<ProtocolFilterEntry>;
#endif // defined(STARBOARD)

// Default QUIC supported versions used in absence of any external
// configuration.
inline NET_EXPORT_PRIVATE quic::ParsedQuicVersionVector
Expand Down Expand Up @@ -201,6 +223,10 @@ struct NET_EXPORT QuicParams {
// If true, delay main job even the request can be sent immediately on an
// available SPDY session.
bool delay_main_job_with_available_spdy_session = false;
#if defined(STARBOARD)
// Override alternative service for an origin.
absl::optional<ProtocolFilter> protocol_filter;
#endif // defined(STARBOARD)
};

// QuicContext contains QUIC-related variables that are shared across all of the
Expand Down

0 comments on commit 0634e60

Please sign in to comment.