Skip to content

Commit

Permalink
mobile: Add Apple proxy resolution APIs to the C++ EngineBuilder (env…
Browse files Browse the repository at this point in the history
…oyproxy#32426)

Previously, Apple proxy resolution API registration only happened in the
Objective-C engine. For those Apple/iOS users using the C++ APIs directly,
we need to support proxy resolution API registration in the C++ EngineBuilder
as well.

This commit also moves the Objective-C API registration to the same place where
other API registration (e.g. key-value store) takes place.

Lastly, to add tests for this, we had to add the Apple CFNetwork and
CoreFoundation frameworks to the linkopts, which required envoy_cc_test being
able to take in an optional linkopts to add to its defaults.

Signed-off-by: Ali Beyad <[email protected]>
  • Loading branch information
abeyad authored Feb 17, 2024
1 parent 678de63 commit f301eeb
Show file tree
Hide file tree
Showing 13 changed files with 77 additions and 17 deletions.
3 changes: 2 additions & 1 deletion bazel/envoy_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def envoy_cc_test(
tags = [],
args = [],
copts = [],
linkopts = [],
condition = None,
shard_count = None,
coverage = True,
Expand All @@ -170,7 +171,7 @@ def envoy_cc_test(
data = data,
copts = envoy_copts(repository, test = True) + copts + envoy_pch_copts(repository, "//test:test_pch"),
additional_linker_inputs = envoy_exported_symbols_input(),
linkopts = _envoy_test_linkopts(),
linkopts = _envoy_test_linkopts() + linkopts,
linkstatic = envoy_linkstatic(),
malloc = tcmalloc_external_dep(repository),
deps = envoy_stdlib_deps() + deps + [envoy_external_dep_path(dep) for dep in external_deps + ["googletest"]] + [
Expand Down
7 changes: 6 additions & 1 deletion mobile/library/cc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,12 @@ envoy_cc_library(
"@envoy_mobile//library/common/extensions/filters/http/network_configuration:filter_cc_proto",
"@envoy_mobile//library/common/extensions/filters/http/socket_tag:filter_cc_proto",
"@envoy_mobile//library/common/types:matcher_data_lib",
],
] + select({
"@envoy//bazel:apple": [
"@envoy_mobile//library/common/network:apple_proxy_resolution_lib",
],
"//conditions:default": [],
}),
)

envoy_cc_library(
Expand Down
17 changes: 17 additions & 0 deletions mobile/library/cc/engine_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#include "library/common/extensions/filters/http/socket_tag/filter.pb.h"
#include "library/common/extensions/key_value/platform/platform.pb.h"

#if defined(__APPLE__)
#include "library/common/network/apple_proxy_resolution.h"
#endif

namespace Envoy {
namespace Platform {

Expand Down Expand Up @@ -374,6 +378,13 @@ EngineBuilder& EngineBuilder::setRuntimeGuard(std::string guard, bool value) {
return *this;
}

#if defined(__APPLE__)
EngineBuilder& EngineBuilder::respectSystemProxySettings(bool value) {
respect_system_proxy_settings_ = value;
return *this;
}
#endif

std::unique_ptr<envoy::config::bootstrap::v3::Bootstrap> EngineBuilder::generateBootstrap() const {
// The yaml utilities have non-relevant thread asserts.
Thread::SkipAsserts skip;
Expand Down Expand Up @@ -894,6 +905,12 @@ EngineSharedPtr EngineBuilder::build() {
}
}

#if defined(__APPLE__)
if (respect_system_proxy_settings_) {
registerAppleProxyResolver();
}
#endif

Engine* engine = new Engine(envoy_engine);

auto options = std::make_unique<Envoy::OptionsImplBase>();
Expand Down
12 changes: 12 additions & 0 deletions mobile/library/cc/engine_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ class EngineBuilder {
EngineBuilder& addKeyValueStore(std::string name, KeyValueStoreSharedPtr key_value_store);
EngineBuilder& addStringAccessor(std::string name, StringAccessorSharedPtr accessor);

#if defined(__APPLE__)
// Right now, this API is only used by Apple (iOS) to register the Apple proxy resolver API for
// use in reading and using the system proxy settings.
// If/when we move Android system proxy registration to the C++ Engine Builder, we will make this
// API available on all platforms.
EngineBuilder& respectSystemProxySettings(bool value);
#endif

// This is separated from build() for the sake of testability
virtual std::unique_ptr<envoy::config::bootstrap::v3::Bootstrap> generateBootstrap() const;

Expand Down Expand Up @@ -242,6 +250,10 @@ class EngineBuilder {
std::vector<std::string> quic_suffixes_;
bool enable_port_migration_ = false;
bool always_use_v6_ = false;
#if defined(__APPLE__)
// TODO(abeyad): once stable, consider setting the default to true.
bool respect_system_proxy_settings_ = false;
#endif
int dns_min_refresh_seconds_ = 60;
int max_connections_per_host_ = 7;

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 @@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) BOOL enforceTrustChainVerification;
@property (nonatomic, assign) BOOL forceIPv6;
@property (nonatomic, assign) BOOL enablePlatformCertificateValidation;
@property (nonatomic, assign) BOOL respectSystemProxySettings;
@property (nonatomic, assign) UInt32 h2ConnectionKeepaliveIdleIntervalMilliseconds;
@property (nonatomic, assign) UInt32 h2ConnectionKeepaliveTimeoutSeconds;
@property (nonatomic, assign) UInt32 maxConnectionsPerHost;
Expand Down Expand Up @@ -81,6 +82,7 @@ NS_ASSUME_NONNULL_BEGIN
enforceTrustChainVerification:(BOOL)enforceTrustChainVerification
forceIPv6:(BOOL)forceIPv6
enablePlatformCertificateValidation:(BOOL)enablePlatformCertificateValidation
respectSystemProxySettings:(BOOL)respectSystemProxySettings
h2ConnectionKeepaliveIdleIntervalMilliseconds:
(UInt32)h2ConnectionKeepaliveIdleIntervalMilliseconds
h2ConnectionKeepaliveTimeoutSeconds:(UInt32)h2ConnectionKeepaliveTimeoutSeconds
Expand Down
3 changes: 3 additions & 0 deletions mobile/library/objective-c/EnvoyConfiguration.mm
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ - (instancetype)initWithConnectTimeoutSeconds:(UInt32)connectTimeoutSeconds
enforceTrustChainVerification:(BOOL)enforceTrustChainVerification
forceIPv6:(BOOL)forceIPv6
enablePlatformCertificateValidation:(BOOL)enablePlatformCertificateValidation
respectSystemProxySettings:(BOOL)respectSystemProxySettings
h2ConnectionKeepaliveIdleIntervalMilliseconds:
(UInt32)h2ConnectionKeepaliveIdleIntervalMilliseconds
h2ConnectionKeepaliveTimeoutSeconds:(UInt32)h2ConnectionKeepaliveTimeoutSeconds
Expand Down Expand Up @@ -143,6 +144,7 @@ - (instancetype)initWithConnectTimeoutSeconds:(UInt32)connectTimeoutSeconds
self.enforceTrustChainVerification = enforceTrustChainVerification;
self.forceIPv6 = forceIPv6;
self.enablePlatformCertificateValidation = enablePlatformCertificateValidation;
self.respectSystemProxySettings = respectSystemProxySettings;
self.h2ConnectionKeepaliveIdleIntervalMilliseconds =
h2ConnectionKeepaliveIdleIntervalMilliseconds;
self.h2ConnectionKeepaliveTimeoutSeconds = h2ConnectionKeepaliveTimeoutSeconds;
Expand Down Expand Up @@ -236,6 +238,7 @@ - (instancetype)initWithConnectTimeoutSeconds:(UInt32)connectTimeoutSeconds
builder.setAppId([self.appId toCXXString]);
builder.setDeviceOs("iOS");
builder.enablePlatformCertificatesValidation(self.enablePlatformCertificateValidation);
builder.respectSystemProxySettings(self.respectSystemProxySettings);
builder.enableDnsCache(self.enableDNSCache, self.dnsCacheSaveIntervalSeconds);

if (self.nodeRegion != nil) {
Expand Down
5 changes: 1 addition & 4 deletions mobile/library/objective-c/EnvoyEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@ NS_ASSUME_NONNULL_BEGIN
@param logger Logging interface.
@param eventTracker Event tracking interface.
@param networkMonitoringMode Configure how the engines observe network reachability.
@param respectSystemProxySettings Whether to respect system proxy settings when performing
network requests.
*/
- (instancetype)initWithRunningCallback:(nullable void (^)())onEngineRunning
logger:(nullable void (^)(NSInteger, NSString *))logger
eventTracker:(nullable void (^)(EnvoyEvent *))eventTracker
networkMonitoringMode:(int)networkMonitoringMode
respectSystemProxySettings:(BOOL)respectSystemProxySettings;
networkMonitoringMode:(int)networkMonitoringMode;
/**
Run the Envoy engine with the provided configuration and log level.
Expand Down
11 changes: 5 additions & 6 deletions mobile/library/objective-c/EnvoyEngineImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -407,8 +407,7 @@ @implementation EnvoyEngineImpl {
- (instancetype)initWithRunningCallback:(nullable void (^)())onEngineRunning
logger:(nullable void (^)(NSInteger, NSString *))logger
eventTracker:(nullable void (^)(EnvoyEvent *))eventTracker
networkMonitoringMode:(int)networkMonitoringMode
respectSystemProxySettings:(BOOL)respectSystemProxySettings {
networkMonitoringMode:(int)networkMonitoringMode {
self = [super init];
if (!self) {
return nil;
Expand Down Expand Up @@ -439,10 +438,6 @@ - (instancetype)initWithRunningCallback:(nullable void (^)())onEngineRunning
_engine = new Envoy::InternalEngine(native_callbacks, native_logger, native_event_tracker);
_engineHandle = reinterpret_cast<envoy_engine_t>(_engine);

if (respectSystemProxySettings) {
registerAppleProxyResolver();
}

if (networkMonitoringMode == 1) {
[_networkMonitor startReachability];
} else if (networkMonitoringMode == 2) {
Expand Down Expand Up @@ -518,6 +513,10 @@ - (void)performRegistrationsForConfig:(EnvoyConfiguration *)config {
for (NSString *name in config.keyValueStores) {
[self registerKeyValueStore:name keyValueStore:config.keyValueStores[name]];
}

if (config.respectSystemProxySettings) {
registerAppleProxyResolver();
}
}

- (int)runWithConfig:(EnvoyConfiguration *)config logLevel:(NSString *)logLevel {
Expand Down
7 changes: 4 additions & 3 deletions mobile/library/swift/EngineBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ open class EngineBuilder: NSObject {
private var quicHints: [String: Int] = [:]
private var quicCanonicalSuffixes: [String] = []
private var enableInterfaceBinding: Bool = false
private var respectSystemProxySettings: Bool = false
private var enforceTrustChainVerification: Bool = true
private var enablePlatformCertificateValidation: Bool = false
private var respectSystemProxySettings: Bool = false
private var enableDrainPostDnsRefresh: Bool = false
private var forceIPv6: Bool = false
private var h2ConnectionKeepaliveIdleIntervalMilliseconds: UInt32 = 1
Expand Down Expand Up @@ -717,8 +717,7 @@ open class EngineBuilder: NSObject {
}
},
eventTracker: self.eventTracker,
networkMonitoringMode: Int32(self.monitoringMode.rawValue),
respectSystemProxySettings: self.respectSystemProxySettings)
networkMonitoringMode: Int32(self.monitoringMode.rawValue))
let config = self.makeConfig()
#if canImport(EnvoyCxxSwiftInterop)
if self.enableSwiftBootstrap {
Expand Down Expand Up @@ -794,6 +793,7 @@ open class EngineBuilder: NSObject {
enforceTrustChainVerification: self.enforceTrustChainVerification,
forceIPv6: self.forceIPv6,
enablePlatformCertificateValidation: self.enablePlatformCertificateValidation,
respectSystemProxySettings: self.respectSystemProxySettings,
h2ConnectionKeepaliveIdleIntervalMilliseconds:
self.h2ConnectionKeepaliveIdleIntervalMilliseconds,
h2ConnectionKeepaliveTimeoutSeconds: self.h2ConnectionKeepaliveTimeoutSeconds,
Expand Down Expand Up @@ -865,6 +865,7 @@ private extension EngineBuilder {
cxxBuilder.enforceTrustChainVerification(self.enforceTrustChainVerification)
cxxBuilder.setForceAlwaysUsev6(self.forceIPv6)
cxxBuilder.enablePlatformCertificatesValidation(self.enablePlatformCertificateValidation)
cxxBuilder.respectSystemProxySettings(self.respectSystemProxySettings)
cxxBuilder.addH2ConnectionKeepaliveIdleIntervalMilliseconds(
Int32(self.h2ConnectionKeepaliveIdleIntervalMilliseconds)
)
Expand Down
3 changes: 1 addition & 2 deletions mobile/library/swift/mocks/MockEnvoyEngine.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import Foundation
final class MockEnvoyEngine: NSObject {
init(runningCallback onEngineRunning: (() -> Void)? = nil,
logger: ((Int, String) -> Void)? = nil,
eventTracker: (([String: String]) -> Void)? = nil, networkMonitoringMode: Int32 = 0,
respectSystemProxySettings: Bool = false) {}
eventTracker: (([String: String]) -> Void)? = nil, networkMonitoringMode: Int32 = 0) {}

/// Closure called when `run(withConfig:)` is called.
static var onRunWithConfig: ((_ config: EnvoyConfiguration, _ logLevel: String?) -> Void)?
Expand Down
8 changes: 8 additions & 0 deletions mobile/test/cc/unit/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ envoy_cc_test(
["envoy_config_test.cc"],
"@envoy",
),
linkopts = select({
"@envoy//bazel:apple": [
# For the TestProxyResolutionApi test.
"-Wl,-framework,CoreFoundation",
"-Wl,-framework,CFNetwork",
],
"//conditions:default": [],
}),
repository = "@envoy",
deps = [
"//library/cc:engine_builder_lib",
Expand Down
8 changes: 8 additions & 0 deletions mobile/test/common/integration/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ envoy_cc_test(
# TODO(willengflow): Remove this once the sandboxNetwork=off works for ipv4 localhost addresses.
"sandboxNetwork": "standard",
},
linkopts = select({
"@envoy//bazel:apple": [
# For the TestProxyResolutionApi test.
"-Wl,-framework,CoreFoundation",
"-Wl,-framework,CFNetwork",
],
"//conditions:default": [],
}),
repository = "@envoy",
shard_count = 6,
deps = [
Expand Down
8 changes: 8 additions & 0 deletions mobile/test/common/integration/client_integration_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1020,5 +1020,13 @@ TEST_P(ClientIntegrationTest, TestStats) {
}
}

#if defined(__APPLE__)
TEST_P(ClientIntegrationTest, TestProxyResolutionApi) {
builder_.respectSystemProxySettings(true);
initialize();
ASSERT_TRUE(Envoy::Api::External::retrieveApi("envoy_proxy_resolver") != nullptr);
}
#endif

} // namespace
} // namespace Envoy

0 comments on commit f301eeb

Please sign in to comment.