diff --git a/library/common/config/config.cc b/library/common/config/config.cc index cfef116472..f17d52dcf5 100644 --- a/library/common/config/config.cc +++ b/library/common/config/config.cc @@ -78,6 +78,7 @@ const char* brotli_config_insert = R"( // clang-format off const std::string config_header = R"( !ignore default_defs: +- &android_force_ipv6 false - &connect_timeout 30s - &dns_fail_base_interval 2s - &dns_fail_max_interval 10s @@ -513,6 +514,7 @@ stats_sinks: *stats_sinks disallow_global_stats: true reloadable_features: allow_multiple_dns_addresses: *dns_multiple_addresses + android_always_use_v6: *android_force_ipv6 http2_delay_keepalive_timeout: *h2_delay_keepalive_timeout )" // Needed due to warning in diff --git a/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java b/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java index 81ab608014..f8954a3ab1 100644 --- a/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java +++ b/library/java/io/envoyproxy/envoymobile/engine/EnvoyConfiguration.java @@ -42,6 +42,7 @@ public enum TrustChainVerification { public final Boolean enableBrotli; public final Boolean enableHappyEyeballs; public final Boolean enableInterfaceBinding; + public final Boolean forceIPv6; public final Integer h2ConnectionKeepaliveIdleIntervalMilliseconds; public final Integer h2ConnectionKeepaliveTimeoutSeconds; public final Boolean h2ExtendKeepaliveTimeout; @@ -82,6 +83,7 @@ public enum TrustChainVerification { * @param enableBrotli whether to enable response brotli decompression. * @param enableHappyEyeballs whether to enable RFC 6555 handling for IPv4/IPv6. * @param enableInterfaceBinding whether to allow interface binding. + * @param forceIPv6 whether to force connections to use IPv6. * @param h2ConnectionKeepaliveIdleIntervalMilliseconds rate in milliseconds seconds to send h2 * pings on stream creation. * @param h2ConnectionKeepaliveTimeoutSeconds rate in seconds to timeout h2 pings. @@ -108,12 +110,12 @@ public EnvoyConfiguration( String dnsPreresolveHostnames, List dnsFallbackNameservers, Boolean dnsFilterUnroutableFamilies, boolean enableDrainPostDnsRefresh, boolean enableHttp3, boolean enableGzip, boolean enableBrotli, boolean enableHappyEyeballs, - boolean enableInterfaceBinding, int h2ConnectionKeepaliveIdleIntervalMilliseconds, - int h2ConnectionKeepaliveTimeoutSeconds, boolean h2ExtendKeepaliveTimeout, - List h2RawDomains, int maxConnectionsPerHost, int statsFlushSeconds, - int streamIdleTimeoutSeconds, int perTryIdleTimeoutSeconds, String appVersion, String appId, - TrustChainVerification trustChainVerification, String virtualClusters, - List nativeFilterChain, + boolean enableInterfaceBinding, boolean forceIPv6, + int h2ConnectionKeepaliveIdleIntervalMilliseconds, int h2ConnectionKeepaliveTimeoutSeconds, + boolean h2ExtendKeepaliveTimeout, List h2RawDomains, int maxConnectionsPerHost, + int statsFlushSeconds, int streamIdleTimeoutSeconds, int perTryIdleTimeoutSeconds, + String appVersion, String appId, TrustChainVerification trustChainVerification, + String virtualClusters, List nativeFilterChain, List httpPlatformFilterFactories, Map stringAccessors, Map keyValueStores) { @@ -135,6 +137,7 @@ public EnvoyConfiguration( this.enableBrotli = enableBrotli; this.enableHappyEyeballs = enableHappyEyeballs; this.enableInterfaceBinding = enableInterfaceBinding; + this.forceIPv6 = forceIPv6; this.h2ConnectionKeepaliveIdleIntervalMilliseconds = h2ConnectionKeepaliveIdleIntervalMilliseconds; this.h2ConnectionKeepaliveTimeoutSeconds = h2ConnectionKeepaliveTimeoutSeconds; @@ -250,6 +253,7 @@ String resolveTemplate(final String configTemplate, final String platformFilterT enableDrainPostDnsRefresh ? "true" : "false")) .append(String.format("- &enable_interface_binding %s\n", enableInterfaceBinding ? "true" : "false")) + .append(String.format("- &android_force_ipv6 %s\n", forceIPv6 ? "true" : "false")) .append(String.format("- &h2_connection_keepalive_idle_interval %ss\n", h2ConnectionKeepaliveIdleIntervalMilliseconds / 1000.0)) .append(String.format("- &h2_connection_keepalive_timeout %ss\n", diff --git a/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java b/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java index 0eb5f29111..cb2c985360 100644 --- a/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java +++ b/library/java/org/chromium/net/impl/NativeCronetEngineBuilderImpl.java @@ -48,6 +48,7 @@ public class NativeCronetEngineBuilderImpl extends CronetEngineBuilderImpl { private boolean mEnableGzip = true; private boolean mEnableHappyEyeballs = false; private boolean mEnableInterfaceBinding = false; + private boolean mForceIPv6 = false; private int mH2ConnectionKeepaliveIdleIntervalMilliseconds = 100000000; private int mH2ConnectionKeepaliveTimeoutSeconds = 10; private boolean mH2ExtendKeepaliveTimeout = false; @@ -108,10 +109,10 @@ private EnvoyConfiguration createEnvoyConfiguration() { mDnsQueryTimeoutSeconds, mDnsMinRefreshSeconds, mDnsPreresolveHostnames, mDnsFallbackNameservers, mEnableDnsFilterUnroutableFamilies, mEnableDrainPostDnsRefresh, mEnableHttp3, mEnableGzip, brotliEnabled(), mEnableHappyEyeballs, mEnableInterfaceBinding, - mH2ConnectionKeepaliveIdleIntervalMilliseconds, mH2ConnectionKeepaliveTimeoutSeconds, - mH2ExtendKeepaliveTimeout, mH2RawDomains, mMaxConnectionsPerHost, mStatsFlushSeconds, - mStreamIdleTimeoutSeconds, mPerTryIdleTimeoutSeconds, mAppVersion, mAppId, - mTrustChainVerification, mVirtualClusters, nativeFilterChain, platformFilterChain, - stringAccessors, keyValueStores); + mForceIPv6, mH2ConnectionKeepaliveIdleIntervalMilliseconds, + mH2ConnectionKeepaliveTimeoutSeconds, mH2ExtendKeepaliveTimeout, mH2RawDomains, + mMaxConnectionsPerHost, mStatsFlushSeconds, mStreamIdleTimeoutSeconds, + mPerTryIdleTimeoutSeconds, mAppVersion, mAppId, mTrustChainVerification, mVirtualClusters, + nativeFilterChain, platformFilterChain, stringAccessors, keyValueStores); } } diff --git a/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt b/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt index 2a29f7be0b..dfdf0cd287 100644 --- a/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt +++ b/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt @@ -46,6 +46,7 @@ open class EngineBuilder( private var enableGzip = true private var enableBrotli = false private var enableInterfaceBinding = false + private var forceIPv6 = false private var h2ConnectionKeepaliveIdleIntervalMilliseconds = 1 private var h2ConnectionKeepaliveTimeoutSeconds = 10 private var h2ExtendKeepaliveTimeout = false @@ -284,6 +285,19 @@ open class EngineBuilder( return this } + /** + * Specify whether to remap IPv4 addresses to the IPv6 space and always force connections + * to use IPv6. Note this is an experimental option and should be enabled with caution. + * + * @param forceIPv6 whether to force connections to use IPv6. + * + * @return This builder. + */ + fun forceIPv6(forceIPv6: Boolean): EngineBuilder { + this.forceIPv6 = forceIPv6 + return this + } + /** * Add a rate at which to ping h2 connections on new stream creation if the connection has * sat idle. Defaults to 1 millisecond which effectively enables h2 ping functionality @@ -571,6 +585,7 @@ open class EngineBuilder( enableBrotli, enableHappyEyeballs, enableInterfaceBinding, + forceIPv6, h2ConnectionKeepaliveIdleIntervalMilliseconds, h2ConnectionKeepaliveTimeoutSeconds, h2ExtendKeepaliveTimeout, diff --git a/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt b/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt index 7624239ab6..5da06cec76 100644 --- a/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt +++ b/test/java/io/envoyproxy/envoymobile/engine/EnvoyConfigurationTest.kt @@ -60,6 +60,7 @@ class EnvoyConfigurationTest { enableBrotli: Boolean = false, enableHappyEyeballs: Boolean = false, enableInterfaceBinding: Boolean = false, + forceIPv6: Boolean = false, h2ConnectionKeepaliveIdleIntervalMilliseconds: Int = 222, h2ConnectionKeepaliveTimeoutSeconds: Int = 333, h2ExtendKeepaliveTimeout: Boolean = false, @@ -92,6 +93,7 @@ class EnvoyConfigurationTest { enableBrotli, enableHappyEyeballs, enableInterfaceBinding, + forceIPv6, h2ConnectionKeepaliveIdleIntervalMilliseconds, h2ConnectionKeepaliveTimeoutSeconds, h2ExtendKeepaliveTimeout, @@ -139,6 +141,9 @@ class EnvoyConfigurationTest { // Interface Binding assertThat(resolvedTemplate).contains("&enable_interface_binding false") + // Forcing IPv6 + assertThat(resolvedTemplate).contains("&android_force_ipv6 false") + // H2 Ping assertThat(resolvedTemplate).contains("&h2_connection_keepalive_idle_interval 0.222s") assertThat(resolvedTemplate).contains("&h2_connection_keepalive_timeout 333s") @@ -192,6 +197,7 @@ class EnvoyConfigurationTest { enableGzip = false, enableBrotli = true, enableInterfaceBinding = true, + forceIPv6 = true, h2ExtendKeepaliveTimeout = true ) @@ -219,6 +225,9 @@ class EnvoyConfigurationTest { // Interface Binding assertThat(resolvedTemplate).contains("&enable_interface_binding true") + + // Forcing IPv6 + assertThat(resolvedTemplate).contains("&android_force_ipv6 true") } @Test diff --git a/test/kotlin/apps/experimental/MainActivity.kt b/test/kotlin/apps/experimental/MainActivity.kt index db5897d21f..45dd82fee4 100644 --- a/test/kotlin/apps/experimental/MainActivity.kt +++ b/test/kotlin/apps/experimental/MainActivity.kt @@ -57,6 +57,7 @@ class MainActivity : Activity() { .addPlatformFilter(::AsyncDemoFilter) .h2ExtendKeepaliveTimeout(true) .enableInterfaceBinding(true) + .forceIPv6(true) .addNativeFilter("envoy.filters.http.buffer", "{\"@type\":\"type.googleapis.com/envoy.extensions.filters.http.buffer.v3.Buffer\",\"max_request_bytes\":5242880}") .addStringAccessor("demo-accessor", { "PlatformString" }) .addKeyValueStore("demo-kv-store", SharedPreferencesStore(preferences))