diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2023-01-13 11:39:51 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2023-01-13 11:39:51 +0300 |
commit | 7c44ed5547e5ffd0dfcea1db3c1ac97a4b5f901a (patch) | |
tree | 78a67c079d402182fdbd6c13105281828ec64750 /contrib | |
parent | 1d7ce7e954244f52dc1e3e0a4eb0ad2adc3ea67b (diff) | |
download | ydb-7c44ed5547e5ffd0dfcea1db3c1ac97a4b5f901a.tar.gz |
Update contrib/restricted/aws/aws-c-io to 0.13.12
Diffstat (limited to 'contrib')
19 files changed, 143 insertions, 88 deletions
diff --git a/contrib/restricted/aws/aws-c-io/CMakeLists.darwin.txt b/contrib/restricted/aws/aws-c-io/CMakeLists.darwin.txt index 1ba288d530..5315cee6d5 100644 --- a/contrib/restricted/aws/aws-c-io/CMakeLists.darwin.txt +++ b/contrib/restricted/aws/aws-c-io/CMakeLists.darwin.txt @@ -14,20 +14,16 @@ target_compile_options(restricted-aws-aws-c-io PRIVATE -DAWS_IO_USE_IMPORT_EXPORT -DAWS_USE_EPOLL -DHAVE_SYSCONF - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED -DS2N_FEATURES_AVAILABLE - -DS2N_HAVE_EXECINFO -DS2N_KYBER512R3_AVX2_BMI2 -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 -DS2N_MADVISE_SUPPORTED - -DS2N_SIKE_P434_R3_ASM + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED -DUSE_S2N -Wno-everything diff --git a/contrib/restricted/aws/aws-c-io/CMakeLists.linux-aarch64.txt b/contrib/restricted/aws/aws-c-io/CMakeLists.linux-aarch64.txt index 1715331613..0b92d0cfa9 100644 --- a/contrib/restricted/aws/aws-c-io/CMakeLists.linux-aarch64.txt +++ b/contrib/restricted/aws/aws-c-io/CMakeLists.linux-aarch64.txt @@ -14,20 +14,16 @@ target_compile_options(restricted-aws-aws-c-io PRIVATE -DAWS_IO_USE_IMPORT_EXPORT -DAWS_USE_EPOLL -DHAVE_SYSCONF - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED -DS2N_FEATURES_AVAILABLE - -DS2N_HAVE_EXECINFO -DS2N_KYBER512R3_AVX2_BMI2 -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 -DS2N_MADVISE_SUPPORTED - -DS2N_SIKE_P434_R3_ASM + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED -DUSE_S2N -Wno-everything diff --git a/contrib/restricted/aws/aws-c-io/CMakeLists.linux.txt b/contrib/restricted/aws/aws-c-io/CMakeLists.linux.txt index 1715331613..0b92d0cfa9 100644 --- a/contrib/restricted/aws/aws-c-io/CMakeLists.linux.txt +++ b/contrib/restricted/aws/aws-c-io/CMakeLists.linux.txt @@ -14,20 +14,16 @@ target_compile_options(restricted-aws-aws-c-io PRIVATE -DAWS_IO_USE_IMPORT_EXPORT -DAWS_USE_EPOLL -DHAVE_SYSCONF - -DS2N_ADX - -DS2N_BIKE_R3_AVX2 - -DS2N_BIKE_R3_AVX512 - -DS2N_BIKE_R3_PCLMUL -DS2N_CLONE_SUPPORTED -DS2N_CPUID_AVAILABLE -DS2N_FALL_THROUGH_SUPPORTED -DS2N_FEATURES_AVAILABLE - -DS2N_HAVE_EXECINFO -DS2N_KYBER512R3_AVX2_BMI2 -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH -DS2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + -DS2N_LIBCRYPTO_SUPPORTS_EVP_RC4 -DS2N_MADVISE_SUPPORTED - -DS2N_SIKE_P434_R3_ASM + -DS2N_STACKTRACE -DS2N___RESTRICT__SUPPORTED -DUSE_S2N -Wno-everything diff --git a/contrib/restricted/aws/aws-c-io/include/aws/io/channel_bootstrap.h b/contrib/restricted/aws/aws-c-io/include/aws/io/channel_bootstrap.h index ac1405b723..9b454d6509 100644 --- a/contrib/restricted/aws/aws-c-io/include/aws/io/channel_bootstrap.h +++ b/contrib/restricted/aws/aws-c-io/include/aws/io/channel_bootstrap.h @@ -82,7 +82,7 @@ struct aws_client_bootstrap_options { /* Optional. If none is provided then default settings are used. * This object is deep-copied by bootstrap. * */ - struct aws_host_resolution_config *host_resolution_config; + const struct aws_host_resolution_config *host_resolution_config; /* Optional. If provided, callback is invoked when client bootstrap has completely shut down. */ aws_client_bootstrap_shutdown_complete_fn *on_shutdown_complete; diff --git a/contrib/restricted/aws/aws-c-io/include/aws/io/host_resolver.h b/contrib/restricted/aws/aws-c-io/include/aws/io/host_resolver.h index a9950cad75..aed7430727 100644 --- a/contrib/restricted/aws/aws-c-io/include/aws/io/host_resolver.h +++ b/contrib/restricted/aws/aws-c-io/include/aws/io/host_resolver.h @@ -86,7 +86,7 @@ struct aws_host_resolver_vtable { struct aws_host_resolver *resolver, const struct aws_string *host_name, aws_on_host_resolved_result_fn *res, - struct aws_host_resolution_config *config, + const struct aws_host_resolution_config *config, void *user_data); /** gives your implementation a hint that an address has some failed connections occuring. Do whatever you want (or * nothing) about it. @@ -183,7 +183,7 @@ AWS_IO_API int aws_default_dns_resolve( */ AWS_IO_API struct aws_host_resolver *aws_host_resolver_new_default( struct aws_allocator *allocator, - struct aws_host_resolver_default_options *options); + const struct aws_host_resolver_default_options *options); /** * Increments the reference count on the host resolver, allowing the caller to take a reference to it. @@ -204,7 +204,7 @@ AWS_IO_API int aws_host_resolver_resolve_host( struct aws_host_resolver *resolver, const struct aws_string *host_name, aws_on_host_resolved_result_fn *res, - struct aws_host_resolution_config *config, + const struct aws_host_resolution_config *config, void *user_data); /** diff --git a/contrib/restricted/aws/aws-c-io/include/aws/io/io.h b/contrib/restricted/aws/aws-c-io/include/aws/io/io.h index 9c6e4614ed..2dfd392dd4 100644 --- a/contrib/restricted/aws/aws-c-io/include/aws/io/io.h +++ b/contrib/restricted/aws/aws-c-io/include/aws/io/io.h @@ -243,6 +243,11 @@ enum aws_io_errors { AWS_ERROR_PKCS11_ENCODING_ERROR, AWS_IO_TLS_ERROR_DEFAULT_TRUST_STORE_NOT_FOUND, + AWS_IO_STREAM_SEEK_FAILED, + AWS_IO_STREAM_GET_LENGTH_FAILED, + AWS_IO_STREAM_SEEK_UNSUPPORTED, + AWS_IO_STREAM_GET_LENGTH_UNSUPPORTED, + AWS_IO_ERROR_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_IO_PACKAGE_ID), AWS_IO_INVALID_FILE_HANDLE = AWS_ERROR_INVALID_FILE_HANDLE, }; diff --git a/contrib/restricted/aws/aws-c-io/include/aws/io/private/pki_utils.h b/contrib/restricted/aws/aws-c-io/include/aws/io/private/pki_utils.h index 8a99038a63..7533f0317f 100644 --- a/contrib/restricted/aws/aws-c-io/include/aws/io/private/pki_utils.h +++ b/contrib/restricted/aws/aws-c-io/include/aws/io/private/pki_utils.h @@ -40,9 +40,11 @@ AWS_IO_API int aws_decode_pem_to_buffer_list( /** * Decodes a PEM file at 'filename' and adds the results to 'cert_chain_or_key' if successful. - * Otherwise, 'cert_chain_or_key' will be empty. The type stored in 'cert_chain_or_key' - * is 'struct aws_byte_buf' by value. This code is slow, and it allocates, so please try - * not to call this in the middle of something that needs to be fast or resource sensitive. + * Otherwise, 'cert_chain_or_key' will be empty. + * The passed-in parameter 'cert_chain_or_key' should be empty and dynamically initialized array_list + * with item type 'struct aws_byte_buf' in value. + * This code is slow, and it allocates, so please try not to call this in the middle of + * something that needs to be fast or resource sensitive. */ AWS_IO_API int aws_read_and_decode_pem_file_to_buffer_list( struct aws_allocator *alloc, diff --git a/contrib/restricted/aws/aws-c-io/include/aws/io/tls_channel_handler.h b/contrib/restricted/aws/aws-c-io/include/aws/io/tls_channel_handler.h index e1847495bc..bb0eed7d39 100644 --- a/contrib/restricted/aws/aws-c-io/include/aws/io/tls_channel_handler.h +++ b/contrib/restricted/aws/aws-c-io/include/aws/io/tls_channel_handler.h @@ -622,6 +622,13 @@ AWS_IO_API int aws_tls_ctx_options_set_alpn_list(struct aws_tls_ctx_options *opt AWS_IO_API void aws_tls_ctx_options_set_verify_peer(struct aws_tls_ctx_options *options, bool verify_peer); /** + * Sets preferred TLS Cipher List + */ +AWS_IO_API void aws_tls_ctx_options_set_tls_cipher_preference( + struct aws_tls_ctx_options *options, + enum aws_tls_cipher_pref cipher_pref); + +/** * Sets the minimum TLS version to allow. */ AWS_IO_API void aws_tls_ctx_options_set_minimum_tls_version( diff --git a/contrib/restricted/aws/aws-c-io/source/bsd/kqueue_event_loop.c b/contrib/restricted/aws/aws-c-io/source/bsd/kqueue_event_loop.c index 4caaf9c674..43130fa497 100644 --- a/contrib/restricted/aws/aws-c-io/source/bsd/kqueue_event_loop.c +++ b/contrib/restricted/aws/aws-c-io/source/bsd/kqueue_event_loop.c @@ -41,7 +41,7 @@ static int s_unsubscribe_from_io_events(struct aws_event_loop *event_loop, struc static void s_free_io_event_resources(void *user_data); static bool s_is_event_thread(struct aws_event_loop *event_loop); -static void s_event_thread_main(void *user_data); +static void aws_event_loop_thread(void *user_data); int aws_open_nonblocking_posix_pipe(int pipe_fds[2]); @@ -368,7 +368,7 @@ static int s_run(struct aws_event_loop *event_loop) { aws_thread_increment_unjoined_count(); int err = - aws_thread_launch(&impl->thread_created_on, s_event_thread_main, (void *)event_loop, &impl->thread_options); + aws_thread_launch(&impl->thread_created_on, aws_event_loop_thread, (void *)event_loop, &impl->thread_options); if (err) { aws_thread_decrement_unjoined_count(); @@ -521,8 +521,6 @@ static void s_subscribe_task(struct aws_task *task, void *user_data, enum aws_ta if (status == AWS_TASK_STATUS_CANCELED) { return; } - AWS_LOGF_TRACE( - AWS_LS_IO_EVENT_LOOP, "id=%p: subscribing to events on fd %d", (void *)event_loop, handle_data->owner->data.fd); /* If handle was unsubscribed before this task could execute, nothing to do */ if (handle_data->state == HANDLE_STATE_UNSUBSCRIBED) { @@ -530,6 +528,8 @@ static void s_subscribe_task(struct aws_task *task, void *user_data, enum aws_ta } AWS_ASSERT(handle_data->state == HANDLE_STATE_SUBSCRIBING); + AWS_LOGF_TRACE( + AWS_LS_IO_EVENT_LOOP, "id=%p: subscribing to events on fd %d", (void *)event_loop, handle_data->owner->data.fd); /* In order to monitor both reads and writes, kqueue requires you to add two separate kevents. * If we're adding two separate kevents, but one of those fails, we need to remove the other kevent. @@ -808,7 +808,20 @@ static int s_aws_event_flags_from_kevent(struct kevent *kevent) { return event_flags; } -static void s_event_thread_main(void *user_data) { +/** + * This just calls kevent() + * + * We broke this out into its own function so that the stacktrace clearly shows + * what this thread is doing. We've had a lot of cases where users think this + * thread is deadlocked because it's stuck here. We want it to be clear + * that it's doing nothing on purpose. It's waiting for events to happen... + */ +AWS_NO_INLINE +static int aws_event_loop_listen_for_io_events(int kq_fd, struct kevent kevents[MAX_EVENTS], struct timespec *timeout) { + return kevent(kq_fd, NULL /*changelist*/, 0 /*nchanges*/, kevents /*eventlist*/, MAX_EVENTS /*nevents*/, timeout); +} + +static void aws_event_loop_thread(void *user_data) { struct aws_event_loop *event_loop = user_data; AWS_LOGF_INFO(AWS_LS_IO_EVENT_LOOP, "id=%p: main loop started", (void *)event_loop); struct kqueue_loop *impl = event_loop->impl_data; @@ -851,8 +864,7 @@ static void s_event_thread_main(void *user_data) { (unsigned long long)timeout.tv_nsec); /* Process kqueue events */ - int num_kevents = kevent( - impl->kq_fd, NULL /*changelist*/, 0 /*nchanges*/, kevents /*eventlist*/, MAX_EVENTS /*nevents*/, &timeout); + int num_kevents = aws_event_loop_listen_for_io_events(impl->kq_fd, kevents, &timeout); aws_event_loop_register_tick_start(event_loop); AWS_LOGF_TRACE( diff --git a/contrib/restricted/aws/aws-c-io/source/channel.c b/contrib/restricted/aws/aws-c-io/source/channel.c index 1cf6886fa1..47beb94c9b 100644 --- a/contrib/restricted/aws/aws-c-io/source/channel.c +++ b/contrib/restricted/aws/aws-c-io/source/channel.c @@ -80,7 +80,7 @@ struct aws_channel { size_t window_update_batch_emit_threshold; struct aws_channel_task window_update_task; bool read_back_pressure_enabled; - bool window_update_in_progress; + bool window_update_scheduled; }; struct channel_setup_args { @@ -833,6 +833,8 @@ static void s_window_update_task(struct aws_channel_task *channel_task, void *ar (void)channel_task; struct aws_channel *channel = arg; + channel->window_update_scheduled = false; + if (status == AWS_TASK_STATUS_RUN_READY && channel->channel_state < AWS_CHANNEL_SHUTTING_DOWN) { /* get the right-most slot to start the updates. */ struct aws_channel_slot *slot = channel->first; @@ -852,7 +854,6 @@ static void s_window_update_task(struct aws_channel_task *channel_task, void *ar "channel %p: channel update task failed with status %d", (void *)slot->channel, aws_last_error()); - slot->channel->window_update_in_progress = false; aws_channel_shutdown(channel, aws_last_error()); return; } @@ -860,7 +861,6 @@ static void s_window_update_task(struct aws_channel_task *channel_task, void *ar slot = slot->adj_left; } } - channel->window_update_in_progress = false; } int aws_channel_slot_increment_read_window(struct aws_channel_slot *slot, size_t window) { @@ -869,9 +869,9 @@ int aws_channel_slot_increment_read_window(struct aws_channel_slot *slot, size_t slot->current_window_update_batch_size = aws_add_size_saturating(slot->current_window_update_batch_size, window); - if (!slot->channel->window_update_in_progress && + if (!slot->channel->window_update_scheduled && slot->window_size <= slot->channel->window_update_batch_emit_threshold) { - slot->channel->window_update_in_progress = true; + slot->channel->window_update_scheduled = true; aws_channel_task_init( &slot->channel->window_update_task, s_window_update_task, slot->channel, "window update task"); aws_channel_schedule_task_now(slot->channel, &slot->channel->window_update_task); diff --git a/contrib/restricted/aws/aws-c-io/source/channel_bootstrap.c b/contrib/restricted/aws/aws-c-io/source/channel_bootstrap.c index b3a638aaff..b43f6591d7 100644 --- a/contrib/restricted/aws/aws-c-io/source/channel_bootstrap.c +++ b/contrib/restricted/aws/aws-c-io/source/channel_bootstrap.c @@ -1348,7 +1348,7 @@ struct aws_socket *aws_server_bootstrap_new_socket_listener( AWS_LS_IO_CHANNEL_BOOTSTRAP, "id=%p: attempting to initialize a new " "server socket listener for %s:%d", - (void *)server_connection_args->bootstrap, + (void *)bootstrap_options->bootstrap, bootstrap_options->host_name, (int)bootstrap_options->port); diff --git a/contrib/restricted/aws/aws-c-io/source/event_loop.c b/contrib/restricted/aws/aws-c-io/source/event_loop.c index 4da4a762e3..5870b87e8d 100644 --- a/contrib/restricted/aws/aws-c-io/source/event_loop.c +++ b/contrib/restricted/aws/aws-c-io/source/event_loop.c @@ -65,10 +65,9 @@ static void s_aws_event_loop_group_shutdown_async(struct aws_event_loop_group *e aws_thread_init(&cleanup_thread, el_group->allocator); - struct aws_thread_options thread_options; - AWS_ZERO_STRUCT(thread_options); - thread_options.cpu_id = -1; + struct aws_thread_options thread_options = *aws_default_thread_options(); thread_options.join_strategy = AWS_TJS_MANAGED; + thread_options.name = aws_byte_cursor_from_c_str("EvntLoopCleanup"); /* 15 characters is max for Linux */ aws_thread_launch(&cleanup_thread, s_event_loop_destroy_async_thread_fn, el_group, &thread_options); } @@ -124,13 +123,21 @@ static struct aws_event_loop_group *s_event_loop_group_new( struct aws_event_loop_options options = { .clock = clock, + .thread_options = &thread_options, }; if (pin_threads) { thread_options.cpu_id = usable_cpus[i].cpu_id; - options.thread_options = &thread_options; } + /* Thread name should be <= 15 characters */ + char thread_name[32] = {0}; + int thread_name_len = snprintf(thread_name, sizeof(thread_name), "AwsEventLoop %d", (int)i + 1); + if (thread_name_len > AWS_THREAD_NAME_RECOMMENDED_STRLEN) { + snprintf(thread_name, sizeof(thread_name), "AwsEventLoop"); + } + thread_options.name = aws_byte_cursor_from_c_str(thread_name); + struct aws_event_loop *loop = new_loop_fn(alloc, &options, new_loop_user_data); if (!loop) { diff --git a/contrib/restricted/aws/aws-c-io/source/host_resolver.c b/contrib/restricted/aws/aws-c-io/source/host_resolver.c index 8cd3c2ba6b..5e3b2633cf 100644 --- a/contrib/restricted/aws/aws-c-io/source/host_resolver.c +++ b/contrib/restricted/aws/aws-c-io/source/host_resolver.c @@ -69,7 +69,7 @@ int aws_host_resolver_resolve_host( struct aws_host_resolver *resolver, const struct aws_string *host_name, aws_on_host_resolved_result_fn *res, - struct aws_host_resolution_config *config, + const struct aws_host_resolution_config *config, void *user_data) { AWS_ASSERT(resolver->vtable && resolver->vtable->resolve_host); return resolver->vtable->resolve_host(resolver, host_name, res, config, user_data); @@ -961,7 +961,7 @@ static bool s_is_host_entry_pinned_by_listener(struct aws_linked_list *listener_ return false; } -static void resolver_thread_fn(void *arg) { +static void aws_host_resolver_thread(void *arg) { struct host_entry *host_entry = arg; size_t unsolicited_resolve_max = host_entry->resolution_config.max_ttl; @@ -1252,7 +1252,7 @@ static inline int create_and_init_host_entry( struct aws_host_resolver *resolver, const struct aws_string *host_name, aws_on_host_resolved_result_fn *res, - struct aws_host_resolution_config *config, + const struct aws_host_resolution_config *config, uint64_t timestamp, void *user_data) { struct host_entry *new_host_entry = aws_mem_calloc(resolver->allocator, 1, sizeof(struct host_entry)); @@ -1359,8 +1359,9 @@ static inline int create_and_init_host_entry( struct aws_thread_options thread_options = *aws_default_thread_options(); thread_options.join_strategy = AWS_TJS_MANAGED; + thread_options.name = aws_byte_cursor_from_c_str("AwsHostResolver"); /* 15 characters is max for Linux */ - aws_thread_launch(&new_host_entry->resolver_thread, resolver_thread_fn, new_host_entry, &thread_options); + aws_thread_launch(&new_host_entry->resolver_thread, aws_host_resolver_thread, new_host_entry, &thread_options); ++default_host_resolver->pending_host_entry_shutdown_completion_callbacks; return AWS_OP_SUCCESS; @@ -1380,7 +1381,7 @@ static int default_resolve_host( struct aws_host_resolver *resolver, const struct aws_string *host_name, aws_on_host_resolved_result_fn *res, - struct aws_host_resolution_config *config, + const struct aws_host_resolution_config *config, void *user_data) { int result = AWS_OP_SUCCESS; @@ -1553,7 +1554,7 @@ static void s_aws_host_resolver_destroy(struct aws_host_resolver *resolver) { struct aws_host_resolver *aws_host_resolver_new_default( struct aws_allocator *allocator, - struct aws_host_resolver_default_options *options) { + const struct aws_host_resolver_default_options *options) { AWS_FATAL_ASSERT(options != NULL); /* NOTE: we don't use el_group yet, but we will in the future. Also, we diff --git a/contrib/restricted/aws/aws-c-io/source/io.c b/contrib/restricted/aws/aws-c-io/source/io.c index 82145c996f..106ec0f978 100644 --- a/contrib/restricted/aws/aws-c-io/source/io.c +++ b/contrib/restricted/aws/aws-c-io/source/io.c @@ -287,6 +287,19 @@ static struct aws_error_info s_errors[] = { "Default TLS trust store not found on this system." " Trusted CA certificates must be installed," " or \"override default trust store\" must be used while creating the TLS context."), + + AWS_DEFINE_ERROR_INFO_IO( + AWS_IO_STREAM_SEEK_FAILED, + "Stream failed to seek from the underlying I/O source."), + AWS_DEFINE_ERROR_INFO_IO( + AWS_IO_STREAM_GET_LENGTH_FAILED, + "Stream failed to get length from the underlying I/O source."), + AWS_DEFINE_ERROR_INFO_IO( + AWS_IO_STREAM_SEEK_UNSUPPORTED, + "Seek is not supported in the underlying I/O source."), + AWS_DEFINE_ERROR_INFO_IO( + AWS_IO_STREAM_GET_LENGTH_UNSUPPORTED, + "Get length is not supported in the underlying I/O source."), }; /* clang-format on */ diff --git a/contrib/restricted/aws/aws-c-io/source/linux/epoll_event_loop.c b/contrib/restricted/aws/aws-c-io/source/linux/epoll_event_loop.c index c7ad9251a3..151ffef9c1 100644 --- a/contrib/restricted/aws/aws-c-io/source/linux/epoll_event_loop.c +++ b/contrib/restricted/aws/aws-c-io/source/linux/epoll_event_loop.c @@ -60,7 +60,7 @@ static int s_unsubscribe_from_io_events(struct aws_event_loop *event_loop, struc static void s_free_io_event_resources(void *user_data); static bool s_is_on_callers_thread(struct aws_event_loop *event_loop); -static void s_main_loop(void *args); +static void aws_event_loop_thread(void *args); static struct aws_event_loop_vtable s_vtable = { .destroy = s_destroy, @@ -272,7 +272,9 @@ static int s_run(struct aws_event_loop *event_loop) { epoll_loop->should_continue = true; aws_thread_increment_unjoined_count(); - if (aws_thread_launch(&epoll_loop->thread_created_on, &s_main_loop, event_loop, &epoll_loop->thread_options)) { + if (aws_thread_launch( + &epoll_loop->thread_created_on, &aws_event_loop_thread, event_loop, &epoll_loop->thread_options)) { + aws_thread_decrement_unjoined_count(); AWS_LOGF_FATAL(AWS_LS_IO_EVENT_LOOP, "id=%p: thread creation failed.", (void *)event_loop); epoll_loop->should_continue = false; @@ -547,7 +549,20 @@ static void s_process_task_pre_queue(struct aws_event_loop *event_loop) { } } -static void s_main_loop(void *args) { +/** + * This just calls epoll_wait() + * + * We broke this out into its own function so that the stacktrace clearly shows + * what this thread is doing. We've had a lot of cases where users think this + * thread is deadlocked because it's stuck here. We want it to be clear + * that it's doing nothing on purpose. It's waiting for events to happen... + */ +AWS_NO_INLINE +static int aws_event_loop_listen_for_io_events(int epoll_fd, struct epoll_event events[MAX_EVENTS], int timeout) { + return epoll_wait(epoll_fd, events, MAX_EVENTS, timeout); +} + +static void aws_event_loop_thread(void *args) { struct aws_event_loop *event_loop = args; AWS_LOGF_INFO(AWS_LS_IO_EVENT_LOOP, "id=%p: main loop started", (void *)event_loop); struct epoll_loop *epoll_loop = event_loop->impl_data; @@ -586,7 +601,7 @@ static void s_main_loop(void *args) { while (epoll_loop->should_continue) { AWS_LOGF_TRACE(AWS_LS_IO_EVENT_LOOP, "id=%p: waiting for a maximum of %d ms", (void *)event_loop, timeout); - int event_count = epoll_wait(epoll_loop->epoll_fd, events, MAX_EVENTS, timeout); + int event_count = aws_event_loop_listen_for_io_events(epoll_loop->epoll_fd, events, timeout); aws_event_loop_register_tick_start(event_loop); AWS_LOGF_TRACE( diff --git a/contrib/restricted/aws/aws-c-io/source/pki_utils.c b/contrib/restricted/aws/aws-c-io/source/pki_utils.c index 8deb0aabcf..2be52e80ce 100644 --- a/contrib/restricted/aws/aws-c-io/source/pki_utils.c +++ b/contrib/restricted/aws/aws-c-io/source/pki_utils.c @@ -162,43 +162,39 @@ int aws_decode_pem_to_buffer_list( if (aws_base64_compute_decoded_len(&byte_cur, &decoded_len)) { aws_raise_error(AWS_IO_FILE_VALIDATION_FAILURE); - goto cleanup_output_due_to_error; + goto cleanup_all; } struct aws_byte_buf decoded_buffer; - if (aws_byte_buf_init(&decoded_buffer, alloc, decoded_len)) { - goto cleanup_output_due_to_error; + goto cleanup_all; } if (aws_base64_decode(&byte_cur, &decoded_buffer)) { aws_raise_error(AWS_IO_FILE_VALIDATION_FAILURE); - aws_byte_buf_clean_up(&decoded_buffer); - goto cleanup_output_due_to_error; + aws_byte_buf_clean_up_secure(&decoded_buffer); + goto cleanup_all; } if (aws_array_list_push_back(cert_chain_or_key, &decoded_buffer)) { - aws_byte_buf_clean_up(&decoded_buffer); - goto cleanup_output_due_to_error; + aws_byte_buf_clean_up_secure(&decoded_buffer); + goto cleanup_all; } } err_code = AWS_OP_SUCCESS; +cleanup_all: + if (err_code != AWS_OP_SUCCESS) { + AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Invalid PEM buffer."); + aws_cert_chain_clean_up(cert_chain_or_key); + } + cleanup_base64_buffer_list: aws_cert_chain_clean_up(&base_64_buffer_list); aws_array_list_clean_up(&base_64_buffer_list); return err_code; - -cleanup_output_due_to_error: - AWS_LOGF_ERROR(AWS_LS_IO_PKI, "static: Invalid PEM buffer."); - aws_cert_chain_clean_up(&base_64_buffer_list); - aws_array_list_clean_up(&base_64_buffer_list); - - aws_cert_chain_clean_up(cert_chain_or_key); - - return AWS_OP_ERR; } int aws_read_and_decode_pem_file_to_buffer_list( diff --git a/contrib/restricted/aws/aws-c-io/source/posix/pipe.c b/contrib/restricted/aws/aws-c-io/source/posix/pipe.c index 141cd05cbe..2b67d90ec4 100644 --- a/contrib/restricted/aws/aws-c-io/source/posix/pipe.c +++ b/contrib/restricted/aws/aws-c-io/source/posix/pipe.c @@ -46,7 +46,7 @@ struct read_end_impl { bool is_subscribed; }; -struct write_request { +struct pipe_write_request { struct aws_byte_cursor original_cursor; struct aws_byte_cursor cursor; /* tracks progress of write */ size_t num_bytes_written; @@ -65,11 +65,11 @@ struct write_end_impl { struct aws_linked_list write_list; /* Valid while invoking user callback on a completed write request. */ - struct write_request *currently_invoking_write_callback; + struct pipe_write_request *currently_invoking_write_callback; bool is_writable; - /* Future optimization idea: avoid an allocation on each write by keeping 1 pre-allocated write_request around + /* Future optimization idea: avoid an allocation on each write by keeping 1 pre-allocated pipe_write_request around * and re-using it whenever possible */ }; @@ -410,14 +410,14 @@ static bool s_write_end_complete_front_write_request(struct aws_pipe_write_end * AWS_ASSERT(!aws_linked_list_empty(&write_impl->write_list)); struct aws_linked_list_node *node = aws_linked_list_pop_front(&write_impl->write_list); - struct write_request *request = AWS_CONTAINER_OF(node, struct write_request, list_node); + struct pipe_write_request *request = AWS_CONTAINER_OF(node, struct pipe_write_request, list_node); struct aws_allocator *alloc = write_impl->alloc; /* Let the write-end know that a callback is in process, so the write-end can inform the callback * whether it resulted in clean_up() being called. */ bool write_end_cleaned_up_during_callback = false; - struct write_request *prev_invoking_request = write_impl->currently_invoking_write_callback; + struct pipe_write_request *prev_invoking_request = write_impl->currently_invoking_write_callback; write_impl->currently_invoking_write_callback = request; if (request->user_callback) { @@ -441,7 +441,7 @@ static void s_write_end_process_requests(struct aws_pipe_write_end *write_end) { while (!aws_linked_list_empty(&write_impl->write_list)) { struct aws_linked_list_node *node = aws_linked_list_front(&write_impl->write_list); - struct write_request *request = AWS_CONTAINER_OF(node, struct write_request, list_node); + struct pipe_write_request *request = AWS_CONTAINER_OF(node, struct pipe_write_request, list_node); int completed_error_code = AWS_ERROR_SUCCESS; @@ -522,7 +522,7 @@ int aws_pipe_write( return aws_raise_error(AWS_ERROR_IO_EVENT_LOOP_THREAD_ONLY); } - struct write_request *request = aws_mem_calloc(write_impl->alloc, 1, sizeof(struct write_request)); + struct pipe_write_request *request = aws_mem_calloc(write_impl->alloc, 1, sizeof(struct pipe_write_request)); if (!request) { return AWS_OP_ERR; } @@ -571,7 +571,7 @@ int aws_pipe_clean_up_write_end(struct aws_pipe_write_end *write_end) { /* Force any outstanding write requests to complete with an error status. */ while (!aws_linked_list_empty(&write_impl->write_list)) { struct aws_linked_list_node *node = aws_linked_list_pop_front(&write_impl->write_list); - struct write_request *request = AWS_CONTAINER_OF(node, struct write_request, list_node); + struct pipe_write_request *request = AWS_CONTAINER_OF(node, struct pipe_write_request, list_node); if (request->user_callback) { request->user_callback(NULL, AWS_IO_BROKEN_PIPE, request->original_cursor, request->user_data); } diff --git a/contrib/restricted/aws/aws-c-io/source/posix/socket.c b/contrib/restricted/aws/aws-c-io/source/posix/socket.c index ab41434eeb..240262ccfb 100644 --- a/contrib/restricted/aws/aws-c-io/source/posix/socket.c +++ b/contrib/restricted/aws/aws-c-io/source/posix/socket.c @@ -101,6 +101,8 @@ static int s_determine_socket_error(int error) { switch (error) { case ECONNREFUSED: return AWS_IO_SOCKET_CONNECTION_REFUSED; + case ECONNRESET: + return AWS_IO_SOCKET_CLOSED; case ETIMEDOUT: return AWS_IO_SOCKET_TIMEOUT; case EHOSTUNREACH: @@ -1296,7 +1298,7 @@ int aws_socket_set_options(struct aws_socket *socket, const struct aws_socket_op return AWS_OP_SUCCESS; } -struct write_request { +struct socket_write_request { struct aws_byte_cursor cursor_cpy; aws_socket_on_write_completed_fn *written_fn; void *write_user_data; @@ -1419,7 +1421,7 @@ int aws_socket_close(struct aws_socket *socket) { while (!aws_linked_list_empty(&socket_impl->written_queue)) { struct aws_linked_list_node *node = aws_linked_list_pop_front(&socket_impl->written_queue); - struct write_request *write_request = AWS_CONTAINER_OF(node, struct write_request, node); + struct socket_write_request *write_request = AWS_CONTAINER_OF(node, struct socket_write_request, node); size_t bytes_written = write_request->original_buffer_len - write_request->cursor_cpy.len; write_request->written_fn(socket, write_request->error_code, bytes_written, write_request->write_user_data); aws_mem_release(socket->allocator, write_request); @@ -1427,7 +1429,7 @@ int aws_socket_close(struct aws_socket *socket) { while (!aws_linked_list_empty(&socket_impl->write_queue)) { struct aws_linked_list_node *node = aws_linked_list_pop_front(&socket_impl->write_queue); - struct write_request *write_request = AWS_CONTAINER_OF(node, struct write_request, node); + struct socket_write_request *write_request = AWS_CONTAINER_OF(node, struct socket_write_request, node); size_t bytes_written = write_request->original_buffer_len - write_request->cursor_cpy.len; write_request->written_fn(socket, AWS_IO_SOCKET_CLOSED, bytes_written, write_request->write_user_data); aws_mem_release(socket->allocator, write_request); @@ -1483,7 +1485,7 @@ static void s_written_task(struct aws_task *task, void *arg, enum aws_task_statu struct aws_linked_list_node *stop_after = aws_linked_list_back(&socket_impl->written_queue); do { struct aws_linked_list_node *node = aws_linked_list_pop_front(&socket_impl->written_queue); - struct write_request *write_request = AWS_CONTAINER_OF(node, struct write_request, node); + struct socket_write_request *write_request = AWS_CONTAINER_OF(node, struct socket_write_request, node); size_t bytes_written = write_request->original_buffer_len - write_request->cursor_cpy.len; write_request->written_fn(socket, write_request->error_code, bytes_written, write_request->write_user_data); aws_mem_release(socket_impl->allocator, write_request); @@ -1500,7 +1502,7 @@ static void s_written_task(struct aws_task *task, void *arg, enum aws_task_statu * 1st scenario, someone called aws_socket_write() and we want to try writing now, so an error can be returned * immediately if something bad has happened to the socket. In this case, `parent_request` is set. * 2nd scenario, the event loop notified us that the socket went writable. In this case `parent_request` is NULL */ -static int s_process_write_requests(struct aws_socket *socket, struct write_request *parent_request) { +static int s_process_socket_write_requests(struct aws_socket *socket, struct socket_write_request *parent_request) { struct posix_socket *socket_impl = socket->impl; if (parent_request) { @@ -1525,7 +1527,7 @@ static int s_process_write_requests(struct aws_socket *socket, struct write_requ /* if a close call happens in the middle, this queue will have been cleaned out from under us. */ while (!aws_linked_list_empty(&socket_impl->write_queue)) { struct aws_linked_list_node *node = aws_linked_list_front(&socket_impl->write_queue); - struct write_request *write_request = AWS_CONTAINER_OF(node, struct write_request, node); + struct socket_write_request *write_request = AWS_CONTAINER_OF(node, struct socket_write_request, node); AWS_LOGF_TRACE( AWS_LS_IO_SOCKET, @@ -1601,7 +1603,7 @@ static int s_process_write_requests(struct aws_socket *socket, struct write_requ if (purge) { while (!aws_linked_list_empty(&socket_impl->write_queue)) { struct aws_linked_list_node *node = aws_linked_list_pop_front(&socket_impl->write_queue); - struct write_request *write_request = AWS_CONTAINER_OF(node, struct write_request, node); + struct socket_write_request *write_request = AWS_CONTAINER_OF(node, struct socket_write_request, node); /* If this fn was invoked directly from aws_socket_write(), don't invoke the error callback * as the user will be able to rely on the return value from aws_socket_write() */ @@ -1677,7 +1679,7 @@ static void s_on_socket_io_event( * have been cleaned up, so this next branch is safe. */ if (socket_impl->currently_subscribed && events & AWS_IO_EVENT_TYPE_WRITABLE) { AWS_LOGF_TRACE(AWS_LS_IO_SOCKET, "id=%p fd=%d: is writable", (void *)socket, socket->io_handle.data.fd); - s_process_write_requests(socket, NULL); + s_process_socket_write_requests(socket, NULL); } end_check: @@ -1811,7 +1813,7 @@ int aws_socket_read(struct aws_socket *socket, struct aws_byte_buf *buffer, size return aws_raise_error(AWS_IO_READ_WOULD_BLOCK); } - if (error == EPIPE) { + if (error == EPIPE || error == ECONNRESET) { AWS_LOGF_INFO(AWS_LS_IO_SOCKET, "id=%p fd=%d: socket is closed.", (void *)socket, socket->io_handle.data.fd); return aws_raise_error(AWS_IO_SOCKET_CLOSED); } @@ -1827,7 +1829,7 @@ int aws_socket_read(struct aws_socket *socket, struct aws_byte_buf *buffer, size (void *)socket, socket->io_handle.data.fd, strerror(error)); - return aws_raise_error(AWS_ERROR_SYS_CALL_FAILURE); + return aws_raise_error(s_determine_socket_error(error)); } int aws_socket_write( @@ -1850,7 +1852,8 @@ int aws_socket_write( AWS_ASSERT(written_fn); struct posix_socket *socket_impl = socket->impl; - struct write_request *write_request = aws_mem_calloc(socket->allocator, 1, sizeof(struct write_request)); + struct socket_write_request *write_request = + aws_mem_calloc(socket->allocator, 1, sizeof(struct socket_write_request)); if (!write_request) { return AWS_OP_ERR; @@ -1862,7 +1865,7 @@ int aws_socket_write( write_request->cursor_cpy = *cursor; aws_linked_list_push_back(&socket_impl->write_queue, &write_request->node); - return s_process_write_requests(socket, write_request); + return s_process_socket_write_requests(socket, write_request); } int aws_socket_get_error(struct aws_socket *socket) { diff --git a/contrib/restricted/aws/aws-c-io/source/tls_channel_handler.c b/contrib/restricted/aws/aws-c-io/source/tls_channel_handler.c index 3a95596984..b667577456 100644 --- a/contrib/restricted/aws/aws-c-io/source/tls_channel_handler.c +++ b/contrib/restricted/aws/aws-c-io/source/tls_channel_handler.c @@ -459,6 +459,12 @@ void aws_tls_ctx_options_set_minimum_tls_version( options->minimum_tls_version = minimum_tls_version; } +void aws_tls_ctx_options_set_tls_cipher_preference( + struct aws_tls_ctx_options *options, + enum aws_tls_cipher_pref cipher_pref) { + options->cipher_pref = cipher_pref; +} + int aws_tls_ctx_options_override_default_trust_store_from_path( struct aws_tls_ctx_options *options, const char *ca_path, |