diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7631a21a..3f0fde7ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: - 'docs' env: - BUILDER_VERSION: v0.9.56 + BUILDER_VERSION: v0.9.63 BUILDER_SOURCE: releases BUILDER_HOST: https://d19elf31gohf1l.cloudfront.net PACKAGE_NAME: aws-crt-cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index bf86c3555..69e534a1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,35 +80,36 @@ if(BUILD_DEPS) if(UNIX AND NOT APPLE AND NOT BYO_CRYPTO) if(NOT USE_OPENSSL) - set(DISABLE_PERL ON CACHE BOOL "Disable Perl for AWS-LC.") - set(DISABLE_GO ON CACHE BOOL "Disable Go for AWS-LC.") - set(BUILD_LIBSSL OFF CACHE BOOL "Build libssl for AWS-LC.") + include(AwsPrebuildDependency) - # temporarily disable certain warnings as errors for the aws-lc build - set(OLD_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + set(AWSLC_CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + # temporarily disable certain warnings as errors for the aws-lc build if(NOT MSVC) check_c_compiler_flag(-Wno-stringop-overflow HAS_WNO_STRINGOP_OVERFLOW) if(HAS_WNO_STRINGOP_OVERFLOW) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-stringop-overflow") + set(AWSLC_CMAKE_C_FLAGS "${AWSLC_CMAKE_C_FLAGS} -Wno-stringop-overflow") endif() check_c_compiler_flag(-Wno-array-parameter HAS_WNO_ARRAY_PARAMETER) if(HAS_WNO_ARRAY_PARAMETER) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-array-parameter") + set(AWSLC_CMAKE_C_FLAGS "${AWSLC_CMAKE_C_FLAGS} -Wno-array-parameter") endif() endif() - add_subdirectory(crt/aws-lc) - - # restore previous build flags - set(CMAKE_C_FLAGS "${OLD_CMAKE_C_FLAGS}") - - set(SEARCH_LIBCRYPTO OFF CACHE BOOL "Let S2N use libcrypto from AWS-LC.") - else() - set(SEARCH_LIBCRYPTO ON CACHE BOOL "Let S2N search libcrypto in the system.") + # s2n-tls uses libcrypto during its configuration, so we need to prebuild aws-lc. + prebuild_dependency( + DEPENDENCY_NAME AWSLC + SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/crt/aws-lc + CMAKE_ARGUMENTS + -DDISABLE_GO=ON + -DDISABLE_PERL=ON + -DBUILD_LIBSSL=OFF + -DBUILD_TESTING=OFF + -DCMAKE_C_FLAGS=${AWSLC_CMAKE_C_FLAGS} + ) endif() set(UNSAFE_TREAT_WARNINGS_AS_ERRORS OFF CACHE BOOL "Disable warnings-as-errors when building S2N") @@ -143,6 +144,10 @@ file(GLOB AWS_CRT_AUTH_HEADERS "include/aws/crt/auth/*.h" ) +file(GLOB AWS_CRT_CHECKSUM_HEADERS + "include/aws/crt/checksum/*.h" +) + file(GLOB AWS_CRT_CRYPTO_HEADERS "include/aws/crt/crypto/*.h" ) @@ -174,6 +179,7 @@ file(GLOB AWS_CRT_CBOR_HEADERS file(GLOB AWS_CRT_PUBLIC_HEADERS ${AWS_CRT_HEADERS} ${AWS_CRT_AUTH_HEADERS} + ${AWS_CRT_CHECKSUM_HEADERS} ${AWS_CRT_CRYPTO_HEADERS} ${AWS_CRT_IO_HEADERS} ${AWS_CRT_IOT_HEADERS} @@ -200,6 +206,10 @@ file(GLOB AWS_CRT_AUTH_SRC "source/auth/*.cpp" ) +file(GLOB AWS_CRT_CHECKSUM_SRC + "source/checksum/*.cpp" +) + file(GLOB AWS_CRT_CRYPTO_SRC "source/crypto/*.cpp" ) @@ -231,6 +241,7 @@ file(GLOB AWS_CRT_CBOR_SRC file(GLOB AWS_CRT_CPP_SRC ${AWS_CRT_SRC} ${AWS_CRT_AUTH_SRC} + ${AWS_CRT_CHECKSUM_SRC} ${AWS_CRT_CRYPTO_SRC} ${AWS_CRT_IO_SRC} ${AWS_CRT_IOT_SRC} @@ -244,6 +255,7 @@ if(WIN32) if(MSVC) source_group("Header Files\\aws\\crt" FILES ${AWS_CRT_HEADERS}) source_group("Header Files\\aws\\crt\\auth" FILES ${AWS_CRT_AUTH_HEADERS}) + source_group("Header Files\\aws\\crt\\checksum" FILES ${AWS_CRT_CHECKSUM_HEADERS}) source_group("Header Files\\aws\\crt\\crypto" FILES ${AWS_CRT_CRYPTO_HEADERS}) source_group("Header Files\\aws\\crt\\io" FILES ${AWS_CRT_IO_HEADERS}) source_group("Header Files\\aws\\iot" FILES ${AWS_CRT_IOT_HEADERS}) @@ -254,6 +266,7 @@ if(WIN32) source_group("Source Files" FILES ${AWS_CRT_SRC}) source_group("Source Files\\auth" FILES ${AWS_CRT_AUTH_SRC}) + source_group("Source Files\\checksum" FILES ${AWS_CRT_CHECKSUM_SRC}) source_group("Source Files\\crypto" FILES ${AWS_CRT_CRYPTO_SRC}) source_group("Source Files\\io" FILES ${AWS_CRT_IO_SRC}) source_group("Source Files\\iot" FILES ${AWS_CRT_IOT_SRC}) @@ -325,6 +338,7 @@ target_link_libraries(${PROJECT_NAME} PUBLIC ${DEP_AWS_LIBS}) install(FILES ${AWS_CRT_HEADERS} DESTINATION "include/aws/crt" COMPONENT Development) install(FILES ${AWS_CRT_AUTH_HEADERS} DESTINATION "include/aws/crt/auth" COMPONENT Development) +install(FILES ${AWS_CRT_CHECKSUM_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_CRYPTO_HEADERS} DESTINATION "include/aws/crt/crypto" COMPONENT Development) install(FILES ${AWS_CRT_IO_HEADERS} DESTINATION "include/aws/crt/io" COMPONENT Development) install(FILES ${AWS_CRT_IOT_HEADERS} DESTINATION "include/aws/iot" COMPONENT Development) diff --git a/VERSION b/VERSION index c7c49b4b4..b79f04f44 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.6 +0.28.3 diff --git a/crt/aws-c-auth b/crt/aws-c-auth index 084868560..08fb6f71a 160000 --- a/crt/aws-c-auth +++ b/crt/aws-c-auth @@ -1 +1 @@ -Subproject commit 084868560e6856943a5b906916ab4957e7c61b70 +Subproject commit 08fb6f71a85f8c9522547af164d497c8fec4f2aa diff --git a/crt/aws-c-cal b/crt/aws-c-cal index 0627591cf..fdaef2ddf 160000 --- a/crt/aws-c-cal +++ b/crt/aws-c-cal @@ -1 +1 @@ -Subproject commit 0627591cf9fc587bd357fea0b34f984dc3609a11 +Subproject commit fdaef2ddfb4cd5850231d9bd9d6e34e91b41c943 diff --git a/crt/aws-c-common b/crt/aws-c-common index 484fddaf0..d223f6009 160000 --- a/crt/aws-c-common +++ b/crt/aws-c-common @@ -1 +1 @@ -Subproject commit 484fddaf09b65e97b6577c020a131e9f5bdb1106 +Subproject commit d223f6009ce979637d3c9e7d2f5f02af08497cc0 diff --git a/crt/aws-c-http b/crt/aws-c-http index 3225effef..7778cd991 160000 --- a/crt/aws-c-http +++ b/crt/aws-c-http @@ -1 +1 @@ -Subproject commit 3225effefb4d6ae99e7f5edd51a55df6fc5d83fa +Subproject commit 7778cd99166087af36b3b1cdc687b57192952f0f diff --git a/crt/aws-c-io b/crt/aws-c-io index 1e29ae8aa..b4680a684 160000 --- a/crt/aws-c-io +++ b/crt/aws-c-io @@ -1 +1 @@ -Subproject commit 1e29ae8aa63847220c339a7ee9903685eca7134b +Subproject commit b4680a684e46d74fb89c9309cccf0c4b4332189d diff --git a/crt/aws-c-mqtt b/crt/aws-c-mqtt index 5edf91839..40d6b2de8 160000 --- a/crt/aws-c-mqtt +++ b/crt/aws-c-mqtt @@ -1 +1 @@ -Subproject commit 5edf91839929ed4059bc3ecc340d344c8e17f5ca +Subproject commit 40d6b2de82ef5b2b95992584678279828d2f8af6 diff --git a/crt/aws-c-s3 b/crt/aws-c-s3 index 5453f6bbd..e77b41178 160000 --- a/crt/aws-c-s3 +++ b/crt/aws-c-s3 @@ -1 +1 @@ -Subproject commit 5453f6bbd424f0924d5df97fdf233f40c10b321e +Subproject commit e77b411787da795510f0aa0877525e544fe6ea57 diff --git a/crt/aws-checksums b/crt/aws-checksums index 53c112b63..38c5d4423 160000 --- a/crt/aws-checksums +++ b/crt/aws-checksums @@ -1 +1 @@ -Subproject commit 53c112b6315ef600a4604d4f1f9b673beb4ec8b0 +Subproject commit 38c5d44237413b241ae648e3becd47568e598061 diff --git a/crt/aws-lc b/crt/aws-lc index 057477806..8ffe277c2 160000 --- a/crt/aws-lc +++ b/crt/aws-lc @@ -1 +1 @@ -Subproject commit 05747780676652f41d0b9c570a495e4bb6608560 +Subproject commit 8ffe277c21915ca82dc78a3bdc6a92e10c284b92 diff --git a/crt/s2n b/crt/s2n index 79c0f1b43..ffe0bf42d 160000 --- a/crt/s2n +++ b/crt/s2n @@ -1 +1 @@ -Subproject commit 79c0f1b434742d9f1152c48d3781433649f6f8fe +Subproject commit ffe0bf42da8f139eff8fd2237f47fbde40b478fb diff --git a/include/aws/crt/StringView.h b/include/aws/crt/StringView.h index 27c162ffe..3b6dc2f0f 100644 --- a/include/aws/crt/StringView.h +++ b/include/aws/crt/StringView.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) @@ -859,6 +860,6 @@ namespace std const Aws::Crt::basic_string_view &val) const noexcept { auto str = std::basic_string(val.data(), val.size()); - return std::hash>()(str); + return std::hash>{}(str); } } // namespace std diff --git a/include/aws/crt/Variant.h b/include/aws/crt/Variant.h index f973316e6..e4cec4af5 100644 --- a/include/aws/crt/Variant.h +++ b/include/aws/crt/Variant.h @@ -53,7 +53,7 @@ namespace Aws { using VariantIndex = short; - template constexpr VariantIndex GetIndexOf(VariantIndex curIndex = -1) + template constexpr VariantIndex GetIndexOf(VariantIndex curIndex = 0) { return std::is_same::value ? curIndex : -1; } diff --git a/include/aws/crt/checksum/CRC.h b/include/aws/crt/checksum/CRC.h new file mode 100644 index 000000000..023d1d21a --- /dev/null +++ b/include/aws/crt/checksum/CRC.h @@ -0,0 +1,39 @@ +#pragma once +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include +#include + +namespace Aws +{ + namespace Crt + { + namespace Checksum + { + /** + * The entry point function to perform a CRC32 (Ethernet, gzip) computation. + * Selects a suitable implementation based on hardware capabilities. + * Pass previousCRC32 if updating a running checksum. + */ + uint32_t AWS_CRT_CPP_API ComputeCRC32(ByteCursor input, uint32_t previousCRC32 = 0) noexcept; + + /** + * The entry point function to perform a Castagnoli CRC32c (iSCSI) computation. + * Selects a suitable implementation based on hardware capabilities. + * Pass previousCRC32C if updating a running checksum. + */ + uint32_t AWS_CRT_CPP_API ComputeCRC32C(ByteCursor input, uint32_t previousCRC32C = 0) noexcept; + + /** + * The entry point function to perform a CRC64-NVME (a.k.a. CRC64-Rocksoft) computation. + * Selects a suitable implementation based on hardware capabilities. + * Pass previousCRC64NVME if updating a running checksum. + * There are many variants of CRC64 algorithms. This CRC64 variant is bit-reflected (based on + * the non bit-reflected polynomial 0xad93d23594c93659) and inverts the CRC input and output bits. + */ + uint64_t AWS_CRT_CPP_API ComputeCRC64NVME(ByteCursor input, uint64_t previousCRC64NVME = 0) noexcept; + } // namespace Checksum + } // namespace Crt +} // namespace Aws diff --git a/include/aws/crt/crypto/Hash.h b/include/aws/crt/crypto/Hash.h index 98e3e3c93..af8a7c7d2 100644 --- a/include/aws/crt/crypto/Hash.h +++ b/include/aws/crt/crypto/Hash.h @@ -189,7 +189,7 @@ namespace Aws /** * Complete the hash computation and write the final digest to output. - * This cannote be called more than once. + * This cannot be called more than once. * If truncate_to is something other than 0, the output must be truncated to that number of bytes. * Raise an AWS error and return false to indicate failure. */ diff --git a/include/aws/crt/io/Stream.h b/include/aws/crt/io/Stream.h index 91c8c36f2..b41f36413 100644 --- a/include/aws/crt/io/Stream.h +++ b/include/aws/crt/io/Stream.h @@ -114,6 +114,19 @@ namespace Aws */ virtual bool ReadImpl(ByteBuf &buffer) noexcept = 0; + /*** + * Read up-to buffer::capacity - buffer::len immediately available bytes into buffer::buffer + * Increment buffer::len by the amount you read in. + * + * @return true if nothing went wrong. + * Return true even if you read 0 bytes because the end-of-file has been reached. + * Return true even if you read 0 bytes because data is not currently available. + * + * Return false if an actual failure condition occurs, + * you SHOULD also raise an error via aws_raise_error(). + */ + virtual bool ReadSomeImpl(ByteBuf &buffer) noexcept = 0; + /** * @return the current status of the stream. */ @@ -136,6 +149,15 @@ namespace Aws */ virtual bool SeekImpl(int64_t offset, StreamSeekBasis seekBasis) noexcept = 0; + /** + * Peeks the stream + * + * Essentially calls peek on the underlying istream + * + * @return return value of the underlying istream::peek + */ + virtual int64_t PeekImpl() const noexcept = 0; + private: static int s_Seek(aws_input_stream *stream, int64_t offset, enum aws_stream_seek_basis basis); static int s_Read(aws_input_stream *stream, aws_byte_buf *dest); @@ -161,9 +183,11 @@ namespace Aws protected: bool ReadImpl(ByteBuf &buffer) noexcept override; + bool ReadSomeImpl(ByteBuf &buffer) noexcept override; StreamStatus GetStatusImpl() const noexcept override; int64_t GetLengthImpl() const noexcept override; bool SeekImpl(OffsetType offsetType, StreamSeekBasis seekBasis) noexcept override; + int64_t PeekImpl() const noexcept override; private: std::shared_ptr m_stream; diff --git a/include/aws/iot/Mqtt5Client.h b/include/aws/iot/Mqtt5Client.h index fbe5b8524..e1711bcee 100644 --- a/include/aws/iot/Mqtt5Client.h +++ b/include/aws/iot/Mqtt5Client.h @@ -298,6 +298,15 @@ namespace Aws */ Mqtt5ClientBuilder &WithCertificateAuthority(const Crt::ByteCursor &cert) noexcept; + /** + * Overrides the socket properties of the underlying MQTT connections made by the client. Leave undefined + * to use defaults (no TCP keep alive, 10 second socket timeout). + * + * @param socketOptions - The socket properties of the underlying MQTT connections made by the client + * @return - The Mqtt5ClientBuilder + */ + Mqtt5ClientBuilder &WithSocketOptions(Crt::Io::SocketOptions socketOptions) noexcept; + /** * Sets http proxy options. * diff --git a/source/checksum/CRC.cpp b/source/checksum/CRC.cpp new file mode 100644 index 000000000..65ed70e28 --- /dev/null +++ b/source/checksum/CRC.cpp @@ -0,0 +1,32 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include + +#include + +namespace Aws +{ + namespace Crt + { + namespace Checksum + { + uint32_t ComputeCRC32(ByteCursor input, uint32_t previousCRC32) noexcept + { + return aws_checksums_crc32_ex(input.ptr, input.len, previousCRC32); + } + + uint32_t ComputeCRC32C(ByteCursor input, uint32_t previousCRC32C) noexcept + { + return aws_checksums_crc32c_ex(input.ptr, input.len, previousCRC32C); + } + + uint64_t ComputeCRC64NVME(ByteCursor input, uint64_t previousCRC64NVME) noexcept + { + return aws_checksums_crc64nvme_ex(input.ptr, input.len, previousCRC64NVME); + } + + } // namespace Checksum + } // namespace Crt +} // namespace Aws diff --git a/source/io/Stream.cpp b/source/io/Stream.cpp index 975d1c516..b16267f10 100644 --- a/source/io/Stream.cpp +++ b/source/io/Stream.cpp @@ -5,6 +5,7 @@ #include #include +#include #include @@ -150,6 +151,26 @@ namespace Aws return status.is_valid && !status.is_end_of_stream; } + bool StdIOStreamInputStream::ReadSomeImpl(ByteBuf &buffer) noexcept + { + // I have no idea why "readsome() doesn't work at all" for the original dev. It works well for me + // Jokes aside, read will always block and try to read till eof + // readsome will return available bytes without waiting for eof and without closing the stream. + auto actuallyRead = m_stream->readsome( + reinterpret_cast(buffer.buffer + buffer.len), buffer.capacity - buffer.len); + + buffer.len += static_cast(actuallyRead); + + if (actuallyRead > 0 || (actuallyRead == 0 && m_stream->eof())) + { + return true; + } + + auto status = GetStatusImpl(); + + return status.is_valid && !status.is_end_of_stream; + } + StreamStatus StdIOStreamInputStream::GetStatusImpl() const noexcept { StreamStatus status; @@ -206,6 +227,11 @@ namespace Aws return true; } + + int64_t StdIOStreamInputStream::PeekImpl() const noexcept + { + return m_stream->peek(); + } } // namespace Io } // namespace Crt } // namespace Aws diff --git a/source/iot/Mqtt5Client.cpp b/source/iot/Mqtt5Client.cpp index e9cc5226e..fa4b27e72 100644 --- a/source/iot/Mqtt5Client.cpp +++ b/source/iot/Mqtt5Client.cpp @@ -344,6 +344,12 @@ namespace Aws return *this; } + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithSocketOptions(Crt::Io::SocketOptions socketOptions) noexcept + { + m_options->WithSocketOptions(std::move(socketOptions)); + return *this; + } + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithHttpProxyOptions( const Crt::Http::HttpClientConnectionProxyOptions &proxyOptions) noexcept { diff --git a/tests/CRCTest.cpp b/tests/CRCTest.cpp new file mode 100644 index 000000000..464fe4862 --- /dev/null +++ b/tests/CRCTest.cpp @@ -0,0 +1,46 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include +#include +#include + +static int s_TestCRC32Piping(struct aws_allocator *allocator, void *) +{ + Aws::Crt::ApiHandle apiHandle(allocator); + uint8_t data[32] = {0}; + + Aws::Crt::ByteCursor dataCur = aws_byte_cursor_from_array(data, sizeof(data)); + + ASSERT_UINT_EQUALS(0x190A55AD, Aws::Crt::Checksum::ComputeCRC32(dataCur)); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(CRC32Piping, s_TestCRC32Piping) + +static int s_TestCRC32CPiping(struct aws_allocator *allocator, void *) +{ + Aws::Crt::ApiHandle apiHandle(allocator); + uint8_t data[32] = {0}; + + Aws::Crt::ByteCursor dataCur = aws_byte_cursor_from_array(data, sizeof(data)); + + ASSERT_UINT_EQUALS(0x8A9136AA, Aws::Crt::Checksum::ComputeCRC32C(dataCur)); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(CRC32CPiping, s_TestCRC32CPiping) + +static int s_TestCRC64NVMEPiping(struct aws_allocator *allocator, void *) +{ + Aws::Crt::ApiHandle apiHandle(allocator); + uint8_t data[32] = {0}; + + Aws::Crt::ByteCursor dataCur = aws_byte_cursor_from_array(data, sizeof(data)); + + ASSERT_UINT_EQUALS(0xCF3473434D4ECF3B, Aws::Crt::Checksum::ComputeCRC64NVME(dataCur)); + + return AWS_OP_SUCCESS; +} +AWS_TEST_CASE(CRC64NVMEPiping, s_TestCRC64NVMEPiping)