Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions include/aws/crt/http/HttpConnectionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ namespace Aws
* reference to the connection manager.
*/
bool EnableBlockingShutdown;

/**
* THIS IS AN EXPERIMENTAL AND UNSTABLE API
* (Optional)
* An array of network interface names. The manager will distribute the connections across network
* interface names provided in this array. If any interface name is invalid, goes down, or has any
* issues like network access, you will see connection failures. If
* `socket_options.network_interface_name` is also set, an `AWS_ERROR_INVALID_ARGUMENT` error will be
* raised.
*
* This option is only supported on Linux, MacOS, and platforms that have either SO_BINDTODEVICE or
* IP_BOUND_IF. It is not supported on Windows. `AWS_ERROR_PLATFORM_NOT_SUPPORTED` will be raised on
* unsupported platforms.
*/
Vector<ByteCursor> NetworkInterfaces;
};

/**
Expand Down
6 changes: 6 additions & 0 deletions source/http/HttpConnectionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ namespace Aws
}
managerOptions.host = aws_byte_cursor_from_c_str(connectionOptions.HostName.c_str());

if (m_options.NetworkInterfaces.size() > 0)
{
managerOptions.network_interface_names_array = m_options.NetworkInterfaces.data();
managerOptions.num_network_interface_names = m_options.NetworkInterfaces.size();
}

m_connectionManager = aws_http_connection_manager_new(allocator, &managerOptions);
}

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ if(NOT BYO_CRYPTO)
add_net_test_case(HttpClientConnectionManagerInvalidTlsConnectionOptions)
add_net_test_case(HttpClientConnectionWithPendingAcquisitions)
add_net_test_case(HttpClientConnectionWithPendingAcquisitionsAndClosedConnections)
add_net_test_case(HttpClientCreateManagerWithNetworkInterfacesList)
add_net_test_case(IotConnectionDestruction)
add_net_test_case(IotConnectionDestructionWithExecutingCallback)
add_net_test_case(IotConnectionDestructionWithinConnectionCallback)
Expand Down
65 changes: 65 additions & 0 deletions tests/HttpClientConnectionManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,4 +447,69 @@ AWS_TEST_CASE(
HttpClientConnectionWithPendingAcquisitionsAndClosedConnections,
s_TestHttpClientConnectionWithPendingAcquisitionsAndClosedConnections)

static int s_TestHttpClientCreateManagerWithNetworkInterfacesList(struct aws_allocator *allocator, void *ctx)
{
(void)ctx;
{
Aws::Crt::ApiHandle apiHandle(allocator);

Aws::Crt::Io::TlsContextOptions tlsCtxOptions = Aws::Crt::Io::TlsContextOptions::InitDefaultClient();

// Ensure that if PQ TLS ciphers are supported on the current platform, that setting them works when connecting
// to S3. This TlsCipherPreference has post quantum ciphers at the top of it's preference list (that will be
// ignored if S3 doesn't support them) followed by regular TLS ciphers that can be chosen and negotiated by S3.
aws_tls_cipher_pref tls_cipher_pref = AWS_IO_TLS_CIPHER_PREF_PQ_DEFAULT;

if (aws_tls_is_cipher_pref_supported(tls_cipher_pref))
{
tlsCtxOptions.SetTlsCipherPreference(tls_cipher_pref);
}

Aws::Crt::Io::TlsContext tlsContext(tlsCtxOptions, Aws::Crt::Io::TlsMode::CLIENT, allocator);
ASSERT_TRUE(tlsContext);

Aws::Crt::Io::TlsConnectionOptions tlsConnectionOptions = tlsContext.NewConnectionOptions();

ByteCursor cursor = ByteCursorFromCString("https://s3.amazonaws.com");
Io::Uri uri(cursor, allocator);

auto hostName = uri.GetHostName();
tlsConnectionOptions.SetServerName(hostName);

Aws::Crt::Io::SocketOptions socketOptions;
socketOptions.SetConnectTimeoutMs(10000);

Aws::Crt::Io::EventLoopGroup eventLoopGroup(1, allocator);
ASSERT_TRUE(eventLoopGroup);

Aws::Crt::Io::DefaultHostResolver defaultHostResolver(eventLoopGroup, 8, 30, allocator);
ASSERT_TRUE(defaultHostResolver);

Aws::Crt::Io::ClientBootstrap clientBootstrap(eventLoopGroup, defaultHostResolver, allocator);
ASSERT_TRUE(clientBootstrap);
clientBootstrap.EnableBlockingShutdown();
Http::HttpClientConnectionOptions connectionOptions;
connectionOptions.Bootstrap = &clientBootstrap;
connectionOptions.SocketOptions = socketOptions;
connectionOptions.TlsOptions = tlsConnectionOptions;
connectionOptions.HostName = String((const char *)hostName.ptr, hostName.len);
connectionOptions.Port = 443;

Http::HttpClientConnectionManagerOptions connectionManagerOptions;
connectionManagerOptions.ConnectionOptions = connectionOptions;
connectionManagerOptions.MaxConnections = 30;
connectionManagerOptions.EnableBlockingShutdown = true;

Vector<ByteCursor> networkInterfaces{ByteCursorFromCString("eth0"), ByteCursorFromCString("eth1")};
connectionManagerOptions.NetworkInterfaces = networkInterfaces;

auto connectionManager =
Http::HttpClientConnectionManager::NewClientConnectionManager(connectionManagerOptions, allocator);
ASSERT_TRUE(connectionManager);
}
return AWS_OP_SUCCESS;
}

AWS_TEST_CASE(HttpClientCreateManagerWithNetworkInterfacesList, s_TestHttpClientCreateManagerWithNetworkInterfacesList)

#endif // !BYO_CRYPTO
Loading