Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package aws-c-io for openSUSE:Factory checked in at 2026-08-05 19:07:39 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aws-c-io (Old) and /work/SRC/openSUSE:Factory/.aws-c-io.new.16738 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aws-c-io" Wed Aug 5 19:07:39 2026 rev:42 rq:1369461 version:0.27.5 Changes: -------- --- /work/SRC/openSUSE:Factory/aws-c-io/aws-c-io.changes 2026-07-13 14:28:52.821085602 +0200 +++ /work/SRC/openSUSE:Factory/.aws-c-io.new.16738/aws-c-io.changes 2026-08-05 19:07:42.003717492 +0200 @@ -1,0 +2,9 @@ +Tue Aug 4 08:58:04 UTC 2026 - John Paul Adrian Glaubitz <[email protected]> + +- Update to version 0.27.5 + * log the negotiated TLS version by @azkrishpy in (#815) + * Expose option to set TCP_NODELAY on sockets by @DmitriyMusatkin in (#816) +- from version 0.27.4 + * Handle optional s2n-tls in the install CMake config by @sfod in (#814) + +------------------------------------------------------------------- Old: ---- v0.27.3.tar.gz New: ---- v0.27.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aws-c-io.spec ++++++ --- /var/tmp/diff_new_pack.mB8PCE/_old 2026-08-05 19:07:42.895748319 +0200 +++ /var/tmp/diff_new_pack.mB8PCE/_new 2026-08-05 19:07:42.899748457 +0200 @@ -21,7 +21,7 @@ %define library_version 1.0.0 %define library_soversion 0unstable Name: aws-c-io -Version: 0.27.3 +Version: 0.27.5 Release: 0 Summary: I/O and TLS package AWS SDK for C License: Apache-2.0 ++++++ v0.27.3.tar.gz -> v0.27.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/CMakeLists.txt new/aws-c-io-0.27.5/CMakeLists.txt --- old/aws-c-io-0.27.3/CMakeLists.txt 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/CMakeLists.txt 2026-07-24 19:02:02.000000000 +0200 @@ -121,6 +121,12 @@ option(USE_S2N "Use s2n-tls as the TLS implementation." OFF) endif() + # Force USE_S2N OFF to avoid pulling in an unused s2n dependency. + if (DEFINED AWS_USE_SECITEM AND USE_S2N) + message(WARNING "AWS_USE_SECITEM takes precedence over s2n-tls; forcing USE_S2N=OFF to avoid linking unused s2n.") + set(USE_S2N OFF CACHE BOOL "Use s2n-tls as the TLS implementation." FORCE) + endif() + elseif (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") file(GLOB AWS_IO_OS_HEADERS ) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/README.md new/aws-c-io-0.27.5/README.md --- old/aws-c-io-0.27.3/README.md 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/README.md 2026-07-24 19:02:02.000000000 +0200 @@ -780,13 +780,12 @@ The following CMake options control how aws-c-io is built: -Option | Platform | Description | Default ---- | --- | --- | --- -`USE_S2N` | Linux | Enables s2n-tls as the TLS implementation. Automatically enabled on Linux. | ON -`USE_S2N` | macOS | Compiles s2n-tls in as an available TLS implementation. User-overridable via `-DUSE_S2N=ON/OFF`. Note that Apple Secure Transport remains the default backend even when `ON` (s2n-tls is only selected when `AWS_CRT_USE_NON_FIPS_TLS_13` is set); setting `OFF` removes s2n-tls from the macOS build entirely. | ON when `AWS_USE_SECITEM` is not defined, otherwise OFF -`AWS_USE_SECITEM` | Apple | Uses Apple's SecItem/Secure Transport API instead of s2n-tls. When defined (regardless of value), the Apple Dispatch Queue event loop is used instead of kqueue. | Not defined -`USE_VSOCK` | Linux | Enables VSOCK socket domain support. Requires an appropriate VSOCK kernel driver. | OFF -`BYO_CRYPTO` | Linux/Non-Apple Unix | Disables the built-in TLS implementation and crypto linkage. Your application must provide its own `aws_tls_ctx` and `aws_channel_handler` implementations. | OFF +Option | Platform | Description | Default +--- | --- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- +`USE_S2N` | macOS | Compiles s2n-tls in as an available TLS implementation. User-overridable via `-DUSE_S2N=ON/OFF`.<br>Note that Apple Secure Transport remains the default backend even when `ON` (s2n-tls is only selected when `AWS_CRT_USE_NON_FIPS_TLS_13` is set); setting `OFF` removes s2n-tls from the macOS build entirely.<br>If `AWS_USE_SECITEM` is defined, s2n-tls is never used at runtime, so `USE_S2N` is forced to `OFF` (with a warning) even if explicitly set to `ON`, to avoid linking an unused s2n dependency. | ON when `AWS_USE_SECITEM` is not defined, otherwise OFF +`AWS_USE_SECITEM` | Apple | Uses Apple's SecItem/Secure Transport API instead of s2n-tls. When defined (regardless of value), the Apple Dispatch Queue event loop is used instead of kqueue. | Not defined +`USE_VSOCK` | Linux | Enables VSOCK socket domain support. Requires an appropriate VSOCK kernel driver. | OFF +`BYO_CRYPTO` | Linux/Non-Apple Unix | Disables the built-in TLS implementation and crypto linkage. Your application must provide its own `aws_tls_ctx` and `aws_channel_handler` implementations. | OFF ### Runtime Environment Variables @@ -794,7 +793,7 @@ Variable | Platform | Description --- | --- | --- -`AWS_CRT_USE_NON_FIPS_TLS_13` | macOS | When set to any non-empty value, the TLS implementation uses s2n-tls instead of Apple Secure Transport. This enables TLS 1.3 support but uses a non-FIPS-validated TLS implementation. If unset or empty, Apple Secure Transport is used by default (which provides FIPS-validated TLS but lacks TLS 1.3 support). Requires `USE_S2N` at build time. +`AWS_CRT_USE_NON_FIPS_TLS_13` | macOS | Requires `USE_S2N=ON` at build time.<br>When set to any non-empty value, the TLS implementation uses s2n-tls instead of Apple Secure Transport. This enables TLS 1.3 support but uses a non-FIPS-validated TLS implementation. If unset or empty, Apple Secure Transport is used by default (which provides FIPS-validated TLS but lacks TLS 1.3 support). ### TLS Backend Selection diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/cmake/aws-c-io-config.cmake new/aws-c-io-0.27.5/cmake/aws-c-io-config.cmake --- old/aws-c-io-0.27.3/cmake/aws-c-io-config.cmake 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/cmake/aws-c-io-config.cmake 2026-07-24 19:02:02.000000000 +0200 @@ -1,6 +1,8 @@ include(CMakeFindDependencyMacro) -if (UNIX AND NOT BYO_CRYPTO) +# USE_S2N is substituted at aws-c-io configure time (configure_file @ONLY) with the +# actual build decision, so this matches whether aws-c-io was really linked against s2n. +if (@USE_S2N@) find_dependency(s2n) endif() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/include/aws/io/private/tls_channel_handler_private.h new/aws-c-io-0.27.5/include/aws/io/private/tls_channel_handler_private.h --- old/aws-c-io-0.27.3/include/aws/io/private/tls_channel_handler_private.h 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/include/aws/io/private/tls_channel_handler_private.h 2026-07-24 19:02:02.000000000 +0200 @@ -39,6 +39,12 @@ AWS_EXTERN_C_BEGIN +/** + * Returns a human-readable name for an aws_tls_versions value (e.g. "TLS1.2"), for logging. + * Shared across TLS backends so version logging reads consistently regardless of platform. + */ +const char *aws_tls_version_to_string(enum aws_tls_versions version); + #ifdef _WIN32 /** * Force to use schannel creds. Default to false. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/include/aws/io/socket.h new/aws-c-io-0.27.5/include/aws/io/socket.h --- old/aws-c-io-0.27.3/include/aws/io/socket.h 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/include/aws/io/socket.h 2026-07-24 19:02:02.000000000 +0200 @@ -50,6 +50,19 @@ #define AWS_NETWORK_INTERFACE_NAME_MAX 16 +/** + * Controls the TCP_NODELAY socket option (whether Nagle's algorithm is disabled). + * TCP only. Ignored for UDP and AWS_SOCKET_LOCAL sockets. + */ +enum aws_socket_tcp_nodelay { + /* Leave the OS default in place (Nagle's algorithm enabled on most platforms). */ + AWS_SOCKET_TCP_NODELAY_DEFAULT = 0, + /* Set TCP_NODELAY on, disabling Nagle's algorithm so small writes are sent immediately. */ + AWS_SOCKET_TCP_NODELAY_ON, + /* Set TCP_NODELAY off, explicitly (re)enabling Nagle's algorithm. */ + AWS_SOCKET_TCP_NODELAY_OFF, +}; + typedef void(aws_socket_on_shutdown_complete_fn)(void *user_data); struct aws_socket_options { @@ -68,6 +81,14 @@ bool keepalive; /** + * (Optional) TCP only. Controls the TCP_NODELAY option (Nagle's algorithm). + * Defaults to AWS_SOCKET_TCP_NODELAY_DEFAULT, which leaves the OS default in place. + * Set to AWS_SOCKET_TCP_NODELAY_ON to disable Nagle's algorithm (send small writes immediately), + * or AWS_SOCKET_TCP_NODELAY_OFF to explicitly enable it. Ignored for UDP and AWS_SOCKET_LOCAL. + */ + enum aws_socket_tcp_nodelay tcp_nodelay; + + /** * THIS IS AN EXPERIMENTAL AND UNSTABLE API * (Optional) * This property is used to bind the socket to a particular network interface by name, such as eth0 and ens32. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/darwin/nw_socket.c new/aws-c-io-0.27.5/source/darwin/nw_socket.c --- old/aws-c-io-0.27.3/source/darwin/nw_socket.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/darwin/nw_socket.c 2026-07-24 19:02:02.000000000 +0200 @@ -525,6 +525,10 @@ nw_tcp_options_set_keepalive_count(tcp_options, options->keep_alive_max_failed_probes); } + if (options->tcp_nodelay != AWS_SOCKET_TCP_NODELAY_DEFAULT) { + nw_tcp_options_set_no_delay(tcp_options, options->tcp_nodelay == AWS_SOCKET_TCP_NODELAY_ON); + } + if (g_aws_channel_max_fragment_size < KB_16) { nw_tcp_options_set_maximum_segment_size(tcp_options, (uint32_t)g_aws_channel_max_fragment_size); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/darwin/secure_transport_tls_channel_handler.c new/aws-c-io-0.27.5/source/darwin/secure_transport_tls_channel_handler.c --- old/aws-c-io-0.27.3/source/darwin/secure_transport_tls_channel_handler.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/darwin/secure_transport_tls_channel_handler.c 2026-07-24 19:02:02.000000000 +0200 @@ -99,6 +99,30 @@ static void s_tls_clean_up_static_state(void) { /* no op */ } +/* SecureTransport reports the negotiated protocol using its own SSLProtocol enum + * (Security/SecureTransport.h), whose values (e.g. kSSLProtocol3, kTLSProtocol12) are not + * guaranteed to line up with our own enum aws_tls_versions, so a direct cast between the two + * would risk silently producing the wrong version if either enum's values ever shift. This + * switch is an explicit, one-time mapping from SecureTransport's enum to ours so the resulting + * enum aws_tls_versions value can be printed with the single shared aws_tls_version_to_string() + * used by every TLS backend. */ +static enum aws_tls_versions s_secure_transport_protocol_to_aws_tls_version(SSLProtocol protocol) { + switch (protocol) { + case kSSLProtocol3: + return AWS_IO_SSLv3; + case kTLSProtocol1: + return AWS_IO_TLSv1; + case kTLSProtocol11: + return AWS_IO_TLSv1_1; + case kTLSProtocol12: + return AWS_IO_TLSv1_2; + case kTLSProtocol13: + return AWS_IO_TLSv1_3; + default: + return (enum aws_tls_versions) - 1; + } +} + struct secure_transport_handler { struct aws_channel_handler handler; struct aws_tls_channel_handler_shared shared_state; @@ -107,6 +131,7 @@ struct aws_linked_list input_queue; struct aws_channel_slot *parent_slot; struct aws_byte_buf protocol; + enum aws_tls_versions minimum_tls_version; /* Note: This is just a copy of the expected server name. * The Secure Transport API doesn't seem to expose actual server name. * SSLGetPeerDomainName just returns whatever was passed earlier to SSLSetPeerDomainName */ @@ -342,6 +367,16 @@ if (status == noErr) { AWS_LOGF_DEBUG(AWS_LS_IO_TLS, "id=%p: negotiation succeeded", (void *)handler); secure_transport_handler->negotiation_finished = true; + + SSLProtocol negotiated_protocol = kSSLProtocolUnknown; + SSLGetNegotiatedProtocolVersion(secure_transport_handler->ctx, &negotiated_protocol); + AWS_LOGF_DEBUG( + AWS_LS_IO_TLS, + "id=%p: (SecureTransport) Negotiated TLS version %s (locally configured minimum %s)", + (void *)handler, + aws_tls_version_to_string(s_secure_transport_protocol_to_aws_tls_version(negotiated_protocol)), + aws_tls_version_to_string(secure_transport_handler->minimum_tls_version)); + CFStringRef protocol = s_get_protocol(secure_transport_handler); if (protocol) { @@ -899,6 +934,7 @@ secure_transport_handler->on_error = options->on_error; secure_transport_handler->on_negotiation_result = options->on_negotiation_result; secure_transport_handler->user_data = options->user_data; + secure_transport_handler->minimum_tls_version = secure_transport_ctx->minimum_tls_version; aws_tls_channel_handler_shared_init( &secure_transport_handler->shared_state, &secure_transport_handler->handler, options); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/posix/socket.c new/aws-c-io-0.27.5/source/posix/socket.c --- old/aws-c-io-0.27.3/source/posix/socket.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/posix/socket.c 2026-07-24 19:02:02.000000000 +0200 @@ -1452,6 +1452,20 @@ #endif } if (options->type == AWS_SOCKET_STREAM && options->domain != AWS_SOCKET_LOCAL) { + if (socket->options.tcp_nodelay != AWS_SOCKET_TCP_NODELAY_DEFAULT) { + int nodelay = socket->options.tcp_nodelay == AWS_SOCKET_TCP_NODELAY_ON ? 1 : 0; + if (AWS_UNLIKELY( + setsockopt(socket->io_handle.data.fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay)))) { + int errno_value = errno; /* Always cache errno before potential side-effect */ + AWS_LOGF_WARN( + AWS_LS_IO_SOCKET, + "id=%p fd=%d: setsockopt() for TCP_NODELAY failed with errno %d.", + (void *)socket, + socket->io_handle.data.fd, + errno_value); + } + } + if (socket->options.keepalive) { int keep_alive = 1; if (AWS_UNLIKELY( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/s2n/s2n_tls_channel_handler.c new/aws-c-io-0.27.5/source/s2n/s2n_tls_channel_handler.c --- old/aws-c-io-0.27.3/source/s2n/s2n_tls_channel_handler.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/s2n/s2n_tls_channel_handler.c 2026-07-24 19:02:02.000000000 +0200 @@ -76,6 +76,7 @@ struct s2n_ctx { struct aws_tls_ctx ctx; struct s2n_config *s2n_config; + enum aws_tls_versions minimum_tls_version; /* Only used in special circumstances (ex: have cert but no key, because key is in PKCS#11) */ struct s2n_cert_chain_and_key *custom_cert_chain_and_key; @@ -461,6 +462,30 @@ } } +/* s2n reports protocol versions using its own S2N_* macros (s2n.h), e.g. S2N_SSLv3 = 30, + * S2N_TLS12 = 33 -- these do not line up with our own enum aws_tls_versions (AWS_IO_SSLv3 = 0, + * AWS_IO_TLSv1_2 = 3, etc), so a direct cast between the two would silently produce the wrong + * version. This switch is an explicit, one-time mapping from s2n's numbering to ours so the + * resulting enum aws_tls_versions value can be printed with the single shared + * aws_tls_version_to_string() used by every TLS backend. s2n's SSLv2 has no equivalent in our + * enum, so it falls through to the "unrecognized" default like any other unmapped value. */ +static enum aws_tls_versions s_s2n_protocol_version_to_aws_tls_version(int s2n_version) { + switch (s2n_version) { + case S2N_SSLv3: + return AWS_IO_SSLv3; + case S2N_TLS10: + return AWS_IO_TLSv1; + case S2N_TLS11: + return AWS_IO_TLSv1_1; + case S2N_TLS12: + return AWS_IO_TLSv1_2; + case S2N_TLS13: + return AWS_IO_TLSv1_3; + default: + return (enum aws_tls_versions) - 1; + } +} + static int s_drive_negotiation(struct aws_channel_handler *handler) { struct s2n_handler *s2n_handler = (struct s2n_handler *)handler->impl; @@ -482,6 +507,26 @@ s2n_handler->protocol = aws_byte_buf_from_c_str(protocol); } + /* + * The actual negotiated version is the highest version supported by both peers + * (pre-TLS1.3: min of the two; TLS1.3+: highest entry common to the client's + * supported_versions list and the server's supported set). It can be lower than + * both peers' max if a downgrade occurred (e.g. version-intolerant middlebox, + * fallback signaling), which is why all three are logged together for diagnosis. + */ + AWS_LOGF_DEBUG( + AWS_LS_IO_TLS, + "id=%p: (s2n) Negotiated TLS version %s (client max supported %s, server max supported %s, " + "locally configured minimum %s)", + (void *)handler, + aws_tls_version_to_string(s_s2n_protocol_version_to_aws_tls_version( + s2n_connection_get_actual_protocol_version(s2n_handler->connection))), + aws_tls_version_to_string(s_s2n_protocol_version_to_aws_tls_version( + s2n_connection_get_client_protocol_version(s2n_handler->connection))), + aws_tls_version_to_string(s_s2n_protocol_version_to_aws_tls_version( + s2n_connection_get_server_protocol_version(s2n_handler->connection))), + aws_tls_version_to_string(s2n_handler->s2n_ctx->minimum_tls_version)); + const char *server_name = s2n_get_server_name(s2n_handler->connection); if (server_name) { @@ -1513,6 +1558,7 @@ s2n_ctx->ctx.alloc = alloc; s2n_ctx->ctx.impl = s2n_ctx; + s2n_ctx->minimum_tls_version = options->minimum_tls_version; aws_ref_count_init(&s2n_ctx->ctx.ref_count, s2n_ctx, (aws_simple_completion_callback *)s_s2n_ctx_destroy); s2n_ctx->s2n_config = s2n_config_new(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/tls_channel_handler.c new/aws-c-io-0.27.5/source/tls_channel_handler.c --- old/aws-c-io-0.27.3/source/tls_channel_handler.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/tls_channel_handler.c 2026-07-24 19:02:02.000000000 +0200 @@ -901,6 +901,25 @@ #endif /* BYO_CRYPTO */ +const char *aws_tls_version_to_string(enum aws_tls_versions version) { + switch (version) { + case AWS_IO_SSLv3: + return "SSLv3"; + case AWS_IO_TLSv1: + return "TLS1.0"; + case AWS_IO_TLSv1_1: + return "TLS1.1"; + case AWS_IO_TLSv1_2: + return "TLS1.2"; + case AWS_IO_TLSv1_3: + return "TLS1.3"; + case AWS_IO_TLS_VER_SYS_DEFAULTS: + return "system defaults"; + default: + return "unrecognized"; + } +} + int aws_channel_setup_client_tls( struct aws_channel_slot *right_of_slot, struct aws_tls_connection_options *tls_options) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/windows/iocp/socket.c new/aws-c-io-0.27.5/source/windows/iocp/socket.c --- old/aws-c-io-0.27.3/source/windows/iocp/socket.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/windows/iocp/socket.c 2026-07-24 19:02:02.000000000 +0200 @@ -2376,6 +2376,24 @@ socket->options = *options; if (socket->options.domain != AWS_SOCKET_LOCAL && socket->options.type == AWS_SOCKET_STREAM) { + if (socket->options.tcp_nodelay != AWS_SOCKET_TCP_NODELAY_DEFAULT) { + int nodelay = socket->options.tcp_nodelay == AWS_SOCKET_TCP_NODELAY_ON ? 1 : 0; + if (setsockopt( + (SOCKET)socket->io_handle.data.handle, + IPPROTO_TCP, + TCP_NODELAY, + (char *)&nodelay, + sizeof(nodelay))) { + int wsa_err = WSAGetLastError(); /* logging may reset error, so cache it */ + AWS_LOGF_WARN( + AWS_LS_IO_SOCKET, + "id=%p handle=%p: setsockopt() call for TCP_NODELAY failed with WSAError %d", + (void *)socket, + (void *)socket->io_handle.data.handle, + wsa_err); + } + } + if (socket->options.keepalive && !(socket->options.keep_alive_interval_sec && socket->options.keep_alive_timeout_sec)) { int keep_alive = 1; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/source/windows/secure_channel_tls_handler.c new/aws-c-io-0.27.5/source/windows/secure_channel_tls_handler.c --- old/aws-c-io-0.27.3/source/windows/secure_channel_tls_handler.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/source/windows/secure_channel_tls_handler.c 2026-07-24 19:02:02.000000000 +0200 @@ -100,6 +100,7 @@ struct aws_channel_slot *slot; struct aws_byte_buf protocol; struct aws_byte_buf server_name; + enum aws_tls_versions minimum_tls_version; TimeStamp sspi_timestamp; int (*s_connection_state_fn)(struct aws_channel_handler *handler); /* @@ -129,6 +130,37 @@ int shutdown_error_code; }; +/* SChannel reports the negotiated protocol as an SP_PROT_*_CLIENT/SP_PROT_*_SERVER value + * (schannel.h), where each protocol is its own distinct bit flag (e.g. SP_PROT_TLS1_2_CLIENT is + * a power-of-two mask bit), not a sequential ordinal like our own enum aws_tls_versions. A direct + * cast between the two is not possible here -- the encodings are fundamentally different, not + * just offset. This switch is an explicit, one-time mapping from SChannel's bit flags to our enum + * so the resulting enum aws_tls_versions value can be printed with the single shared + * aws_tls_version_to_string() used by every TLS backend. */ +static enum aws_tls_versions s_schannel_protocol_to_aws_tls_version(DWORD protocol) { + switch (protocol) { + case SP_PROT_SSL3_CLIENT: + case SP_PROT_SSL3_SERVER: + return AWS_IO_SSLv3; + case SP_PROT_TLS1_0_CLIENT: + case SP_PROT_TLS1_0_SERVER: + return AWS_IO_TLSv1; + case SP_PROT_TLS1_1_CLIENT: + case SP_PROT_TLS1_1_SERVER: + return AWS_IO_TLSv1_1; + case SP_PROT_TLS1_2_CLIENT: + case SP_PROT_TLS1_2_SERVER: + return AWS_IO_TLSv1_2; +#if defined(SP_PROT_TLS1_3_CLIENT) + case SP_PROT_TLS1_3_CLIENT: + case SP_PROT_TLS1_3_SERVER: + return AWS_IO_TLSv1_3; +#endif + default: + return (enum aws_tls_versions) - 1; + } +} + static size_t s_message_overhead(struct aws_channel_handler *handler) { struct secure_channel_handler *sc_handler = handler->impl; @@ -783,6 +815,17 @@ } sc_handler->negotiation_finished = true; + SecPkgContext_ConnectionInfo connection_info; + if (QueryContextAttributes(&sc_handler->sec_handle, SECPKG_ATTR_CONNECTION_INFO, &connection_info) == + SEC_E_OK) { + AWS_LOGF_DEBUG( + AWS_LS_IO_TLS, + "id=%p: (SChannel) Negotiated TLS version %s (locally configured minimum %s)", + (void *)handler, + aws_tls_version_to_string(s_schannel_protocol_to_aws_tls_version(connection_info.dwProtocol)), + aws_tls_version_to_string(sc_handler->minimum_tls_version)); + } + /* force query of the sizes so future calls to encrypt will be loaded. */ s_message_overhead(handler); @@ -1083,6 +1126,18 @@ } } sc_handler->negotiation_finished = true; + + SecPkgContext_ConnectionInfo connection_info; + if (QueryContextAttributes(&sc_handler->sec_handle, SECPKG_ATTR_CONNECTION_INFO, &connection_info) == + SEC_E_OK) { + AWS_LOGF_DEBUG( + AWS_LS_IO_TLS, + "id=%p: (SChannel) Negotiated TLS version %s (locally configured minimum %s)", + (void *)handler, + aws_tls_version_to_string(s_schannel_protocol_to_aws_tls_version(connection_info.dwProtocol)), + aws_tls_version_to_string(sc_handler->minimum_tls_version)); + } + /* force the sizes query, so future Encrypt message calls work.*/ s_message_overhead(handler); @@ -1991,6 +2046,7 @@ sc_handler->on_error = options->on_error; sc_handler->on_negotiation_result = options->on_negotiation_result; sc_handler->user_data = options->user_data; + sc_handler->minimum_tls_version = sc_ctx->minimum_tls_version; if (!options->alpn_list && sc_ctx->alpn_list) { sc_handler->alpn_list = aws_string_new_from_string(alloc, sc_ctx->alpn_list); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/tests/CMakeLists.txt new/aws-c-io-0.27.5/tests/CMakeLists.txt --- old/aws-c-io-0.27.3/tests/CMakeLists.txt 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/tests/CMakeLists.txt 2026-07-24 19:02:02.000000000 +0200 @@ -66,6 +66,7 @@ add_test_case(socket_posix_creation) add_test_case(socket_winsock_creation) add_test_case(local_socket_communication) +add_test_case(socket_tcp_nodelay) add_net_test_case(tcp_socket_communication) add_net_test_case(udp_socket_communication) add_net_test_case(test_socket_with_bind_to_interface) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/tests/socket_test.c new/aws-c-io-0.27.5/tests/socket_test.c --- old/aws-c-io-0.27.3/tests/socket_test.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/tests/socket_test.c 2026-07-24 19:02:02.000000000 +0200 @@ -3,6 +3,17 @@ * SPDX-License-Identifier: Apache-2.0. */ +/* winsock headers must be included before anything that pulls in windows.h to avoid + * redefinition errors between winsock v1 (from windows.h) and winsock2. */ +#if defined(_WIN32) +# include <winsock2.h> +# include <ws2tcpip.h> +#else +# include <netinet/in.h> +# include <netinet/tcp.h> +# include <sys/socket.h> +#endif + #include <aws/testing/aws_test_harness.h> #include <aws/common/clock.h> @@ -804,6 +815,53 @@ AWS_TEST_CASE(tcp_socket_communication, s_test_tcp_socket_communication) +/* + * Verify that the tcp_nodelay option is applied to the underlying socket. aws_socket_init() calls + * aws_socket_set_options(), so simply initializing the socket is enough to exercise the option. + * We read the option back with getsockopt() on platforms that expose a file descriptor. + */ +static int s_test_socket_tcp_nodelay(struct aws_allocator *allocator, void *ctx) { + (void)ctx; + + /* Apple Network Framework doesn't expose a file descriptor to read the option back from. */ + if (aws_socket_get_default_impl_type() == AWS_SOCKET_IMPL_APPLE_NETWORK_FRAMEWORK) { + return AWS_OP_SUCCESS; + } + + aws_io_library_init(allocator); + + struct aws_socket_options options; + AWS_ZERO_STRUCT(options); + options.connect_timeout_ms = 3000; + options.type = AWS_SOCKET_STREAM; + options.domain = AWS_SOCKET_IPV4; + options.tcp_nodelay = AWS_SOCKET_TCP_NODELAY_ON; + + struct aws_socket socket; + ASSERT_SUCCESS(aws_socket_init(&socket, allocator, &options)); + +#if defined(_WIN32) + SOCKET fd = (SOCKET)socket.io_handle.data.handle; + int nodelay = 0; + socklen_t len = sizeof(nodelay); + ASSERT_INT_EQUALS(0, getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, &len)); + ASSERT_TRUE(nodelay != 0); +#else + int fd = socket.io_handle.data.fd; + int nodelay = 0; + socklen_t len = sizeof(nodelay); + ASSERT_INT_EQUALS(0, getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, &len)); + ASSERT_TRUE(nodelay != 0); +#endif + + aws_socket_clean_up(&socket); + aws_io_library_clean_up(); + + return 0; +} + +AWS_TEST_CASE(socket_tcp_nodelay, s_test_socket_tcp_nodelay) + static int s_test_socket_with_bind_to_interface(struct aws_allocator *allocator, void *ctx) { (void)ctx; struct aws_socket_options options; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aws-c-io-0.27.3/tests/tls_handler_test.c new/aws-c-io-0.27.5/tests/tls_handler_test.c --- old/aws-c-io-0.27.3/tests/tls_handler_test.c 2026-07-09 01:04:54.000000000 +0200 +++ new/aws-c-io-0.27.5/tests/tls_handler_test.c 2026-07-24 19:02:02.000000000 +0200 @@ -48,14 +48,17 @@ bool s_is_apple_with_secure_transport(struct aws_allocator *allocator) { (void)allocator; -# ifdef __APPLE__ +# if defined(__APPLE__) && defined(USE_S2N) + /* When s2n is compiled in, AWS_CRT_USE_NON_FIPS_TLS_13 selects s2n over Secure Transport. */ struct aws_string *use_non_fips_13 = aws_get_env_nonempty(allocator, "AWS_CRT_USE_NON_FIPS_TLS_13"); if (use_non_fips_13) { aws_string_destroy(use_non_fips_13); return false; - } else { - return true; } + return true; +# elif defined(__APPLE__) + /* Without s2n compiled in, Secure Transport is always used and the env var has no effect. */ + return true; # else return false; # endif
