From 0a1eed372176393b437c01252beeb583742cf0ab Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 13:29:21 -0700 Subject: [PATCH 01/33] wip --- include/aws/http/connection_manager.h | 2 ++ source/connection_manager.c | 41 ++++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index 70b1e77b..cbec1cfd 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -124,6 +124,8 @@ struct aws_http_connection_manager_options { * timeout will be closed automatically. */ uint64_t max_connection_idle_in_milliseconds; + + struct aws_array_list *network_interface_names_list; }; AWS_EXTERN_C_BEGIN diff --git a/source/connection_manager.c b/source/connection_manager.c index 195a7d6c..7e01ace9 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -292,6 +292,9 @@ struct aws_http_connection_manager { */ struct aws_task *cull_task; struct aws_event_loop *cull_event_loop; + + struct aws_array_list *network_interface_names_list; + uint32_t network_interface_names_list_index; }; struct aws_http_connection_manager_snapshot { @@ -703,6 +706,15 @@ static void s_aws_http_connection_manager_finish_destroy(struct aws_http_connect aws_http_proxy_config_destroy(manager->proxy_config); } + if (manager->network_interface_names_list) { + for (size_t i = 0; i < aws_array_list_length(manager->network_interface_names_list); i++) { + struct aws_string *interface_name = NULL; + aws_array_list_get_at(manager->network_interface_names_list, &interface_name, i); + aws_string_destroy(interface_name); + } + aws_array_list_clean_up(manager->network_interface_names_list); + } + /* * If this task exists then we are actually in the corresponding event loop running the final destruction task. * In that case, we've already cancelled this task and when you cancel, it runs synchronously. So in that @@ -896,6 +908,21 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->max_closed_streams = options->max_closed_streams; manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; + size_t network_interface_names_list_length = aws_array_list_length(options->network_interface_names_list); + if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { + aws_array_list_init_dynamic( + manager->network_interface_names_list, + allocator, + network_interface_names_list_length, + sizeof(struct aws_string *)); + for (size_t i = 0; i < network_interface_names_list_length; i++) { + struct aws_byte_cursor interface_name; + aws_array_list_get_at(options->network_interface_names_list, &interface_name, i); + aws_array_list_push_back( + manager->network_interface_names_list, aws_string_new_from_cursor(allocator, &interface_name)); + } + } + /* NOTHING can fail after here */ s_schedule_connection_culling(manager); @@ -990,7 +1017,19 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti options.host_name = aws_byte_cursor_from_string(manager->host); options.port = manager->port; options.initial_window_size = manager->initial_window_size; - options.socket_options = &manager->socket_options; + struct aws_socket_options socket_options = manager->socket_options; + if (manager->network_interface_names_list != NULL) { + struct aws_string *interface_name; + aws_array_list_get_at( + manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); + manager->network_interface_names_list_index = manager->network_interface_names_list_index++ % + aws_array_list_length(manager->network_interface_names_list); + strncpy( + socket_options.network_interface_name, + aws_string_c_str(interface_name), + aws_min_size(interface_name->len, AWS_NETWORK_INTERFACE_MAX_LEN)); + } + options.socket_options = &socket_options; options.on_setup = s_aws_http_connection_manager_on_connection_setup; options.on_shutdown = s_aws_http_connection_manager_on_connection_shutdown; options.manual_window_management = manager->enable_read_back_pressure; From 0a28f71148e191c827189929cf4255c30175137e Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 13:31:11 -0700 Subject: [PATCH 02/33] null fix --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 7e01ace9..f3202613 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1019,7 +1019,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti options.initial_window_size = manager->initial_window_size; struct aws_socket_options socket_options = manager->socket_options; if (manager->network_interface_names_list != NULL) { - struct aws_string *interface_name; + struct aws_string *interface_name = NULL; aws_array_list_get_at( manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); manager->network_interface_names_list_index = manager->network_interface_names_list_index++ % From 65caced4c1243380412791058560c478545097ef Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 13:48:18 -0700 Subject: [PATCH 03/33] fix warning --- source/connection_manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/connection_manager.c b/source/connection_manager.c index f3202613..2ab3b30a 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -908,6 +908,7 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->max_closed_streams = options->max_closed_streams; manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; + manager->network_interface_names_list_index = 0; size_t network_interface_names_list_length = aws_array_list_length(options->network_interface_names_list); if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { aws_array_list_init_dynamic( From 213bd12d550833da6d54daa14f0db4fb9b65cc4c Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 13:57:54 -0700 Subject: [PATCH 04/33] maybe? --- source/connection_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 2ab3b30a..9e18de45 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -294,7 +294,7 @@ struct aws_http_connection_manager { struct aws_event_loop *cull_event_loop; struct aws_array_list *network_interface_names_list; - uint32_t network_interface_names_list_index; + size_t network_interface_names_list_index; }; struct aws_http_connection_manager_snapshot { @@ -1023,7 +1023,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti struct aws_string *interface_name = NULL; aws_array_list_get_at( manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); - manager->network_interface_names_list_index = manager->network_interface_names_list_index++ % + manager->network_interface_names_list_index = (manager->network_interface_names_list_index+1) % aws_array_list_length(manager->network_interface_names_list); strncpy( socket_options.network_interface_name, From 283caf0d5da99a902200a91b02777dda43587e5b Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 14:09:54 -0700 Subject: [PATCH 05/33] fix null behavior --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 9e18de45..efec9d57 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -909,7 +909,7 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; manager->network_interface_names_list_index = 0; - size_t network_interface_names_list_length = aws_array_list_length(options->network_interface_names_list); + size_t network_interface_names_list_length = options->network_interface_names_list != NULL ? aws_array_list_length(options->network_interface_names_list) : 0; if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { aws_array_list_init_dynamic( manager->network_interface_names_list, From 1d7ececc84f022a18ef4811ce20a8cbd54342690 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 14:38:36 -0700 Subject: [PATCH 06/33] suppress warning --- source/connection_manager.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index efec9d57..d8e3b502 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1024,7 +1024,11 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti aws_array_list_get_at( manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); manager->network_interface_names_list_index = (manager->network_interface_names_list_index+1) % - aws_array_list_length(manager->network_interface_names_list); + aws_array_list_length(manager->network_interface_names_list); +#ifdef AWS_OS_WINDOWS + /* suppress deprecation warning for strncpy */ + #pragma warning(suppress : 4996) +#endif strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), From 0225d80e292b1df870574b4896dda10a062c8358 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 14:47:24 -0700 Subject: [PATCH 07/33] use push pop --- source/connection_manager.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index d8e3b502..674dbe95 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1025,14 +1025,16 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); manager->network_interface_names_list_index = (manager->network_interface_names_list_index+1) % aws_array_list_length(manager->network_interface_names_list); -#ifdef AWS_OS_WINDOWS - /* suppress deprecation warning for strncpy */ - #pragma warning(suppress : 4996) +#if defined(_MSC_VER) +# pragma warning(disable : 4996) /* deprecation */ #endif strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), aws_min_size(interface_name->len, AWS_NETWORK_INTERFACE_MAX_LEN)); +#if defined(_MSC_VER) +# pragma pop +#endif } options.socket_options = &socket_options; options.on_setup = s_aws_http_connection_manager_on_connection_setup; From cf0db5cdbbbd09fe5a2f742d94aab09d6965cae1 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 14:51:46 -0700 Subject: [PATCH 08/33] push? --- source/connection_manager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/connection_manager.c b/source/connection_manager.c index 674dbe95..6cf9735b 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1026,6 +1026,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti manager->network_interface_names_list_index = (manager->network_interface_names_list_index+1) % aws_array_list_length(manager->network_interface_names_list); #if defined(_MSC_VER) +# pragma warning(push) # pragma warning(disable : 4996) /* deprecation */ #endif strncpy( From 3a882953f7f25a08d0d01047e4eadb2a86ecdea7 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Thu, 27 Jun 2024 14:56:00 -0700 Subject: [PATCH 09/33] fix pragma --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 6cf9735b..e319550e 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1034,7 +1034,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti aws_string_c_str(interface_name), aws_min_size(interface_name->len, AWS_NETWORK_INTERFACE_MAX_LEN)); #if defined(_MSC_VER) -# pragma pop +# pragma warning(pop) #endif } options.socket_options = &socket_options; From 039d96eed0364d32b18d13a9ca0b73a472bd7f7d Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 08:40:17 -0700 Subject: [PATCH 10/33] wip test --- source/connection_manager.c | 22 +++++++-------- tests/CMakeLists.txt | 1 + tests/test_connection_manager.c | 49 +++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index e319550e..8578b903 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -293,7 +293,7 @@ struct aws_http_connection_manager { struct aws_task *cull_task; struct aws_event_loop *cull_event_loop; - struct aws_array_list *network_interface_names_list; + struct aws_array_list network_interface_names_list; size_t network_interface_names_list_index; }; @@ -706,14 +706,12 @@ static void s_aws_http_connection_manager_finish_destroy(struct aws_http_connect aws_http_proxy_config_destroy(manager->proxy_config); } - if (manager->network_interface_names_list) { - for (size_t i = 0; i < aws_array_list_length(manager->network_interface_names_list); i++) { + for (size_t i = 0; i < aws_array_list_length(&manager->network_interface_names_list); i++) { struct aws_string *interface_name = NULL; - aws_array_list_get_at(manager->network_interface_names_list, &interface_name, i); + aws_array_list_get_at(&manager->network_interface_names_list, &interface_name, i); aws_string_destroy(interface_name); } - aws_array_list_clean_up(manager->network_interface_names_list); - } + aws_array_list_clean_up(&manager->network_interface_names_list); /* * If this task exists then we are actually in the corresponding event loop running the final destruction task. @@ -912,7 +910,7 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( size_t network_interface_names_list_length = options->network_interface_names_list != NULL ? aws_array_list_length(options->network_interface_names_list) : 0; if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { aws_array_list_init_dynamic( - manager->network_interface_names_list, + &manager->network_interface_names_list, allocator, network_interface_names_list_length, sizeof(struct aws_string *)); @@ -920,7 +918,7 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( struct aws_byte_cursor interface_name; aws_array_list_get_at(options->network_interface_names_list, &interface_name, i); aws_array_list_push_back( - manager->network_interface_names_list, aws_string_new_from_cursor(allocator, &interface_name)); + &manager->network_interface_names_list, aws_string_new_from_cursor(allocator, &interface_name)); } } @@ -1019,12 +1017,12 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti options.port = manager->port; options.initial_window_size = manager->initial_window_size; struct aws_socket_options socket_options = manager->socket_options; - if (manager->network_interface_names_list != NULL) { + if (aws_array_list_length(&manager->network_interface_names_list)) { struct aws_string *interface_name = NULL; aws_array_list_get_at( - manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); + &manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); manager->network_interface_names_list_index = (manager->network_interface_names_list_index+1) % - aws_array_list_length(manager->network_interface_names_list); + aws_array_list_length(&manager->network_interface_names_list); #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4996) /* deprecation */ @@ -1032,7 +1030,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), - aws_min_size(interface_name->len, AWS_NETWORK_INTERFACE_MAX_LEN)); + aws_min_size(interface_name->len + 1, AWS_NETWORK_INTERFACE_MAX_LEN)); #if defined(_MSC_VER) # pragma warning(pop) #endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9422fc80..845c7976 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -533,6 +533,7 @@ add_net_test_case(test_connection_manager_single_http2_connection) add_net_test_case(test_connection_manager_single_http2_connection_failed) add_net_test_case(test_connection_manager_single_http2_connection_with_settings) add_net_test_case(test_connection_manager_many_connections) +add_net_test_case(test_connection_manager_with_network_interface_list) add_net_test_case(test_connection_manager_many_http2_connections) add_net_test_case(test_connection_manager_acquire_release) add_net_test_case(test_connection_manager_close_and_release) diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index 616939e9..ab16a86c 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -58,6 +58,7 @@ struct cm_tester_options { struct aws_http2_setting *initial_settings_array; size_t num_initial_settings; bool self_lib_init; + struct aws_array_list *verify_network_interface_names; }; struct cm_tester { @@ -73,6 +74,7 @@ struct cm_tester { struct aws_tls_ctx_options tls_ctx_options; struct aws_tls_connection_options tls_connection_options; struct aws_http_proxy_options *verify_proxy_options; + struct aws_array_list *verify_network_interface_names; struct aws_mutex lock; struct aws_condition_variable signal; @@ -234,6 +236,7 @@ static int s_cm_tester_init(struct cm_tester_options *options) { } tester->mock_table = options->mock_table; + tester->verify_network_interface_names = options->verify_network_interface_names; aws_atomic_store_int(&tester->next_connection_id, 0); @@ -590,6 +593,46 @@ AWS_TEST_CASE( test_connection_manager_single_http2_connection_with_settings, s_test_connection_manager_single_http2_connection_with_settings); + + +static int s_test_connection_manager_with_network_interface_list(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + struct aws_array_list interface_names_list; + aws_array_list_init_dynamic(&interface_names_list, allocator, 3, sizeof(struct aws_string *)); + struct aws_string *ens32 = aws_string_new_from_c_str(allocator, "ens32"); + struct aws_string *ens64 = aws_string_new_from_c_str(allocator, "ens64"); + struct aws_string *ens96 = aws_string_new_from_c_str(allocator, "ens96"); + aws_array_list_push_back(&interface_names_list, &ens32); + aws_array_list_push_back(&interface_names_list, &ens64); + aws_array_list_push_back(&interface_names_list, &ens96); + // aws_array_list_push_back(&interface_names_list, aws_string_new_from_c_str(allocator, "ens64")); + // aws_array_list_push_back(&interface_names_list, aws_string_new_from_c_str(allocator, "ens96")); + // struct cm_tester_options options = { + // .allocator = allocator, + // .max_connections = 20, + // .verify_network_interface_names = &interface_names_list, + // }; + + // ASSERT_SUCCESS(s_cm_tester_init(&options)); + + // s_acquire_connections(6); + + // ASSERT_SUCCESS(s_wait_on_connection_reply_count(6)); + + // ASSERT_SUCCESS(s_release_connections(6, false)); + // ASSERT_UINT_EQUALS(0, s_tester.connection_errors); + + // ASSERT_SUCCESS(s_cm_tester_clean_up()); + for(size_t i=0;iverify_network_interface_names) { + struct aws_string *interface_name; + aws_array_list_get_at(tester->verify_network_interface_names, &interface_name,aws_atomic_load_int(&tester->next_connection_id)); + ASSERT_STR_EQUALS(aws_string_c_str(interface_name), options->socket_options->network_interface_name); + } + size_t next_connection_id = aws_atomic_fetch_add(&tester->next_connection_id, 1); ASSERT_SUCCESS(aws_mutex_lock(&tester->lock)); From fedc27bd633f98c40df9c4e26caa9e28779c1a95 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 09:16:24 -0700 Subject: [PATCH 11/33] wip test --- include/aws/http/connection_manager.h | 2 +- source/connection_manager.c | 24 ++++---- tests/test_connection_manager.c | 89 ++++++++++++++------------- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index cbec1cfd..6e9f212e 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -125,7 +125,7 @@ struct aws_http_connection_manager_options { */ uint64_t max_connection_idle_in_milliseconds; - struct aws_array_list *network_interface_names_list; + struct aws_array_list *network_interface_names_list; }; AWS_EXTERN_C_BEGIN diff --git a/source/connection_manager.c b/source/connection_manager.c index 8578b903..b0118890 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -706,12 +706,12 @@ static void s_aws_http_connection_manager_finish_destroy(struct aws_http_connect aws_http_proxy_config_destroy(manager->proxy_config); } - for (size_t i = 0; i < aws_array_list_length(&manager->network_interface_names_list); i++) { - struct aws_string *interface_name = NULL; - aws_array_list_get_at(&manager->network_interface_names_list, &interface_name, i); - aws_string_destroy(interface_name); - } - aws_array_list_clean_up(&manager->network_interface_names_list); + for (size_t i = 0; i < aws_array_list_length(&manager->network_interface_names_list); i++) { + struct aws_string *interface_name = NULL; + aws_array_list_get_at(&manager->network_interface_names_list, &interface_name, i); + aws_string_destroy(interface_name); + } + aws_array_list_clean_up(&manager->network_interface_names_list); /* * If this task exists then we are actually in the corresponding event loop running the final destruction task. @@ -907,7 +907,9 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; manager->network_interface_names_list_index = 0; - size_t network_interface_names_list_length = options->network_interface_names_list != NULL ? aws_array_list_length(options->network_interface_names_list) : 0; + size_t network_interface_names_list_length = options->network_interface_names_list != NULL + ? aws_array_list_length(options->network_interface_names_list) + : 0; if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { aws_array_list_init_dynamic( &manager->network_interface_names_list, @@ -917,8 +919,8 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( for (size_t i = 0; i < network_interface_names_list_length; i++) { struct aws_byte_cursor interface_name; aws_array_list_get_at(options->network_interface_names_list, &interface_name, i); - aws_array_list_push_back( - &manager->network_interface_names_list, aws_string_new_from_cursor(allocator, &interface_name)); + struct aws_string *interface_name_str = aws_string_new_from_cursor(allocator, &interface_name); + aws_array_list_push_back(&manager->network_interface_names_list, &interface_name_str); } } @@ -1021,8 +1023,8 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti struct aws_string *interface_name = NULL; aws_array_list_get_at( &manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); - manager->network_interface_names_list_index = (manager->network_interface_names_list_index+1) % - aws_array_list_length(&manager->network_interface_names_list); + manager->network_interface_names_list_index = (manager->network_interface_names_list_index + 1) % + aws_array_list_length(&manager->network_interface_names_list); #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4996) /* deprecation */ diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index ab16a86c..fcf960b0 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -221,6 +221,7 @@ static int s_cm_tester_init(struct cm_tester_options *options) { .http2_prior_knowledge = !options->use_tls && options->http2, .initial_settings_array = options->initial_settings_array, .num_initial_settings = options->num_initial_settings, + .network_interface_names_list = options->verify_network_interface_names, }; if (options->mock_table) { @@ -593,46 +594,6 @@ AWS_TEST_CASE( test_connection_manager_single_http2_connection_with_settings, s_test_connection_manager_single_http2_connection_with_settings); - - -static int s_test_connection_manager_with_network_interface_list(struct aws_allocator *allocator, void *ctx) { - (void)ctx; - struct aws_array_list interface_names_list; - aws_array_list_init_dynamic(&interface_names_list, allocator, 3, sizeof(struct aws_string *)); - struct aws_string *ens32 = aws_string_new_from_c_str(allocator, "ens32"); - struct aws_string *ens64 = aws_string_new_from_c_str(allocator, "ens64"); - struct aws_string *ens96 = aws_string_new_from_c_str(allocator, "ens96"); - aws_array_list_push_back(&interface_names_list, &ens32); - aws_array_list_push_back(&interface_names_list, &ens64); - aws_array_list_push_back(&interface_names_list, &ens96); - // aws_array_list_push_back(&interface_names_list, aws_string_new_from_c_str(allocator, "ens64")); - // aws_array_list_push_back(&interface_names_list, aws_string_new_from_c_str(allocator, "ens96")); - // struct cm_tester_options options = { - // .allocator = allocator, - // .max_connections = 20, - // .verify_network_interface_names = &interface_names_list, - // }; - - // ASSERT_SUCCESS(s_cm_tester_init(&options)); - - // s_acquire_connections(6); - - // ASSERT_SUCCESS(s_wait_on_connection_reply_count(6)); - - // ASSERT_SUCCESS(s_release_connections(6, false)); - // ASSERT_UINT_EQUALS(0, s_tester.connection_errors); - - // ASSERT_SUCCESS(s_cm_tester_clean_up()); - for(size_t i=0;iverify_network_interface_names) { - struct aws_string *interface_name; - aws_array_list_get_at(tester->verify_network_interface_names, &interface_name,aws_atomic_load_int(&tester->next_connection_id)); - ASSERT_STR_EQUALS(aws_string_c_str(interface_name), options->socket_options->network_interface_name); + if (tester->verify_network_interface_names) { + struct aws_byte_cursor interface_name; + aws_array_list_get_at( + tester->verify_network_interface_names, &interface_name, aws_atomic_load_int(&tester->next_connection_id)); + ASSERT_TRUE(aws_byte_cursor_eq_c_str(&interface_name, options->socket_options->network_interface_name)); } size_t next_connection_id = aws_atomic_fetch_add(&tester->next_connection_id, 1); @@ -868,6 +830,45 @@ static struct aws_http_connection_manager_system_vtable s_synchronous_mocks = { .aws_http_connection_get_version = s_aws_http_connection_manager_connection_get_version_sync_mock, }; +static int s_test_connection_manager_with_network_interface_list(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + struct aws_array_list interface_names_list; + aws_array_list_init_dynamic(&interface_names_list, allocator, 3, sizeof(struct aws_byte_cursor)); + struct aws_byte_cursor ens32 = aws_byte_cursor_from_c_str("lo0"); + // struct aws_byte_cursor ens64 = aws_byte_cursor_from_c_str("en1"); + // struct aws_byte_cursor ens96 = aws_byte_cursor_from_c_str("en2"); + aws_array_list_push_back(&interface_names_list, &ens32); + // aws_array_list_push_back(&interface_names_list, &ens64); + // aws_array_list_push_back(&interface_names_list, &ens96); + + struct aws_byte_cursor interface_name; + aws_array_list_get_at(&interface_names_list, &interface_name, 0); + struct cm_tester_options options = { + .allocator = allocator, + .max_connections = 20, + .mock_table = &s_synchronous_mocks, + .verify_network_interface_names = &interface_names_list, + }; + + ASSERT_SUCCESS(s_cm_tester_init(&options)); + int num_connections = 1; + for (size_t i = 0; i < num_connections; ++i) { + s_add_mock_connections(1, AWS_NCRT_SUCCESS, i % 1 == 0); + } + s_acquire_connections(num_connections); + + ASSERT_SUCCESS(s_wait_on_connection_reply_count(num_connections)); + ASSERT_SUCCESS(s_release_connections(num_connections, false)); + ASSERT_UINT_EQUALS(0, s_tester.connection_errors); + + ASSERT_SUCCESS(s_cm_tester_clean_up()); + aws_array_list_clean_up(&interface_names_list); + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE( + test_connection_manager_with_network_interface_list, + s_test_connection_manager_with_network_interface_list); + static int s_test_connection_manager_acquire_release_mix_synchronous(struct aws_allocator *allocator, void *ctx) { (void)ctx; From fdeb101bc71e064c7176ea96cc3cc1b18be91255 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 09:19:02 -0700 Subject: [PATCH 12/33] fix test --- tests/test_connection_manager.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index fcf960b0..9411831f 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -736,7 +736,10 @@ static int s_aws_http_connection_manager_create_connection_sync_mock( if (tester->verify_network_interface_names) { struct aws_byte_cursor interface_name; aws_array_list_get_at( - tester->verify_network_interface_names, &interface_name, aws_atomic_load_int(&tester->next_connection_id)); + tester->verify_network_interface_names, + &interface_name, + aws_atomic_load_int(&tester->next_connection_id) % + aws_array_list_length(tester->verify_network_interface_names)); ASSERT_TRUE(aws_byte_cursor_eq_c_str(&interface_name, options->socket_options->network_interface_name)); } @@ -835,11 +838,11 @@ static int s_test_connection_manager_with_network_interface_list(struct aws_allo struct aws_array_list interface_names_list; aws_array_list_init_dynamic(&interface_names_list, allocator, 3, sizeof(struct aws_byte_cursor)); struct aws_byte_cursor ens32 = aws_byte_cursor_from_c_str("lo0"); - // struct aws_byte_cursor ens64 = aws_byte_cursor_from_c_str("en1"); - // struct aws_byte_cursor ens96 = aws_byte_cursor_from_c_str("en2"); + struct aws_byte_cursor ens64 = aws_byte_cursor_from_c_str("en1"); + struct aws_byte_cursor ens96 = aws_byte_cursor_from_c_str("en2"); aws_array_list_push_back(&interface_names_list, &ens32); - // aws_array_list_push_back(&interface_names_list, &ens64); - // aws_array_list_push_back(&interface_names_list, &ens96); + aws_array_list_push_back(&interface_names_list, &ens64); + aws_array_list_push_back(&interface_names_list, &ens96); struct aws_byte_cursor interface_name; aws_array_list_get_at(&interface_names_list, &interface_name, 0); @@ -851,7 +854,7 @@ static int s_test_connection_manager_with_network_interface_list(struct aws_allo }; ASSERT_SUCCESS(s_cm_tester_init(&options)); - int num_connections = 1; + int num_connections = 6; for (size_t i = 0; i < num_connections; ++i) { s_add_mock_connections(1, AWS_NCRT_SUCCESS, i % 1 == 0); } From ba4e9ecf8b93ab6897a64f9c806a8a82e52007e4 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 09:24:22 -0700 Subject: [PATCH 13/33] fix type --- tests/test_connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index 9411831f..bc5ce2bc 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -854,7 +854,7 @@ static int s_test_connection_manager_with_network_interface_list(struct aws_allo }; ASSERT_SUCCESS(s_cm_tester_init(&options)); - int num_connections = 6; + size_t num_connections = 6; for (size_t i = 0; i < num_connections; ++i) { s_add_mock_connections(1, AWS_NCRT_SUCCESS, i % 1 == 0); } From aa888aba4f1517e8afca33214c4d629bb2d15903 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 09:39:32 -0700 Subject: [PATCH 14/33] copy to max len --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index b0118890..e0ce0d0d 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1032,7 +1032,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), - aws_min_size(interface_name->len + 1, AWS_NETWORK_INTERFACE_MAX_LEN)); + AWS_NETWORK_INTERFACE_MAX_LEN); #if defined(_MSC_VER) # pragma warning(pop) #endif From 625d2704b1c49bc12598e94c37ec8a9729fd8193 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 09:40:40 -0700 Subject: [PATCH 15/33] lint --- source/connection_manager.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index e0ce0d0d..0e7984e7 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1029,10 +1029,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti # pragma warning(push) # pragma warning(disable : 4996) /* deprecation */ #endif - strncpy( - socket_options.network_interface_name, - aws_string_c_str(interface_name), - AWS_NETWORK_INTERFACE_MAX_LEN); + strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_MAX_LEN); #if defined(_MSC_VER) # pragma warning(pop) #endif From f911659a4bdd9b052037881ba4a6fb8aac62c13c Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 09:47:56 -0700 Subject: [PATCH 16/33] test refactor --- tests/CMakeLists.txt | 2 +- tests/test_connection_manager.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 845c7976..6a0a4de1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -525,6 +525,7 @@ add_net_test_case(test_connection_manager_idle_culling_single) add_net_test_case(test_connection_manager_idle_culling_many) add_net_test_case(test_connection_manager_idle_culling_mixture) add_net_test_case(test_connection_manager_idle_culling_refcount) +add_net_test_case(test_connection_manager_with_network_interface_list) # tests where we establish real connections add_net_test_case(test_connection_manager_single_connection) @@ -533,7 +534,6 @@ add_net_test_case(test_connection_manager_single_http2_connection) add_net_test_case(test_connection_manager_single_http2_connection_failed) add_net_test_case(test_connection_manager_single_http2_connection_with_settings) add_net_test_case(test_connection_manager_many_connections) -add_net_test_case(test_connection_manager_with_network_interface_list) add_net_test_case(test_connection_manager_many_http2_connections) add_net_test_case(test_connection_manager_acquire_release) add_net_test_case(test_connection_manager_close_and_release) diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index bc5ce2bc..5dbc4e25 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -837,15 +837,13 @@ static int s_test_connection_manager_with_network_interface_list(struct aws_allo (void)ctx; struct aws_array_list interface_names_list; aws_array_list_init_dynamic(&interface_names_list, allocator, 3, sizeof(struct aws_byte_cursor)); - struct aws_byte_cursor ens32 = aws_byte_cursor_from_c_str("lo0"); - struct aws_byte_cursor ens64 = aws_byte_cursor_from_c_str("en1"); - struct aws_byte_cursor ens96 = aws_byte_cursor_from_c_str("en2"); + struct aws_byte_cursor ens32 = aws_byte_cursor_from_c_str("ens32"); + struct aws_byte_cursor ens64 = aws_byte_cursor_from_c_str("ens64"); + struct aws_byte_cursor ens96 = aws_byte_cursor_from_c_str("ens96"); aws_array_list_push_back(&interface_names_list, &ens32); aws_array_list_push_back(&interface_names_list, &ens64); aws_array_list_push_back(&interface_names_list, &ens96); - struct aws_byte_cursor interface_name; - aws_array_list_get_at(&interface_names_list, &interface_name, 0); struct cm_tester_options options = { .allocator = allocator, .max_connections = 20, From 1eacac3402d112759a7dfa406eec6595c3deecb6 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 10:08:02 -0700 Subject: [PATCH 17/33] add docs --- include/aws/http/connection_manager.h | 8 ++++++++ source/connection_manager.c | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index 6e9f212e..b9cae72e 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -125,6 +125,14 @@ struct aws_http_connection_manager_options { */ uint64_t max_connection_idle_in_milliseconds; + /** + * (Optional) + * An `aws_array_list` of network interface names. The manager will distribute the + * connections across network interface names provided in this list. 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 set, this list will be ignored and all the connections will go to that network interface. This option is only + * supported on Linux and macOS and will be ignored on other platforms. + */ struct aws_array_list *network_interface_names_list; }; diff --git a/source/connection_manager.c b/source/connection_manager.c index 0e7984e7..7df95022 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -293,7 +293,15 @@ struct aws_http_connection_manager { struct aws_task *cull_task; struct aws_event_loop *cull_event_loop; + /* + * An aws_array_list of network interface names to distribute the connections using the + * round-robin algorithm. We picked round-robin because it is trivial to implement and good enough. We can later + * update to a more complex distribution algorithm if required. + */ struct aws_array_list network_interface_names_list; + /* + * Current index in the network_interface_names list. + */ size_t network_interface_names_list_index; }; @@ -910,6 +918,7 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( size_t network_interface_names_list_length = options->network_interface_names_list != NULL ? aws_array_list_length(options->network_interface_names_list) : 0; + /* Ignore the network_interface_names_list if socket_options already contains a network_interface_name. */ if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { aws_array_list_init_dynamic( &manager->network_interface_names_list, From c48c24dbc48227417beb09c98b9bb1e5a74138ef Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Fri, 28 Jun 2024 10:46:39 -0700 Subject: [PATCH 18/33] const --- include/aws/http/connection_manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index b9cae72e..7c301d55 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -133,7 +133,7 @@ struct aws_http_connection_manager_options { * is set, this list will be ignored and all the connections will go to that network interface. This option is only * supported on Linux and macOS and will be ignored on other platforms. */ - struct aws_array_list *network_interface_names_list; + const struct aws_array_list *network_interface_names_list; }; AWS_EXTERN_C_BEGIN From a0edccb25ca52f01901b379155ccead25b1da84a Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Mon, 1 Jul 2024 13:50:50 -0700 Subject: [PATCH 19/33] update max len rename --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 7df95022..af410d29 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1038,7 +1038,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti # pragma warning(push) # pragma warning(disable : 4996) /* deprecation */ #endif - strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_MAX_LEN); + strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); #if defined(_MSC_VER) # pragma warning(pop) #endif From f6765f596c11922f14a9168962ae93f1024b54d3 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Mon, 1 Jul 2024 13:57:32 -0700 Subject: [PATCH 20/33] Update source/connection_manager.c Co-authored-by: Michael Graeb --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index af410d29..fa45c51e 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1036,7 +1036,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti aws_array_list_length(&manager->network_interface_names_list); #if defined(_MSC_VER) # pragma warning(push) -# pragma warning(disable : 4996) /* deprecation */ +# pragma warning(disable : 4996) /* allow strncpy() */ #endif strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); #if defined(_MSC_VER) From 2a6636ae03632b17b62ad89d8791f5989ab21e93 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 13:12:16 -0700 Subject: [PATCH 21/33] use byte cursor array --- include/aws/http/connection_manager.h | 11 ++++---- source/connection_manager.c | 13 +++------- tests/test_connection_manager.c | 37 ++++++++++++--------------- 3 files changed, 26 insertions(+), 35 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index 7c301d55..166f967c 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -127,13 +127,14 @@ struct aws_http_connection_manager_options { /** * (Optional) - * An `aws_array_list` of network interface names. The manager will distribute the - * connections across network interface names provided in this list. If any interface name is invalid, goes down, or + * 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 set, this list will be ignored and all the connections will go to that network interface. This option is only - * supported on Linux and macOS and will be ignored on other platforms. + * is set, an `` error will be raised. This option is only + * supported on Linux and MacOS. On other platforms, `AWS_ERROR_PLATFORM_NOT_SUPPORTED` will be raised. */ - const struct aws_array_list *network_interface_names_list; + const struct aws_byte_cursor *network_interface_names_array; + size_t num_network_interface_names; }; AWS_EXTERN_C_BEGIN diff --git a/source/connection_manager.c b/source/connection_manager.c index fa45c51e..bfd81a88 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -915,19 +915,14 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; manager->network_interface_names_list_index = 0; - size_t network_interface_names_list_length = options->network_interface_names_list != NULL - ? aws_array_list_length(options->network_interface_names_list) - : 0; - /* Ignore the network_interface_names_list if socket_options already contains a network_interface_name. */ - if (manager->socket_options.network_interface_name[0] == '\0' && network_interface_names_list_length > 0) { + if (manager->socket_options.network_interface_name[0] == '\0' && options->num_network_interface_names > 0) { aws_array_list_init_dynamic( &manager->network_interface_names_list, allocator, - network_interface_names_list_length, + options->num_network_interface_names, sizeof(struct aws_string *)); - for (size_t i = 0; i < network_interface_names_list_length; i++) { - struct aws_byte_cursor interface_name; - aws_array_list_get_at(options->network_interface_names_list, &interface_name, i); + for (size_t i = 0; i < options->num_network_interface_names; i++) { + struct aws_byte_cursor interface_name = options->network_interface_names_array[i]; struct aws_string *interface_name_str = aws_string_new_from_cursor(allocator, &interface_name); aws_array_list_push_back(&manager->network_interface_names_list, &interface_name_str); } diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index 5dbc4e25..254b92c3 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -58,7 +58,8 @@ struct cm_tester_options { struct aws_http2_setting *initial_settings_array; size_t num_initial_settings; bool self_lib_init; - struct aws_array_list *verify_network_interface_names; + const struct aws_byte_cursor *verify_network_interface_names_array; + size_t num_network_interface_names; }; struct cm_tester { @@ -74,7 +75,8 @@ struct cm_tester { struct aws_tls_ctx_options tls_ctx_options; struct aws_tls_connection_options tls_connection_options; struct aws_http_proxy_options *verify_proxy_options; - struct aws_array_list *verify_network_interface_names; + const struct aws_byte_cursor *verify_network_interface_names_array; + size_t num_network_interface_names; struct aws_mutex lock; struct aws_condition_variable signal; @@ -221,7 +223,8 @@ static int s_cm_tester_init(struct cm_tester_options *options) { .http2_prior_knowledge = !options->use_tls && options->http2, .initial_settings_array = options->initial_settings_array, .num_initial_settings = options->num_initial_settings, - .network_interface_names_list = options->verify_network_interface_names, + .network_interface_names_array = options->verify_network_interface_names_array, + .num_network_interface_names = options->num_network_interface_names, }; if (options->mock_table) { @@ -237,7 +240,8 @@ static int s_cm_tester_init(struct cm_tester_options *options) { } tester->mock_table = options->mock_table; - tester->verify_network_interface_names = options->verify_network_interface_names; + tester->verify_network_interface_names_array = options->verify_network_interface_names_array; + tester->num_network_interface_names = options->num_network_interface_names; aws_atomic_store_int(&tester->next_connection_id, 0); @@ -733,13 +737,8 @@ static int s_aws_http_connection_manager_create_connection_sync_mock( const struct aws_http_client_connection_options *options) { struct cm_tester *tester = &s_tester; - if (tester->verify_network_interface_names) { - struct aws_byte_cursor interface_name; - aws_array_list_get_at( - tester->verify_network_interface_names, - &interface_name, - aws_atomic_load_int(&tester->next_connection_id) % - aws_array_list_length(tester->verify_network_interface_names)); + if (tester->num_network_interface_names) { + struct aws_byte_cursor interface_name = tester->verify_network_interface_names_array[aws_atomic_load_int(&tester->next_connection_id) % tester->num_network_interface_names]; ASSERT_TRUE(aws_byte_cursor_eq_c_str(&interface_name, options->socket_options->network_interface_name)); } @@ -835,20 +834,16 @@ static struct aws_http_connection_manager_system_vtable s_synchronous_mocks = { static int s_test_connection_manager_with_network_interface_list(struct aws_allocator *allocator, void *ctx) { (void)ctx; - struct aws_array_list interface_names_list; - aws_array_list_init_dynamic(&interface_names_list, allocator, 3, sizeof(struct aws_byte_cursor)); - struct aws_byte_cursor ens32 = aws_byte_cursor_from_c_str("ens32"); - struct aws_byte_cursor ens64 = aws_byte_cursor_from_c_str("ens64"); - struct aws_byte_cursor ens96 = aws_byte_cursor_from_c_str("ens96"); - aws_array_list_push_back(&interface_names_list, &ens32); - aws_array_list_push_back(&interface_names_list, &ens64); - aws_array_list_push_back(&interface_names_list, &ens96); + struct aws_byte_cursor *interface_names_array = aws_mem_calloc(allocator, 3, sizeof(struct aws_byte_cursor)); + interface_names_array[0] = aws_byte_cursor_from_c_str("ens32"); + interface_names_array[1] = aws_byte_cursor_from_c_str("ens64"); + interface_names_array[2] = aws_byte_cursor_from_c_str("ens96"); struct cm_tester_options options = { .allocator = allocator, .max_connections = 20, .mock_table = &s_synchronous_mocks, - .verify_network_interface_names = &interface_names_list, + .verify_network_interface_names_array = interface_names_array, }; ASSERT_SUCCESS(s_cm_tester_init(&options)); @@ -863,7 +858,7 @@ static int s_test_connection_manager_with_network_interface_list(struct aws_allo ASSERT_UINT_EQUALS(0, s_tester.connection_errors); ASSERT_SUCCESS(s_cm_tester_clean_up()); - aws_array_list_clean_up(&interface_names_list); + aws_mem_release(allocator, interface_names_array); return AWS_OP_SUCCESS; } AWS_TEST_CASE( From 47ce3ee9a0e85baa140f9df0b5671cacab608679 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 13:15:21 -0700 Subject: [PATCH 22/33] lint --- include/aws/http/connection_manager.h | 8 ++++---- source/connection_manager.c | 3 ++- tests/test_connection_manager.c | 4 +++- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index 166f967c..c2be6da2 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -128,10 +128,10 @@ struct aws_http_connection_manager_options { /** * (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 set, an `` error will be raised. This option is only - * supported on Linux and MacOS. On other platforms, `AWS_ERROR_PLATFORM_NOT_SUPPORTED` will be raised. + * 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 set, an `` error will be raised. This option is only supported on + * Linux and MacOS. On other platforms, `AWS_ERROR_PLATFORM_NOT_SUPPORTED` will be raised. */ const struct aws_byte_cursor *network_interface_names_array; size_t num_network_interface_names; diff --git a/source/connection_manager.c b/source/connection_manager.c index bfd81a88..4e4f1c0a 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1033,7 +1033,8 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif - strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); + strncpy( + socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); #if defined(_MSC_VER) # pragma warning(pop) #endif diff --git a/tests/test_connection_manager.c b/tests/test_connection_manager.c index 254b92c3..5e394b9d 100644 --- a/tests/test_connection_manager.c +++ b/tests/test_connection_manager.c @@ -738,7 +738,9 @@ static int s_aws_http_connection_manager_create_connection_sync_mock( struct cm_tester *tester = &s_tester; if (tester->num_network_interface_names) { - struct aws_byte_cursor interface_name = tester->verify_network_interface_names_array[aws_atomic_load_int(&tester->next_connection_id) % tester->num_network_interface_names]; + struct aws_byte_cursor interface_name = + tester->verify_network_interface_names_array + [aws_atomic_load_int(&tester->next_connection_id) % tester->num_network_interface_names]; ASSERT_TRUE(aws_byte_cursor_eq_c_str(&interface_name, options->socket_options->network_interface_name)); } From 469f9104bb02e0c2132aeb20a910e5bfc5ec6cea Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 13:30:42 -0700 Subject: [PATCH 23/33] rename list --- source/connection_manager.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 4e4f1c0a..33dc1095 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -298,11 +298,11 @@ struct aws_http_connection_manager { * round-robin algorithm. We picked round-robin because it is trivial to implement and good enough. We can later * update to a more complex distribution algorithm if required. */ - struct aws_array_list network_interface_names_list; + struct aws_array_list network_interface_names; /* * Current index in the network_interface_names list. */ - size_t network_interface_names_list_index; + size_t network_interface_names_index; }; struct aws_http_connection_manager_snapshot { @@ -714,12 +714,12 @@ static void s_aws_http_connection_manager_finish_destroy(struct aws_http_connect aws_http_proxy_config_destroy(manager->proxy_config); } - for (size_t i = 0; i < aws_array_list_length(&manager->network_interface_names_list); i++) { + for (size_t i = 0; i < aws_array_list_length(&manager->network_interface_names); i++) { struct aws_string *interface_name = NULL; - aws_array_list_get_at(&manager->network_interface_names_list, &interface_name, i); + aws_array_list_get_at(&manager->network_interface_names, &interface_name, i); aws_string_destroy(interface_name); } - aws_array_list_clean_up(&manager->network_interface_names_list); + aws_array_list_clean_up(&manager->network_interface_names); /* * If this task exists then we are actually in the corresponding event loop running the final destruction task. @@ -914,17 +914,17 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->max_closed_streams = options->max_closed_streams; manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; - manager->network_interface_names_list_index = 0; + manager->network_interface_names_index = 0; if (manager->socket_options.network_interface_name[0] == '\0' && options->num_network_interface_names > 0) { aws_array_list_init_dynamic( - &manager->network_interface_names_list, + &manager->network_interface_names, allocator, options->num_network_interface_names, sizeof(struct aws_string *)); for (size_t i = 0; i < options->num_network_interface_names; i++) { struct aws_byte_cursor interface_name = options->network_interface_names_array[i]; struct aws_string *interface_name_str = aws_string_new_from_cursor(allocator, &interface_name); - aws_array_list_push_back(&manager->network_interface_names_list, &interface_name_str); + aws_array_list_push_back(&manager->network_interface_names, &interface_name_str); } } @@ -1023,12 +1023,12 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti options.port = manager->port; options.initial_window_size = manager->initial_window_size; struct aws_socket_options socket_options = manager->socket_options; - if (aws_array_list_length(&manager->network_interface_names_list)) { + if (aws_array_list_length(&manager->network_interface_names)) { struct aws_string *interface_name = NULL; aws_array_list_get_at( - &manager->network_interface_names_list, &interface_name, manager->network_interface_names_list_index); - manager->network_interface_names_list_index = (manager->network_interface_names_list_index + 1) % - aws_array_list_length(&manager->network_interface_names_list); + &manager->network_interface_names, &interface_name, manager->network_interface_names_index); + manager->network_interface_names_index = (manager->network_interface_names_index + 1) % + aws_array_list_length(&manager->network_interface_names); #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ From a07346fea0dda8bf1902af30e00d326d7a0e8c1d Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 13:36:03 -0700 Subject: [PATCH 24/33] error if both set --- include/aws/http/connection_manager.h | 6 ++++-- source/connection_manager.c | 10 +++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index c2be6da2..b3d90ee6 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -130,8 +130,10 @@ struct aws_http_connection_manager_options { * 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 set, an `` error will be raised. This option is only supported on - * Linux and MacOS. On other platforms, `AWS_ERROR_PLATFORM_NOT_SUPPORTED` will be raised. + * `socket_options.network_interface_name` is 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. */ const struct aws_byte_cursor *network_interface_names_array; size_t num_network_interface_names; diff --git a/source/connection_manager.c b/source/connection_manager.c index 33dc1095..8278f097 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -837,6 +837,14 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( return NULL; } + if(options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0){ + AWS_LOGF_ERROR( + AWS_LS_HTTP_CONNECTION_MANAGER, "Invalid options - socket_options.network_interface_name and network_interface_names_array can not be both set."); + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + return NULL; + } + + struct aws_http_connection_manager *manager = aws_mem_calloc(allocator, 1, sizeof(struct aws_http_connection_manager)); if (manager == NULL) { @@ -915,7 +923,7 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( manager->http2_conn_manual_window_management = options->http2_conn_manual_window_management; manager->network_interface_names_index = 0; - if (manager->socket_options.network_interface_name[0] == '\0' && options->num_network_interface_names > 0) { + if (options->num_network_interface_names > 0) { aws_array_list_init_dynamic( &manager->network_interface_names, allocator, From b252fd13fad2baaf26e347575295114c6521612a Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:01:45 -0700 Subject: [PATCH 25/33] cleanup --- include/aws/http/connection_manager.h | 4 +- source/connection_manager.c | 79 +++++++++++++++++++-------- 2 files changed, 58 insertions(+), 25 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index b3d90ee6..c33ebbd9 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -130,9 +130,9 @@ struct aws_http_connection_manager_options { * 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 set, an `AWS_ERROR_INVALID_ARGUMENT` error will be raised. + * `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 + * 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. */ const struct aws_byte_cursor *network_interface_names_array; diff --git a/source/connection_manager.c b/source/connection_manager.c index 8278f097..df136d0b 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -300,7 +300,7 @@ struct aws_http_connection_manager { */ struct aws_array_list network_interface_names; /* - * Current index in the network_interface_names list. + * Current index in the network_interface_names array_list. */ size_t network_interface_names_index; }; @@ -837,14 +837,15 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( return NULL; } - if(options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0){ + if (options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0) { AWS_LOGF_ERROR( - AWS_LS_HTTP_CONNECTION_MANAGER, "Invalid options - socket_options.network_interface_name and network_interface_names_array can not be both set."); + AWS_LS_HTTP_CONNECTION_MANAGER, + "Invalid options - socket_options.network_interface_name and network_interface_names_array cannot be both " + "set."); aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); return NULL; } - struct aws_http_connection_manager *manager = aws_mem_calloc(allocator, 1, sizeof(struct aws_http_connection_manager)); if (manager == NULL) { @@ -1035,15 +1036,17 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti struct aws_string *interface_name = NULL; aws_array_list_get_at( &manager->network_interface_names, &interface_name, manager->network_interface_names_index); - manager->network_interface_names_index = (manager->network_interface_names_index + 1) % - aws_array_list_length(&manager->network_interface_names); + manager->network_interface_names_index = + (manager->network_interface_names_index + 1) % aws_array_list_length(&manager->network_interface_names); #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif + /* If the interface_name is too long or not null terminated, it will be caught in the aws-c-io so we don't need + * to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); -#if defined(_MSC_VER) +#if defined(_MSC_VER)conmng.c # pragma warning(pop) #endif } @@ -1072,26 +1075,56 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti if (aws_http_connection_monitoring_options_is_valid(&manager->monitoring_options)) { options.monitoring_options = &manager->monitoring_options; } + strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); +#if defined(_MSC_VER) +# pragma warning(pop) +#endif +} +options.socket_options = &socket_options; +options.on_setup = s_aws_http_connection_manager_on_connection_setup; +options.on_shutdown = s_aws_http_connection_manager_on_connection_shutdown; +options.manual_window_management = manager->enable_read_back_pressure; +options.proxy_ev_settings = &manager->proxy_ev_settings; +options.prior_knowledge_http2 = manager->http2_prior_knowledge; + +struct aws_http2_connection_options h2_options; +AWS_ZERO_STRUCT(h2_options); +if (manager->initial_settings) { + h2_options.initial_settings_array = manager->initial_settings->data; + h2_options.num_initial_settings = aws_array_list_length(manager->initial_settings); +} +h2_options.max_closed_streams = manager->max_closed_streams; +h2_options.conn_manual_window_management = manager->http2_conn_manual_window_management; +/* The initial_settings_completed invoked after the other side acknowledges it, and will always be invoked if the + * connection set up */ +h2_options.on_initial_settings_completed = s_aws_http_connection_manager_h2_on_initial_settings_completed; +h2_options.on_goaway_received = s_aws_http_connection_manager_h2_on_goaway_received; - struct aws_http_proxy_options proxy_options; - AWS_ZERO_STRUCT(proxy_options); +options.http2_options = &h2_options; - if (manager->proxy_config) { - aws_http_proxy_options_init_from_config(&proxy_options, manager->proxy_config); - options.proxy_options = &proxy_options; - } +if (aws_http_connection_monitoring_options_is_valid(&manager->monitoring_options)) { + options.monitoring_options = &manager->monitoring_options; +} - if (manager->system_vtable->aws_http_client_connect(&options)) { - AWS_LOGF_ERROR( - AWS_LS_HTTP_CONNECTION_MANAGER, - "id=%p: http connection creation failed with error code %d(%s)", - (void *)manager, - aws_last_error(), - aws_error_str(aws_last_error())); - return AWS_OP_ERR; - } +struct aws_http_proxy_options proxy_options; +AWS_ZERO_STRUCT(proxy_options); - return AWS_OP_SUCCESS; +if (manager->proxy_config) { + aws_http_proxy_options_init_from_config(&proxy_options, manager->proxy_config); + options.proxy_options = &proxy_options; +} + +if (manager->system_vtable->aws_http_client_connect(&options)) { + AWS_LOGF_ERROR( + AWS_LS_HTTP_CONNECTION_MANAGER, + "id=%p: http connection creation failed with error code %d(%s)", + (void *)manager, + aws_last_error(), + aws_error_str(aws_last_error())); + return AWS_OP_ERR; +} + +return AWS_OP_SUCCESS; } static void s_aws_http_connection_manager_execute_transaction(struct aws_connection_management_transaction *work) { From e1fcf622f4d3a8ba2423d5c5e9580f11a898232c Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:02:05 -0700 Subject: [PATCH 26/33] lint --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index df136d0b..0c23a0fa 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1046,7 +1046,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti * to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); -#if defined(_MSC_VER)conmng.c +#if defined(_MSC_VER) conmng.c # pragma warning(pop) #endif } From ed135f59acb0795ae9845f88f900ab0c21ce391d Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:09:42 -0700 Subject: [PATCH 27/33] Revert "lint" This reverts commit e1fcf622f4d3a8ba2423d5c5e9580f11a898232c. --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 0c23a0fa..df136d0b 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1046,7 +1046,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti * to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); -#if defined(_MSC_VER) conmng.c +#if defined(_MSC_VER)conmng.c # pragma warning(pop) #endif } From 32ea3613fe103717e6b9dfcad8d22bb99356b314 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:09:47 -0700 Subject: [PATCH 28/33] Revert "cleanup" This reverts commit b252fd13fad2baaf26e347575295114c6521612a. --- include/aws/http/connection_manager.h | 4 +- source/connection_manager.c | 79 ++++++++------------------- 2 files changed, 25 insertions(+), 58 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index c33ebbd9..b3d90ee6 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -130,9 +130,9 @@ struct aws_http_connection_manager_options { * 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. + * `socket_options.network_interface_name` is 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 + * 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. */ const struct aws_byte_cursor *network_interface_names_array; diff --git a/source/connection_manager.c b/source/connection_manager.c index df136d0b..8278f097 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -300,7 +300,7 @@ struct aws_http_connection_manager { */ struct aws_array_list network_interface_names; /* - * Current index in the network_interface_names array_list. + * Current index in the network_interface_names list. */ size_t network_interface_names_index; }; @@ -837,15 +837,14 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( return NULL; } - if (options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0) { + if(options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0){ AWS_LOGF_ERROR( - AWS_LS_HTTP_CONNECTION_MANAGER, - "Invalid options - socket_options.network_interface_name and network_interface_names_array cannot be both " - "set."); + AWS_LS_HTTP_CONNECTION_MANAGER, "Invalid options - socket_options.network_interface_name and network_interface_names_array can not be both set."); aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); return NULL; } + struct aws_http_connection_manager *manager = aws_mem_calloc(allocator, 1, sizeof(struct aws_http_connection_manager)); if (manager == NULL) { @@ -1036,17 +1035,15 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti struct aws_string *interface_name = NULL; aws_array_list_get_at( &manager->network_interface_names, &interface_name, manager->network_interface_names_index); - manager->network_interface_names_index = - (manager->network_interface_names_index + 1) % aws_array_list_length(&manager->network_interface_names); + manager->network_interface_names_index = (manager->network_interface_names_index + 1) % + aws_array_list_length(&manager->network_interface_names); #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif - /* If the interface_name is too long or not null terminated, it will be caught in the aws-c-io so we don't need - * to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); -#if defined(_MSC_VER)conmng.c +#if defined(_MSC_VER) # pragma warning(pop) #endif } @@ -1075,56 +1072,26 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti if (aws_http_connection_monitoring_options_is_valid(&manager->monitoring_options)) { options.monitoring_options = &manager->monitoring_options; } - strncpy(socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); -#if defined(_MSC_VER) -# pragma warning(pop) -#endif -} -options.socket_options = &socket_options; -options.on_setup = s_aws_http_connection_manager_on_connection_setup; -options.on_shutdown = s_aws_http_connection_manager_on_connection_shutdown; -options.manual_window_management = manager->enable_read_back_pressure; -options.proxy_ev_settings = &manager->proxy_ev_settings; -options.prior_knowledge_http2 = manager->http2_prior_knowledge; - -struct aws_http2_connection_options h2_options; -AWS_ZERO_STRUCT(h2_options); -if (manager->initial_settings) { - h2_options.initial_settings_array = manager->initial_settings->data; - h2_options.num_initial_settings = aws_array_list_length(manager->initial_settings); -} -h2_options.max_closed_streams = manager->max_closed_streams; -h2_options.conn_manual_window_management = manager->http2_conn_manual_window_management; -/* The initial_settings_completed invoked after the other side acknowledges it, and will always be invoked if the - * connection set up */ -h2_options.on_initial_settings_completed = s_aws_http_connection_manager_h2_on_initial_settings_completed; -h2_options.on_goaway_received = s_aws_http_connection_manager_h2_on_goaway_received; - -options.http2_options = &h2_options; -if (aws_http_connection_monitoring_options_is_valid(&manager->monitoring_options)) { - options.monitoring_options = &manager->monitoring_options; -} - -struct aws_http_proxy_options proxy_options; -AWS_ZERO_STRUCT(proxy_options); + struct aws_http_proxy_options proxy_options; + AWS_ZERO_STRUCT(proxy_options); -if (manager->proxy_config) { - aws_http_proxy_options_init_from_config(&proxy_options, manager->proxy_config); - options.proxy_options = &proxy_options; -} + if (manager->proxy_config) { + aws_http_proxy_options_init_from_config(&proxy_options, manager->proxy_config); + options.proxy_options = &proxy_options; + } -if (manager->system_vtable->aws_http_client_connect(&options)) { - AWS_LOGF_ERROR( - AWS_LS_HTTP_CONNECTION_MANAGER, - "id=%p: http connection creation failed with error code %d(%s)", - (void *)manager, - aws_last_error(), - aws_error_str(aws_last_error())); - return AWS_OP_ERR; -} + if (manager->system_vtable->aws_http_client_connect(&options)) { + AWS_LOGF_ERROR( + AWS_LS_HTTP_CONNECTION_MANAGER, + "id=%p: http connection creation failed with error code %d(%s)", + (void *)manager, + aws_last_error(), + aws_error_str(aws_last_error())); + return AWS_OP_ERR; + } -return AWS_OP_SUCCESS; + return AWS_OP_SUCCESS; } static void s_aws_http_connection_manager_execute_transaction(struct aws_connection_management_transaction *work) { From 3529a2a34a10c2437ad936b4effcfe9103b08b0f Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:12:13 -0700 Subject: [PATCH 29/33] cleanup --- include/aws/http/connection_manager.h | 4 ++-- source/connection_manager.c | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/include/aws/http/connection_manager.h b/include/aws/http/connection_manager.h index b3d90ee6..c33ebbd9 100644 --- a/include/aws/http/connection_manager.h +++ b/include/aws/http/connection_manager.h @@ -130,9 +130,9 @@ struct aws_http_connection_manager_options { * 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 set, an `AWS_ERROR_INVALID_ARGUMENT` error will be raised. + * `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 + * 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. */ const struct aws_byte_cursor *network_interface_names_array; diff --git a/source/connection_manager.c b/source/connection_manager.c index 8278f097..8269e101 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -300,7 +300,7 @@ struct aws_http_connection_manager { */ struct aws_array_list network_interface_names; /* - * Current index in the network_interface_names list. + * Current index in the network_interface_names array_list. */ size_t network_interface_names_index; }; @@ -837,14 +837,15 @@ struct aws_http_connection_manager *aws_http_connection_manager_new( return NULL; } - if(options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0){ + if (options->socket_options->network_interface_name[0] != '\0' && options->num_network_interface_names > 0) { AWS_LOGF_ERROR( - AWS_LS_HTTP_CONNECTION_MANAGER, "Invalid options - socket_options.network_interface_name and network_interface_names_array can not be both set."); + AWS_LS_HTTP_CONNECTION_MANAGER, + "Invalid options - socket_options.network_interface_name and network_interface_names_array cannot be both " + "set."); aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); return NULL; } - struct aws_http_connection_manager *manager = aws_mem_calloc(allocator, 1, sizeof(struct aws_http_connection_manager)); if (manager == NULL) { @@ -1035,12 +1036,14 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti struct aws_string *interface_name = NULL; aws_array_list_get_at( &manager->network_interface_names, &interface_name, manager->network_interface_names_index); - manager->network_interface_names_index = (manager->network_interface_names_index + 1) % - aws_array_list_length(&manager->network_interface_names); + manager->network_interface_names_index = + (manager->network_interface_names_index + 1) % aws_array_list_length(&manager->network_interface_names); #if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif + /* If the interface_name is too long or not null terminated, it will be caught in the aws-c-io so we don't need + * to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); #if defined(_MSC_VER) From aa1a51245a4e801aafa72d2a30701537a2d29643 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:44:38 -0700 Subject: [PATCH 30/33] fix comment --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 8269e101..10dda395 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1042,7 +1042,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif - /* If the interface_name is too long or not null terminated, it will be caught in the aws-c-io so we don't need + /* If the interface_name is too long or not null terminated, it will be caught in the aws_socket_init function so we don't need * to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); From eb321710d60982bc156c75a9b560ac896786a8ac Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:46:09 -0700 Subject: [PATCH 31/33] lint --- source/connection_manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index 10dda395..d0beaefb 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1042,8 +1042,8 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif - /* If the interface_name is too long or not null terminated, it will be caught in the aws_socket_init function so we don't need - * to worry about that here.*/ + /* If the interface_name is too long or not null terminated, it will be caught in the aws_socket_init function + * so we don't need to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); #if defined(_MSC_VER) From 545b4e948ccaedafd7ea7cd76c84003e4327641a Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Wed, 3 Jul 2024 14:48:04 -0700 Subject: [PATCH 32/33] fix comment --- source/connection_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/connection_manager.c b/source/connection_manager.c index d0beaefb..5fb3199e 100644 --- a/source/connection_manager.c +++ b/source/connection_manager.c @@ -1042,7 +1042,7 @@ static int s_aws_http_connection_manager_new_connection(struct aws_http_connecti # pragma warning(push) # pragma warning(disable : 4996) /* allow strncpy() */ #endif - /* If the interface_name is too long or not null terminated, it will be caught in the aws_socket_init function + /* If the interface_name is too long or not null terminated, it will be caught in the `aws_socket_init` function * so we don't need to worry about that here.*/ strncpy( socket_options.network_interface_name, aws_string_c_str(interface_name), AWS_NETWORK_INTERFACE_NAME_MAX); From 3f123bd68001240f64a690db93b10910f1eb7d41 Mon Sep 17 00:00:00 2001 From: Waqar Ahmed Khan Date: Mon, 8 Jul 2024 10:56:09 -0700 Subject: [PATCH 33/33] latest macos? --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b24b6cd7..6bd58e84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -161,7 +161,7 @@ jobs: python3 builder.pyz build -p aws-c-http --cmake-extra=-DENABLE_LOCALHOST_INTEGRATION_TESTS=ON --config Debug localhost-test-mac: - runs-on: macos-11 # latest + runs-on: macos-13 # latest steps: - name: Checkout uses: actions/checkout@v3