// Copyright 2022 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. package org.chromium.net; import androidx.annotation.Nullable; import androidx.annotation.RequiresOptIn; import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; /** * Configuration options for QUIC in Cronet. * *
The settings in this class are only relevant if QUIC is enabled. Use
* {@link org.chromium.net.CronetEngine.Builder#enableQuic(boolean)} to enable / disable QUIC for
* the Cronet engine.
*/
public class QuicOptions {
private final Set If no hosts are specified, the per-host allowlist functionality is disabled.
* Otherwise, Cronet will only use QUIC when talking to hosts on the allowlist.
*
* @return the builder for chaining
*/
public Builder addAllowedQuicHost(String quicHost) {
mQuicHostAllowlist.add(quicHost);
return this;
}
/**
* Adds a QUIC version to the list of QUIC versions to enable.
*
* If no versions are specified, Cronet will use a list of default QUIC versions.
*
* The version format is specified by
* QUICHE.
* Outside of filtering out values known to be obsolete, Cronet doesn't process the versions
* anyhow and simply passes them along to QUICHE.
*
* @return the builder for chaining
*/
@QuichePassthroughOption
public Builder addEnabledQuicVersion(String enabledQuicVersion) {
mEnabledQuicVersions.add(enabledQuicVersion);
return this;
}
/**
* Adds a QUIC tag to send in a QUIC handshake's connection options.
*
* The QUIC tags should be presented as strings up to four letters long
* (for instance, {@code NBHD}).
*
* As the QUIC tags are under active development and some are only relevant to the
* server, Cronet doesn't attempt to maintain a complete list of all supported QUIC flags as
* a part of the API. The flags. Flags supported by QUICHE, a QUIC implementation used by
* Cronet and Google servers, can be found here.
*
* @return the builder for chaining
*/
@QuichePassthroughOption
public Builder addConnectionOption(String connectionOption) {
mConnectionOptions.add(connectionOption);
return this;
}
/**
* Adds a QUIC tag to send in a QUIC handshake's connection options that only affects
* the client.
*
* See {@link #addConnectionOption(String)} for more details.
*/
@QuichePassthroughOption
public Builder addClientConnectionOption(String clientConnectionOption) {
mClientConnectionOptions.add(clientConnectionOption);
return this;
}
/**
* Sets how many server configurations (metadata like list of alt svc, whether QUIC is
* supported, etc.) should be held in memory.
*
* If the storage path is set ({@link
* org.chromium.net.CronetEngine.Builder#setStoragePath(String)}, Cronet will also persist
* the server configurations on disk.
*
* @return the builder for chaining
*/
public Builder setInMemoryServerConfigsCacheSize(int inMemoryServerConfigsCacheSize) {
this.mInMemoryServerConfigsCacheSize = inMemoryServerConfigsCacheSize;
return this;
}
/**
* Sets the user agent to be used outside of HTTP requests (for example for QUIC
* handshakes).
*
* To set the default user agent for HTTP requests, use
* {@link CronetEngine.Builder#setUserAgent(String)} instead.
*
* @return the builder for chaining
*/
public Builder setHandshakeUserAgent(String handshakeUserAgent) {
this.mHandshakeUserAgent = handshakeUserAgent;
return this;
}
/**
* Sets whether requests that failed with a QUIC protocol errors should be retried without
* using any {@code alt-svc} servers.
*
* @return the builder for chaining
*/
@Experimental
public Builder retryWithoutAltSvcOnQuicErrors(boolean retryWithoutAltSvcOnQuicErrors) {
this.mRetryWithoutAltSvcOnQuicErrors = retryWithoutAltSvcOnQuicErrors;
return this;
}
/**
* Sets whether TLS with 0-RTT should be enabled.
*
* 0-RTT is a performance optimization avoiding an extra round trip when resuming
* connections to a known server.
*
* @see Cloudflare's 0-RTT
* blogpost
*
* @return the builder for chaining
*/
@Experimental
public Builder enableTlsZeroRtt(boolean enableTlsZeroRtt) {
this.mEnableTlsZeroRtt = enableTlsZeroRtt;
return this;
}
/**
* Sets the maximum idle time for a connection which hasn't completed a SSL handshake yet.
*
* @return the builder for chaining
*/
@Experimental
public Builder setPreCryptoHandshakeIdleTimeoutSeconds(
long preCryptoHandshakeIdleTimeoutSeconds) {
this.mPreCryptoHandshakeIdleTimeoutSeconds = preCryptoHandshakeIdleTimeoutSeconds;
return this;
}
/**
* Sets the timeout for a connection SSL handshake.
*
* @return the builder for chaining
*/
@Experimental
public Builder setCryptoHandshakeTimeoutSeconds(long cryptoHandshakeTimeoutSeconds) {
this.mCryptoHandshakeTimeoutSeconds = cryptoHandshakeTimeoutSeconds;
return this;
}
/**
* Sets the maximum idle time for a connection.
*
* TODO what happens to connection that are idle for too long?
*
* @return the builder for chaining
*/
public Builder setIdleConnectionTimeoutSeconds(long idleConnectionTimeoutSeconds) {
this.mIdleConnectionTimeoutSeconds = idleConnectionTimeoutSeconds;
return this;
}
/**
* Sets the maximum desired time between packets on wire.
*
* When the retransmittable-on-wire time is exceeded Cronet will probe quality of the
* network using artificial traffic. Smaller timeouts will typically result in faster
* discovery of a broken or degrading path, but also larger usage of resources (battery,
* data).
*
* @return the builder for chaining
*/
@Experimental
public Builder setRetransmittableOnWireTimeoutMillis(
long retransmittableOnWireTimeoutMillis) {
this.mRetransmittableOnWireTimeoutMillis = retransmittableOnWireTimeoutMillis;
return this;
}
/**
* Sets whether QUIC sessions should be closed on IP address change.
*
* Don't use in combination with connection migration
* (configured using {@link ConnectionMigrationOptions}).
*
* @return the builder for chaining
*/
@Experimental
public Builder closeSessionsOnIpChange(boolean closeSessionsOnIpChange) {
this.mCloseSessionsOnIpChange = closeSessionsOnIpChange;
return this;
}
/**
* Sets whether QUIC sessions should be goaway'd on IP address change.
*
* Don't use in combination with connection migration
* (configured using {@link ConnectionMigrationOptions}).
*
* @return the builder for chaining
*/
@Experimental
public Builder goawaySessionsOnIpChange(boolean goawaySessionsOnIpChange) {
this.mGoawaySessionsOnIpChange = goawaySessionsOnIpChange;
return this;
}
/**
* Sets the initial for which Cronet shouldn't attempt to use QUIC for a given server after
* the server's QUIC support turned out to be broken.
*
* Once Cronet detects that a server advertises QUIC but doesn't actually speak it, it
* marks the server as broken and doesn't attempt to use QUIC when talking to the server for
* an amount of time. Once Cronet is past this point it will try using QUIC again. This is
* to balance short term (there's no point wasting resources to try QUIC if the server is
* broken) and long term (the breakage might have been temporary, using QUIC is generally
* beneficial) interests.
*
* The delay is increased every unsuccessful consecutive retry. See
* {@link #increaseBrokenServicePeriodExponentially(boolean)} for details.
*
* @return the builder for chaining
*/
@Experimental
public Builder setInitialBrokenServicePeriodSeconds(
long initialBrokenServicePeriodSeconds) {
this.mInitialBrokenServicePeriodSeconds = initialBrokenServicePeriodSeconds;
return this;
}
/**
* Sets whether the broken server period should scale exponentially.
*
* If set to true, the initial delay (configurable
* by {@link #setInitialBrokenServicePeriodSeconds}) will be scaled exponentially for
* subsequent retries ({@code SCALING_FACTOR^NUM_TRIES * delay}). If false, the delay will
* scale linearly (SCALING_FACTOR * NUM_TRIES * delay).
*
* @return the builder for chaining
*/
@Experimental
public Builder increaseBrokenServicePeriodExponentially(
boolean increaseBrokenServicePeriodExponentially) {
this.mIncreaseBrokenServicePeriodExponentially =
increaseBrokenServicePeriodExponentially;
return this;
}
/**
* Sets whether Cronet should wait for the primary path (usually QUIC) to be ready even if
* there's a secondary path of reaching the server (SPDY / HTTP2) which is ready
* immediately.
*
* @return the builder for chaining
*/
@Experimental
public Builder delayJobsWithAvailableSpdySession(
boolean delayJobsWithAvailableSpdySession) {
this.mDelayJobsWithAvailableSpdySession = delayJobsWithAvailableSpdySession;
return this;
}
/**
* Sets an arbitrary QUICHE flag. Flags should be passed in {@code FLAG_NAME=FLAG_VALUE}
* format.
*
* See the QUICHE code base for a full list
* of flags.
*
* @return the builder for chaining
*/
@QuichePassthroughOption
public Builder addExtraQuicheFlag(String extraQuicheFlag) {
this.mExtraQuicheFlags.add(extraQuicheFlag);
return this;
}
/**
* Creates and returns the final {@link QuicOptions} instance, based on the values
* in this builder.
*/
public QuicOptions build() {
return new QuicOptions(this);
}
}
/**
* An annotation for APIs which are not considered stable yet.
*
* Experimental APIs are subject to change, breakage, or removal at any time and may not be
* production ready.
*
* It's highly recommended to reach out to Cronet maintainers
* ( By using an Experimental API, applications acknowledge that they are doing so at their own
* risk.
*/
@RequiresOptIn
public @interface Experimental {}
/**
* An annotation for APIs which configure QUICHE options not curated by Cronet.
*
* APIs annotated by this are considered stable from Cronet's perspective. However, they
* simply pass the configuration options to QUICHE, a library that provides the HTTP3
* implementation. As the dependency is under active development those flags might change
* behavior, or get deleted. The application accepts the stability contract as stated by QUICHE.
* Cronet is just a mediator passing the messages back and forth.
*
* Cronet provides the APIs as a compromise between customer development velocity (some
* customers value access to bleeding edge QUICHE features ASAP), and Cronet's own interests
* (stability and readability of the API, capacity to propagate new QUICHE changes). Most Cronet
* customers shouldn't need to use those APIs directly. Mature QUICHE features that are
* generally useful will be exposed by Cronet as proper top level APIs or configuration options.
*/
@RequiresOptIn
public @interface QuichePassthroughOption {}
}
net-dev@chromium.org
) before using one of the APIs annotated as experimental
* outside of debugging and proof-of-concept code.
*
*