Skip to content

Commit

Permalink
mobile: Add EngineBuilder::setDnsNumRetries (#35906)
Browse files Browse the repository at this point in the history
This PR adds a configuration to set the number of DNS retries. If not
specified, the DNS resolver will indefinitely retry until it succeeds or
the DNS query times out.

Risk Level: low (a new feature)
Testing: unit tests
Docs Changes: n/a
Release Notes: n/a
Platform Specific Features: mobile

---------

Signed-off-by: Fredy Wijaya <[email protected]>
  • Loading branch information
fredyw committed Aug 29, 2024
1 parent ac40224 commit db12a70
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 31 deletions.
8 changes: 8 additions & 0 deletions mobile/library/cc/engine_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ EngineBuilder& EngineBuilder::addDnsQueryTimeoutSeconds(int dns_query_timeout_se
return *this;
}

EngineBuilder& EngineBuilder::setDnsNumRetries(uint32_t dns_num_retries) {
dns_num_retries_ = dns_num_retries;
return *this;
}

EngineBuilder& EngineBuilder::addDnsPreresolveHostnames(const std::vector<std::string>& hostnames) {
// Add a default port of 443 for all hosts. We'll eventually change this API so it takes a single
// {host, pair} and it can be called multiple times.
Expand Down Expand Up @@ -488,6 +493,9 @@ std::unique_ptr<envoy::config::bootstrap::v3::Bootstrap> EngineBuilder::generate
} else {
envoy::extensions::network::dns_resolver::getaddrinfo::v3::GetAddrInfoDnsResolverConfig
resolver_config;
if (dns_num_retries_.has_value()) {
resolver_config.mutable_num_retries()->set_value(*dns_num_retries_);
}
dns_cache_config->mutable_typed_dns_resolver_config()->set_name(
"envoy.network.dns_resolver.getaddrinfo");
dns_cache_config->mutable_typed_dns_resolver_config()->mutable_typed_config()->PackFrom(
Expand Down
2 changes: 2 additions & 0 deletions mobile/library/cc/engine_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class EngineBuilder {
EngineBuilder& addDnsFailureRefreshSeconds(int base, int max);
EngineBuilder& addDnsQueryTimeoutSeconds(int dns_query_timeout_seconds);
EngineBuilder& addDnsMinRefreshSeconds(int dns_min_refresh_seconds);
EngineBuilder& setDnsNumRetries(uint32_t dns_num_retries);
EngineBuilder& addMaxConnectionsPerHost(int max_connections_per_host);
EngineBuilder& addH2ConnectionKeepaliveIdleIntervalMilliseconds(
int h2_connection_keepalive_idle_interval_milliseconds);
Expand Down Expand Up @@ -138,6 +139,7 @@ class EngineBuilder {
int dns_failure_refresh_seconds_base_ = 2;
int dns_failure_refresh_seconds_max_ = 10;
int dns_query_timeout_seconds_ = 5;
absl::optional<uint32_t> dns_num_retries_ = absl::nullopt;
int h2_connection_keepalive_idle_interval_milliseconds_ = 100000000;
int h2_connection_keepalive_timeout_seconds_ = 10;
std::string app_version_ = "unspecified";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public enum TrustChainVerification {
public final List<String> dnsPreresolveHostnames;
public final Boolean enableDNSCache;
public final Integer dnsCacheSaveIntervalSeconds;
public final int dnsNumRetries;
public final Boolean enableDrainPostDnsRefresh;
public final Boolean enableHttp3;
public final Boolean useCares;
Expand Down Expand Up @@ -85,6 +86,8 @@ public enum TrustChainVerification {
* @param enableDNSCache whether to enable DNS cache.
* @param dnsCacheSaveIntervalSeconds the interval at which to save results to
* the configured key value store.
* @param dnsNumRetries the number of retries before the DNS
* resolver gives up
* @param enableDrainPostDnsRefresh whether to drain connections after soft
* DNS refresh.
* @param enableHttp3 whether to enable experimental support for
Expand Down Expand Up @@ -130,8 +133,8 @@ public EnvoyConfiguration(
int connectTimeoutSeconds, int dnsRefreshSeconds, int dnsFailureRefreshSecondsBase,
int dnsFailureRefreshSecondsMax, int dnsQueryTimeoutSeconds, int dnsMinRefreshSeconds,
List<String> dnsPreresolveHostnames, boolean enableDNSCache, int dnsCacheSaveIntervalSeconds,
boolean enableDrainPostDnsRefresh, boolean enableHttp3, boolean useCares, boolean useGro,
String http3ConnectionOptions, String http3ClientConnectionOptions,
int dnsNumRetries, boolean enableDrainPostDnsRefresh, boolean enableHttp3, boolean useCares,
boolean useGro, String http3ConnectionOptions, String http3ClientConnectionOptions,
Map<String, Integer> quicHints, List<String> quicCanonicalSuffixes,
boolean enableGzipDecompression, boolean enableBrotliDecompression,
boolean enablePortMigration, boolean enableSocketTagging, boolean enableInterfaceBinding,
Expand All @@ -153,6 +156,7 @@ public EnvoyConfiguration(
this.dnsPreresolveHostnames = dnsPreresolveHostnames;
this.enableDNSCache = enableDNSCache;
this.dnsCacheSaveIntervalSeconds = dnsCacheSaveIntervalSeconds;
this.dnsNumRetries = dnsNumRetries;
this.enableDrainPostDnsRefresh = enableDrainPostDnsRefresh;
this.enableHttp3 = enableHttp3;
this.useCares = useCares;
Expand Down Expand Up @@ -215,13 +219,14 @@ public long createBootstrap() {
return JniLibrary.createBootstrap(
connectTimeoutSeconds, dnsRefreshSeconds, dnsFailureRefreshSecondsBase,
dnsFailureRefreshSecondsMax, dnsQueryTimeoutSeconds, dnsMinRefreshSeconds, dnsPreresolve,
enableDNSCache, dnsCacheSaveIntervalSeconds, enableDrainPostDnsRefresh, enableHttp3,
useCares, useGro, http3ConnectionOptions, http3ClientConnectionOptions, quicHints,
quicSuffixes, enableGzipDecompression, enableBrotliDecompression, enablePortMigration,
enableSocketTagging, enableInterfaceBinding, h2ConnectionKeepaliveIdleIntervalMilliseconds,
h2ConnectionKeepaliveTimeoutSeconds, maxConnectionsPerHost, streamIdleTimeoutSeconds,
perTryIdleTimeoutSeconds, appVersion, appId, enforceTrustChainVerification, filterChain,
enablePlatformCertificatesValidation, upstreamTlsSni, runtimeGuards);
enableDNSCache, dnsCacheSaveIntervalSeconds, dnsNumRetries, enableDrainPostDnsRefresh,
enableHttp3, useCares, useGro, http3ConnectionOptions, http3ClientConnectionOptions,
quicHints, quicSuffixes, enableGzipDecompression, enableBrotliDecompression,
enablePortMigration, enableSocketTagging, enableInterfaceBinding,
h2ConnectionKeepaliveIdleIntervalMilliseconds, h2ConnectionKeepaliveTimeoutSeconds,
maxConnectionsPerHost, streamIdleTimeoutSeconds, perTryIdleTimeoutSeconds, appVersion,
appId, enforceTrustChainVerification, filterChain, enablePlatformCertificatesValidation,
upstreamTlsSni, runtimeGuards);
}

static class ConfigurationException extends RuntimeException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,9 @@ public static native long createBootstrap(
long connectTimeoutSeconds, long dnsRefreshSeconds, long dnsFailureRefreshSecondsBase,
long dnsFailureRefreshSecondsMax, long dnsQueryTimeoutSeconds, long dnsMinRefreshSeconds,
byte[][] dnsPreresolveHostnames, boolean enableDNSCache, long dnsCacheSaveIntervalSeconds,
boolean enableDrainPostDnsRefresh, boolean enableHttp3, boolean useCares, boolean useGro,
String http3ConnectionOptions, String http3ClientConnectionOptions, byte[][] quicHints,
byte[][] quicCanonicalSuffixes, boolean enableGzipDecompression,
int dnsNumRetries, boolean enableDrainPostDnsRefresh, boolean enableHttp3, boolean useCares,
boolean useGro, String http3ConnectionOptions, String http3ClientConnectionOptions,
byte[][] quicHints, byte[][] quicCanonicalSuffixes, boolean enableGzipDecompression,
boolean enableBrotliDecompression, boolean enablePortMigration, boolean enableSocketTagging,
boolean enableInterfaceBinding, long h2ConnectionKeepaliveIdleIntervalMilliseconds,
long h2ConnectionKeepaliveTimeoutSeconds, long maxConnectionsPerHost,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.chromium.net.ExperimentalCronetEngine;
import org.chromium.net.ICronetEngineBuilder;
import com.google.protobuf.Any;
Expand All @@ -44,6 +46,7 @@ public class NativeCronvoyEngineBuilderImpl extends CronvoyEngineBuilderImpl {
private final List<String> mDnsPreresolveHostnames = Collections.emptyList();
private final boolean mEnableDNSCache = false;
private final int mDnsCacheSaveIntervalSeconds = 1;
private Optional<Integer> mDnsNumRetries = Optional.empty();
private final List<String> mDnsFallbackNameservers = Collections.emptyList();
private final boolean mEnableDnsFilterUnroutableFamilies = true;
private boolean mUseCares = false;
Expand Down Expand Up @@ -143,6 +146,18 @@ public NativeCronvoyEngineBuilderImpl setMinDnsRefreshSeconds(int minRefreshSeco
return this;
}

/**
* Specifies the number of retries before the resolver gives up. If not specified, the resolver
* will retry indefinitely until it succeeds or the DNS query times out.
*
* @param dnsNumRetries the number of retries
* @return this builder
*/
public NativeCronvoyEngineBuilderImpl setDnsNumRetries(int dnsNumRetries) {
mDnsNumRetries = Optional.of(dnsNumRetries);
return this;
}

/**
* Set the stream idle timeout, in seconds, which is defined as the period in which there are no
* active requests. When the idle timeout is reached, the connection is closed.
Expand Down Expand Up @@ -250,10 +265,10 @@ private EnvoyConfiguration createEnvoyConfiguration() {
mConnectTimeoutSeconds, mDnsRefreshSeconds, mDnsFailureRefreshSecondsBase,
mDnsFailureRefreshSecondsMax, mDnsQueryTimeoutSeconds, mDnsMinRefreshSeconds,
mDnsPreresolveHostnames, mEnableDNSCache, mDnsCacheSaveIntervalSeconds,
mEnableDrainPostDnsRefresh, quicEnabled(), mUseCares, mUseGro, quicConnectionOptions(),
quicClientConnectionOptions(), quicHints(), quicCanonicalSuffixes(),
mEnableGzipDecompression, brotliEnabled(), portMigrationEnabled(), mEnableSocketTag,
mEnableInterfaceBinding, mH2ConnectionKeepaliveIdleIntervalMilliseconds,
mDnsNumRetries.orElse(-1), mEnableDrainPostDnsRefresh, quicEnabled(), mUseCares, mUseGro,
quicConnectionOptions(), quicClientConnectionOptions(), quicHints(),
quicCanonicalSuffixes(), mEnableGzipDecompression, brotliEnabled(), portMigrationEnabled(),
mEnableSocketTag, mEnableInterfaceBinding, mH2ConnectionKeepaliveIdleIntervalMilliseconds,
mH2ConnectionKeepaliveTimeoutSeconds, mMaxConnectionsPerHost, mStreamIdleTimeoutSeconds,
mPerTryIdleTimeoutSeconds, mAppVersion, mAppId, mTrustChainVerification, nativeFilterChain,
platformFilterChain, stringAccessors, keyValueStores, mRuntimeGuards,
Expand Down
32 changes: 18 additions & 14 deletions mobile/library/jni/jni_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1195,12 +1195,13 @@ void configureBuilder(Envoy::JNI::JniHelper& jni_helper, jlong connect_timeout_s
jlong dns_failure_refresh_seconds_max, jlong dns_query_timeout_seconds,
jlong dns_min_refresh_seconds, jobjectArray dns_preresolve_hostnames,
jboolean enable_dns_cache, jlong dns_cache_save_interval_seconds,
jboolean enable_drain_post_dns_refresh, jboolean enable_http3,
jboolean use_cares, jboolean use_gro, jstring http3_connection_options,
jstring http3_client_connection_options, jobjectArray quic_hints,
jobjectArray quic_canonical_suffixes, jboolean enable_gzip_decompression,
jboolean enable_brotli_decompression, jboolean enable_port_migration,
jboolean enable_socket_tagging, jboolean enable_interface_binding,
jint dns_num_retries, jboolean enable_drain_post_dns_refresh,
jboolean enable_http3, jboolean use_cares, jboolean use_gro,
jstring http3_connection_options, jstring http3_client_connection_options,
jobjectArray quic_hints, jobjectArray quic_canonical_suffixes,
jboolean enable_gzip_decompression, jboolean enable_brotli_decompression,
jboolean enable_port_migration, jboolean enable_socket_tagging,
jboolean enable_interface_binding,
jlong h2_connection_keepalive_idle_interval_milliseconds,
jlong h2_connection_keepalive_timeout_seconds, jlong max_connections_per_host,
jlong stream_idle_timeout_seconds, jlong per_try_idle_timeout_seconds,
Expand All @@ -1215,6 +1216,9 @@ void configureBuilder(Envoy::JNI::JniHelper& jni_helper, jlong connect_timeout_s
builder.addDnsQueryTimeoutSeconds((dns_query_timeout_seconds));
builder.addDnsMinRefreshSeconds((dns_min_refresh_seconds));
builder.enableDnsCache(enable_dns_cache == JNI_TRUE, dns_cache_save_interval_seconds);
if (dns_num_retries >= 0) {
builder.setDnsNumRetries(dns_num_retries);
}
builder.addMaxConnectionsPerHost((max_connections_per_host));
builder.addH2ConnectionKeepaliveIdleIntervalMilliseconds(
(h2_connection_keepalive_idle_interval_milliseconds));
Expand Down Expand Up @@ -1288,13 +1292,13 @@ extern "C" JNIEXPORT jlong JNICALL Java_io_envoyproxy_envoymobile_engine_JniLibr
jlong dns_failure_refresh_seconds_base, jlong dns_failure_refresh_seconds_max,
jlong dns_query_timeout_seconds, jlong dns_min_refresh_seconds,
jobjectArray dns_preresolve_hostnames, jboolean enable_dns_cache,
jlong dns_cache_save_interval_seconds, jboolean enable_drain_post_dns_refresh,
jboolean enable_http3, jboolean use_cares, jboolean use_gro, jstring http3_connection_options,
jstring http3_client_connection_options, jobjectArray quic_hints,
jobjectArray quic_canonical_suffixes, jboolean enable_gzip_decompression,
jboolean enable_brotli_decompression, jboolean enable_port_migration,
jboolean enable_socket_tagging, jboolean enable_interface_binding,
jlong h2_connection_keepalive_idle_interval_milliseconds,
jlong dns_cache_save_interval_seconds, jint dns_num_retries,
jboolean enable_drain_post_dns_refresh, jboolean enable_http3, jboolean use_cares,
jboolean use_gro, jstring http3_connection_options, jstring http3_client_connection_options,
jobjectArray quic_hints, jobjectArray quic_canonical_suffixes,
jboolean enable_gzip_decompression, jboolean enable_brotli_decompression,
jboolean enable_port_migration, jboolean enable_socket_tagging,
jboolean enable_interface_binding, jlong h2_connection_keepalive_idle_interval_milliseconds,
jlong h2_connection_keepalive_timeout_seconds, jlong max_connections_per_host,
jlong stream_idle_timeout_seconds, jlong per_try_idle_timeout_seconds, jstring app_version,
jstring app_id, jboolean trust_chain_verification, jobjectArray filter_chain,
Expand All @@ -1306,7 +1310,7 @@ extern "C" JNIEXPORT jlong JNICALL Java_io_envoyproxy_envoymobile_engine_JniLibr
configureBuilder(
jni_helper, connect_timeout_seconds, dns_refresh_seconds, dns_failure_refresh_seconds_base,
dns_failure_refresh_seconds_max, dns_query_timeout_seconds, dns_min_refresh_seconds,
dns_preresolve_hostnames, enable_dns_cache, dns_cache_save_interval_seconds,
dns_preresolve_hostnames, enable_dns_cache, dns_cache_save_interval_seconds, dns_num_retries,
enable_drain_post_dns_refresh, enable_http3, use_cares, use_gro, http3_connection_options,
http3_client_connection_options, quic_hints, quic_canonical_suffixes,
enable_gzip_decompression, enable_brotli_decompression, enable_port_migration,
Expand Down
15 changes: 15 additions & 0 deletions mobile/library/kotlin/io/envoyproxy/envoymobile/EngineBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ open class EngineBuilder() {
private var dnsPreresolveHostnames = listOf<String>()
private var enableDNSCache = false
private var dnsCacheSaveIntervalSeconds = 1
// null means the DNS resolver will try indefinitely until it succeeds.
private var dnsNumRetries: Int? = null
private var enableDrainPostDnsRefresh = false
internal var enableHttp3 = true
internal var useCares = false
Expand Down Expand Up @@ -142,6 +144,18 @@ open class EngineBuilder() {
return this
}

/**
* Specifies the number of retries before the resolver gives up. If not specified, the resolver
* will retry indefinitely until it succeeds or the DNS query times out.
*
* @param dnsNumRetries the number of retries
* @return this builder
*/
fun setDnsNumRetries(dnsNumRetries: Int): EngineBuilder {
this.dnsNumRetries = dnsNumRetries
return this
}

/**
* Specify whether to drain connections after the resolution of a soft DNS refresh. A refresh may
* be triggered directly via the Engine API, or as a result of a network status update provided by
Expand Down Expand Up @@ -526,6 +540,7 @@ open class EngineBuilder() {
dnsPreresolveHostnames,
enableDNSCache,
dnsCacheSaveIntervalSeconds,
dnsNumRetries ?: -1,
enableDrainPostDnsRefresh,
enableHttp3,
useCares,
Expand Down
2 changes: 2 additions & 0 deletions mobile/library/objective-c/EnvoyConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) UInt32 dnsRefreshSeconds;
@property (nonatomic, assign) BOOL enableDNSCache;
@property (nonatomic, assign) UInt32 dnsCacheSaveIntervalSeconds;
@property (nonatomic, assign) NSInteger dnsNumRetries;
@property (nonatomic, assign) BOOL enableHttp3;
@property (nonatomic, strong) NSDictionary<NSString *, NSNumber *> *quicHints;
@property (nonatomic, strong) NSArray<NSString *> *quicCanonicalSuffixes;
Expand Down Expand Up @@ -60,6 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
dnsPreresolveHostnames:(NSArray<NSString *> *)dnsPreresolveHostnames
enableDNSCache:(BOOL)enableDNSCache
dnsCacheSaveIntervalSeconds:(UInt32)dnsCacheSaveIntervalSeconds
dnsNumRetries:(NSInteger)dnsNumRetries
enableHttp3:(BOOL)enableHttp3
quicHints:(NSDictionary<NSString *, NSNumber *> *)quicHints
quicCanonicalSuffixes:(NSArray<NSString *> *)quicCanonicalSuffixes
Expand Down
6 changes: 5 additions & 1 deletion mobile/library/objective-c/EnvoyConfiguration.mm
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ - (instancetype)initWithConnectTimeoutSeconds:(UInt32)connectTimeoutSeconds
dnsPreresolveHostnames:(NSArray<NSString *> *)dnsPreresolveHostnames
enableDNSCache:(BOOL)enableDNSCache
dnsCacheSaveIntervalSeconds:(UInt32)dnsCacheSaveIntervalSeconds
dnsNumRetries:(NSInteger)dnsNumRetries
enableHttp3:(BOOL)enableHttp3
quicHints:(NSDictionary<NSString *, NSNumber *> *)quicHints
quicCanonicalSuffixes:(NSArray<NSString *> *)quicCanonicalSuffixes
Expand Down Expand Up @@ -122,6 +123,7 @@ - (instancetype)initWithConnectTimeoutSeconds:(UInt32)connectTimeoutSeconds
self.dnsPreresolveHostnames = dnsPreresolveHostnames;
self.enableDNSCache = enableDNSCache;
self.dnsCacheSaveIntervalSeconds = dnsCacheSaveIntervalSeconds;
self.dnsNumRetries = dnsNumRetries;
self.enableHttp3 = enableHttp3;
self.quicHints = quicHints;
self.quicCanonicalSuffixes = quicCanonicalSuffixes;
Expand Down Expand Up @@ -214,7 +216,9 @@ - (instancetype)initWithConnectTimeoutSeconds:(UInt32)connectTimeoutSeconds
builder.enablePlatformCertificatesValidation(self.enablePlatformCertificateValidation);
builder.respectSystemProxySettings(self.respectSystemProxySettings);
builder.enableDnsCache(self.enableDNSCache, self.dnsCacheSaveIntervalSeconds);

if (self.dnsNumRetries >= 0) {
builder.setDnsNumRetries(self.dnsNumRetries);
}
if (self.upstreamTlsSni != nil) {
builder.setUpstreamTlsSni([self.upstreamTlsSni toCXXString]);
}
Expand Down
Loading

0 comments on commit db12a70

Please sign in to comment.