diff --git a/.vscode/launch.json b/.vscode/launch.json index 03bb844..8e066e9 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -36,10 +36,10 @@ "justMyCode": true }, { - "name": "Python: Test Client", + "name": "Python: PyTest Current File", "type": "python", "request": "launch", - "program": "${workspaceFolder}/examples/test.py", + "program": "pytest ${file}", "console": "integratedTerminal", "justMyCode": false, "subProcess": true diff --git a/CMakeLists.txt b/CMakeLists.txt index e38476b..2412144 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,212 +1,296 @@ cmake_minimum_required(VERSION 3.20 FATAL_ERROR) project( - ucall - VERSION 0.5.5 - LANGUAGES C CXX - DESCRIPTION "Up to 100x Faster FastAPI. JSON-RPC with io_uring, SIMD-acceleration, and pure CPython bindings" - HOMEPAGE_URL "https://github.com/unum-cloud/ucall") + ucall + VERSION 0.5.5 + LANGUAGES C CXX + DESCRIPTION + "Up to 100x Faster FastAPI. JSON-RPC with io_uring, SIMD-acceleration, and pure CPython bindings" + HOMEPAGE_URL "https://github.com/unum-cloud/ucall") set(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS NO) -option(UCALL_BUILD_BENCHMARKS "Builds all available backend for the summation server to run benchmarks" OFF) -option(UCALL_BUILD_EXAMPLES "Builds examples for Redis-like server and PyTorch deployment") -message("CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") +# Detect software capabilities before setting options +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + execute_process( + COMMAND uname -r + OUTPUT_VARIABLE UNAME_RESULT + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "Linux Kernel version: ${UNAME_RESULT}") + string(REGEX MATCH "([0-9]+)\\.([0-9]+)" _ ${UNAME_RESULT}) + set(LINUX_MAJOR_VERSION ${CMAKE_MATCH_1}) + set(LINUX_MINOR_VERSION ${CMAKE_MATCH_2}) + + # Combine major and minor version numbers into one for comparison + set(LINUX_VERSION "${LINUX_MAJOR_VERSION}.${LINUX_MINOR_VERSION}") + message(STATUS "Parsed Linux Kernel version: ${LINUX_VERSION}") + + # Check if the Linux kernel version is 5.19 or newer + if(${LINUX_VERSION} VERSION_GREATER_EQUAL "5.19") + set(SUPPORTS_IO_URING ON) + else() + set(SUPPORTS_IO_URING OFF) + endif() +endif() + +# Set the default values for options based on whether io_uring is supported +option(UCALL_BUILD_LIB_POSIX "Builds the C library for the `posix` backend" ON) +option(UCALL_BUILD_PYTHON_POSIX + "Builds CPython bindings for the `posix` backend" ON) + +# Options depending on SUPPORTS_IO_URING +option(UCALL_BUILD_LIB_URING "Builds the C library for the `uring` backend" + ${SUPPORTS_IO_URING}) +option(UCALL_BUILD_PYTHON_URING + "Builds CPython bindings for the `uring` backend" ${SUPPORTS_IO_URING}) + +option(UCALL_BUILD_BENCHMARKS + "Builds all available backend for the summation server to run benchmarks" + OFF) +option(UCALL_BUILD_EXAMPLES + "Builds examples for Redis-like server and PyTorch deployment" OFF) +option(UCALL_BUILD_TESTS "Builds unit tests for the C library" OFF) +option(UCALL_BUILD_ALL "Builds all supported target" OFF) + +# Enforce options based on SUPPORTS_IO_URING after its value is known +if(SUPPORTS_IO_URING) + set(UCALL_BUILD_LIB_URING + ON + CACHE BOOL "Force enable UCALL_BUILD_LIB_URING" FORCE) + set(UCALL_BUILD_PYTHON_URING + ON + CACHE BOOL "Force enable UCALL_BUILD_PYTHON_URING" FORCE) +endif() + +if(UCALL_BUILD_PYTHON_URING) + set(UCALL_BUILD_LIB_URING ON) +endif() + +if(UCALL_BUILD_ALL) + set(UCALL_BUILD_BENCHMARKS ON) + set(UCALL_BUILD_EXAMPLES ON) + set(UCALL_BUILD_TESTS ON) +endif() + +message(STATUS "Supports io_uring: ${SUPPORTS_IO_URING}") +message(STATUS "Building ucall_server_posix: ${UCALL_BUILD_LIB_POSIX}") +message(STATUS "Building ucall_server_uring: ${UCALL_BUILD_LIB_URING}") +message(STATUS "Building py_ucall_posix: ${UCALL_BUILD_PYTHON_POSIX}") +message(STATUS "Building py_ucall_uring: ${UCALL_BUILD_PYTHON_URING}") +message(STATUS "Building benchmarks: ${UCALL_BUILD_BENCHMARKS}") +message(STATUS "Building examples: ${UCALL_BUILD_EXAMPLES}") # Make Release by default if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) + set(CMAKE_BUILD_TYPE Release) endif() set(CMAKE_CACHEFILE_DIR "${CMAKE_SOURCE_DIR}/build") -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/build/lib" CACHE PATH "Path to static libs") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/build/lib" CACHE PATH "Path to shared libs") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/build/lib" + CACHE PATH "Path to static libs") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/build/lib" + CACHE PATH "Path to shared libs") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/build/bin") +message(STATUS "Library output directory: ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") +message(STATUS "Archive output directory: ${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}") +message(STATUS "Runtime output directory: ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") +message(STATUS "Running on OS: ${CMAKE_SYSTEM_NAME}") + if(MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DEBUG") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2") - set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /DEBUG") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /DEBUG") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO + "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /O2 /DEBUG") else() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=1") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fmax-errors=1") endif() # Check if we are running on Linux if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(LINUX TRUE) + set(LINUX TRUE) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set(CMAKE_OSX_DEPLOYMENT_TARGET "11") - set(CMAKE_OSX_SYSROOT CACHE STRING "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk") - set(CMAKE_OSX_DEPLOYMENT_TARGET "11" CACHE STRING "Minimum OS X deployment version") - set(CMAKE_OSX_ARCHITECTURES "x86_64" "universal2" "arm64" CACHE STRING "Minimum OS X deployment version") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++17") -endif() - -# Pull the version of Linux kernel, to check if io_uring is available -if(LINUX) - execute_process(COMMAND uname -r OUTPUT_VARIABLE UNAME_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE) - message(-- " Linux Kernel version: " ${UNAME_RESULT}) - string(REGEX MATCH "[0-9]+.[0-9]+" LINUX_KERNEL_VERSION ${UNAME_RESULT}) + set(CMAKE_OSX_DEPLOYMENT_TARGET "11") + set(CMAKE_OSX_SYSROOT + CACHE STRING "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk") + set(CMAKE_OSX_DEPLOYMENT_TARGET + "11" + CACHE STRING "Minimum OS X deployment version") + set(CMAKE_OSX_ARCHITECTURES + "x86_64" "universal2" "arm64" + CACHE STRING "Minimum OS X deployment version") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++ -std=c++17") endif() include(FetchContent) include(ExternalProject) +find_package(Threads REQUIRED) FetchContent_Declare( - simdjson - GIT_REPOSITORY https://github.com/simdjson/simdjson.git - GIT_TAG v3.1.6 - GIT_SHALLOW 1 -) + simdjson + GIT_REPOSITORY https://github.com/simdjson/simdjson.git + GIT_TAG v3.1.6 + GIT_SHALLOW 1) FetchContent_MakeAvailable(simdjson) include_directories(${simdjson_SOURCE_DIR}/include) -if(${UCALL_BUILD_BENCHMARKS}) - set(BENCHMARK_ENABLE_TESTING OFF) - set(BENCHMARK_ENABLE_INSTALL OFF) - set(BENCHMARK_ENABLE_DOXYGEN OFF) - set(BENCHMARK_INSTALL_DOCS OFF) - set(BENCHMARK_DOWNLOAD_DEPENDENCIES ON) - set(BENCHMARK_ENABLE_GTEST_TESTS OFF) - set(BENCHMARK_USE_BUNDLED_GTEST ON) - FetchContent_Declare( - benchmark - GIT_REPOSITORY https://github.com/google/benchmark - GIT_TAG v1.7.0 - GIT_SHALLOW 1 - ) - FetchContent_MakeAvailable(benchmark) - include_directories(${benchmark_SOURCE_DIR}/include) -endif() - -# CLI +# Parsing HTTP headers On MacOS you may need to locate headers here: export +# CPATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ FetchContent_Declare( - cxxopts - GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git - GIT_TAG v3.1.1 - GIT_SHALLOW 1 -) + cxxopts + GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git + GIT_TAG v3.1.1 + GIT_SHALLOW 1) FetchContent_MakeAvailable(cxxopts) include_directories(${cxxopts_SOURCE_DIR}/include) -# Parsing HTTP headers -# On MacOS you may need to locate headers here: -# export CPATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ +# Parsing HTTP headers On MacOS you may need to locate headers here: export +# CPATH=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/ FetchContent_Declare( - picohttpparser - GIT_REPOSITORY https://github.com/unum-cloud/picohttpparser.git - GIT_SHALLOW 1 -) + picohttpparser + # GIT_REPOSITORY https://github.com/unum-cloud/picohttpparser.git + GIT_REPOSITORY https://github.com/MarkReedZ/picohttpparser.git + GIT_SHALLOW 1) FetchContent_MakeAvailable(picohttpparser) include_directories(${picohttpparser_SOURCE_DIR}) # Base64 decoding FetchContent_Declare( - tb64 - GIT_REPOSITORY https://github.com/unum-cloud/Turbo-Base64.git - GIT_SHALLOW 1 -) + tb64 + GIT_REPOSITORY https://github.com/unum-cloud/Turbo-Base64.git + GIT_SHALLOW 1) FetchContent_MakeAvailable(tb64) include_directories(${tb64_SOURCE_DIR}) set(CMAKE_POSITION_INDEPENDENT_CODE ON) -FetchContent_Declare( - mbedtls - GIT_REPOSITORY https://github.com/Mbed-TLS/mbedtls/ - GIT_TAG v3.4.0 - CMAKE_ARGS - -DENABLE_PROGRAMS=OFF - -DENABLE_TESTING=OFF - -DUSE_SHARED_MBEDTLS_LIBRARY=OFF - -DUSE_STATIC_MBEDTLS_LIBRARY=ON -) - -FetchContent_MakeAvailable(mbedtls) -include_directories(${mbedtls_SOURCE_DIR}/include) -set(mbedtls_LIBS mbedtls mbedcrypto mbedx509) - # LibUring -if(LINUX) - set(URING_DIR ${CMAKE_BINARY_DIR}/_deps/liburing-ep) - ExternalProject_Add( - liburing-ep - GIT_REPOSITORY https://github.com/axboe/liburing.git - GIT_TAG liburing-2.3 - GIT_SHALLOW 1 - PREFIX ${CMAKE_BINARY_DIR}/_deps/ - SOURCE_DIR ${URING_DIR} - CONFIGURE_COMMAND echo Configuring LibUring && cd ${URING_DIR} && ./configure --nolibc --cc=${CMAKE_C_COMPILER} --cxx=${CMAKE_CXX_COMPILER}; - BUILD_COMMAND cd ${URING_DIR} && make; - INSTALL_COMMAND "" - UPDATE_COMMAND "" - ) - add_library(uring_internal STATIC IMPORTED GLOBAL) - add_dependencies(uring_internal liburing-ep) - set_property(TARGET uring_internal - PROPERTY IMPORTED_LOCATION - ${URING_DIR}/src/liburing.a - ) - - include_directories(${URING_DIR}/src/include/) - set(URING_LIBS uring_internal) +if(UCALL_BUILD_LIB_URING) + set(URING_DIR ${CMAKE_BINARY_DIR}/_deps/liburing-ep) + ExternalProject_Add( + liburing-ep + GIT_REPOSITORY https://github.com/axboe/liburing.git + GIT_TAG liburing-2.3 + GIT_SHALLOW 1 + PREFIX ${CMAKE_BINARY_DIR}/_deps/ + SOURCE_DIR ${URING_DIR} + CONFIGURE_COMMAND + echo Configuring LibUring && cd ${URING_DIR} && ./configure --nolibc + --cc=${CMAKE_C_COMPILER} --cxx=${CMAKE_CXX_COMPILER}; + BUILD_COMMAND cd ${URING_DIR} && make; + INSTALL_COMMAND "" + UPDATE_COMMAND "") + add_library(uring_internal STATIC IMPORTED GLOBAL) + add_dependencies(uring_internal liburing-ep) + set_property(TARGET uring_internal PROPERTY IMPORTED_LOCATION + ${URING_DIR}/src/liburing.a) + + include_directories(${URING_DIR}/src/include/) + set(URING_LIBS uring_internal) endif() -find_package(Threads REQUIRED) -include_directories(include/ src/) +if(UCALL_BUILD_BENCHMARKS) + set(BENCHMARK_ENABLE_TESTING OFF) + set(BENCHMARK_ENABLE_INSTALL OFF) + set(BENCHMARK_ENABLE_DOXYGEN OFF) + set(BENCHMARK_INSTALL_DOCS OFF) + set(BENCHMARK_DOWNLOAD_DEPENDENCIES ON) + set(BENCHMARK_ENABLE_GTEST_TESTS OFF) + set(BENCHMARK_USE_BUNDLED_GTEST ON) + FetchContent_Declare( + benchmark + GIT_REPOSITORY https://github.com/google/benchmark + GIT_TAG v1.7.0 + GIT_SHALLOW 1) + FetchContent_MakeAvailable(benchmark) + include_directories(${benchmark_SOURCE_DIR}/include) +endif() -add_library(ucall_server_posix src/engine_posix.cpp) -target_link_libraries(ucall_server_posix simdjson::simdjson Threads::Threads ${mbedtls_LIBS}) -set(PYTHON_BACKEND ucall_server_posix) +if(UCALL_BUILD_EXAMPLES) + # CLI + FetchContent_Declare( + cxxopts + GIT_REPOSITORY https://github.com/jarro2783/cxxopts.git + GIT_TAG v3.1.1 + GIT_SHALLOW 1) + FetchContent_MakeAvailable(cxxopts) + include_directories(${cxxopts_SOURCE_DIR}/include) +endif() -add_executable(ucall_example_login_posix examples/login/ucall_server.cpp) -target_link_libraries(ucall_example_login_posix ucall_server_posix cxxopts) -target_compile_options(ucall_example_login_posix PUBLIC -DCXXOPTS_NO_EXCEPTIONS=ON) +include_directories(include/ src/) -if(LINUX) - add_library(ucall_server_uring src/engine_uring.cpp) - set(PYTHON_BACKEND ucall_server_uring) - target_link_libraries(ucall_server_uring simdjson::simdjson Threads::Threads ${URING_LIBS}) - add_executable(ucall_example_login_uring examples/login/ucall_server.cpp) - target_link_libraries(ucall_example_login_uring ucall_server_uring cxxopts) - target_compile_options(ucall_example_login_uring PUBLIC -DCXXOPTS_NO_EXCEPTIONS=ON) +if(UCALL_BUILD_LIB_POSIX) + add_library(ucall_server_posix src/engine_posix.cpp) + target_link_libraries(ucall_server_posix simdjson::simdjson Threads::Threads) + set(PYTHON_BACKEND ucall_server_posix) endif() -if(UCALL_BUILD_EXAMPLES) - add_executable(ucall_example_redis examples/redis/ucall_server.cpp) - target_link_libraries(ucall_example_redis ucall_server_posix) - - find_package(Torch) - add_executable(ucall_example_pytorcs examples/pytorch/ucall_server.cpp) - target_link_libraries(ucall_example_pytorcs ucall_server_posix "${TORCH_LIBRARIES}") +if(UCALL_BUILD_LIB_URING) + add_library(ucall_server_uring src/engine_uring.cpp) + set(PYTHON_BACKEND ucall_server_uring) + target_link_libraries(ucall_server_uring simdjson::simdjson Threads::Threads + ${URING_LIBS}) endif() # Python bindings find_package(Python3 REQUIRED Development.Module) include_directories(${Python_INCLUDE_DIRS}) -if(LINUX) - Python3_add_library(py_ucall_uring src/python.c) - target_include_directories(py_ucall_uring PUBLIC src/ include/) - target_link_libraries(py_ucall_uring PRIVATE ucall_server_uring base64) - set_target_properties(py_ucall_uring PROPERTIES OUTPUT_NAME uring) - target_compile_definitions(py_ucall_uring PRIVATE UCALL_PYTHON_MODULE_NAME=uring) +if(UCALL_BUILD_PYTHON_POSIX) + python3_add_library(py_ucall_posix python/lib.c) + target_include_directories(py_ucall_posix PUBLIC src/ include/) + target_link_libraries(py_ucall_posix PRIVATE ucall_server_posix base64) + + # set_target_properties(py_ucall_posix PROPERTIES OUTPUT_NAME posix) + target_compile_definitions(py_ucall_posix + PRIVATE UCALL_PYTHON_MODULE_NAME=posix) + message( + STATUS + "Building ucall_server_posix with output in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + ) +endif() + +if(UCALL_BUILD_PYTHON_URING) + python3_add_library(py_ucall_uring python/lib.c) + target_include_directories(py_ucall_uring PUBLIC src/ include/) + target_link_libraries(py_ucall_uring PRIVATE ucall_server_uring base64) + + # set_target_properties(py_ucall_uring PROPERTIES OUTPUT_NAME uring) + target_compile_definitions(py_ucall_uring + PRIVATE UCALL_PYTHON_MODULE_NAME=uring) + message( + STATUS + "Building py_ucall_uring with output in ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}" + ) +endif() + +if(UCALL_BUILD_EXAMPLES) + add_executable(ucall_example_server_posix examples/ucall_server.cpp) + target_link_libraries(ucall_example_server_posix ucall_server_posix cxxopts + fmt::fmt) + target_compile_options(ucall_example_server_posix + PUBLIC -DCXXOPTS_NO_EXCEPTIONS=ON) endif() -Python3_add_library(py_ucall_posix src/python.c) -target_include_directories(py_ucall_posix PUBLIC src/ include/) -target_link_libraries(py_ucall_posix PRIVATE ucall_server_posix base64) -set_target_properties(py_ucall_posix PROPERTIES OUTPUT_NAME posix) -target_compile_definitions(py_ucall_posix PRIVATE UCALL_PYTHON_MODULE_NAME=posix) +if(UCALL_BUILD_EXAMPLES AND UCALL_BUILD_LIB_URING) + add_executable(ucall_example_server_uring examples/ucall_server.cpp) + target_link_libraries(ucall_example_server_uring ucall_server_uring cxxopts + fmt::fmt) + target_compile_options(ucall_example_server_uring + PUBLIC -DCXXOPTS_NO_EXCEPTIONS=ON) +endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..881440d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,30 @@ +# Contributing to UCall Development + +## Setup the Environment + +Ideally, for development, you'd need a Linux machine with a recent kernel version. +Docker also works, but may cause additional overhead. + +```bash +# Install the required packages +sudo apt-get install -y build-essential cmake +``` + +## Build the Project + + + +```bash +git clone https://github.com/unum-cloud/ucall.git + +cmake -DUCALL_BUILD_ALL=1 -B build_debug +cmake --build ./build_debug --config Debug # Which will produce the following targets: +./build_debug/stringzilla_test_cpp20 # Unit test for the entire library compiled for current hardware +./build_debug/stringzilla_test_cpp20_x86_serial # x86 variant compiled for IvyBridge - last arch. before AVX2 +./build_debug/stringzilla_test_cpp20_arm_serial # Arm variant compiled without Neon +``` + +## Test and Debug in C + +## Test and Debug in Python + diff --git a/README.md b/README.md index a929013..30785cd 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ server.run() It takes over a millisecond to handle a trivial FastAPI call on a recent 8-core CPU. -In that time, light could have traveled 300 km through optics to the neighboring city or country, in my case. +In that time, light could have traveled 300 km through optics to the neighboring city or country. How does UCall compare to FastAPI and gRPC? | Setup | 🔁 | Server | Latency w 1 client | Throughput w 32 clients | @@ -96,8 +96,8 @@ How does UCall compare to FastAPI and gRPC?
Table legend -All benchmarks were conducted on AWS on general purpose instances with **Ubuntu 22.10 AMI**. -It is the first major AMI to come with **Linux Kernel 5.19**, featuring much wider `io_uring` support for networking operations. +All benchmarks were conducted on AWS on general purpose instances with __Ubuntu 22.10 AMI__. +It is the first major AMI to come with __Linux Kernel 5.19__, featuring much wider `io_uring` support for networking operations. These specific numbers were obtained on `c7g.metal` beefy instances with Graviton 3 chips. - The 🔁 column marks, if the TCP/IP connection is being reused during subsequent requests. @@ -114,19 +114,10 @@ These specific numbers were obtained on `c7g.metal` beefy instances with Gravito ## How is that possible?! How can a tiny pet-project with just a couple thousand lines of code compete with two of the most established networking libraries? -**UCall stands on the shoulders of Giants**: +__UCall stands on the shoulders of Giants__: -- `io_uring` for interrupt-less IO. - - `io_uring_prep_read_fixed` on 5.1+. - - `io_uring_prep_accept_direct` on 5.19+. - - `io_uring_register_files_sparse` on 5.19+. - - `IORING_SETUP_COOP_TASKRUN` optional on 5.19+. - - `IORING_SETUP_SINGLE_ISSUER` optional on 6.0+. - -- SIMD-accelerated parsers with manual memory control. - - [`simdjson`][simdjson] to parse JSON faster than gRPC can unpack `ProtoBuf`. - - [`Turbo-Base64`][base64] to decode binary values from a `Base64` form. - - [`picohttpparser`][picohttpparser] to navigate HTTP headers. +- UCall uses `io_uring` for interrupt-less IO. It mainly relies on `io_uring_prep_read_fixed` (5.1+), `io_uring_prep_accept_direct` (5.19+), `io_uring_register_files_sparse` (5.19+), `IORING_SETUP_COOP_TASKRUN` optional (5.19+), `IORING_SETUP_SINGLE_ISSUER` optional (6.0+). +- SIMD-accelerated parsers with manual memory control. [`simdjson`][simdjson] to parse JSON faster than gRPC can unpack `ProtoBuf`. [`turbo-base64`][base64] to decode binary values from a `Base64` form. [`stringzilla`][stringzilla] to navigate HTTP headers. You have already seen the latency of the round trip..., the throughput in requests per second..., want to see the bandwidth? Try yourself! @@ -144,7 +135,7 @@ This comes handy when you build real applications or want to deploy Multi-Modal ```python from ucall.rich_posix import Server -import ufrom +import uform server = Server() model = uform.get_model('unum-cloud/uform-vl-multilingual') @@ -307,12 +298,14 @@ int main(int argc, char** argv) { - [x] JSON-RPC over TCP with HTTP - [x] Concurrent sessions - [x] NumPy `array` and Pillow serialization -- [ ] HTTP**S** support - [ ] Batch-capable endpoints for ML -- [ ] Zero-ETL relay calls -- [ ] Integrating with [UKV][ukv] -- [ ] WebSockets for web interfaces -- [ ] AF_XDP and UDP-based analogs on Linux +- [ ] HTTP __S__ support + +Possible long-term goals: + +- [ ] Zero-ETL relay calls? +- [ ] WebSockets for web interfaces? +- [ ] AF_XDP and UDP-based analogs on Linux? > Want to affect the roadmap and request a feature? Join the discussions on Discord. @@ -322,8 +315,10 @@ int main(int argc, char** argv) { - Application layer is optional: use HTTP or not. - Unlike REST APIs, there is just one way to pass arguments. +## What is JSON-RPC and How It Compares to REST and gRPC? + [simdjson]: https://github.com/simdjson/simdjson [base64]: https://github.com/powturbo/Turbo-Base64 -[picohttpparser]: https://github.com/h2o/picohttpparser +[stringzilla]: https://github.com/ashvardanian/stringzilla [sum-examples]: https://github.com/unum-cloud/ucall/tree/dev/examples/sum [ukv]: https://github.com/unum-cloud/ukv diff --git a/examples/login/original.jpg b/assets/original.jpg similarity index 100% rename from examples/login/original.jpg rename to assets/original.jpg diff --git a/examples/login/README.md b/examples/README.md similarity index 52% rename from examples/login/README.md rename to examples/README.md index 40f40e9..f4dea22 100644 --- a/examples/login/README.md +++ b/examples/README.md @@ -1,17 +1,62 @@ -# Summation Examples and Benchmarks +# UCall Example & Benchmark + +This folder implements a group of different servers with identical functionality, but using different RPC frameworks, including: + +- FastAPI server in Python, compatible with WSGI: `fastapi_server.py` +- UCall server in Python: `ucall_server.py` +- UCall server in C++: `ucall_server.cpp` +- gRPC server in Python: `grpc_server.py` + +All of them implement identical endpoints: + +- `echo` - return back the payload it received for throughput benchmarks +- `validate_session` - lightweight operation on two integers, returning a boolean, to benchmark the request latency on tiny tasks +- `create_user` - more complex operation on flat dictionary input with strings and integers +- `validate_user_identity` - that validates arguments, raises exceptions, and returns complex nested objects +- `set` & `get` - key-value store operations, similar to Redis +- `resize` - batch-capable image processing operation for Base64-encoded images +- `dot_product` - batch-capable matrix vector-vector multiplication operation -The simplest possible endpoint after `hello-world` and `echo`, is probably `sum`. -We would just accept two numbers and return their aggregate. -Packets are tiny, so it is great for benchmarking the request latency. ## Reproducing Benchmarks +```sh +cd examples +``` + +### Debugging FastAPI + +To start the server: + +```sh +uvicorn fastapi_server:app --port 8000 --reload +``` + +To run the client tests using HTTPX: + +```sh +pytest fastapi_client.py -s -x +pytest fastapi_client.py -s -x -k set_get # for a single test +``` + +To run HTTPX stress tests and benchmarks: + +```sh + +``` + ### FastAPI ```sh pip install uvicorn fastapi websocket-client requests tqdm fire -cd examples && uvicorn sum.fastapi_server:app --log-level critical & -cd .. + +# To start the server in the background +uvicorn fastapi_server:app --log-level critical --port 8000 & + +# To check if it works as expected +pytest fastapi_client.py + + python examples/bench.py "fastapi_client.ClientREST" --progress python examples/bench.py "fastapi_client.ClientWebSocket" --progress kill %% @@ -27,13 +72,14 @@ python examples/bench.py "fastapi_client.ClientWebSocket" --threads 8 ### UCall UCall can produce both a POSIX compliant old-school server, and a modern `io_uring`-based version for Linux kernel 5.19 and newer. -You would either run `ucall_example_sum_posix` or `ucall_example_sum_uring`. +You would either run `ucall_example_server_posix` or `ucall_example_server_uring`. ```sh sudo apt-get install cmake g++ build-essential -cmake -DCMAKE_BUILD_TYPE=Release -B ./build_release && make -C ./build_release -./build_release/build/bin/ucall_example_sum_posix & -./build_release/build/bin/ucall_example_sum_uring & +cmake -DCMAKE_BUILD_TYPE=Release -B build_release +cmake --build build_release --config Release +build_release/build/bin/ucall_example_server_posix & +build_release/build/bin/ucall_example_server_uring & python examples/bench.py "jsonrpc_client.CaseTCP" --progress python examples/bench.py "jsonrpc_client.CaseHTTP" --progress python examples/bench.py "jsonrpc_client.CaseHTTPBatches" --progress @@ -43,7 +89,7 @@ kill %% Want to customize server settings? ```sh -./build_release/build/bin/ucall_example_sum_uring --nic=127.0.0.1 --port=8545 --threads=16 --silent=false +build_release/build/bin/ucall_example_server_uring --nic=127.0.0.1 --port=8545 --threads=16 --silent=false ``` Want to dispatch more clients and aggregate more accurate statistics? diff --git a/examples/bench.go b/examples/bench.go new file mode 100644 index 0000000..6bfe4f0 --- /dev/null +++ b/examples/bench.go @@ -0,0 +1,120 @@ +package main + +import ( + "errors" + "fmt" + "io" + "math/rand" + "net" + "os" + "time" + "bytes" + "flag" + "strconv" +) + +var( + limitSeconds int + numConnections int + hostname string + port int + batch int + html bool + req string + buffer bytes.Buffer +) + +func load_buffer() { + for i := 0; i < batch; i++ { + a := rand.Intn(1000) + b := rand.Intn(1000) + jRPC := fmt.Sprintf(`{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":%d,"session_id":%d},"id":0}`, a, b) + buffer.WriteString(fmt.Sprintf("POST / HTTP/1.1\r\nHost: localhost:8545\r\nUser-Agent: python-requests/2.31.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: %d\r\nContent-Type: application/json\r\n\r\n%s", len(jRPC), jRPC)) + } + fmt.Printf("%s\n",buffer.String()) +} + +func client(c chan int, tcpAddr *net.TCPAddr, tid int ) { + reply := make([]byte, 4096) + transmits := 0 + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("Dial failed:", err.Error()) + os.Exit(1) + } + + start := time.Now() + for { + _, err = conn.Write(buffer.Bytes()) + if err != nil { + fmt.Printf("Write Error: %v\n", err) + break + } + + _, err := conn.Read(reply) + //fmt.Printf("Reply\n%s",reply[:l]) + if err != nil && !errors.Is(err, io.EOF) { + break + } + if time.Since(start).Seconds() >= float64(limitSeconds) { + break + } + transmits++ + } + conn.Close() + c <- transmits +} + +func formatInt(number int64) string { + output := strconv.FormatInt(number, 10) + startOffset := 3 + if number < 0 { + startOffset++ + } + for outputIndex := len(output); outputIndex > startOffset; { + outputIndex -= 3 + output = output[:outputIndex] + "," + output[outputIndex:] + } + return output +} + + +func main() { + + flag.StringVar(&hostname, "h", "localhost", "hostname") + flag.IntVar(&port, "p", 8545, "port") + flag.IntVar(&numConnections, "c", 16, "Number of connections") + flag.IntVar(&limitSeconds, "s", 2, "Stop after n seconds") + flag.IntVar(&batch, "b", 1, "Batch n requests together") + flag.BoolVar(&html, "html", false, "Send an html request instead of jsonrpc") + flag.Parse() + + load_buffer(); + + servAddr := fmt.Sprintf(`%s:%d`,hostname,port) + tcpAddr, err := net.ResolveTCPAddr("tcp", servAddr) + if err != nil { + println("ResolveTCPAddr failed:", err.Error()) + os.Exit(1) + } + + fmt.Printf("Benchmarking jsonrpc for %d seconds with %d connections and a batch size of %d \n", limitSeconds, numConnections, batch); + + start := time.Now() + c := make(chan int) + for i := 0; i < numConnections; i++ { + go client( c, tcpAddr, i ) + } + + // Wait for all connections to finish + transmits := 0 + for i := 0; i < numConnections; i++ { + transmits += <-c + } + + elapsed := time.Since(start) + latency := float64(elapsed.Microseconds()) / float64(transmits) + speed := int64((float64(transmits) / float64(elapsed.Seconds())) * float64(batch)) + fmt.Printf(" %s commands/second, mean latency %.1fu\n", formatInt(speed), latency) + +} diff --git a/examples/bench.py b/examples/bench.py index 6a6897e..037cb39 100644 --- a/examples/bench.py +++ b/examples/bench.py @@ -18,27 +18,27 @@ class Stats: requests_failure: int = 0 mean_latency_secs: float = 0 total_secs: float = 0 - last_failure: str = '' + last_failure: str = "" @property def success_rate(self) -> float: return (self.requests_correct * 1.0 / self.requests) if self.requests else 1.0 def __repr__(self) -> str: - bandwidth = self.requests / \ - self.total_secs if self.total_secs > 0 else 0.0 - result = f''' + bandwidth = self.requests / self.total_secs if self.total_secs > 0 else 0.0 + result = f""" - Took: {self.total_secs:.1f} CPU seconds - Total exchanges: {self.requests:,} - Success rate: {self.success_rate:.3%} - Mean latency: {self.mean_latency_secs * 1e6:.1f} microseconds - Mean bandwidth: {bandwidth:.1f} requests/s - ''' + """ return I(result) def bench_serial( - callable, *, + callable, + *, requests_count: int = 100_000, seconds: float = 10, progress: bool = False, @@ -90,19 +90,21 @@ def bench_parallel( callable=callable, seconds=seconds, requests_count=requests_count, - progress=progress) + progress=progress, + ) - requests_correct = Value('i', 0) - requests_incorrect = Value('i', 0) - requests = Value('i', 0) - mean_latency_secs = Value('f', 0) + requests_correct = Value("i", 0) + requests_incorrect = Value("i", 0) + requests = Value("i", 0) + mean_latency_secs = Value("f", 0) def run(): stats = bench_serial( callable=callable, seconds=seconds, requests_count=requests_count, - progress=False) + progress=False, + ) requests_correct.value += stats.requests_correct requests_incorrect.value += stats.requests_incorrect requests.value += stats.requests @@ -129,9 +131,19 @@ def run(): ) -def main(class_name: str, *, threads: int = 1, requests: int = 100_000, seconds: float = 10, progress: bool = False): +def main( + class_name: str, + *, + threads: int = 1, + requests: int = 100_000, + seconds: float = 10, + progress: bool = False, +): script_dir = os.path.dirname(os.path.abspath(__file__)) - sys.path.append(f'{script_dir}/login') + project_dir = os.path.dirname(script_dir) + sys.path.append(f"{script_dir}/login") + sys.path.append(os.path.join(project_dir, "python")) + class_ = locate(class_name) stats = bench_parallel( callable=class_(), @@ -143,5 +155,5 @@ def main(class_name: str, *, threads: int = 1, requests: int = 100_000, seconds: print(stats) -if __name__ == '__main__': +if __name__ == "__main__": fire.Fire(main) diff --git a/examples/fastapi_client.py b/examples/fastapi_client.py new file mode 100644 index 0000000..0b9d000 --- /dev/null +++ b/examples/fastapi_client.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python3 +import base64 +import io +import pytest +import httpx +from PIL import Image +import numpy as np + +# Setup base URL +BASE_URL = "http://localhost:8000" + + +def echo(client, data: str) -> bool: + response = client.post("/echo", json={"data": data}) + assert response.status_code == 200 + return response.json() == {"data": data} + + +def test_echo(): + with httpx.Client(base_url=BASE_URL) as client: + data = "Hello, World!" + assert echo(client, data) + + +def validate_session(client, user_id: int, session_id: int) -> bool: + response = client.post( + "/validate_session", + json={"user_id": user_id, "session_id": session_id}, + ) + assert response.status_code == 200 + return response.json() == True + + +def test_validate_session(): + with httpx.Client(base_url=BASE_URL) as client: + user_id = 111 + session_id = 111 + assert validate_session(client, user_id, session_id) + + +def create_user(client, name: str, age: int, bio: str, avatar: str) -> bool: + data = {"name": name, "age": age, "bio": bio, "avatar": avatar} + response = client.post("/create_user", json=data) + assert response.status_code == 200 + return "avatar_size" in response.json() + + +def test_create_user(): + with httpx.Client(base_url=BASE_URL) as client: + name = "Jane Doe" + age = 25 + bio = "Lorem ipsum" + avatar = create_avatar_base64_string() + assert create_user(client, name, age, bio, avatar) + + +def validate_user_identity( + client, name: str, age: float, user_id: int, access_token: str +) -> bool: + data = {"name": name, "age": age, "user_id": user_id, "access_token": access_token} + response = client.post("/validate_user_identity", json=data) + assert response.status_code == 200 + return True + + +def test_validate_user_identity(): + with httpx.Client(base_url=BASE_URL) as client: + name = "John Doe" + age = 25.0 + user_id = 123 + access_token = base64.b64encode(f"{name} Token".encode()).decode() + assert validate_user_identity(client, name, age, user_id, access_token) + + +def set_get(client, key: str, value: str) -> bool: + set_response = client.post("/set", json={"key": key, "value": value}) + assert set_response.status_code == 200 + assert set_response.json() == True + + get_response = client.post("/get", json={"key": key}) + assert get_response.status_code == 200 + return get_response.json() == value + + +def test_set_get(): + with httpx.Client(base_url=BASE_URL) as client: + key = "testkey" + value = "testvalue" + assert set_get(client, key, value) + + +def resize(client, image: str, width: int, height: int) -> bool: + response = client.post( + "/resize", json={"image": image, "width": width, "height": height} + ) + assert response.status_code == 200 + + image_bytes = base64.b64decode(response.json()) + pil_image = Image.open(io.BytesIO(image_bytes)) + return pil_image.size == (width, height) + + +def test_resize(): + with httpx.Client(base_url=BASE_URL) as client: + width, height = 100, 100 + image = create_avatar_base64_string() + assert resize(client, image, width, height) + + +def dot_product(client, a: np.ndarray, b: np.ndarray) -> bool: + a_base64 = base64.b64encode(a.tobytes()).decode() + b_base64 = base64.b64encode(b.tobytes()).decode() + response = client.post("/dot_product", json={"a": a_base64, "b": b_base64}) + assert response.status_code == 200 + expected_dot_product = float(np.dot(a, b)) + return abs(response.json() - expected_dot_product) < 1e-6 + + +def test_dot_product(): + with httpx.Client(base_url=BASE_URL) as client: + a = np.random.rand(10).astype(np.float32) + b = np.random.rand(10).astype(np.float32) + assert dot_product(client, a, b) + + +def create_avatar_base64_string() -> str: + image = Image.new("RGB", (10, 10), color="red") + buf = io.BytesIO() + image.save(buf, format="PNG") + byte_im = buf.getvalue() + return base64.b64encode(byte_im).decode() + + +if __name__ == "__main__": + pytest.main() diff --git a/examples/fastapi_server.py b/examples/fastapi_server.py new file mode 100644 index 0000000..3594140 --- /dev/null +++ b/examples/fastapi_server.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python +import io +import base64 +import random +from typing import List +import logging + +import numpy as np +from PIL import Image +from fastapi import FastAPI, HTTPException, Body +from pydantic import BaseModel + +app = FastAPI() + + +class EchoItem(BaseModel): + data: str + + +@app.post("/echo") +async def echo(item: EchoItem = Body(...)): + return {"data": item.data} + + +class ValidateSessionItem(BaseModel): + user_id: int + session_id: int + + +@app.post("/validate_session") +async def validate_session(item: ValidateSessionItem = Body(...)): + return (item.user_id ^ item.session_id) % 23 == 0 + + +class CreateUserItem(BaseModel): + name: str + age: int + bio: str + avatar: str # in reality - a binary string + + +@app.post("/create_user") +async def create_user(item: CreateUserItem = Body(...)) -> str: + avatar_bytes = base64.b64decode(item.avatar) + return f"Created {item.name} aged {item.age} with bio {item.bio} and avatar_size {len(avatar_bytes)}" + + +class ValidateUserIdentityItem(BaseModel): + user_id: int + name: str + age: float + access_token: str + + +@app.post("/validate_user_identity") +async def validate_user_identity(item: ValidateUserIdentityItem = Body(...)): + if item.age < 18: + raise HTTPException( + status_code=400, detail=f"{item.name} must be older than 18" + ) + + access_token_bytes = base64.b64decode(item.access_token) + if not access_token_bytes.decode().startswith(item.name): + raise HTTPException( + status_code=400, detail=f"Invalid access token for {item.name}" + ) + + suggested_session_ids = [ + random.random() * item.age * item.user_id for _ in range(round(item.age)) + ] + return { + "session_ids": suggested_session_ids, + "user": { + "name": item.name, + "age": item.age, + "user_id": item.user_id, + "access_token": access_token_bytes, + "repeated_sesson_ids": suggested_session_ids, + }, + } + + +redis = {} + + +class SetItem(BaseModel): + key: str + value: str + + +@app.post("/set") +async def set(item: SetItem = Body(...)) -> bool: + redis[item.key] = item.value + return True + + +class GetItem(BaseModel): + key: str + + +@app.post("/get") +async def get(item: GetItem = Body(...)) -> str: + return redis.get(item.key, None) + + +class ResizeItem(BaseModel): + image: bytes + width: int + height: int + + +@app.post("/resize") +async def resize(item: ResizeItem = Body(...)) -> bytes: + image_bytes = base64.b64decode(item.image) + pil_image = Image.open(io.BytesIO(image_bytes)) + resized_image = pil_image.resize((item.width, item.height)) + buf = io.BytesIO() + resized_image.save(buf, format="PNG") + image_base64 = base64.b64encode(buf.getvalue()).decode() + return image_base64 + + +class DotProductItem(BaseModel): + a: bytes + b: bytes + + +@app.post("/dot_product") +async def dot_product(item: DotProductItem = Body(...)) -> float: + a_array = np.frombuffer(base64.b64decode(item.a), dtype=np.float32) + b_array = np.frombuffer(base64.b64decode(item.b), dtype=np.float32) + return float(np.dot(a_array, b_array)) + + +# Setup basic logging +logging.basicConfig(level=logging.INFO) + + +@app.get("/") +async def root(): + logging.info("Handling request to the root endpoint") + return {"message": "Hello World"} diff --git a/examples/login/certs/cas.pem b/examples/login/certs/cas.pem deleted file mode 100644 index 2513619..0000000 --- a/examples/login/certs/cas.pem +++ /dev/null @@ -1,21 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDazCCAlOgAwIBAgIUNkTMNg4Wf5upbGx85ZeulBYCUuQwDQYJKoZIhvcNAQEL -BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM -GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMzA0MDMxMzQ1MjVaFw0yMzA1 -MDMxMzQ1MjVaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw -HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB -AQUAA4IBDwAwggEKAoIBAQC4gSfAQUeshU4hD85Np/hj1WYeJVhUqvi1NcM4/qpK -WETQN73MrGk+3kUqqy8UhyPkw31dpE68hAGzfhjzpvh/hejRIbcSaw8jz3P70Tl1 -4zRfz8rLSgpXieI1HekSadT4Hat1YmYxoMVFN025qwQjglxJCUp8bicxOBtNHwbo -aTLzdTxnVWqkK2DBCNnnRAfttTxIPuSya8ZeCUv1sjlFD9ObTipJ+kjvuDScLFu4 -dErz1WMEJuXLMduEXZ76t7uqv/Y7jdkSAsArnsOj95iLJqohsrvAeyd0K/UkGp7C -ZccPyqD6qjGgsCnWQsQ99pq4HrzgTkbkR1sL8MvHyZfpAgMBAAGjUzBRMB0GA1Ud -DgQWBBQeFV7OnGedbdUSzJ7vtLu6z8KZZDAfBgNVHSMEGDAWgBQeFV7OnGedbdUS -zJ7vtLu6z8KZZDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCi -sgPyakz5NKjRv4KBChvlUGOenZBcsZSBSDtTPkkqW+H23XJpwKQYhnZoniYLriKu -7PGbaNMY5EdClLlTCz1OWZ4JSqyo3hhgGDFmCM5mLDR2JR2rBNh14GodLR2R83c3 -to7C2jINVGIrkahOyCLSui2CBn50Xk/y/1FWU79o8WbSpBAH0EBk1zUSZxL7TAC1 -m42VHx5+BTG8RkWcC/SoY4FLwV7yqPIJtPDvU2AaaywXzixn1/hkzJ0Myn3y9JJu -KZnFg64LcRz5IJcn8+7dvG9lgBwBKbiANqQuQRy5pNpDSlEcRf1VWOVK+amUaV+y -tlXGCB1p86PprDGXwL5d ------END CERTIFICATE----- diff --git a/examples/login/certs/gen.sh b/examples/login/certs/gen.sh deleted file mode 100644 index 977562b..0000000 --- a/examples/login/certs/gen.sh +++ /dev/null @@ -1,4 +0,0 @@ -openssl genpkey -algorithm RSA -out main.key -pkeyopt rsa_keygen_bits:2048 && -openssl req -new -key main.key -out srv.csr && -openssl x509 -req -days 365 -in srv.csr -signkey main.key -out srv.crt && -openssl req -new -x509 -key main.key -out cas.pem \ No newline at end of file diff --git a/examples/login/certs/main.key b/examples/login/certs/main.key deleted file mode 100644 index 5a91862..0000000 --- a/examples/login/certs/main.key +++ /dev/null @@ -1,28 +0,0 @@ ------BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4gSfAQUeshU4h -D85Np/hj1WYeJVhUqvi1NcM4/qpKWETQN73MrGk+3kUqqy8UhyPkw31dpE68hAGz -fhjzpvh/hejRIbcSaw8jz3P70Tl14zRfz8rLSgpXieI1HekSadT4Hat1YmYxoMVF -N025qwQjglxJCUp8bicxOBtNHwboaTLzdTxnVWqkK2DBCNnnRAfttTxIPuSya8Ze -CUv1sjlFD9ObTipJ+kjvuDScLFu4dErz1WMEJuXLMduEXZ76t7uqv/Y7jdkSAsAr -nsOj95iLJqohsrvAeyd0K/UkGp7CZccPyqD6qjGgsCnWQsQ99pq4HrzgTkbkR1sL -8MvHyZfpAgMBAAECggEAFyMnM35cOR/McOv1AJsIVKitsikXvyJjpwHTdgHFpCYW -lw/ubszOM/KWtOebs1TRJP546bXRo+Vf+zzcby2oqwFFdXhnZ1lioCiDUHhn3sc7 -yaoascyaqGijo+qY0FTSPr0lw8Yvr5iMNIZfamGuVq+h2AzguOLtakgxcEXsTVex -ZrwzPHyIzpM0F4arzCQfHkwBOkPrQzjpcVmLq4ZSq3/ht3wrTBF+9cbriEnw+WNb -CHjlc2teB96Dp/yVrHSCoQOEot65lET5orbD0v7p0Viky6gqFx9M+h7mVNWM2vEp -yJziwoFMFHjjRNFjdTnOcI4HdDgj3Cf/LbNGxOWWKwKBgQDWH+34LyXhRH2r5PZm -/ixZI12Fp5VQheJce0ClEPWHyx+P4md/K+TFSWZPxA2PlkfFi4aHcDMZP+VEXBex -m22Fa/mtouXBmmbsOBzS8iGBXWgPSFRr3MEXMCMr99jTl0VdDTcaDdxbYZBObpve -Do6UBZ4eL8Pe4wedZKjp5PdKOwKBgQDclk0okZdVEh3apvBYkGnEvNHtOUoDF41l -RIPPvliK21cwwaxRLqlw66VxLjuyGRll38x4K7+MNq5OCNIMDZBrbomNsFWYMQ3S -T1qs5+NtoBQ6zn+iUSxM3nnf54+hMfKeITTOYn/qGIgTK9MvTfCgQHNRol1kpai8 -Bwzu8p5gKwKBgAf+szT0Fbb+hq63Ytffn6pIXsKRykpyZUxMsdI3+uLyG6CUtIaU -DfurzO0nhdYZp15h4kkGUHId56KQybWw9vrnWDA6h9edu0AQrErYDZY19Z+0dKp+ -WJtUCcwneeoUmNtrleYcJGEpGGlFSf6Vjo9KUmgQIoEc+vjOfFwXV4BnAoGBAKXm -/P0IEvNOftmWOKnDY2kuQgzSy5Frw1Jop2I1XM6CjR8Eap9cIt/kuzdWeFtIeUuf -eF7hOF0yOwJBrAiYowfJyPahqp6eNjD4sc/dT7WBcfWQnXns5w6hPLRjqiioMjsv -6lFWz7G25ZDVoy2uxs0f7Bt3rBooZbGU8+s62lalAoGBAM0a527Oe2+SB5nf3cJa -pKbpLiGyiiJYwq5Kz0iRQcZCvJgiZ74V3xhIuXtBYrHQJRuiLhtCE1Y4ldUFTDuJ -ZHwoPNr/RoP7Paz7KAIoWBVBp+1aOupPkmcdUY61QfqtnI8mJ5O5VSVo5hgdNJEb -8wQdB1kfdX8/uVqsVCD+P2yg ------END PRIVATE KEY----- diff --git a/examples/login/certs/srv.crt b/examples/login/certs/srv.crt deleted file mode 100644 index b668fd0..0000000 --- a/examples/login/certs/srv.crt +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDSzCCAjMCFG9cZkrKAoKUF+KcdWYgNW9JRj80MA0GCSqGSIb3DQEBCwUAMGIx -CzAJBgNVBAYTAkFVMQwwCgYDVQQIDANhc2QxDDAKBgNVBAcMA2FzZDELMAkGA1UE -CgwCYXMxCjAIBgNVBAsMAWQxDDAKBgNVBAMMA2FzZDEQMA4GCSqGSIb3DQEJARYB -YTAeFw0yMzA0MDMxMzQ1MTdaFw0yNDA0MDIxMzQ1MTdaMGIxCzAJBgNVBAYTAkFV -MQwwCgYDVQQIDANhc2QxDDAKBgNVBAcMA2FzZDELMAkGA1UECgwCYXMxCjAIBgNV -BAsMAWQxDDAKBgNVBAMMA2FzZDEQMA4GCSqGSIb3DQEJARYBYTCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBALiBJ8BBR6yFTiEPzk2n+GPVZh4lWFSq+LU1 -wzj+qkpYRNA3vcysaT7eRSqrLxSHI+TDfV2kTryEAbN+GPOm+H+F6NEhtxJrDyPP -c/vROXXjNF/PystKCleJ4jUd6RJp1Pgdq3ViZjGgxUU3TbmrBCOCXEkJSnxuJzE4 -G00fBuhpMvN1PGdVaqQrYMEI2edEB+21PEg+5LJrxl4JS/WyOUUP05tOKkn6SO+4 -NJwsW7h0SvPVYwQm5csx24Rdnvq3u6q/9juN2RICwCuew6P3mIsmqiGyu8B7J3Qr -9SQansJlxw/KoPqqMaCwKdZCxD32mrgevOBORuRHWwvwy8fJl+kCAwEAATANBgkq -hkiG9w0BAQsFAAOCAQEABUPMGhDCjfWEXJFlBbmv+DNrrac3s5SSnIQ8bFgtiW8w -soDk7/42HiL8zBKvx0Ym7Gw9aYSyuCSm5FYj4H5H3DTO+FOB+s4N8hfhX84wJK68 -xEN/dbuXXY0iGIm24cpokW37xjCNuw7UTj9vFzf+uq3ghRWxTxG5e3+5ayVZ2/V7 -cub3EdMKSpgalhv740Jy5wPb+X9DllJE9eO9vQb6cGsADAfpBNfrIsG2onrzeW1f -F4omD3roWJmQ3yyk2OPPJf7WTXGAbZeEClNZw+UeaISPwsf/1JdjzDDs85sDEq01 -uvICmE5ks4WJCXvDupmGAPpOgQMXRLJPQSgHO+4h/w== ------END CERTIFICATE----- diff --git a/examples/login/certs/srv.csr b/examples/login/certs/srv.csr deleted file mode 100644 index a1ada8c..0000000 --- a/examples/login/certs/srv.csr +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE REQUEST----- -MIICvDCCAaQCAQAwYjELMAkGA1UEBhMCQVUxDDAKBgNVBAgMA2FzZDEMMAoGA1UE -BwwDYXNkMQswCQYDVQQKDAJhczEKMAgGA1UECwwBZDEMMAoGA1UEAwwDYXNkMRAw -DgYJKoZIhvcNAQkBFgFhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -uIEnwEFHrIVOIQ/OTaf4Y9VmHiVYVKr4tTXDOP6qSlhE0De9zKxpPt5FKqsvFIcj -5MN9XaROvIQBs34Y86b4f4Xo0SG3EmsPI89z+9E5deM0X8/Ky0oKV4niNR3pEmnU -+B2rdWJmMaDFRTdNuasEI4JcSQlKfG4nMTgbTR8G6Gky83U8Z1VqpCtgwQjZ50QH -7bU8SD7ksmvGXglL9bI5RQ/Tm04qSfpI77g0nCxbuHRK89VjBCblyzHbhF2e+re7 -qr/2O43ZEgLAK57Do/eYiyaqIbK7wHsndCv1JBqewmXHD8qg+qoxoLAp1kLEPfaa -uB684E5G5EdbC/DLx8mX6QIDAQABoBUwEwYJKoZIhvcNAQkHMQYMBDAwOTkwDQYJ -KoZIhvcNAQELBQADggEBAJjTginMRIdd1njaHxgOZ9TD8yxcM/Z5jjaghiyz7b2c -ls0Y8ORW5BDdGWFOoKw9Mnf4VpXk60EbBh9Rpmz7yxKwA+LRtQ2uhfy6XplriIHG -J1bV/uNDbiz34JRquoRtqY8lRAxYq7alPDSngG7dZsURMpiRTuTc+wGRdLgGHh0i -PGxxZziJiJDAF9IMs5fYDmwUAQ8W4zj0nsS+plLgWh0HKYymha7I9KFgIkoVRDsF -gyFf4VhitmLgJ4vxzxW2Qss57ma0QSzxpZfn6Hk9f+vI+m+YA0LIAgol4REm0pPA -SXLiTMV6AHhAnI2ExecAJdINrK3NkwA2wWRoxpEPuPI= ------END CERTIFICATE REQUEST----- diff --git a/examples/login/fastapi_client.py b/examples/login/fastapi_client.py deleted file mode 100644 index 2b2f46c..0000000 --- a/examples/login/fastapi_client.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python3 -import os -import struct -import random -import string -import base64 -from typing import Optional - -# Dependencies -import requests -from websocket import create_connection - -# The ID of the current running proccess, used as a default -# identifier for requests originating from here. -PROCESS_ID = os.getpid() - - -class ClientREST: - - def __init__(self, uri: str = '127.0.0.1', port: int = 8000, identity: int = PROCESS_ID) -> None: - self.identity = identity - self.url = f'http://{uri}:{port}/' - - def __call__(self, *, a: Optional[int] = None, b: Optional[int] = None) -> int: - a = random.randint(1, 1000) if a is None else a - b = random.randint(1, 1000) if b is None else b - result = requests.get( - f'{self.url}validate_session?user_id={a}&session_id={b}').text - c = int(result) - assert ((a ^ b) % 23 == 0) == c, 'Wrong Answer' - return c - - -class ClientRESTReddit: - - def __init__(self, uri: str = '127.0.0.1', port: int = 8000, identity: int = PROCESS_ID) -> None: - self.identity = identity - self.url = f'http://{uri}:{port}/' - self.bin_len = 1500 - self.avatar = base64.b64encode(random.randbytes(self.bin_len)).decode() - self.bio = ''.join(random.choices( - string.ascii_uppercase, k=self.bin_len)) - self.name = 'John' - - def __call__(self) -> int: - age = random.randint(1, 1000) - result = requests.get( - f'{self.url}create_user?age={age}&bio={self.bio}&name={self.name}&text={self.bio}').text - return result - - -class ClientWebSocket: - - def __init__(self, uri: str = '127.0.0.1', port: int = 8000, identity: int = PROCESS_ID) -> None: - self.identity = identity - self.sock = create_connection(f'ws://{uri}:{port}/validate_session_ws') - - def __call__(self, *, a: Optional[int] = None, b: Optional[int] = None) -> int: - a = random.randint(1, 1000) if a is None else a - b = random.randint(1, 1000) if b is None else b - self.sock.send_binary(struct.pack(' // `std::to_chars` -#include // `std::fprintf` -#include -#include - -#include - -#include "ucall/ucall.h" - -static void validate_session(ucall_call_t call, ucall_callback_tag_t) { - int64_t a{}, b{}; - char c_str[256]{}; - bool got_a = ucall_param_named_i64(call, "user_id", 0, &a); - bool got_b = ucall_param_named_i64(call, "session_id", 0, &b); - if (!got_a || !got_b) - return ucall_call_reply_error_invalid_params(call); - - const char* res = ((a ^ b) % 23 == 0) ? "true" : "false"; - ucall_call_reply_content(call, res, strlen(res)); -} - -int main(int argc, char** argv) { - - cxxopts::Options options("Summation Server", "If device can't sum integers, just send them over with JSON-RPC :)"); - options.add_options() // - ("h,help", "Print usage") // - ("nic", "Networking Interface Internal IP to use", cxxopts::value()->default_value("127.0.0.1")) // - ("p,port", "On which port to server JSON-RPC", cxxopts::value()->default_value("8545")) // - ("j,threads", "How many threads to run", cxxopts::value()->default_value("1")) // - ("s,silent", "Silence statistics output", cxxopts::value()->default_value("false")) // - ; - auto result = options.parse(argc, argv); - if (result.count("help")) { - std::cout << options.help() << std::endl; - exit(0); - } - - ucall_server_t server{}; - ucall_config_t config{}; - config.hostname = result["nic"].as().c_str(); - config.port = result["port"].as(); - config.max_threads = result["threads"].as(); - config.max_concurrent_connections = 1024; - config.queue_depth = 4096 * config.max_threads; - config.max_lifetime_exchanges = UINT32_MAX; - config.logs_file_descriptor = result["silent"].as() ? -1 : fileno(stdin); - config.logs_format = "human"; - // config.use_ssl = true; - // config.ssl_private_key_path = "./examples/login/certs/main.key"; - // const char* crts[] = {"./examples/login/certs/srv.crt", "./examples/login/certs/cas.pem"}; - // config.ssl_certificates_paths = crts; - // config.ssl_certificates_count = 2; - - ucall_init(&config, &server); - if (!server) { - std::printf("Failed to start server: %s:%i\n", config.hostname, config.port); - return -1; - } - - std::printf("Initialized server: %s:%i\n", config.hostname, config.port); - std::printf("- %zu threads\n", static_cast(config.max_threads)); - std::printf("- %zu max concurrent connections\n", static_cast(config.max_concurrent_connections)); - if (result["silent"].as()) - std::printf("- silent\n"); - - // Add all the callbacks we need - ucall_add_procedure(server, "validate_session", &validate_session, nullptr); - - if (config.max_threads > 1) { - std::vector threads; - for (uint16_t i = 0; i != config.max_threads; ++i) - threads.emplace_back(&ucall_take_calls, server, i); - for (auto& thread : threads) - thread.join(); - } else - ucall_take_calls(server, 0); - - ucall_free(server); - return 0; -} \ No newline at end of file diff --git a/examples/login/ucall_server.py b/examples/login/ucall_server.py deleted file mode 100644 index 6e0d115..0000000 --- a/examples/login/ucall_server.py +++ /dev/null @@ -1,52 +0,0 @@ -import random - -from ucall.posix import Server - -server = Server( - port=8545, - # ssl_pk='./examples/login/certs/main.key', - # ssl_certs=[ - # './examples/login/certs/srv.crt', - # './examples/login/certs/cas.pem'] -) - - -@server -def validate_session(user_id: int, session_id: int): - return (user_id ^ session_id) % 23 == 0 - - -@server -def echo(data: bytes): - return data - - -@server -def create_user(age: int, name: str, avatar: bytes, bio: str): - return f'Created {name} aged {age} with bio {bio} and avatar_size {len(avatar)}' - - -@server -def transform(age: float, name: str, value: int, identity: bytes): - - if age < 15: - return False - - if age >= 15 and age < 19: - return (False, f'{name} must be older than 19') - - new_identity = identity.decode() + f'_{name}' - - return { - 'name': name, - 'pins': [random.random()*age for _ in range(round(age))], - 'val': { - 'len': value, - 'identity': new_identity.encode(), - 'data': [random.randbytes(value) for _ in range(value)], - } - } - - -if __name__ == '__main__': - server.run() diff --git a/examples/login/ucall_server_rich.py b/examples/login/ucall_server_rich.py deleted file mode 100644 index fdef46c..0000000 --- a/examples/login/ucall_server_rich.py +++ /dev/null @@ -1,34 +0,0 @@ -import numpy as np -from PIL import Image -from ucall.rich_posix import Server - -server = Server(port=8545, - ssl_pk='./examples/login/certs/main.key', - ssl_certs=['./examples/login/certs/srv.crt', - './examples/login/certs/cas.pem'] - ) - - -@server -def validate_session(user_id: int, session_id: int) -> bool: - return (user_id ^ session_id) % 23 == 0 - - -@server -def create_user(age: int, name: str, avatar: bytes, bio: str) -> str: - return f'Created {name} aged {age} with bio {bio} and avatar_size {len(avatar)}' - - -@server -def rotate_avatar(image: Image.Image) -> Image.Image: - rotated = image.rotate(45) - return rotated - - -@server -def validate_all_sessions(user_ids: np.ndarray, session_ids: np.ndarray) -> bool: - return np.mod(np.logical_xor(user_ids, session_ids), 23) - - -if __name__ == '__main__': - server.run() diff --git a/examples/login/ucx_client.py b/examples/login/ucx_client.py deleted file mode 100644 index 8b7bc60..0000000 --- a/examples/login/ucx_client.py +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env python3 -import random -import asyncio - -import ucp -import numpy as np - -from benchmark import benchmark_request_async - -triplet = np.empty(3, dtype='u4') -host = ucp.get_address() -port = 13337 -port_reuse = 13338 - - -async def request_validate_reuse(endpoint: ucp.Endpoint): - triplet[0] = random.randint(1, 1000) - triplet[1] = random.randint(1, 1000) - await endpoint.send(triplet[:2]) - await endpoint.recv(triplet[2:]) - assert triplet[0] + triplet[1] == triplet[2], 'Wrong Answer' - - -async def request_validate(): - endpoint = await ucp.create_endpoint(host, port) - triplet[0] = random.randint(1, 1000) - triplet[1] = random.randint(1, 1000) - await endpoint.send(triplet[:2]) - await endpoint.recv(triplet[2:]) - assert triplet[0] + triplet[1] == triplet[2], 'Wrong Answer' - await endpoint.close() - - -async def bench_reusing(): - endpoint = await ucp.create_endpoint(host, port_reuse) - await benchmark_request_async(request_validate_reuse, endpoint) - await endpoint.close() - - -async def bench_creating(): - await benchmark_request_async(request_validate) - - -if __name__ == '__main__': - loop = asyncio.new_event_loop() - print("Creating") - loop.run_until_complete(bench_creating()) - print("Reuseing") - loop.run_until_complete(bench_reusing()) - loop.close() diff --git a/examples/login/ucx_server.py b/examples/login/ucx_server.py deleted file mode 100644 index 68935a2..0000000 --- a/examples/login/ucx_server.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 -import asyncio - -import ucp -import numpy as np - -triplet = np.empty(3, dtype='u4') -port = 13337 -port_reuse = 13338 -listener = None -listener_reuse = None - - -async def respond_reusers(endpoint: ucp.Endpoint): - while True: - await endpoint.recv(triplet[:2]) - triplet[2] = ((triplet[0] ^ triplet[1]) % 23 == 0) - await endpoint.send(triplet[2:]) - - -async def respond(endpoint: ucp.Endpoint): - await endpoint.recv(triplet[:2]) - triplet[2] = ((triplet[0] ^ triplet[1]) % 23 == 0) - await endpoint.send(triplet[2:]) - - -async def main(): - global listener, listener_reuse - listener = ucp.create_listener(respond, port) - listener_reuse = ucp.create_listener(respond_reusers, port_reuse) - while not listener.closed() and not listener_reuse.closed(): - await asyncio.sleep(0.001) - - -if __name__ == '__main__': - try: - asyncio.run(main()) - except KeyboardInterrupt: - listener.close() - listener_reuse.close() diff --git a/examples/lua/json-echo.lua b/examples/lua/json-echo.lua new file mode 100755 index 0000000..b02a48a --- /dev/null +++ b/examples/lua/json-echo.lua @@ -0,0 +1,18 @@ +-- example script demonstrating HTTP pipelining + +init = function(args) + + depth = tonumber(args[1]) or 1 + wrk.headers["Content-Type"] = "application/json" + + local r = {} + for i=1,depth do + r[i] = wrk.format('POST','/', nil, '{"jsonrpc":"2.0","method":"echo","params":{"data":"echomesomedata"},"id":0}') + end + req = table.concat(r) + +end + +request = function() + return req +end diff --git a/examples/lua/json.lua b/examples/lua/json.lua new file mode 100755 index 0000000..055a070 --- /dev/null +++ b/examples/lua/json.lua @@ -0,0 +1,18 @@ +-- example script demonstrating HTTP pipelining + +init = function(args) + + depth = tonumber(args[1]) or 1 + wrk.headers["Content-Type"] = "application/json" + + local r = {} + for i=1,depth do + r[i] = wrk.format('POST','/json', nil, '{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":55,"session_id":21},"id":0}') + end + req = table.concat(r) + +end + +request = function() + return req +end diff --git a/examples/pytorch/ucall_server.cpp b/examples/pytorch/ucall_server.cpp deleted file mode 100644 index a1b3544..0000000 --- a/examples/pytorch/ucall_server.cpp +++ /dev/null @@ -1,55 +0,0 @@ -/** - * @brief Example of building a Redis-like in-memory store with UCall. - * - * @see Reading materials on using the C++ PyTorch Frontend. - * https://pytorch.org/tutorials/advanced/cpp_frontend.html - * https://pytorch.org/cppdocs/installing.html - */ -#include // `std::printf` -#include -#include - -#include - -#include "ucall/ucall.h" - -static std::unordered_map store; - -static void summarize(ucall_call_t call) { - char const* text_ptr{}; - size_t text_len{}; - bool text_found = ucall_param_named_str(call, "text", 3, &text_ptr, &text_len); - if (!text_found) - return ucall_call_reply_error_invalid_params(call); - - return ucall_call_reply_content(call, "OK", 2); -} - -static void continue_(ucall_call_t call) { - char const* text_ptr{}; - size_t text_len{}; - bool text_found = ucall_param_named_str(call, "text", 4, &text_ptr, &text_len); - if (!text_found) - return ucall_call_reply_error_invalid_params(call); - - return ucall_call_reply_content(call, "", 0); -} - -int main(int argc, char** argv) { - ucall_server_t server{}; - ucall_config_t config{}; - config.port = 6379; - ucall_init(&config, &server); - if (!server) { - std::printf("Failed to initialize server!\n"); - return -1; - } - - std::printf("Initialized server!\n"); - ucall_add_procedure(server, "summarize", &summarize); - ucall_add_procedure(server, "continue", &continue_); - - ucall_take_calls(server, 0); - ucall_free(server); - return 0; -} \ No newline at end of file diff --git a/examples/redis/ucall_server.cpp b/examples/redis/ucall_server.cpp deleted file mode 100644 index 8bfbfe1..0000000 --- a/examples/redis/ucall_server.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/** - * @brief Example of building a Redis-like in-memory store with UCall. - */ -#include // `std::printf` -#include -#include - -#include "ucall/ucall.h" - -static std::unordered_map store; - -static void set(ucall_call_t call) { - char const* key_ptr{}; - char const* value_ptr{}; - size_t key_len{}; - size_t value_len{}; - bool key_found = ucall_param_named_str(call, "key", 3, &key_ptr, &key_len); - bool value_found = ucall_param_named_str(call, "value", 5, &value_ptr, &value_len); - if (!key_found || !value_found) - return ucall_call_reply_error_invalid_params(call); - - store.insert_or_assign(std::string_view{key_ptr, key_len}, std::string_view{value_ptr, value_len}); - return ucall_call_reply_content(call, "OK", 2); -} - -static void get(ucall_call_t call) { - char const* key_ptr{}; - size_t key_len{}; - bool key_found = ucall_param_named_str(call, "key", 4, &key_ptr, &key_len); - if (!key_found) - return ucall_call_reply_error_invalid_params(call); - - auto iterator = store.find(std::string_view{key_ptr, key_len}); - if (iterator == store.end()) - return ucall_call_reply_content(call, "", 0); - else - return ucall_call_reply_content(call, iterator.second.c_str(), iterator.second.size()); -} - -int main(int argc, char** argv) { - ucall_server_t server{}; - ucall_config_t config{}; - config.port = 6379; - ucall_init(&config, &server); - if (!server) { - std::printf("Failed to initialize server!\n"); - return -1; - } - - std::printf("Initialized server!\n"); - ucall_add_procedure(server, "set", &set); - ucall_add_procedure(server, "get", &get); - - ucall_take_calls(server, 0); - ucall_free(server); - return 0; -} \ No newline at end of file diff --git a/examples/test.go b/examples/test.go new file mode 100644 index 0000000..ff2ef2e --- /dev/null +++ b/examples/test.go @@ -0,0 +1,284 @@ +package main + +import ( + "errors" + "fmt" + "io" + "net" + "os" + "time" + "bytes" + "flag" + "strings" +) + +var( + limitSeconds int + numConnections int + hostname string + port int + batch int + html bool + req string + buffer bytes.Buffer +) + +func load_buffer() { + a := 46 + b := 23 + jRPC := fmt.Sprintf(`{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":%d,"session_id":%d},"id":0}`, a, b) + buffer.WriteString(fmt.Sprintf("POST / HTTP/1.1\r\nHost: localhost:8545\r\nUser-Agent: python-requests/2.31.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: %d\r\nContent-Type: application/json\r\n\r\n%s", len(jRPC), jRPC)) + //fmt.Printf("%s\n",buffer.String()) +} + + +func test_http(tcpAddr *net.TCPAddr ) { + print(" Test http ... ") + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("connection failed:", err.Error()) + return + } + reply := make([]byte, 4096) + + jrpc := fmt.Sprintf(`{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":46,"session_id":0},"id":0}`) + req := fmt.Sprintf("POST / HTTP/1.1\r\nHost: localhost:8558\r\nUser-Agent: python-requests/2.31.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: %d\r\nContent-Type: application/json\r\n\r\n%s", len(jrpc), jrpc) + + _, err = conn.Write([]byte(req)) + if err != nil { + println("write error: %v\n", err) + return + } + n, err := conn.Read(reply) + if err != nil && !errors.Is(err, io.EOF) { + println("read error: %v\n", err) + return + } + rep := fmt.Sprintf("HTTP/1.1 200 OK\r\nContent-Length: 38 \r\nContent-Type: application/json\r\n\r\n{\"jsonrpc\":\"2.0\",\"id\":0,\"result\":true}") + + if rep != string(reply[:n]) { + println("unexpected reply") + println(" exp: ", rep) + println(" act: ", string(reply[:n])) + return + } + + println("successful") +} +func test_big(tcpAddr *net.TCPAddr ) { + print(" Test 4097 byte json ... ") + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("connection failed:", err.Error()) + return + } + reply := make([]byte, 4096) + pad := bytes.Repeat([]byte("a"), 3992) + req = fmt.Sprintf(`{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":46,"session_id":0},"id":0, "padding":"%s"}`,pad) + _, err = conn.Write([]byte(req)) + if err != nil { + println("write error: %v\n", err) + return + } + n, err := conn.Read(reply) + if err != nil && !errors.Is(err, io.EOF) { + println("read error: %v\n", err) + return + } + rep := `{"jsonrpc":"2.0","id":0,"result":true}` + if strings.Compare( rep, string(reply[:n]) ) != 0 { + println("unexpected reply") + println(" exp: ", rep) + println(" act: ", string(reply[:n])) + return + } + + println("successful") +} +func test_partial(tcpAddr *net.TCPAddr ) { + print(" Test partial ... ") + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("connection failed:", err.Error()) + return + } + reply := make([]byte, 4096) + + req = fmt.Sprintf(`{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":46,"session_id"`) + _, err = conn.Write([]byte(req)) + if err != nil { + println("write error: %v\n", err) + return + } + time.Sleep(1000 * time.Millisecond) + req = fmt.Sprintf(`:0},"id":0}`) + _, err = conn.Write([]byte(req)) + if err != nil { + println("write second part error: %v\n", err) + return + } + n, err := conn.Read(reply) + if err != nil && !errors.Is(err, io.EOF) { + println("read error: %v\n", err) + return + } + rep := fmt.Sprintf(`{"jsonrpc":"2.0","id":0,"result":true}`) + if strings.Compare( rep, string(reply[:n]) ) != 0 { + println("unexpected reply") + println(" exp: ", rep) + println(" act: ", string(reply[:n])) + return + } + + println("successful") +} + +func test_close(tcpAddr *net.TCPAddr ) { + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("connection failed:", err.Error()) + return + } + _, err = conn.Write(buffer.Bytes()) + if err != nil { + fmt.Printf("Write Error: %v\n", err) + } + conn.Close() +} + + + +func client(c chan int, tcpAddr *net.TCPAddr, tid int ) { + reply := make([]byte, 4096) + + start := time.Now() + transmits := 0 + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("Dial failed:", err.Error()) + os.Exit(1) + } + + for { + _, err = conn.Write(buffer.Bytes()) + if err != nil { + fmt.Printf("Write Error: %v\n", err) + break + } + + //conn.SetReadDeadline(time.Now().Add(time.Second*5)) + _, err := conn.Read(reply) + //fmt.Printf("Reply\n%s",reply[:l]) + if err != nil && !errors.Is(err, io.EOF) { + break + } + if time.Since(start).Seconds() >= float64(limitSeconds) { + break + } + transmits++ + } + conn.Close() + c <- transmits +} + +func test_generic(name string, tcpAddr *net.TCPAddr, req []byte, rep []byte ) { + print(" Test ",name," ... ") + conn, err := net.DialTCP("tcp", nil, tcpAddr) + if err != nil { + println("connection failed:", err.Error()) + return + } + rbuf := make([]byte, 4096) + request := fmt.Sprintf("POST / HTTP/1.1\r\nHost: localhost:8558\r\nUser-Agent: python-requests/2.31.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nContent-Length: %d\r\nContent-Type: application/json\r\n\r\n%s", len(req), req) + + _, err = conn.Write([]byte(request)) + if err != nil { + println("write error: %v\n", err) + return + } + n, err := conn.Read(rbuf) + if err != nil && !errors.Is(err, io.EOF) { + println("read error: %v\n", err) + return + } + //reply := fmt.Sprintf("HTTP/1.1 200 OK\r\nContent-Length: %d\r\nContent-Type: application/json\r\n\r\n%s", len(rep), rep) + if string(rep) != string(rbuf[78:n]) { + println("unexpected reply") + println(" exp: ", string(rep)) + println(" act: ", string(rbuf[78:n])) + return + } + + println("successful") +} + + +func main() { + + flag.StringVar(&hostname, "h", "localhost", "hostname") + flag.IntVar(&port, "p", 8545, "port") + flag.IntVar(&numConnections, "c", 16, "Number of connections") + flag.IntVar(&limitSeconds, "s", 2, "Stop after n seconds") + flag.IntVar(&batch, "b", 1, "Batch n requests together") + flag.BoolVar(&html, "html", false, "Send an html request instead of jsonrpc") + flag.Parse() + + servAddr := fmt.Sprintf(`%s:%d`,hostname,port) + tcpAddr, err := net.ResolveTCPAddr("tcp", servAddr) + if err != nil { + println("ResolveTCPAddr failed:", err.Error()) + os.Exit(1) + } + + //test_rpc(tcpAddr) + //test_http(tcpAddr) + //test_big(tcpAddr) + //test_partial(tcpAddr) + + + req := fmt.Sprintf(`{"jsonrpc":"2.0","method":"validate_session","params":{"user_id":46,"session_id":0},"id":0}`) + rep := fmt.Sprintf(`{"jsonrpc":"2.0","id":0,"result":true}`) + test_generic("validate_session", tcpAddr, []byte(req), []byte(rep) ) + + req = fmt.Sprintf(`{"jsonrpc":"2.0","method":"echo","params":{"data":"session_id"},"id":0}`) + rep = fmt.Sprintf(`{"jsonrpc":"2.0","id":0,"result":"session_id"}`) + test_generic("echo", tcpAddr, []byte(req), []byte(rep) ) + + req = fmt.Sprintf(`{"jsonrpc":"2.0","method":"create_user","params":{"age":46,"name":"My Name","bio":"My bio","avatar":"fdasfsadbfasdfasdwefdsahfsds"},"id":0}`) + rep = fmt.Sprintf(`{"jsonrpc":"2.0","method":"create_user","params":{"age":46,"name":"My Name","bio":"My bio","avatar":"fdasfsadbfasdfasdwefdsahfsds"},"id":0}`) + test_generic("create_user", tcpAddr, []byte(req), []byte(rep) ) + + req = fmt.Sprintf(`{"jsonrpc":"2.0","method":"set","params":{"key":"test","value":"val"},"id":0}`) + rep = fmt.Sprintf(`{"jsonrpc":"2.0","id":0,"result":"OK"}`) + test_generic("set", tcpAddr, []byte(req), []byte(rep) ) + req = fmt.Sprintf(`{"jsonrpc":"2.0","method":"get","params":{"key":"test","value":"val"},"id":0}`) + rep = fmt.Sprintf(`{"jsonrpc":"2.0","id":0,"result":"val"}`) + test_generic("get", tcpAddr, []byte(req), []byte(rep) ) + + + print(" Test closing connections ... ") + n := 1 + for n < 2000 { + test_close(tcpAddr) + n += 1 + } + println("successful") + + test_http(tcpAddr) + + load_buffer() + + print(" Test many connections ... ") + num := 1024 + c := make(chan int) + for i := 0; i < num; i++ { + go client( c, tcpAddr, i ) + } + + // Wait for all connections to finish + transmits := 0 + for i := 0; i < num; i++ { + transmits += <-c + } + +} diff --git a/examples/test.py b/examples/test.py index 3724503..bda97e6 100644 --- a/examples/test.py +++ b/examples/test.py @@ -10,8 +10,8 @@ class ClientGeneric: """JSON-RPC Client that uses classic sync Python `requests` to pass JSON calls over HTTP""" - def __init__(self, uri: str = '127.0.0.1', port: int = 8545) -> None: - self.url = f'http://{uri}:{port}/' + def __init__(self, uri: str = "127.0.0.1", port: int = 8545) -> None: + self.url = f"http://{uri}:{port}/" def __call__(self, jsonrpc: object) -> object: return requests.post(self.url, json=jsonrpc).json() @@ -19,10 +19,7 @@ def __call__(self, jsonrpc: object) -> object: def shuffled_n_identities(class_, count_clients: int = 3, count_cycles: int = 1000): - clients = [ - class_(identity=identity) - for identity in range(count_clients) - ] + clients = [class_(identity=identity) for identity in range(count_clients)] for _ in range(count_cycles): random.shuffle(clients) @@ -96,60 +93,77 @@ def test_normal_positional_tls(): def test_notification(): client = ClientGeneric() - response = client({ - 'method': 'validate_session', - 'params': {'user_id': 2, 'session_id': 2}, - 'jsonrpc': '2.0', - }) + response = client( + { + "method": "validate_session", + "params": {"user_id": 2, "session_id": 2}, + "jsonrpc": "2.0", + } + ) assert len(response) == 0 def test_method_missing(): client = ClientGeneric() - response = client({ - 'method': 'sumsum', - 'params': {'a': 2, 'b': 2}, - 'jsonrpc': '2.0', - 'id': 0, - }) - assert response['error']['code'] == -32601 + response = client( + { + "method": "sumsum", + "params": {"a": 2, "b": 2}, + "jsonrpc": "2.0", + "id": 0, + } + ) + assert response["error"]["code"] == -32601 def test_param_missing(): client = ClientGeneric() - response = client({ - 'method': 'validate_session', - 'params': {'user_id': 2}, - 'jsonrpc': '2.0', - 'id': 0, - }) - assert response['error']['code'] == -32602 + response = client( + { + "method": "validate_session", + "params": {"user_id": 2}, + "jsonrpc": "2.0", + "id": 0, + } + ) + assert response["error"]["code"] == -32602 def test_param_type(): client = ClientGeneric() - response = client({ - 'method': 'validate_session', - 'params': {'user_id': 2.0, 'session_id': 3.5}, - 'jsonrpc': '2.0', - 'id': 0, - }) - assert response['error']['code'] == -32602 + response = client( + { + "method": "validate_session", + "params": {"user_id": 2.0, "session_id": 3.5}, + "jsonrpc": "2.0", + "id": 0, + } + ) + assert response["error"]["code"] == -32602 def test_non_uniform_batch(): a = 2 b = 2 - r_normal = {'method': 'validate_session', 'params': { - 'user_id': a, 'session_id': b}, 'jsonrpc': '2.0', 'id': 0} - r_notification = {'method': 'validate_session', 'params': { - 'user_id': a, 'session_id': b}, 'jsonrpc': '2.0'} + r_normal = { + "method": "validate_session", + "params": {"user_id": a, "session_id": b}, + "jsonrpc": "2.0", + "id": 0, + } + r_notification = { + "method": "validate_session", + "params": {"user_id": a, "session_id": b}, + "jsonrpc": "2.0", + } client = ClientGeneric() - response = client([ - r_normal, - r_notification, - ]) + response = client( + [ + r_normal, + r_notification, + ] + ) def test_numpy(): @@ -157,18 +171,20 @@ def test_numpy(): b = np.random.randint(0, 101, size=(1, 3, 10)) res = np.mod(np.logical_xor(a, b), 23) client = Client() - response = client({ - 'method': 'validate_all_sessions', - 'params': {'user_ids': a, 'session_ids': b}, - 'jsonrpc': '2.0', - 'id': 100, - }) + response = client( + { + "method": "validate_all_sessions", + "params": {"user_ids": a, "session_ids": b}, + "jsonrpc": "2.0", + "id": 100, + } + ) response.raise_for_status() assert np.array_equal(response.numpy, res) def test_pillow(): - img = Image.open('examples/login/original.jpg') + img = Image.open("examples/login/original.jpg") res = img.rotate(45) client = Client() response = client.rotate_avatar(image=img) @@ -183,18 +199,20 @@ def test_numpy_tls(): b = np.random.randint(0, 101, size=(1, 3, 10)) res = np.mod(np.logical_xor(a, b), 23) client = ClientTLS(allow_self_signed=True) - response = client({ - 'method': 'validate_all_sessions', - 'params': {'user_ids': a, 'session_ids': b}, - 'jsonrpc': '2.0', - 'id': 100, - }) + response = client( + { + "method": "validate_all_sessions", + "params": {"user_ids": a, "session_ids": b}, + "jsonrpc": "2.0", + "id": 100, + } + ) response.raise_for_status() assert np.array_equal(response.numpy, res) def test_pillow_tls(): - img = Image.open('examples/login/original.jpg') + img = Image.open("examples/login/original.jpg") res = img.rotate(45) client = ClientTLS(allow_self_signed=True) response = client.rotate_avatar(image=img) @@ -204,7 +222,7 @@ def test_pillow_tls(): assert np.array_equal(ar1, ar2) -if __name__ == '__main__': +if __name__ == "__main__": test_normal() test_normal_positional() # test_normal_tls() diff --git a/examples/ucall_server.cpp b/examples/ucall_server.cpp new file mode 100644 index 0000000..4160266 --- /dev/null +++ b/examples/ucall_server.cpp @@ -0,0 +1,410 @@ +/** + * @brief Example server application. + * @file ucall_server.cpp + * + * This module implements a pseudo-backend for benchmarking and demostration purposes for the + * UCall JSON-RPC implementation. It provides a simplified in-memory key-value store and image + * manipulation functions, alongside user management utilities. + */ +#include // `std::printf` +#include // `std::memcpy` +#include // `std::unique_lock` +#include // `std::bad_alloc` +#include // `std::shared_mutex` +#include // `std::string` +#include // `std::string_view` +#include // `std::thread` +#include // `std::unordered_set` + +#include // Parsing CLI arguments + +#include +#include + +/** + * Echoes back the received data. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param data A byte string received from the client. + */ +static void echo(ucall_call_t call, ucall_callback_tag_t) { + ucall_str_t data_ptr{}; + std::size_t data_len{}; + if (!ucall_param_named_str(call, "data", 4, &data_ptr, &data_len)) { + return ucall_call_reply_error_invalid_params(call); + } + ucall_call_reply_content(call, data_ptr, data_len); +} + +/** + * Validates if the session ID is valid for the given user ID based on a hashing scheme. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param user_id The user's unique identifier as an integer. + * @param session_id The session's unique identifier as an integer. + */ +static void validate_session(ucall_call_t call, ucall_callback_tag_t) { + int64_t user_id{}, session_id{}; + if (!ucall_param_named_i64(call, "user_id", 7, &user_id) || + !ucall_param_named_i64(call, "session_id", 10, &session_id)) { + return ucall_call_reply_error_invalid_params(call); + } + char const* res = ((user_id ^ session_id) % 23 == 0) ? "true" : "false"; + ucall_call_reply_content(call, res, strlen(res)); +} + +/** + * Registers a new user with the given details and returns a summary. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param age The user's age as an integer. + * @param name The user's full name as a string. + * @param avatar Binary data representing the user's avatar. + * @param bio The user's biography as a string. + */ +static void create_user(ucall_call_t call, ucall_callback_tag_t) { + ucall_str_t name_ptr{}, bio_ptr{}, avatar_ptr{}; + std::size_t name_len{}, bio_len{}, avatar_len{}; + int64_t age{}; + if (!ucall_param_named_i64(call, "age", 3, &age) || // + !ucall_param_named_str(call, "name", 4, &name_ptr, &name_len) || + !ucall_param_named_str(call, "avatar", 6, &avatar_ptr, &avatar_len) || + !ucall_param_named_str(call, "bio", 3, &bio_ptr, &bio_len)) { + return ucall_call_reply_error_invalid_params(call); + } + + char result[1024]; + ucall_call_reply_content(call, result, strlen(result)); +} + +#include // for std::invalid_argument +#include // for std::string +#include // for std::vector + +/** + * Validates the user's identity similar to JWT. Showcases argument validation & exception handling in the C++ layer, + * as well as complex structured returned values. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param user_id An integer user identifier. Must be provided as a 64-bit integer. + * @param name The user's name. Provided as a string. + * @param age The user's age. Must be a floating-point number and over 18. + * @param access_token A binary string representing an authentication token. Must start with the user's name. + */ +static void validate_user_identity(ucall_call_t call, ucall_callback_tag_t) { + int64_t user_id{}; + double age{}; + ucall_str_t name_ptr{}, token_ptr{}; + std::size_t name_len{}, token_len{}; + + if (!ucall_param_named_i64(call, "user_id", 7, &user_id) || !ucall_param_named_f64(call, "age", 3, &age) || + !ucall_param_named_str(call, "name", 4, &name_ptr, &name_len) || + !ucall_param_named_str(call, "access_token", 12, &token_ptr, &token_len)) { + return ucall_call_reply_error_invalid_params(call); + } + + char result[1024]; + std::vector suggested_session_ids; + // TODO: populate suggested_session_ids + auto format_result = fmt::format_to_n( + result, + sizeof(result), + "{{\n" + " \"session_ids\": [{0}],\n" + " \"user\": {{\n" + " \"name\": \"{1}\",\n" + " \"age\": {2},\n" + " \"user_id\": {3},\n" + " \"access_token\": \"{4}\",\n" + " \"repeated_sesson_ids\": [{0}]\n" + " }}\n" + "}}", + fmt::join(suggested_session_ids, ", "), + fmt::string_view(name_ptr, name_len), + age, + user_id, + fmt::string_view(token_ptr, token_len)); + if (format_result.size > sizeof(result)) { + return ucall_call_reply_error_out_of_memory(call); + } + ucall_call_reply_content(call, result, format_result.size); +} + +struct key_value_pair { + char* key_and_value = nullptr; + std::size_t key_length = 0; + std::size_t value_length = 0; + + std::string_view key() const noexcept { return std::string_view(key_and_value, key_length); } + std::string_view value() const noexcept { return std::string_view(key_and_value + key_length, value_length); } + explicit operator bool() const noexcept { return key_length && value_length && key_and_value; } + + key_value_pair() = default; + key_value_pair(std::string_view key, std::string_view value) : key_length(key.size()), value_length(value.size()) { + std::size_t total_length = key_length + value_length; + key_and_value = reinterpret_cast(std::malloc(total_length)); + if (total_length && !key_and_value) + return; // Invalid state + if (key_and_value) + std::memcpy(key_and_value, key.data(), key_length), + std::memcpy(key_and_value + key_length, value.data(), value_length); + else + key_length = value_length = 0; + } + key_value_pair(key_value_pair const& other) : key_length(other.key_length), value_length(other.value_length) { + std::size_t total_length = key_length + value_length; + key_and_value = reinterpret_cast(std::malloc(total_length)); + if (total_length && !key_and_value) + return; // Invalid state + if (key_and_value) + std::memcpy(key_and_value, other.key_and_value, total_length); + else + key_length = value_length = 0; + } + key_value_pair(key_value_pair&& other) noexcept + : key_and_value(other.key_and_value), key_length(other.key_length), value_length(other.value_length) { + other.key_and_value = nullptr; + other.key_length = other.value_length = 0; + } + key_value_pair& operator=(key_value_pair const& other) { + if (this == &other) + return *this; + + std::free(key_and_value); + key_length = other.key_length; + value_length = other.value_length; + key_and_value = reinterpret_cast(std::malloc(key_length + value_length)); + if (key_and_value) + std::memcpy(key_and_value, other.key_and_value, key_length + value_length); + else + key_length = value_length = 0; + + return *this; + } + key_value_pair& operator=(key_value_pair&& other) noexcept { + if (this == &other) + return *this; + + std::free(key_and_value); + key_and_value = other.key_and_value; + key_length = other.key_length; + value_length = other.value_length; + other.key_and_value = nullptr; + other.key_length = other.value_length = 0; + + return *this; + } +}; + +std::string_view get_key(key_value_pair const& pair) noexcept { return pair.key(); } +std::string_view get_key(std::string_view const& key) noexcept { return key; } + +struct key_hash { + using is_transparent = void; + + template std::size_t operator()(key_type const& key) const noexcept { + return std::hash{}(get_key(key)); + } +}; + +struct key_equal { + using is_transparent = void; + + template + bool operator()(first_at const& lhs, second_at const& rhs) const noexcept { + return get_key(lhs) == get_key(rhs); + } +}; + +static std::shared_mutex store_mutex; +static std::unordered_set store; + +/** + * Sets a key-value pair in the store. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param key The key under which the value is stored as a string. + * @param value The value to be stored as a string. + */ +static void set(ucall_call_t call, ucall_callback_tag_t) { + ucall_str_t key_ptr{}, value_ptr{}; + std::size_t key_len{}, value_len{}; + if (!ucall_param_named_str(call, "key", 3, &key_ptr, &key_len) || + !ucall_param_named_str(call, "value", 5, &value_ptr, &value_len)) { + return ucall_call_reply_error_invalid_params(call); + } + std::unique_lock lock(store_mutex); + key_value_pair pair{std::string_view(key_ptr, key_len), std::string_view(value_ptr, value_len)}; + if (!pair) + return ucall_call_reply_error_out_of_memory(call); + store.insert(std::move(pair)); + ucall_call_reply_content(call, "OK", 2); +} + +/** + * Retrieves a value from the store based on the key. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param key The key for which the value needs to be retrieved as a string. + */ +static void get(ucall_call_t call, ucall_callback_tag_t) { + ucall_str_t key_ptr{}; + std::size_t key_len{}; + if (!ucall_param_named_str(call, "key", 3, &key_ptr, &key_len)) { + return ucall_call_reply_error_invalid_params(call); + } + std::shared_lock lock(store_mutex); + auto iterator = store.find(std::string_view(key_ptr, key_len)); + if (iterator == store.end()) + return ucall_call_reply_content(call, "", 0); + else + return ucall_call_reply_content(call, iterator->value().data(), iterator->value().size()); +} + +/** + * Resizes an image provided as a binary string. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param image A binary string that represents the image to resize. + * @param width The target width as an integer. + * @param height The target height as an integer. + */ +static void resize(ucall_call_t call, ucall_callback_tag_t) { + ucall_str_t image_data{}; + std::size_t image_len{}; + int64_t width{}, height{}; + if (!ucall_param_named_str(call, "image", 5, &image_data, &image_len) || + !ucall_param_named_i64(call, "width", 5, &width) || !ucall_param_named_i64(call, "height", 6, &height)) { + return ucall_call_reply_error_invalid_params(call); + } + + char resized_image[1024]; // Placeholder for actual image processing logic + ucall_call_reply_content(call, resized_image, strlen(resized_image)); +} + +/** + * Resizes a batch of images provided as a list of binary strings. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param images A list of binary strings each representing an image to resize. + * @param width The target width for all images as an integer. + * @param height The target height for all images as an integer. + */ +static void resize_batch(ucall_call_t call, ucall_callback_tag_t) { + // Implementing batch processing might involve more complex data handling + std::vector images; // Placeholder for actual image processing logic + int64_t width{}, height{}; + if (!ucall_param_named_i64(call, "width", 5, &width) || !ucall_param_named_i64(call, "height", 6, &height)) { + return ucall_call_reply_error_invalid_params(call); + } + + char result[1024]; // Placeholder for actual result + ucall_call_reply_content(call, result, strlen(result)); +} + +/** + * Calculates the dot product of two vectors provided as binary strings. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param a A binary string representing the first vector. + * @param b A binary string representing the second vector. + */ +static void dot_product(ucall_call_t call, ucall_callback_tag_t) { + ucall_str_t a_data{}, b_data{}; + std::size_t a_len{}, b_len{}; + if (!ucall_param_named_str(call, "a", 1, &a_data, &a_len) || + !ucall_param_named_str(call, "b", 1, &b_data, &b_len)) { + return ucall_call_reply_error_invalid_params(call); + } + + // Assuming vector processing and dot product calculation + char const* result = "0.0"; + ucall_call_reply_content(call, result, strlen(result)); +} + +/** + * Calculates the dot products of multiple pairs of vectors provided as lists of binary strings. + * + * @param call A ucall_call_t object that represents the RPC call context. + * @param a List of binary strings each representing a first vector in a pair. + * @param b List of binary strings each representing a second vector in a pair. + */ +static void dot_product_batch(ucall_call_t call, ucall_callback_tag_t) { + char const* result = "0.0"; + ucall_call_reply_content(call, result, strlen(result)); +} + +int main(int argc, char** argv) { + + auto server_description = ""; + + cxxopts::Options options("UCall Example Server", server_description); + options.add_options() // + ("h,help", "Print usage") // + ("nic", "Networking Interface Internal IP to use", cxxopts::value()->default_value("127.0.0.1")) // + ("p,port", "On which port to server JSON-RPC", cxxopts::value()->default_value("8545")) // + ("j,threads", "How many threads to run", cxxopts::value()->default_value("1")) // + ("s,silent", "Silence statistics output", cxxopts::value()->default_value("false")) // + ; + auto result = options.parse(argc, argv); + if (result.count("help")) { + std::cout << options.help() << std::endl; + exit(0); + } + + // Initialize the server + ucall_server_t server{}; + ucall_config_t config{}; + config.hostname = result["nic"].as().c_str(); + config.port = result["port"].as(); + config.max_threads = result["threads"].as(); + config.max_concurrent_connections = 1024; + config.queue_depth = 4096 * config.max_threads; + config.max_lifetime_exchanges = UINT32_MAX; + config.logs_file_descriptor = result["silent"].as() ? -1 : fileno(stdin); + config.logs_format = "human"; + + ucall_init(&config, &server); + if (!server) { + std::printf("Failed to initialize server!\n"); + return -1; + } + + std::printf("Initialized server: %s:%i\n", config.hostname, config.port); + std::printf("- %zu threads\n", static_cast(config.max_threads)); + std::printf("- %zu max concurrent connections\n", static_cast(config.max_concurrent_connections)); + if (result["silent"].as()) + std::printf("- silent\n"); + + // Basic operations and types + ucall_add_procedure(server, "echo", &echo, NULL); + ucall_add_procedure(server, "validate_session", &validate_session, NULL); + ucall_add_procedure(server, "create_user", &create_user, NULL); + ucall_add_procedure(server, "validate_user_identity", &validate_user_identity, NULL); + + // Redis functionality + ucall_add_procedure(server, "set", &set, NULL); + ucall_add_procedure(server, "get", &get, NULL); + + // Rich data types + ucall_add_procedure(server, "resize", &resize, NULL); + ucall_add_procedure(server, "resize_batch", &resize_batch, NULL); + ucall_add_procedure(server, "dot_product", &dot_product, NULL); + ucall_add_procedure(server, "dot_product_batch", &dot_product_batch, NULL); + + // Start the server + if (config.max_threads > 1) { + // Allocate `config.max_threads - 1` threads in addition to the current one + std::vector threads; + for (uint16_t i = 1; i != config.max_threads; ++i) + threads.emplace_back(&ucall_take_calls, server, i); + // Populate the current main thread + ucall_take_calls(server, 0); + for (auto& thread : threads) + thread.join(); + } else + ucall_take_calls(server, 0); + + ucall_free(server); + return 0; +} \ No newline at end of file diff --git a/examples/ucall_server.py b/examples/ucall_server.py new file mode 100644 index 0000000..dc73d76 --- /dev/null +++ b/examples/ucall_server.py @@ -0,0 +1,213 @@ +""" +This module implements a pseudo-backend for benchmarking and demostration purposes for the UCall JSON-RPC implementation. +It provides a simplified in-memory key-value store and image manipulation functions, alongside user management utilities. +""" + +import random +from typing import List + +import numpy as np +import PIL.Image as pil + +from ucall.posix import Server + + +# Initialize the RPC server on port 8545 +server = Server(port=8545) + + +@server +def echo(data: bytes) -> bytes: + """ + Returns the same data it receives. + + Args: + data (bytes): Data to be echoed back. + + Returns: + bytes: The same data received. + """ + return data + + +@server +def validate_session(user_id: int, session_id: int) -> bool: + """ + Validates if the session ID is valid for the given user ID based on a hashing scheme. + + Args: + user_id (int): The user's unique identifier. + session_id (int): The session's unique identifier. + + Returns: + bool: True if the session is valid, False otherwise. + """ + return (user_id ^ session_id) % 23 == 0 + + +@server +def create_user(age: int, name: str, avatar: bytes, bio: str) -> str: + """ + Registers a new user with the given details and returns a summary. + + Args: + age (int): User's age. + name (str): User's full name. + avatar (bytes): User's avatar image in binary format. + bio (str): User's biography. + + Returns: + str: Confirmation message with user details. + """ + return f"Created {name} aged {age} with bio {bio} and avatar_size {len(avatar)}" + + +@server +def validate_user_identity( + user_id: int, + name: str, + age: float, + access_token: bytes, +) -> dict: + """ + Similar to JWT, validates the user's identity based on the provided data. + Showcases argument validation & exception handling in the Python layer, + as well as complex structured returned values. + + Args: + user_id (int): An integer user identifier. + name (str): The user's name. + age (float): Must be over 18. + access_token (bytes): Must start with user's name. + + Returns: + dict: Transformed data including a list of generated session IDs + that the client can reuse for future connections. + """ + if age < 18: + raise ValueError(f"{name} must be older than 18") + + if not access_token.decode().startswith(name): + raise ValueError(f"Invalid access token for {name}") + + suggested_session_ids = [random.random() * age * user_id for _ in range(round(age))] + return { + "session_ids": suggested_session_ids, + "user": { + "name": name, + "age": age, + "user_id": user_id, + "access_token": access_token, + "repeated_sesson_ids": suggested_session_ids, + }, + } + + +# Simulating a Redis-like in-memory key-value store +redis = dict() + + +@server +def set(key: str, value: str) -> bool: + """ + Sets a value in the key-value store. + + Args: + key (str): The key under which the value is stored. + value (str): The value to store. + + Returns: + bool: True if the operation was successful, otherwise False. + """ + redis[key] = value + return True + + +@server +def get(key: str) -> str: + """ + Retrieves a value from the key-value store based on the key. + + Args: + key (str): The key whose value needs to be retrieved. + + Returns: + str: The value if found, otherwise None. + """ + return redis.get(key, None) + + +@server +def resize(image: pil.Image, width: int, height: int) -> pil.Image: + """ + Resizes a single image to the specified width and height. + Showcases how UCall handles complex binary types like images, + encoding them into Base64. + + Args: + image (pil.Image): The image to resize. + width (int): The target width. + height (int): The target height. + + Returns: + pil.Image: The resized image. + """ + return image.resize((width, height)) + + +@server(batch=True, name="resize") +def resize_batch(images: List[pil.Image], width: int, height: int) -> List[pil.Image]: + """ + Resizes a batch of images to the specified dimensions. + Showcases how UCall handles complex binary types like images, + encoding them into Base64, and regrouping them into lists + for batch processing. + + Args: + images (List[pil.Image]): List of images to resize. + width (int): The target width for all images. + height (int): The target height for all images. + + Returns: + List[pil.Image]: List of resized images. + """ + return [image.resize((width, height)) for image in images] + + +@server +def dot_product(a: np.ndarray, b: np.ndarray) -> float: + """ + Calculates the dot product of two vectors. + Showcases how UCall handles complex binary types like NumPy arrays, + encoding them into Base64. + + Args: + a (np.ndarray): The first vector. Must be one-dimensional. + b (np.ndarray): The second vector. Must be of the same shape as `a`. + + Returns: + float: The dot product of the two vectors. + """ + return float(np.dot(a, b)) + + +@server(batch=True, name="dot_product") +def dot_product_batch(a: List[np.ndarray], b: List[np.ndarray]) -> List[float]: + """ + Calculates the dot products of many vectors. + Showcases how UCall handles complex binary types like NumPy arrays, + encoding them into Base64, and regrouping them into lists + for batch processing. + + Args: + a (List[np.ndarray]): List of first vectors. + b (List[np.ndarray]): List of second vectors. Must be of the same shape as `a`. + + Returns: + List[float]: List of dot products of the two vectors. + """ + return [float(np.dot(a[i], b[i])) for i in range(len(a))] + + +if __name__ == "__main__": + server.run() diff --git a/include/mbedtls/config.h b/include/mbedtls/config.h deleted file mode 100644 index 6042d5f..0000000 --- a/include/mbedtls/config.h +++ /dev/null @@ -1,3926 +0,0 @@ -/** - * \file mbedtls_config.h - * - * \brief Configuration options (set of defines) - * - * This set of compile-time options may be used to enable - * or disable features selectively, and reduce the global - * memory footprint. - */ -/* - * Copyright The Mbed TLS Contributors - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This is an optional version symbol that enables compatibility handling of - * config files. - * - * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that - * introduced the config format we want to be compatible with. - */ -//#define MBEDTLS_CONFIG_VERSION 0x03000000 - -/** - * \name SECTION: System support - * - * This section sets system specific settings. - * \{ - */ - -/** - * \def MBEDTLS_HAVE_ASM - * - * The compiler has support for asm(). - * - * Requires support for asm() in compiler. - * - * Used in: - * library/aesni.h - * library/aria.c - * library/bn_mul.h - * library/constant_time.c - * library/padlock.h - * - * Required by: - * MBEDTLS_AESCE_C - * MBEDTLS_AESNI_C (on some platforms) - * MBEDTLS_PADLOCK_C - * - * Comment to disable the use of assembly code. - */ -#define MBEDTLS_HAVE_ASM - -/** - * \def MBEDTLS_NO_UDBL_DIVISION - * - * The platform lacks support for double-width integer division (64-bit - * division on a 32-bit platform, 128-bit division on a 64-bit platform). - * - * Used in: - * include/mbedtls/bignum.h - * library/bignum.c - * - * The bignum code uses double-width division to speed up some operations. - * Double-width division is often implemented in software that needs to - * be linked with the program. The presence of a double-width integer - * type is usually detected automatically through preprocessor macros, - * but the automatic detection cannot know whether the code needs to - * and can be linked with an implementation of division for that type. - * By default division is assumed to be usable if the type is present. - * Uncomment this option to prevent the use of double-width division. - * - * Note that division for the native integer type is always required. - * Furthermore, a 64-bit type is always required even on a 32-bit - * platform, but it need not support multiplication or division. In some - * cases it is also desirable to disable some double-width operations. For - * example, if double-width division is implemented in software, disabling - * it can reduce code size in some embedded targets. - */ -//#define MBEDTLS_NO_UDBL_DIVISION - -/** - * \def MBEDTLS_NO_64BIT_MULTIPLICATION - * - * The platform lacks support for 32x32 -> 64-bit multiplication. - * - * Used in: - * library/poly1305.c - * - * Some parts of the library may use multiplication of two unsigned 32-bit - * operands with a 64-bit result in order to speed up computations. On some - * platforms, this is not available in hardware and has to be implemented in - * software, usually in a library provided by the toolchain. - * - * Sometimes it is not desirable to have to link to that library. This option - * removes the dependency of that library on platforms that lack a hardware - * 64-bit multiplier by embedding a software implementation in Mbed TLS. - * - * Note that depending on the compiler, this may decrease performance compared - * to using the library function provided by the toolchain. - */ -//#define MBEDTLS_NO_64BIT_MULTIPLICATION - -/** - * \def MBEDTLS_HAVE_SSE2 - * - * CPU supports SSE2 instruction set. - * - * Uncomment if the CPU supports SSE2 (IA-32 specific). - */ -//#define MBEDTLS_HAVE_SSE2 - -/** - * \def MBEDTLS_HAVE_TIME - * - * System has time.h and time(). - * The time does not need to be correct, only time differences are used, - * by contrast with MBEDTLS_HAVE_TIME_DATE - * - * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, - * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and - * MBEDTLS_PLATFORM_STD_TIME. - * - * Comment if your system does not support time functions. - * - * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing - * interface - timing.c will include time.h on suitable platforms - * regardless of the setting of MBEDTLS_HAVE_TIME, unless - * MBEDTLS_TIMING_ALT is used. See timing.c for more information. - */ -#define MBEDTLS_HAVE_TIME - -/** - * \def MBEDTLS_HAVE_TIME_DATE - * - * System has time.h, time(), and an implementation for - * mbedtls_platform_gmtime_r() (see below). - * The time needs to be correct (not necessarily very accurate, but at least - * the date should be correct). This is used to verify the validity period of - * X.509 certificates. - * - * Comment if your system does not have a correct clock. - * - * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that - * behaves similarly to the gmtime_r() function from the C standard. Refer to - * the documentation for mbedtls_platform_gmtime_r() for more information. - * - * \note It is possible to configure an implementation for - * mbedtls_platform_gmtime_r() at compile-time by using the macro - * MBEDTLS_PLATFORM_GMTIME_R_ALT. - */ -#define MBEDTLS_HAVE_TIME_DATE - -/** - * \def MBEDTLS_PLATFORM_MEMORY - * - * Enable the memory allocation layer. - * - * By default mbed TLS uses the system-provided calloc() and free(). - * This allows different allocators (self-implemented or provided) to be - * provided to the platform abstraction layer. - * - * Enabling MBEDTLS_PLATFORM_MEMORY without the - * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide - * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and - * free() function pointer at runtime. - * - * Enabling MBEDTLS_PLATFORM_MEMORY and specifying - * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the - * alternate function at compile time. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Enable this layer to allow use of alternative memory allocators. - */ -//#define MBEDTLS_PLATFORM_MEMORY - -/** - * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - * - * Do not assign standard functions in the platform layer (e.g. calloc() to - * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) - * - * This makes sure there are no linking errors on platforms that do not support - * these functions. You will HAVE to provide alternatives, either at runtime - * via the platform_set_xxx() functions or at compile time by setting - * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a - * MBEDTLS_PLATFORM_XXX_MACRO. - * - * Requires: MBEDTLS_PLATFORM_C - * - * Uncomment to prevent default assignment of standard functions in the - * platform layer. - */ -//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS - -/** - * \def MBEDTLS_PLATFORM_EXIT_ALT - * - * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let mbed TLS support the - * function in the platform abstraction layer. - * - * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, mbed TLS will - * provide a function "mbedtls_platform_set_printf()" that allows you to set an - * alternative printf function pointer. - * - * All these define require MBEDTLS_PLATFORM_C to be defined! - * - * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; - * it will be enabled automatically by check_config.h - * - * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as - * MBEDTLS_PLATFORM_XXX_MACRO! - * - * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME - * - * Uncomment a macro to enable alternate implementation of specific base - * platform function - */ -//#define MBEDTLS_PLATFORM_SETBUF_ALT -//#define MBEDTLS_PLATFORM_EXIT_ALT -//#define MBEDTLS_PLATFORM_TIME_ALT -//#define MBEDTLS_PLATFORM_FPRINTF_ALT -//#define MBEDTLS_PLATFORM_PRINTF_ALT -//#define MBEDTLS_PLATFORM_SNPRINTF_ALT -//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT -//#define MBEDTLS_PLATFORM_NV_SEED_ALT -//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT - -/** - * \def MBEDTLS_DEPRECATED_WARNING - * - * Mark deprecated functions and features so that they generate a warning if - * used. Functionality deprecated in one version will usually be removed in the - * next version. You can enable this to help you prepare the transition to a - * new major version by making sure your code is not using this functionality. - * - * This only works with GCC and Clang. With other compilers, you may want to - * use MBEDTLS_DEPRECATED_REMOVED - * - * Uncomment to get warnings on using deprecated functions and features. - */ -//#define MBEDTLS_DEPRECATED_WARNING - -/** - * \def MBEDTLS_DEPRECATED_REMOVED - * - * Remove deprecated functions and features so that they generate an error if - * used. Functionality deprecated in one version will usually be removed in the - * next version. You can enable this to help you prepare the transition to a - * new major version by making sure your code is not using this functionality. - * - * Uncomment to get errors on using deprecated functions and features. - */ -//#define MBEDTLS_DEPRECATED_REMOVED - -/** \} name SECTION: System support */ - -/** - * \name SECTION: mbed TLS feature support - * - * This section sets support for features that are or are not needed - * within the modules that are enabled. - * \{ - */ - -/** - * \def MBEDTLS_TIMING_ALT - * - * Uncomment to provide your own alternate implementation for - * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() - * - * Only works if you have MBEDTLS_TIMING_C enabled. - * - * You will need to provide a header "timing_alt.h" and an implementation at - * compile time. - */ -//#define MBEDTLS_TIMING_ALT - -/** - * \def MBEDTLS_AES_ALT - * - * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternate core implementation of a symmetric crypto, an arithmetic or hash - * module (e.g. platform specific assembly optimized implementations). Keep - * in mind that the function prototypes should remain the same. - * - * This replaces the whole module. If you only want to replace one of the - * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_AES_ALT, mbed TLS will no longer - * provide the "struct mbedtls_aes_context" definition and omit the base - * function declarations and implementations. "aes_alt.h" will be included from - * "aes.h" to include the new function definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * module. - * - * \warning MD5, DES and SHA-1 are considered weak and their - * use constitutes a security risk. If possible, we recommend - * avoiding dependencies on them, and considering stronger message - * digests and ciphers instead. - * - */ -//#define MBEDTLS_AES_ALT -//#define MBEDTLS_ARIA_ALT -//#define MBEDTLS_CAMELLIA_ALT -//#define MBEDTLS_CCM_ALT -//#define MBEDTLS_CHACHA20_ALT -//#define MBEDTLS_CHACHAPOLY_ALT -//#define MBEDTLS_CMAC_ALT -//#define MBEDTLS_DES_ALT -//#define MBEDTLS_DHM_ALT -//#define MBEDTLS_ECJPAKE_ALT -//#define MBEDTLS_GCM_ALT -//#define MBEDTLS_NIST_KW_ALT -//#define MBEDTLS_MD5_ALT -//#define MBEDTLS_POLY1305_ALT -//#define MBEDTLS_RIPEMD160_ALT -//#define MBEDTLS_RSA_ALT -//#define MBEDTLS_SHA1_ALT -//#define MBEDTLS_SHA256_ALT -//#define MBEDTLS_SHA512_ALT - -/* - * When replacing the elliptic curve module, please consider, that it is - * implemented with two .c files: - * - ecp.c - * - ecp_curves.c - * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT - * macros as described above. The only difference is that you have to make sure - * that you provide functionality for both .c files. - */ -//#define MBEDTLS_ECP_ALT - -/** - * \def MBEDTLS_SHA256_PROCESS_ALT - * - * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use you - * alternate core implementation of symmetric crypto or hash function. Keep in - * mind that function prototypes should remain the same. - * - * This replaces only one function. The header file from mbed TLS is still - * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. - * - * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, mbed TLS will - * no longer provide the mbedtls_sha1_process() function, but it will still provide - * the other function (using your mbedtls_sha1_process() function) and the definition - * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible - * with this definition. - * - * \note If you use the AES_xxx_ALT macros, then it is recommended to also set - * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES - * tables. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - * - * \warning MD5, DES and SHA-1 are considered weak and their use - * constitutes a security risk. If possible, we recommend avoiding - * dependencies on them, and considering stronger message digests - * and ciphers instead. - * - * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are - * enabled, then the deterministic ECDH signature functions pass the - * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore - * alternative implementations should use the RNG only for generating - * the ephemeral key and nothing else. If this is not possible, then - * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative - * implementation should be provided for mbedtls_ecdsa_sign_det_ext(). - * - */ -//#define MBEDTLS_MD5_PROCESS_ALT -//#define MBEDTLS_RIPEMD160_PROCESS_ALT -//#define MBEDTLS_SHA1_PROCESS_ALT -//#define MBEDTLS_SHA256_PROCESS_ALT -//#define MBEDTLS_SHA512_PROCESS_ALT -//#define MBEDTLS_DES_SETKEY_ALT -//#define MBEDTLS_DES_CRYPT_ECB_ALT -//#define MBEDTLS_DES3_CRYPT_ECB_ALT -//#define MBEDTLS_AES_SETKEY_ENC_ALT -//#define MBEDTLS_AES_SETKEY_DEC_ALT -//#define MBEDTLS_AES_ENCRYPT_ALT -//#define MBEDTLS_AES_DECRYPT_ALT -//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT -//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT -//#define MBEDTLS_ECDSA_VERIFY_ALT -//#define MBEDTLS_ECDSA_SIGN_ALT -//#define MBEDTLS_ECDSA_GENKEY_ALT - -/** - * \def MBEDTLS_ECP_INTERNAL_ALT - * - * Expose a part of the internal interface of the Elliptic Curve Point module. - * - * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let mbed TLS use your - * alternative core implementation of elliptic curve arithmetic. Keep in mind - * that function prototypes should remain the same. - * - * This partially replaces one function. The header file from mbed TLS is still - * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation - * is still present and it is used for group structures not supported by the - * alternative. - * - * The original implementation can in addition be removed by setting the - * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the - * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be - * able to fallback to curves not supported by the alternative implementation. - * - * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT - * and implementing the following functions: - * unsigned char mbedtls_internal_ecp_grp_capable( - * const mbedtls_ecp_group *grp ) - * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) - * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) - * The mbedtls_internal_ecp_grp_capable function should return 1 if the - * replacement functions implement arithmetic for the given group and 0 - * otherwise. - * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are - * called before and after each point operation and provide an opportunity to - * implement optimized set up and tear down instructions. - * - * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and - * MBEDTLS_ECP_DOUBLE_JAC_ALT, mbed TLS will still provide the ecp_double_jac() - * function, but will use your mbedtls_internal_ecp_double_jac() if the group - * for the operation is supported by your implementation (i.e. your - * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the - * group is not supported by your implementation, then the original mbed TLS - * implementation of ecp_double_jac() is used instead, unless this fallback - * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case - * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). - * - * The function prototypes and the definition of mbedtls_ecp_group and - * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your - * implementation of mbedtls_internal_ecp__function_name__ must be compatible - * with their definitions. - * - * Uncomment a macro to enable alternate implementation of the corresponding - * function. - */ -/* Required for all the functions in this section */ -//#define MBEDTLS_ECP_INTERNAL_ALT -/* Turn off software fallback for curves not supported in hardware */ -//#define MBEDTLS_ECP_NO_FALLBACK -/* Support for Weierstrass curves with Jacobi representation */ -//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT -//#define MBEDTLS_ECP_ADD_MIXED_ALT -//#define MBEDTLS_ECP_DOUBLE_JAC_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT -//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT -/* Support for curves with Montgomery arithmetic */ -//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT -//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT -//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT - -/** - * \def MBEDTLS_ENTROPY_HARDWARE_ALT - * - * Uncomment this macro to let mbed TLS use your own implementation of a - * hardware entropy collector. - * - * Your function must be called \c mbedtls_hardware_poll(), have the same - * prototype as declared in library/entropy_poll.h, and accept NULL as first - * argument. - * - * Uncomment to use your own hardware entropy collector. - */ -//#define MBEDTLS_ENTROPY_HARDWARE_ALT - -/** - * \def MBEDTLS_AES_ROM_TABLES - * - * Use precomputed AES tables stored in ROM. - * - * Uncomment this macro to use precomputed AES tables stored in ROM. - * Comment this macro to generate AES tables in RAM at runtime. - * - * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb - * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the - * initialization time before the first AES operation can be performed. - * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c - * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded - * performance if ROM access is slower than RAM access. - * - * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. - * - */ -//#define MBEDTLS_AES_ROM_TABLES - -/** - * \def MBEDTLS_AES_FEWER_TABLES - * - * Use less ROM/RAM for AES tables. - * - * Uncommenting this macro omits 75% of the AES tables from - * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) - * by computing their values on the fly during operations - * (the tables are entry-wise rotations of one another). - * - * Tradeoff: Uncommenting this reduces the RAM / ROM footprint - * by ~6kb but at the cost of more arithmetic operations during - * runtime. Specifically, one has to compare 4 accesses within - * different tables to 4 accesses with additional arithmetic - * operations within the same table. The performance gain/loss - * depends on the system and memory details. - * - * This option is independent of \c MBEDTLS_AES_ROM_TABLES. - * - */ -//#define MBEDTLS_AES_FEWER_TABLES - -/** - * \def MBEDTLS_CAMELLIA_SMALL_MEMORY - * - * Use less ROM for the Camellia implementation (saves about 768 bytes). - * - * Uncomment this macro to use less memory for Camellia. - */ -//#define MBEDTLS_CAMELLIA_SMALL_MEMORY - -/** - * \def MBEDTLS_CHECK_RETURN_WARNING - * - * If this macro is defined, emit a compile-time warning if application code - * calls a function without checking its return value, but the return value - * should generally be checked in portable applications. - * - * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is - * implemented. Otherwise this option has no effect. - * - * Uncomment to get warnings on using fallible functions without checking - * their return value. - * - * \note This feature is a work in progress. - * Warnings will be added to more functions in the future. - * - * \note A few functions are considered critical, and ignoring the return - * value of these functions will trigger a warning even if this - * macro is not defined. To completely disable return value check - * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. - */ -//#define MBEDTLS_CHECK_RETURN_WARNING - -/** - * \def MBEDTLS_CIPHER_MODE_CBC - * - * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CBC - -/** - * \def MBEDTLS_CIPHER_MODE_CFB - * - * Enable Cipher Feedback mode (CFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CFB - -/** - * \def MBEDTLS_CIPHER_MODE_CTR - * - * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_CTR - -/** - * \def MBEDTLS_CIPHER_MODE_OFB - * - * Enable Output Feedback mode (OFB) for symmetric ciphers. - */ -#define MBEDTLS_CIPHER_MODE_OFB - -/** - * \def MBEDTLS_CIPHER_MODE_XTS - * - * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. - */ -#define MBEDTLS_CIPHER_MODE_XTS - -/** - * \def MBEDTLS_CIPHER_NULL_CIPHER - * - * Enable NULL cipher. - * Warning: Only do so when you know what you are doing. This allows for - * encryption or channels without any security! - * - * To enable the following ciphersuites: - * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_WITH_NULL_SHA - * MBEDTLS_TLS_RSA_WITH_NULL_MD5 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA - * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 - * MBEDTLS_TLS_PSK_WITH_NULL_SHA - * - * Uncomment this macro to enable the NULL cipher and ciphersuites - */ -//#define MBEDTLS_CIPHER_NULL_CIPHER - -/** - * \def MBEDTLS_CIPHER_PADDING_PKCS7 - * - * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for - * specific padding modes in the cipher layer with cipher modes that support - * padding (e.g. CBC) - * - * If you disable all padding modes, only full blocks can be used with CBC. - * - * Enable padding modes in the cipher layer. - */ -#define MBEDTLS_CIPHER_PADDING_PKCS7 -#define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS -#define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN -#define MBEDTLS_CIPHER_PADDING_ZEROS - -/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - * - * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. - * By default, CTR_DRBG uses a 256-bit key. - */ -//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY - -/** - * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED - * - * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve - * module. By default all supported curves are enabled. - * - * Comment macros to disable the curve and functions for it - */ -/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -/* Montgomery curves (supporting ECP) */ -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_DP_CURVE448_ENABLED - -/** - * \def MBEDTLS_ECP_NIST_OPTIM - * - * Enable specific 'modulo p' routines for each NIST prime. - * Depending on the prime and architecture, makes operations 4 to 8 times - * faster on the corresponding curve. - * - * Comment this macro to disable NIST curves optimisation. - */ -#define MBEDTLS_ECP_NIST_OPTIM - -/** - * \def MBEDTLS_ECP_RESTARTABLE - * - * Enable "non-blocking" ECC operations that can return early and be resumed. - * - * This allows various functions to pause by returning - * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, - * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in - * order to further progress and eventually complete their operation. This is - * controlled through mbedtls_ecp_set_max_ops() which limits the maximum - * number of ECC operations a function may perform before pausing; see - * mbedtls_ecp_set_max_ops() for more information. - * - * This is useful in non-threaded environments if you want to avoid blocking - * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. - * - * This option: - * - Adds xxx_restartable() variants of existing operations in the - * following modules, with corresponding restart context types: - * - ECP (for Short Weierstrass curves only): scalar multiplication (mul), - * linear combination (muladd); - * - ECDSA: signature generation & verification; - * - PK: signature generation & verification; - * - X509: certificate chain verification. - * - Adds mbedtls_ecdh_enable_restart() in the ECDH module. - * - Changes the behaviour of TLS 1.2 clients (not servers) when using the - * ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC - * computations restartable: - * - ECDH operations from the key exchange, only for Short Weierstrass - * curves, only when MBEDTLS_USE_PSA_CRYPTO is not enabled. - * - verification of the server's key exchange signature; - * - verification of the server's certificate chain; - * - generation of the client's signature if client authentication is used, - * with an ECC key/certificate. - * - * \note In the cases above, the usual SSL/TLS functions, such as - * mbedtls_ssl_handshake(), can now return - * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS. - * - * \note When this option and MBEDTLS_USE_PSA_CRYPTO are both enabled, - * restartable operations in PK, X.509 and TLS (see above) are not - * using PSA. On the other hand, ECDH computations in TLS are using - * PSA, and are not restartable. These are temporary limitations that - * should be lifted in the future. - * - * \note This option only works with the default software implementation of - * elliptic curve functionality. It is incompatible with - * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT. - * - * Requires: MBEDTLS_ECP_C - * - * Uncomment this macro to enable restartable ECC computations. - */ -//#define MBEDTLS_ECP_RESTARTABLE - -/** - * \def MBEDTLS_ECDSA_DETERMINISTIC - * - * Enable deterministic ECDSA (RFC 6979). - * Standard ECDSA is "fragile" in the sense that lack of entropy when signing - * may result in a compromise of the long-term signing key. This is avoided by - * the deterministic variant. - * - * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C - * - * Comment this macro to disable deterministic ECDSA. - */ -#define MBEDTLS_ECDSA_DETERMINISTIC - -/** - * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - * - * Enable the PSK based ciphersuite modes in SSL / TLS. - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - * - * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - * - * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - * - * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - * - * Enable the RSA-only based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - */ -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - * - * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - * - * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, - * MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - * - * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C, - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - * - * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_ECDSA_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - * - * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_RSA_C, MBEDTLS_X509_CRT_PARSE_C - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - */ -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED - -/** - * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - * - * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. - * - * \warning This is currently experimental. EC J-PAKE support is based on the - * Thread v1.0.0 specification; incompatible changes to the specification - * might still happen. For this reason, this is disabled by default. - * - * Requires: MBEDTLS_ECJPAKE_C - * SHA-256 (via MD if present, or via PSA, see MBEDTLS_ECJPAKE_C) - * MBEDTLS_ECP_DP_SECP256R1_ENABLED - * - * This enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 - */ -//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED - -/** - * \def MBEDTLS_PK_PARSE_EC_EXTENDED - * - * Enhance support for reading EC keys using variants of SEC1 not allowed by - * RFC 5915 and RFC 5480. - * - * Currently this means parsing the SpecifiedECDomain choice of EC - * parameters (only known groups are supported, not arbitrary domains, to - * avoid validation issues). - * - * Disable if you only need to support RFC 5915 + 5480 key formats. - */ -#define MBEDTLS_PK_PARSE_EC_EXTENDED - -/** - * \def MBEDTLS_ERROR_STRERROR_DUMMY - * - * Enable a dummy error function to make use of mbedtls_strerror() in - * third party libraries easier when MBEDTLS_ERROR_C is disabled - * (no effect when MBEDTLS_ERROR_C is enabled). - * - * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're - * not using mbedtls_strerror() or error_strerror() in your application. - * - * Disable if you run into name conflicts and want to really remove the - * mbedtls_strerror() - */ -#define MBEDTLS_ERROR_STRERROR_DUMMY - -/** - * \def MBEDTLS_GENPRIME - * - * Enable the prime-number generation code. - * - * Requires: MBEDTLS_BIGNUM_C - */ -#define MBEDTLS_GENPRIME - -/** - * \def MBEDTLS_FS_IO - * - * Enable functions that use the filesystem. - */ -#define MBEDTLS_FS_IO - -/** - * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - * - * Do not add default entropy sources in mbedtls_entropy_init(). - * - * This is useful to have more control over the added entropy sources in an - * application. - * - * Uncomment this macro to prevent loading of default entropy functions. - */ -//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES - -/** - * \def MBEDTLS_NO_PLATFORM_ENTROPY - * - * Do not use built-in platform entropy functions. - * This is useful if your platform does not support - * standards like the /dev/urandom or Windows CryptoAPI. - * - * Uncomment this macro to disable the built-in platform entropy functions. - */ -//#define MBEDTLS_NO_PLATFORM_ENTROPY - -/** - * \def MBEDTLS_ENTROPY_FORCE_SHA256 - * - * Force the entropy accumulator to use a SHA-256 accumulator instead of the - * default SHA-512 based one (if both are available). - * - * Requires: MBEDTLS_SHA256_C - * - * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option - * if you have performance concerns. - * - * This option is only useful if both MBEDTLS_SHA256_C and - * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. - */ -//#define MBEDTLS_ENTROPY_FORCE_SHA256 - -/** - * \def MBEDTLS_ENTROPY_NV_SEED - * - * Enable the non-volatile (NV) seed file-based entropy source. - * (Also enables the NV seed read/write functions in the platform layer) - * - * This is crucial (if not required) on systems that do not have a - * cryptographic entropy source (in hardware or kernel) available. - * - * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C - * - * \note The read/write functions that are used by the entropy source are - * determined in the platform layer, and can be modified at runtime and/or - * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. - * - * \note If you use the default implementation functions that read a seedfile - * with regular fopen(), please make sure you make a seedfile with the - * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at - * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from - * and written to or you will get an entropy source error! The default - * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE - * bytes from the file. - * - * \note The entropy collector will write to the seed file before entropy is - * given to an external source, to update it. - */ -//#define MBEDTLS_ENTROPY_NV_SEED - -/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - * - * Enable key identifiers that encode a key owner identifier. - * - * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t - * which is currently hard-coded to be int32_t. - * - * Note that this option is meant for internal use only and may be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER - -/** - * \def MBEDTLS_MEMORY_DEBUG - * - * Enable debugging of buffer allocator memory issues. Automatically prints - * (to stderr) all (fatal) messages on memory allocation issues. Enables - * function for 'debug output' of allocated memory. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Uncomment this macro to let the buffer allocator print out error messages. - */ -//#define MBEDTLS_MEMORY_DEBUG - -/** - * \def MBEDTLS_MEMORY_BACKTRACE - * - * Include backtrace information with each allocated block. - * - * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C - * GLIBC-compatible backtrace() and backtrace_symbols() support - * - * Uncomment this macro to include backtrace information - */ -//#define MBEDTLS_MEMORY_BACKTRACE - -/** - * \def MBEDTLS_PK_RSA_ALT_SUPPORT - * - * Support external private RSA keys (eg from a HSM) in the PK layer. - * - * Comment this macro to disable support for external private RSA keys. - */ -#define MBEDTLS_PK_RSA_ALT_SUPPORT - -/** - * \def MBEDTLS_PKCS1_V15 - * - * Enable support for PKCS#1 v1.5 encoding. - * - * Requires: MBEDTLS_RSA_C - * - * This enables support for PKCS#1 v1.5 operations. - */ -#define MBEDTLS_PKCS1_V15 - -/** - * \def MBEDTLS_PKCS1_V21 - * - * Enable support for PKCS#1 v2.1 encoding. - * - * Requires: MBEDTLS_RSA_C and (MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C). - * - * \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init() - * before doing any PKCS#1 v2.1 operation. - * - * \warning When building with MBEDTLS_MD_C, all hashes used with this - * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C, - * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by - * this module in builds where MBEDTLS_MD_C is disabled. - * - * This enables support for RSAES-OAEP and RSASSA-PSS operations. - */ -#define MBEDTLS_PKCS1_V21 - -/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS - * - * Enable support for platform built-in keys. If you enable this feature, - * you must implement the function mbedtls_psa_platform_get_builtin_key(). - * See the documentation of that function for more information. - * - * Built-in keys are typically derived from a hardware unique key or - * stored in a secure element. - * - * Requires: MBEDTLS_PSA_CRYPTO_C. - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS - -/** \def MBEDTLS_PSA_CRYPTO_CLIENT - * - * Enable support for PSA crypto client. - * - * \note This option allows to include the code necessary for a PSA - * crypto client when the PSA crypto implementation is not included in - * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the - * code to set and get PSA key attributes. - * The development of PSA drivers partially relying on the library to - * fulfill the hardware gaps is another possible usage of this option. - * - * \warning This interface is experimental and may change or be removed - * without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_CLIENT - -/** \def MBEDTLS_PSA_CRYPTO_DRIVERS - * - * Enable support for the experimental PSA crypto driver interface. - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \warning This interface is experimental. We intend to maintain backward - * compatibility with application code that relies on drivers, - * but the driver interfaces may change without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_DRIVERS - -/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - * - * Make the PSA Crypto module use an external random generator provided - * by a driver, instead of Mbed TLS's entropy and DRBG modules. - * - * \note This random generator must deliver random numbers with cryptographic - * quality and high performance. It must supply unpredictable numbers - * with a uniform distribution. The implementation of this function - * is responsible for ensuring that the random generator is seeded - * with sufficient entropy. If you have a hardware TRNG which is slow - * or delivers non-uniform output, declare it as an entropy source - * with mbedtls_entropy_add_source() instead of enabling this option. - * - * If you enable this option, you must configure the type - * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h - * and define a function called mbedtls_psa_external_get_random() - * with the following prototype: - * ``` - * psa_status_t mbedtls_psa_external_get_random( - * mbedtls_psa_external_random_context_t *context, - * uint8_t *output, size_t output_size, size_t *output_length); - * ); - * ``` - * The \c context value is initialized to 0 before the first call. - * The function must fill the \c output buffer with \p output_size bytes - * of random data and set \c *output_length to \p output_size. - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \warning If you enable this option, code that uses the PSA cryptography - * interface will not use any of the entropy sources set up for - * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED - * enables. - * - * \note This option is experimental and may be removed without notice. - */ -//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - -/** - * \def MBEDTLS_PSA_CRYPTO_SPM - * - * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure - * Partition Manager) integration which separates the code into two parts: a - * NSPE (Non-Secure Process Environment) and an SPE (Secure Process - * Environment). - * - * Module: library/psa_crypto.c - * Requires: MBEDTLS_PSA_CRYPTO_C - * - */ -//#define MBEDTLS_PSA_CRYPTO_SPM - -/** - * \def MBEDTLS_PSA_INJECT_ENTROPY - * - * Enable support for entropy injection at first boot. This feature is - * required on systems that do not have a built-in entropy source (TRNG). - * This feature is currently not supported on systems that have a built-in - * entropy source. - * - * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED - * - */ -//#define MBEDTLS_PSA_INJECT_ENTROPY - -/** - * \def MBEDTLS_RSA_NO_CRT - * - * Do not use the Chinese Remainder Theorem - * for the RSA private operation. - * - * Uncomment this macro to disable the use of CRT in RSA. - * - */ -//#define MBEDTLS_RSA_NO_CRT - -/** - * \def MBEDTLS_SELF_TEST - * - * Enable the checkup functions (*_self_test). - */ -#define MBEDTLS_SELF_TEST - -/** - * \def MBEDTLS_SHA256_SMALLER - * - * Enable an implementation of SHA-256 that has lower ROM footprint but also - * lower performance. - * - * The default implementation is meant to be a reasonable compromise between - * performance and size. This version optimizes more aggressively for size at - * the expense of performance. Eg on Cortex-M4 it reduces the size of - * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about - * 30%. - * - * Uncomment to enable the smaller implementation of SHA256. - */ -//#define MBEDTLS_SHA256_SMALLER - -/** - * \def MBEDTLS_SHA512_SMALLER - * - * Enable an implementation of SHA-512 that has lower ROM footprint but also - * lower performance. - * - * Uncomment to enable the smaller implementation of SHA512. - */ -//#define MBEDTLS_SHA512_SMALLER - -/** - * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES - * - * Enable sending of alert messages in case of encountered errors as per RFC. - * If you choose not to send the alert messages, mbed TLS can still communicate - * with other servers, only debugging of failures is harder. - * - * The advantage of not sending alert messages, is that no information is given - * about reasons for failures thus preventing adversaries of gaining intel. - * - * Enable sending of all alert messages - */ -#define MBEDTLS_SSL_ALL_ALERT_MESSAGES - -/** - * \def MBEDTLS_SSL_DTLS_CONNECTION_ID - * - * Enable support for the DTLS Connection ID (CID) extension, - * which allows to identify DTLS connections across changes - * in the underlying transport. The CID functionality is described - * in RFC 9146. - * - * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, - * mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and - * `mbedtls_ssl_conf_cid()`. See the corresponding documentation for - * more information. - * - * The maximum lengths of outgoing and incoming CIDs can be configured - * through the options - * - MBEDTLS_SSL_CID_OUT_LEN_MAX - * - MBEDTLS_SSL_CID_IN_LEN_MAX. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment to enable the Connection ID extension. - */ -#define MBEDTLS_SSL_DTLS_CONNECTION_ID - -/** - * \def MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT - * - * Defines whether RFC 9146 (default) or the legacy version - * (version draft-ietf-tls-dtls-connection-id-05, - * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) - * is used. - * - * Set the value to 0 for the standard version, and - * 1 for the legacy draft version. - * - * \deprecated Support for the legacy version of the DTLS - * Connection ID feature is deprecated. Please - * switch to the standardized version defined - * in RFC 9146 enabled by utilizing - * MBEDTLS_SSL_DTLS_CONNECTION_ID without use - * of MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT. - * - * Requires: MBEDTLS_SSL_DTLS_CONNECTION_ID - */ -#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0 - -/** - * \def MBEDTLS_SSL_ASYNC_PRIVATE - * - * Enable asynchronous external private key operations in SSL. This allows - * you to configure an SSL connection to call an external cryptographic - * module to perform private key operations instead of performing the - * operation inside the library. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - */ -//#define MBEDTLS_SSL_ASYNC_PRIVATE - -/** - * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION - * - * Enable serialization of the TLS context structures, through use of the - * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). - * - * This pair of functions allows one side of a connection to serialize the - * context associated with the connection, then free or re-use that context - * while the serialized state is persisted elsewhere, and finally deserialize - * that state to a live context for resuming read/write operations on the - * connection. From a protocol perspective, the state of the connection is - * unaffected, in particular this is entirely transparent to the peer. - * - * Note: this is distinct from TLS session resumption, which is part of the - * protocol and fully visible by the peer. TLS session resumption enables - * establishing new connections associated to a saved session with shorter, - * lighter handshakes, while context serialization is a local optimization in - * handling a single, potentially long-lived connection. - * - * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are - * saved after the handshake to allow for more efficient serialization, so if - * you don't need this feature you'll save RAM by disabling it. - * - * Requires: MBEDTLS_GCM_C or MBEDTLS_CCM_C or MBEDTLS_CHACHAPOLY_C - * - * Comment to disable the context serialization APIs. - */ -#define MBEDTLS_SSL_CONTEXT_SERIALIZATION - -/** - * \def MBEDTLS_SSL_DEBUG_ALL - * - * Enable the debug messages in SSL module for all issues. - * Debug messages have been disabled in some places to prevent timing - * attacks due to (unbalanced) debugging function calls. - * - * If you need all error reporting you should enable this during debugging, - * but remove this for production servers that should log as well. - * - * Uncomment this macro to report all debug messages on errors introducing - * a timing side-channel. - * - */ -//#define MBEDTLS_SSL_DEBUG_ALL - -/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC - * - * Enable support for Encrypt-then-MAC, RFC 7366. - * - * This allows peers that both support it to use a more robust protection for - * ciphersuites using CBC, providing deep resistance against timing attacks - * on the padding or underlying cipher. - * - * This only affects CBC ciphersuites, and is useless if none is defined. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Encrypt-then-MAC - */ -#define MBEDTLS_SSL_ENCRYPT_THEN_MAC - -/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET - * - * Enable support for RFC 7627: Session Hash and Extended Master Secret - * Extension. - * - * This was introduced as "the proper fix" to the Triple Handshake family of - * attacks, but it is recommended to always use it (even if you disable - * renegotiation), since it actually fixes a more fundamental issue in the - * original SSL/TLS design, and has implications beyond Triple Handshake. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for Extended Master Secret. - */ -#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET - -/** - * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * - * This option controls the availability of the API mbedtls_ssl_get_peer_cert() - * giving access to the peer's certificate after completion of the handshake. - * - * Unless you need mbedtls_ssl_peer_cert() in your application, it is - * recommended to disable this option for reduced RAM usage. - * - * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still - * defined, but always returns \c NULL. - * - * \note This option has no influence on the protection against the - * triple handshake attack. Even if it is disabled, Mbed TLS will - * still ensure that certificates do not change during renegotiation, - * for example by keeping a hash of the peer's certificate. - * - * \note This option is required if MBEDTLS_SSL_PROTO_TLS1_3 is set. - * - * Comment this macro to disable storing the peer's certificate - * after the handshake. - */ -#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - -/** - * \def MBEDTLS_SSL_RENEGOTIATION - * - * Enable support for TLS renegotiation. - * - * The two main uses of renegotiation are (1) refresh keys on long-lived - * connections and (2) client authentication after the initial handshake. - * If you don't need renegotiation, it's probably better to disable it, since - * it has been associated with security issues in the past and is easy to - * misuse/misunderstand. - * - * Comment this to disable support for renegotiation. - * - * \note Even if this option is disabled, both client and server are aware - * of the Renegotiation Indication Extension (RFC 5746) used to - * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). - * (See \c mbedtls_ssl_conf_legacy_renegotiation for the - * configuration of this extension). - * - */ -#define MBEDTLS_SSL_RENEGOTIATION - -/** - * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - * - * Enable support for RFC 6066 max_fragment_length extension in SSL. - * - * Comment this macro to disable support for the max_fragment_length extension - */ -#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - -/** - * \def MBEDTLS_SSL_RECORD_SIZE_LIMIT - * - * Enable support for RFC 8449 record_size_limit extension in SSL (TLS 1.3 only). - * - * \warning This extension is currently in development and must NOT be used except - * for testing purposes. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_3 - * - * Uncomment this macro to enable support for the record_size_limit extension - */ -//#define MBEDTLS_SSL_RECORD_SIZE_LIMIT - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_2 - * - * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). - * - * Requires: Without MBEDTLS_USE_PSA_CRYPTO: MBEDTLS_MD_C and - * (MBEDTLS_SHA1_C or MBEDTLS_SHA256_C or MBEDTLS_SHA512_C) - * With MBEDTLS_USE_PSA_CRYPTO: - * PSA_WANT_ALG_SHA_1 or PSA_WANT_ALG_SHA_256 or - * PSA_WANT_ALG_SHA_512 - * - * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call - * psa_crypto_init() before doing any TLS operations. - * - * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 - */ -#define MBEDTLS_SSL_PROTO_TLS1_2 - -/** - * \def MBEDTLS_SSL_PROTO_TLS1_3 - * - * Enable support for TLS 1.3. - * - * \note The support for TLS 1.3 is not comprehensive yet, in particular - * pre-shared keys are not supported. - * See docs/architecture/tls13-support.md for a description of the TLS - * 1.3 support that this option enables. - * - * Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * \note TLS 1.3 uses PSA crypto for cryptographic operations that are - * directly performed by TLS 1.3 code. As a consequence, you must - * call psa_crypto_init() before the first TLS 1.3 handshake. - * - * \note Cryptographic operations performed indirectly via another module - * (X.509, PK) or by code shared with TLS 1.2 (record protection, - * running handshake hash) only use PSA crypto if - * #MBEDTLS_USE_PSA_CRYPTO is enabled. - * - * Uncomment this macro to enable the support for TLS 1.3. - */ -//#define MBEDTLS_SSL_PROTO_TLS1_3 - -/** - * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE - * - * Enable TLS 1.3 middlebox compatibility mode. - * - * As specified in Section D.4 of RFC 8446, TLS 1.3 offers a compatibility - * mode to make a TLS 1.3 connection more likely to pass through middle boxes - * expecting TLS 1.2 traffic. - * - * Turning on the compatibility mode comes at the cost of a few added bytes - * on the wire, but it doesn't affect compatibility with TLS 1.3 implementations - * that don't use it. Therefore, unless transmission bandwidth is critical and - * you know that middlebox compatibility issues won't occur, it is therefore - * recommended to set this option. - * - * Comment to disable compatibility mode for TLS 1.3. If - * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any - * effect on the build. - * - */ -//#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE - -/** - * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED - * - * Enable TLS 1.3 PSK key exchange mode. - * - * Comment to disable support for the PSK key exchange mode in TLS 1.3. If - * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any - * effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED - -/** - * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED - * - * Enable TLS 1.3 ephemeral key exchange mode. - * - * Requires: MBEDTLS_ECDH_C, MBEDTLS_X509_CRT_PARSE_C, MBEDTLS_ECDSA_C or - * MBEDTLS_PKCS1_V21 - * - * Comment to disable support for the ephemeral key exchange mode in TLS 1.3. - * If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any - * effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED - -/** - * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED - * - * Enable TLS 1.3 PSK ephemeral key exchange mode. - * - * Requires: MBEDTLS_ECDH_C - * - * Comment to disable support for the PSK ephemeral key exchange mode in - * TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not - * have any effect on the build. - * - */ -#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED - -/** - * \def MBEDTLS_SSL_EARLY_DATA - * - * Enable support for RFC 8446 TLS 1.3 early data. - * - * Requires: MBEDTLS_SSL_SESSION_TICKETS and either - * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or - * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED - * - * Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3 - * is not enabled, this option does not have any effect on the build. - * - * This feature is experimental, not completed and thus not ready for - * production. - * - */ -//#define MBEDTLS_SSL_EARLY_DATA - -/** - * \def MBEDTLS_SSL_MAX_EARLY_DATA_SIZE - * - * The default maximum amount of 0-RTT data. See the documentation of - * \c mbedtls_ssl_tls13_conf_max_early_data_size() for more information. - * - * It must be positive and smaller than UINT32_MAX. - * - * If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not - * have any impact on the build. - * - * This feature is experimental, not completed and thus not ready for - * production. - * - */ -#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 - -/** - * \def MBEDTLS_SSL_PROTO_DTLS - * - * Enable support for DTLS (all available versions). - * - * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. - * - * Requires: MBEDTLS_SSL_PROTO_TLS1_2 - * - * Comment this macro to disable support for DTLS - */ -#define MBEDTLS_SSL_PROTO_DTLS - -/** - * \def MBEDTLS_SSL_ALPN - * - * Enable support for RFC 7301 Application Layer Protocol Negotiation. - * - * Comment this macro to disable support for ALPN. - */ -#define MBEDTLS_SSL_ALPN - -/** - * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY - * - * Enable support for the anti-replay mechanism in DTLS. - * - * Requires: MBEDTLS_SSL_TLS_C - * MBEDTLS_SSL_PROTO_DTLS - * - * \warning Disabling this is often a security risk! - * See mbedtls_ssl_conf_dtls_anti_replay() for details. - * - * Comment this to disable anti-replay in DTLS. - */ -#define MBEDTLS_SSL_DTLS_ANTI_REPLAY - -/** - * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Enable support for HelloVerifyRequest on DTLS servers. - * - * This feature is highly recommended to prevent DTLS servers being used as - * amplifiers in DoS attacks against other hosts. It should always be enabled - * unless you know for sure amplification cannot be a problem in the - * environment in which your server operates. - * - * \warning Disabling this can be a security risk! (see above) - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Comment this to disable support for HelloVerifyRequest. - */ -#define MBEDTLS_SSL_DTLS_HELLO_VERIFY - -/** - * \def MBEDTLS_SSL_DTLS_SRTP - * - * Enable support for negotiation of DTLS-SRTP (RFC 5764) - * through the use_srtp extension. - * - * \note This feature provides the minimum functionality required - * to negotiate the use of DTLS-SRTP and to allow the derivation of - * the associated SRTP packet protection key material. - * In particular, the SRTP packet protection itself, as well as the - * demultiplexing of RTP and DTLS packets at the datagram layer - * (see Section 5 of RFC 5764), are not handled by this feature. - * Instead, after successful completion of a handshake negotiating - * the use of DTLS-SRTP, the extended key exporter API - * mbedtls_ssl_conf_export_keys_cb() should be used to implement - * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 - * (this is implemented in the SSL example programs). - * The resulting key should then be passed to an SRTP stack. - * - * Setting this option enables the runtime API - * mbedtls_ssl_conf_dtls_srtp_protection_profiles() - * through which the supported DTLS-SRTP protection - * profiles can be configured. You must call this API at - * runtime if you wish to negotiate the use of DTLS-SRTP. - * - * Requires: MBEDTLS_SSL_PROTO_DTLS - * - * Uncomment this to enable support for use_srtp extension. - */ -//#define MBEDTLS_SSL_DTLS_SRTP - -/** - * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - * - * Enable server-side support for clients that reconnect from the same port. - * - * Some clients unexpectedly close the connection and try to reconnect using the - * same source port. This needs special support from the server to handle the - * new connection securely, as described in section 4.2.8 of RFC 6347. This - * flag enables that support. - * - * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY - * - * Comment this to disable support for clients reusing the source port. - */ -#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE - -/** - * \def MBEDTLS_SSL_SESSION_TICKETS - * - * Enable support for RFC 5077 session tickets in SSL. - * Client-side, provides full support for session tickets (maintenance of a - * session store remains the responsibility of the application, though). - * Server-side, you also need to provide callbacks for writing and parsing - * tickets, including authenticated encryption and key management. Example - * callbacks are provided by MBEDTLS_SSL_TICKET_C. - * - * Comment this macro to disable support for SSL session tickets - */ -#define MBEDTLS_SSL_SESSION_TICKETS - -/** - * \def MBEDTLS_SSL_SERVER_NAME_INDICATION - * - * Enable support for RFC 6066 server name indication (SNI) in SSL. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Comment this macro to disable support for server name indication in SSL - */ -#define MBEDTLS_SSL_SERVER_NAME_INDICATION - -/** - * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - * - * When this option is enabled, the SSL buffer will be resized automatically - * based on the negotiated maximum fragment length in each direction. - * - * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - */ -//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - * - * Enable testing of the constant-flow nature of some sensitive functions with - * clang's MemorySanitizer. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires compiling with clang -fsanitize=memory. The test - * suites can then be run normally. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN - -/** - * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - * - * Enable testing of the constant-flow nature of some sensitive functions with - * valgrind's memcheck tool. This causes some existing tests to also test - * this non-functional property of the code under test. - * - * This setting requires valgrind headers for building, and is only useful for - * testing if the tests suites are run with valgrind's memcheck. This can be - * done for an individual test suite with 'valgrind ./test_suite_xxx', or when - * using CMake, this can be done for all test suites with 'make memcheck'. - * - * \warning This macro is only used for extended testing; it is not considered - * part of the library's API, so it may change or disappear at any time. - * - * Uncomment to enable testing of the constant-flow nature of selected code. - */ -//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND - -/** - * \def MBEDTLS_TEST_HOOKS - * - * Enable features for invasive testing such as introspection functions and - * hooks for fault injection. This enables additional unit tests. - * - * Merely enabling this feature should not change the behavior of the product. - * It only adds new code, and new branching points where the default behavior - * is the same as when this feature is disabled. - * However, this feature increases the attack surface: there is an added - * risk of vulnerabilities, and more gadgets that can make exploits easier. - * Therefore this feature must never be enabled in production. - * - * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more - * information. - * - * Uncomment to enable invasive tests. - */ -//#define MBEDTLS_TEST_HOOKS - -/** - * \def MBEDTLS_THREADING_ALT - * - * Provide your own alternate threading implementation. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to allow your own alternate threading implementation. - */ -//#define MBEDTLS_THREADING_ALT - -/** - * \def MBEDTLS_THREADING_PTHREAD - * - * Enable the pthread wrapper layer for the threading layer. - * - * Requires: MBEDTLS_THREADING_C - * - * Uncomment this to enable pthread mutexes. - */ -//#define MBEDTLS_THREADING_PTHREAD - -/** - * \def MBEDTLS_USE_PSA_CRYPTO - * - * Make the X.509 and TLS library use PSA for cryptographic operations, and - * enable new APIs for using keys handled by PSA Crypto. - * - * \note Development of this option is currently in progress, and parts of Mbed - * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts - * will still continue to work as usual, so enabling this option should not - * break backwards compatibility. - * - * \note See docs/use-psa-crypto.md for a complete description of what this - * option currently does, and of parts that are not affected by it so far. - * - * \warning If you enable this option, you need to call `psa_crypto_init()` - * before calling any function from the SSL/TLS, X.509 or PK modules. - * - * Requires: MBEDTLS_PSA_CRYPTO_C. - * - * Uncomment this to enable internal use of PSA Crypto and new associated APIs. - */ -//#define MBEDTLS_USE_PSA_CRYPTO - -/** - * \def MBEDTLS_PSA_CRYPTO_CONFIG - * - * This setting allows support for cryptographic mechanisms through the PSA - * API to be configured separately from support through the mbedtls API. - * - * When this option is disabled, the PSA API exposes the cryptographic - * mechanisms that can be implemented on top of the `mbedtls_xxx` API - * configured with `MBEDTLS_XXX` symbols. - * - * When this option is enabled, the PSA API exposes the cryptographic - * mechanisms requested by the `PSA_WANT_XXX` symbols defined in - * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are - * automatically enabled if required (i.e. if no PSA driver provides the - * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols - * in mbedtls_config.h. - * - * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies - * an alternative header to include instead of include/psa/crypto_config.h. - * - * This feature is still experimental and is not ready for production since - * it is not completed. - */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG - -/** - * \def MBEDTLS_VERSION_FEATURES - * - * Allow run-time checking of compile-time enabled features. Thus allowing users - * to check at run-time if the library is for instance compiled with threading - * support via mbedtls_version_check_feature(). - * - * Requires: MBEDTLS_VERSION_C - * - * Comment this to disable run-time checking and save ROM space - */ -#define MBEDTLS_VERSION_FEATURES - -/** - * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - * - * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` - * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure - * the set of trusted certificates through a callback instead of a linked - * list. - * - * This is useful for example in environments where a large number of trusted - * certificates is present and storing them in a linked list isn't efficient - * enough, or when the set of trusted certificates changes frequently. - * - * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and - * `mbedtls_ssl_conf_ca_cb()` for more information. - * - * Requires: MBEDTLS_X509_CRT_PARSE_C - * - * Uncomment to enable trusted certificate callbacks. - */ -//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK - -/** - * \def MBEDTLS_X509_REMOVE_INFO - * - * Disable mbedtls_x509_*_info() and related APIs. - * - * Uncomment to omit mbedtls_x509_*_info(), as well as mbedtls_debug_print_crt() - * and other functions/constants only used by these functions, thus reducing - * the code footprint by several KB. - */ -//#define MBEDTLS_X509_REMOVE_INFO - -/** - * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT - * - * Enable parsing and verification of X.509 certificates, CRLs and CSRS - * signed with RSASSA-PSS (aka PKCS#1 v2.1). - * - * Comment this macro to disallow using RSASSA-PSS in certificates. - */ -#define MBEDTLS_X509_RSASSA_PSS_SUPPORT -/** \} name SECTION: mbed TLS feature support */ - -/** - * \name SECTION: mbed TLS modules - * - * This section enables or disables entire modules in mbed TLS - * \{ - */ - -/** - * \def MBEDTLS_AESNI_C - * - * Enable AES-NI support on x86-64 or x86-32. - * - * \note AESNI is only supported with certain compilers and target options: - * - Visual Studio 2013: supported. - * - GCC, x86-64, target not explicitly supporting AESNI: - * requires MBEDTLS_HAVE_ASM. - * - GCC, x86-32, target not explicitly supporting AESNI: - * not supported. - * - GCC, x86-64 or x86-32, target supporting AESNI: supported. - * For this assembly-less implementation, you must currently compile - * `library/aesni.c` and `library/aes.c` with machine options to enable - * SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or - * `clang -maes -mpclmul`. - * - Non-x86 targets: this option is silently ignored. - * - Other compilers: this option is silently ignored. - * - * \note - * Above, "GCC" includes compatible compilers such as Clang. - * The limitations on target support are likely to be relaxed in the future. - * - * Module: library/aesni.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM (on some platforms, see note) - * - * This modules adds support for the AES-NI instructions on x86. - */ -#define MBEDTLS_AESNI_C - -/** - * \def MBEDTLS_AESCE_C - * - * Enable AES cryptographic extension support on 64-bit Arm. - * - * Module: library/aesce.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM, MBEDTLS_AES_C - * - * \warning Runtime detection only works on Linux. For non-Linux operating - * system, Armv8-A Cryptographic Extensions must be supported by - * the CPU when this option is enabled. - * - * This module adds support for the AES Armv8-A Cryptographic Extensions on Aarch64 systems. - */ -#define MBEDTLS_AESCE_C - -/** - * \def MBEDTLS_AES_C - * - * Enable the AES block cipher. - * - * Module: library/aes.c - * Caller: library/cipher.c - * library/pem.c - * library/ctr_drbg.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA - * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA - * - * PEM_PARSE uses AES for decrypting encrypted keys. - */ -#define MBEDTLS_AES_C - -/** - * \def MBEDTLS_ASN1_PARSE_C - * - * Enable the generic ASN1 parser. - * - * Module: library/asn1.c - * Caller: library/x509.c - * library/dhm.c - * library/pkcs12.c - * library/pkcs5.c - * library/pkparse.c - */ -#define MBEDTLS_ASN1_PARSE_C - -/** - * \def MBEDTLS_ASN1_WRITE_C - * - * Enable the generic ASN1 writer. - * - * Module: library/asn1write.c - * Caller: library/ecdsa.c - * library/pkwrite.c - * library/x509_create.c - * library/x509write_crt.c - * library/x509write_csr.c - */ -#define MBEDTLS_ASN1_WRITE_C - -/** - * \def MBEDTLS_BASE64_C - * - * Enable the Base64 module. - * - * Module: library/base64.c - * Caller: library/pem.c - * - * This module is required for PEM support (required by X.509). - */ -#define MBEDTLS_BASE64_C - -/** - * \def MBEDTLS_BIGNUM_C - * - * Enable the multi-precision integer library. - * - * Module: library/bignum.c - * library/bignum_core.c - * library/bignum_mod.c - * library/bignum_mod_raw.c - * Caller: library/dhm.c - * library/ecp.c - * library/ecdsa.c - * library/rsa.c - * library/rsa_alt_helpers.c - * library/ssl_tls.c - * - * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. - */ -#define MBEDTLS_BIGNUM_C - -/** - * \def MBEDTLS_CAMELLIA_C - * - * Enable the Camellia block cipher. - * - * Module: library/camellia.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 - */ -#define MBEDTLS_CAMELLIA_C - -/** - * \def MBEDTLS_ARIA_C - * - * Enable the ARIA block cipher. - * - * Module: library/aria.c - * Caller: library/cipher.c - * - * This module enables the following ciphersuites (if other requisites are - * enabled as well): - * - * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 - * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 - * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 - * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 - */ -#define MBEDTLS_ARIA_C - -/** - * \def MBEDTLS_CCM_C - * - * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. - * - * Module: library/ccm.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or - * MBEDTLS_ARIA_C - * - * This module enables the AES-CCM ciphersuites, if other requisites are - * enabled as well. - */ -#define MBEDTLS_CCM_C - -/** - * \def MBEDTLS_CHACHA20_C - * - * Enable the ChaCha20 stream cipher. - * - * Module: library/chacha20.c - */ -#define MBEDTLS_CHACHA20_C - -/** - * \def MBEDTLS_CHACHAPOLY_C - * - * Enable the ChaCha20-Poly1305 AEAD algorithm. - * - * Module: library/chachapoly.c - * - * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C - */ -#define MBEDTLS_CHACHAPOLY_C - -/** - * \def MBEDTLS_CIPHER_C - * - * Enable the generic cipher layer. - * - * Module: library/cipher.c - * Caller: library/ccm.c - * library/cmac.c - * library/gcm.c - * library/nist_kw.c - * library/pkcs12.c - * library/pkcs5.c - * library/psa_crypto_aead.c - * library/psa_crypto_mac.c - * library/ssl_ciphersuites.c - * library/ssl_msg.c - * library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled) - * - * Uncomment to enable generic cipher wrappers. - */ -#define MBEDTLS_CIPHER_C - -/** - * \def MBEDTLS_CMAC_C - * - * Enable the CMAC (Cipher-based Message Authentication Code) mode for block - * ciphers. - * - * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying - * implementation of the CMAC algorithm is provided by an alternate - * implementation, that alternate implementation may opt to not support - * AES-192 or 3DES as underlying block ciphers for the CMAC operation. - * - * Module: library/cmac.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C - * - */ -#define MBEDTLS_CMAC_C - -/** - * \def MBEDTLS_CTR_DRBG_C - * - * Enable the CTR_DRBG AES-based random generator. - * The CTR_DRBG generator uses AES-256 by default. - * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. - * - * \note To achieve a 256-bit security strength with CTR_DRBG, - * you must use AES-256 *and* use sufficient entropy. - * See ctr_drbg.h for more details. - * - * Module: library/ctr_drbg.c - * Caller: - * - * Requires: MBEDTLS_AES_C - * - * This module provides the CTR_DRBG AES random number generator. - */ -#define MBEDTLS_CTR_DRBG_C - -/** - * \def MBEDTLS_DEBUG_C - * - * Enable the debug functions. - * - * Module: library/debug.c - * Caller: library/ssl_msg.c - * library/ssl_tls.c - * library/ssl_tls12_*.c - * library/ssl_tls13_*.c - * - * This module provides debugging functions. - */ -#define MBEDTLS_DEBUG_C - -/** - * \def MBEDTLS_DES_C - * - * Enable the DES block cipher. - * - * Module: library/des.c - * Caller: library/pem.c - * library/cipher.c - * - * PEM_PARSE uses DES/3DES for decrypting encrypted keys. - * - * \warning DES/3DES are considered weak ciphers and their use constitutes a - * security risk. We recommend considering stronger ciphers instead. - */ -#define MBEDTLS_DES_C - -/** - * \def MBEDTLS_DHM_C - * - * Enable the Diffie-Hellman-Merkle module. - * - * Module: library/dhm.c - * Caller: library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * DHE-RSA, DHE-PSK - * - * \warning Using DHE constitutes a security risk as it - * is not possible to validate custom DH parameters. - * If possible, it is recommended users should consider - * preferring other methods of key exchange. - * See dhm.h for more details. - * - */ -#define MBEDTLS_DHM_C - -/** - * \def MBEDTLS_ECDH_C - * - * Enable the elliptic curve Diffie-Hellman library. - * - * Module: library/ecdh.c - * Caller: library/psa_crypto.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK - * - * Requires: MBEDTLS_ECP_C - */ -#define MBEDTLS_ECDH_C - -/** - * \def MBEDTLS_ECDSA_C - * - * Enable the elliptic curve DSA library. - * - * Module: library/ecdsa.c - * Caller: - * - * This module is used by the following key exchanges: - * ECDHE-ECDSA - * - * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, - * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a - * short Weierstrass curve. - */ -#define MBEDTLS_ECDSA_C - -/** - * \def MBEDTLS_ECJPAKE_C - * - * Enable the elliptic curve J-PAKE library. - * - * \note EC J-PAKE support is based on the Thread v1.0.0 specification. - * It has not been reviewed for compliance with newer standards such as - * Thread v1.1 or RFC 8236. - * - * Module: library/ecjpake.c - * Caller: - * - * This module is used by the following key exchanges: - * ECJPAKE - * - * Requires: MBEDTLS_ECP_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C - * - * \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init() - * before doing any EC J-PAKE operations. - * - * \warning When building with MBEDTLS_MD_C, all hashes used with this - * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C, - * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by - * this module in builds where MBEDTLS_MD_C is disabled. - */ -#define MBEDTLS_ECJPAKE_C - -/** - * \def MBEDTLS_ECP_C - * - * Enable the elliptic curve over GF(p) library. - * - * Module: library/ecp.c - * Caller: library/ecdh.c - * library/ecdsa.c - * library/ecjpake.c - * - * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED - */ -#define MBEDTLS_ECP_C - -/** - * \def MBEDTLS_ENTROPY_C - * - * Enable the platform-specific entropy code. - * - * Module: library/entropy.c - * Caller: - * - * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C - * - * This module provides a generic entropy pool - */ -#define MBEDTLS_ENTROPY_C - -/** - * \def MBEDTLS_ERROR_C - * - * Enable error code to error string conversion. - * - * Module: library/error.c - * Caller: - * - * This module enables mbedtls_strerror(). - */ -#define MBEDTLS_ERROR_C - -/** - * \def MBEDTLS_GCM_C - * - * Enable the Galois/Counter Mode (GCM). - * - * Module: library/gcm.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or - * MBEDTLS_ARIA_C - * - * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other - * requisites are enabled as well. - */ -#define MBEDTLS_GCM_C - -/** - * \def MBEDTLS_HKDF_C - * - * Enable the HKDF algorithm (RFC 5869). - * - * Module: library/hkdf.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * This module adds support for the Hashed Message Authentication Code - * (HMAC)-based key derivation function (HKDF). - */ -#define MBEDTLS_HKDF_C - -/** - * \def MBEDTLS_HMAC_DRBG_C - * - * Enable the HMAC_DRBG random generator. - * - * Module: library/hmac_drbg.c - * Caller: - * - * Requires: MBEDTLS_MD_C - * - * Uncomment to enable the HMAC_DRBG random number generator. - */ -#define MBEDTLS_HMAC_DRBG_C - -/** - * \def MBEDTLS_LMS_C - * - * Enable the LMS stateful-hash asymmetric signature algorithm. - * - * Module: library/lms.c - * Caller: - * - * Requires: MBEDTLS_PSA_CRYPTO_C - * - * Uncomment to enable the LMS verification algorithm and public key operations. - */ -#define MBEDTLS_LMS_C - -/** - * \def MBEDTLS_LMS_PRIVATE - * - * Enable LMS private-key operations and signing code. Functions enabled by this - * option are experimental, and should not be used in production. - * - * Requires: MBEDTLS_LMS_C - * - * Uncomment to enable the LMS signature algorithm and private key operations. - */ -//#define MBEDTLS_LMS_PRIVATE - -/** - * \def MBEDTLS_NIST_KW_C - * - * Enable the Key Wrapping mode for 128-bit block ciphers, - * as defined in NIST SP 800-38F. Only KW and KWP modes - * are supported. At the moment, only AES is approved by NIST. - * - * Module: library/nist_kw.c - * - * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C - */ -#define MBEDTLS_NIST_KW_C - -/** - * \def MBEDTLS_MD_C - * - * Enable the generic layer for message digest (hashing) and HMAC. - * - * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C, - * MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C, - * MBEDTLS_SHA512_C. - * Module: library/md.c - * Caller: library/constant_time.c - * library/ecdsa.c - * library/ecjpake.c - * library/hkdf.c - * library/hmac_drbg.c - * library/pk.c - * library/pkcs5.c - * library/pkcs12.c - * library/psa_crypto_ecp.c - * library/psa_crypto_rsa.c - * library/rsa.c - * library/ssl_cookie.c - * library/ssl_msg.c - * library/ssl_tls.c - * library/x509.c - * library/x509_crt.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Uncomment to enable generic message digest wrappers. - */ -#define MBEDTLS_MD_C - -/** - * \def MBEDTLS_MD5_C - * - * Enable the MD5 hash algorithm. - * - * Module: library/md5.c - * Caller: library/md.c - * library/pem.c - * library/ssl_tls.c - * - * This module is required for TLS 1.2 depending on the handshake parameters. - * Further, it is used for checking MD5-signed certificates, and for PBKDF1 - * when decrypting PEM-encoded encrypted keys. - * - * \warning MD5 is considered a weak message digest and its use constitutes a - * security risk. If possible, we recommend avoiding dependencies on - * it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_MD5_C - -/** - * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C - * - * Enable the buffer allocator implementation that makes use of a (stack) - * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() - * calls) - * - * Module: library/memory_buffer_alloc.c - * - * Requires: MBEDTLS_PLATFORM_C - * MBEDTLS_PLATFORM_MEMORY (to use it within mbed TLS) - * - * Enable this module to enable the buffer memory allocator. - */ -//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C - -/** - * \def MBEDTLS_NET_C - * - * Enable the TCP and UDP over IPv6/IPv4 networking routines. - * - * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) - * and Windows. For other platforms, you'll want to disable it, and write your - * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/net_sockets.c - * - * This module provides networking routines. - */ -#define MBEDTLS_NET_C - -/** - * \def MBEDTLS_OID_C - * - * Enable the OID database. - * - * Module: library/oid.c - * Caller: library/asn1write.c - * library/pkcs5.c - * library/pkparse.c - * library/pkwrite.c - * library/rsa.c - * library/x509.c - * library/x509_create.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * This modules translates between OIDs and internal values. - */ -#define MBEDTLS_OID_C - -/** - * \def MBEDTLS_PADLOCK_C - * - * Enable VIA Padlock support on x86. - * - * Module: library/padlock.c - * Caller: library/aes.c - * - * Requires: MBEDTLS_HAVE_ASM - * - * This modules adds support for the VIA PadLock on x86. - */ -#define MBEDTLS_PADLOCK_C - -/** - * \def MBEDTLS_PEM_PARSE_C - * - * Enable PEM decoding / parsing. - * - * Module: library/pem.c - * Caller: library/dhm.c - * library/pkparse.c - * library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for decoding / parsing PEM files. - */ -#define MBEDTLS_PEM_PARSE_C - -/** - * \def MBEDTLS_PEM_WRITE_C - * - * Enable PEM encoding / writing. - * - * Module: library/pem.c - * Caller: library/pkwrite.c - * library/x509write_crt.c - * library/x509write_csr.c - * - * Requires: MBEDTLS_BASE64_C - * - * This modules adds support for encoding / writing PEM files. - */ -#define MBEDTLS_PEM_WRITE_C - -/** - * \def MBEDTLS_PK_C - * - * Enable the generic public (asymmetric) key layer. - * - * Module: library/pk.c - * Caller: library/psa_crypto_rsa.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * library/x509.c - * - * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C or MBEDTLS_ECP_C - * - * Uncomment to enable generic public key wrappers. - */ -#define MBEDTLS_PK_C - -/** - * \def MBEDTLS_PK_PARSE_C - * - * Enable the generic public (asymmetric) key parser. - * - * Module: library/pkparse.c - * Caller: library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key parse functions. - */ -#define MBEDTLS_PK_PARSE_C - -/** - * \def MBEDTLS_PK_WRITE_C - * - * Enable the generic public (asymmetric) key writer. - * - * Module: library/pkwrite.c - * Caller: library/x509write.c - * - * Requires: MBEDTLS_PK_C - * - * Uncomment to enable generic public key write functions. - */ -#define MBEDTLS_PK_WRITE_C - -/** - * \def MBEDTLS_PKCS5_C - * - * Enable PKCS#5 functions. - * - * Module: library/pkcs5.c - * - * Requires: MBEDTLS_CIPHER_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C. - * - * \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init() - * before doing any PKCS5 operation. - * - * \warning When building with MBEDTLS_MD_C, all hashes used with this - * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C, - * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by - * this module in builds where MBEDTLS_MD_C is disabled. - * - * This module adds support for the PKCS#5 functions. - */ -#define MBEDTLS_PKCS5_C - -/** - * \def MBEDTLS_PKCS7_C - * - * Enable PKCS #7 core for using PKCS #7-formatted signatures. - * RFC Link - https://tools.ietf.org/html/rfc2315 - * - * Module: library/pkcs7.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, - * MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C, - * MBEDTLS_BIGNUM_C, MBEDTLS_MD_C - * - * This module is required for the PKCS #7 parsing modules. - */ -#define MBEDTLS_PKCS7_C - -/** - * \def MBEDTLS_PKCS12_C - * - * Enable PKCS#12 PBE functions. - * Adds algorithms for parsing PKCS#8 encrypted private keys - * - * Module: library/pkcs12.c - * Caller: library/pkparse.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_CIPHER_C and either - * MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C. - * - * \warning If building without MBEDTLS_MD_C, you must call psa_crypto_init() - * before doing any PKCS12 operation. - * - * \warning When building with MBEDTLS_MD_C, all hashes used with this - * need to be available as built-ins (that is, for SHA-256, MBEDTLS_SHA256_C, - * etc.) as opposed to just PSA drivers. So far, PSA drivers are only used by - * this module in builds where MBEDTLS_MD_C is disabled. - * - * This module enables PKCS#12 functions. - */ -#define MBEDTLS_PKCS12_C - -/** - * \def MBEDTLS_PLATFORM_C - * - * Enable the platform abstraction layer that allows you to re-assign - * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). - * - * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT - * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned - * above to be specified at runtime or compile time respectively. - * - * \note This abstraction layer must be enabled on Windows (including MSYS2) - * as other modules rely on it for a fixed snprintf implementation. - * - * Module: library/platform.c - * Caller: Most other .c files - * - * This module enables abstraction of common (libc) functions. - */ -#define MBEDTLS_PLATFORM_C - -/** - * \def MBEDTLS_POLY1305_C - * - * Enable the Poly1305 MAC algorithm. - * - * Module: library/poly1305.c - * Caller: library/chachapoly.c - */ -#define MBEDTLS_POLY1305_C - -/** - * \def MBEDTLS_PSA_CRYPTO_C - * - * Enable the Platform Security Architecture cryptography API. - * - * Module: library/psa_crypto.c - * - * Requires: MBEDTLS_CIPHER_C, - * either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, - * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, - * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. - * - */ -#define MBEDTLS_PSA_CRYPTO_C - -/** - * \def MBEDTLS_PSA_CRYPTO_SE_C - * - * Enable dynamic secure element support in the Platform Security Architecture - * cryptography API. - * - * \deprecated This feature is deprecated. Please switch to the driver - * interface enabled by #MBEDTLS_PSA_CRYPTO_DRIVERS. - * - * Module: library/psa_crypto_se.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C - * - */ -//#define MBEDTLS_PSA_CRYPTO_SE_C - -/** - * \def MBEDTLS_PSA_CRYPTO_STORAGE_C - * - * Enable the Platform Security Architecture persistent key storage. - * - * Module: library/psa_crypto_storage.c - * - * Requires: MBEDTLS_PSA_CRYPTO_C, - * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of - * the PSA ITS interface - */ -#define MBEDTLS_PSA_CRYPTO_STORAGE_C - -/** - * \def MBEDTLS_PSA_ITS_FILE_C - * - * Enable the emulation of the Platform Security Architecture - * Internal Trusted Storage (PSA ITS) over files. - * - * Module: library/psa_its_file.c - * - * Requires: MBEDTLS_FS_IO - */ -#define MBEDTLS_PSA_ITS_FILE_C - -/** - * \def MBEDTLS_RIPEMD160_C - * - * Enable the RIPEMD-160 hash algorithm. - * - * Module: library/ripemd160.c - * Caller: library/md.c - * - */ -#define MBEDTLS_RIPEMD160_C - -/** - * \def MBEDTLS_RSA_C - * - * Enable the RSA public-key cryptosystem. - * - * Module: library/rsa.c - * library/rsa_alt_helpers.c - * Caller: library/pk.c - * library/psa_crypto.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module is used by the following key exchanges: - * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C - */ -#define MBEDTLS_RSA_C - -/** - * \def MBEDTLS_SHA1_C - * - * Enable the SHA1 cryptographic hash algorithm. - * - * Module: library/sha1.c - * Caller: library/md.c - * library/psa_crypto_hash.c - * - * This module is required for TLS 1.2 depending on the handshake parameters, - * and for SHA1-signed certificates. - * - * \warning SHA-1 is considered a weak message digest and its use constitutes - * a security risk. If possible, we recommend avoiding dependencies - * on it, and considering stronger message digests instead. - * - */ -#define MBEDTLS_SHA1_C - -/** - * \def MBEDTLS_SHA224_C - * - * Enable the SHA-224 cryptographic hash algorithm. - * - * Module: library/sha256.c - * Caller: library/md.c - * library/ssl_cookie.c - * - * This module adds support for SHA-224. - */ -#define MBEDTLS_SHA224_C - -/** - * \def MBEDTLS_SHA256_C - * - * Enable the SHA-256 cryptographic hash algorithm. - * - * Module: library/sha256.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * This module adds support for SHA-256. - * This module is required for the SSL/TLS 1.2 PRF function. - */ -#define MBEDTLS_SHA256_C - -/** - * \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT - * - * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions if they are available at runtime. - * If not, the library will fall back to the C implementation. - * - * \note If MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT is defined when building - * for a non-Aarch64 build it will be silently ignored. - * - * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the - * same time as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. - * - * Requires: MBEDTLS_SHA256_C. - * - * Module: library/sha256.c - * - * Uncomment to have the library check for the A64 SHA-256 crypto extensions - * and use them if available. - */ -#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT - -/** - * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY - * - * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions, which must be available at runtime - * or else an illegal instruction fault will occur. - * - * \note This allows builds with a smaller code size than with - * MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT - * - * \warning MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY cannot be defined at the same - * time as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. - * - * Requires: MBEDTLS_SHA256_C. - * - * Module: library/sha256.c - * - * Uncomment to have the library use the A64 SHA-256 crypto extensions - * unconditionally. - */ -//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY - -/** - * \def MBEDTLS_SHA384_C - * - * Enable the SHA-384 cryptographic hash algorithm. - * - * Module: library/sha512.c - * Caller: library/md.c - * library/psa_crypto_hash.c - * library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * Comment to disable SHA-384 - */ -#define MBEDTLS_SHA384_C - -/** - * \def MBEDTLS_SHA512_C - * - * Enable SHA-512 cryptographic hash algorithms. - * - * Module: library/sha512.c - * Caller: library/entropy.c - * library/md.c - * library/ssl_tls.c - * library/ssl_cookie.c - * - * This module adds support for SHA-512. - */ -#define MBEDTLS_SHA512_C - -/** - * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT - * - * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions if they are available at runtime. - * If not, the library will fall back to the C implementation. - * - * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building - * for a non-Aarch64 build it will be silently ignored. - * - * \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or - * Clang >= 7. - * - * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the - * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. - * - * Requires: MBEDTLS_SHA512_C. - * - * Module: library/sha512.c - * - * Uncomment to have the library check for the A64 SHA-512 crypto extensions - * and use them if available. - */ -#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT - -/** - * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY - * - * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms - * with the ARMv8 cryptographic extensions, which must be available at runtime - * or else an illegal instruction fault will occur. - * - * \note This allows builds with a smaller code size than with - * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT - * - * \note The code uses the SHA-512 Neon intrinsics, so requires GCC >= 8 or - * Clang >= 7. - * - * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same - * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. - * - * Requires: MBEDTLS_SHA512_C. - * - * Module: library/sha512.c - * - * Uncomment to have the library use the A64 SHA-512 crypto extensions - * unconditionally. - */ -//#define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY - -/** - * \def MBEDTLS_SSL_CACHE_C - * - * Enable simple SSL cache implementation. - * - * Module: library/ssl_cache.c - * Caller: - * - * Requires: MBEDTLS_SSL_CACHE_C - */ -#define MBEDTLS_SSL_CACHE_C - -/** - * \def MBEDTLS_SSL_COOKIE_C - * - * Enable basic implementation of DTLS cookies for hello verification. - * - * Module: library/ssl_cookie.c - * Caller: - */ -#define MBEDTLS_SSL_COOKIE_C - -/** - * \def MBEDTLS_SSL_TICKET_C - * - * Enable an implementation of TLS server-side callbacks for session tickets. - * - * Module: library/ssl_ticket.c - * Caller: - * - * Requires: (MBEDTLS_CIPHER_C || MBEDTLS_USE_PSA_CRYPTO) && - * (MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C) - */ -#define MBEDTLS_SSL_TICKET_C - -/** - * \def MBEDTLS_SSL_CLI_C - * - * Enable the SSL/TLS client code. - * - * Module: library/ssl*_client.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS client support. - */ -#define MBEDTLS_SSL_CLI_C - -/** - * \def MBEDTLS_SSL_SRV_C - * - * Enable the SSL/TLS server code. - * - * Module: library/ssl*_server.c - * Caller: - * - * Requires: MBEDTLS_SSL_TLS_C - * - * This module is required for SSL/TLS server support. - */ -#define MBEDTLS_SSL_SRV_C - -/** - * \def MBEDTLS_SSL_TLS_C - * - * Enable the generic SSL/TLS code. - * - * Module: library/ssl_tls.c - * Caller: library/ssl*_client.c - * library/ssl*_server.c - * - * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C - * and at least one of the MBEDTLS_SSL_PROTO_XXX defines - * - * This module is required for SSL/TLS. - */ -#define MBEDTLS_SSL_TLS_C - -/** - * \def MBEDTLS_THREADING_C - * - * Enable the threading abstraction layer. - * By default mbed TLS assumes it is used in a non-threaded environment or that - * contexts are not shared between threads. If you do intend to use contexts - * between threads, you will need to enable this layer to prevent race - * conditions. See also our Knowledge Base article about threading: - * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading - * - * Module: library/threading.c - * - * This allows different threading implementations (self-implemented or - * provided). - * - * You will have to enable either MBEDTLS_THREADING_ALT or - * MBEDTLS_THREADING_PTHREAD. - * - * Enable this layer to allow use of mutexes within mbed TLS - */ -//#define MBEDTLS_THREADING_C - -/** - * \def MBEDTLS_TIMING_C - * - * Enable the semi-portable timing interface. - * - * \note The provided implementation only works on POSIX/Unix (including Linux, - * BSD and OS X) and Windows. On other platforms, you can either disable that - * module and provide your own implementations of the callbacks needed by - * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide - * your own implementation of the whole module by setting - * \c MBEDTLS_TIMING_ALT in the current file. - * - * \note The timing module will include time.h on suitable platforms - * regardless of the setting of MBEDTLS_HAVE_TIME, unless - * MBEDTLS_TIMING_ALT is used. See timing.c for more information. - * - * \note See also our Knowledge Base article about porting to a new - * environment: - * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS - * - * Module: library/timing.c - */ -#define MBEDTLS_TIMING_C - -/** - * \def MBEDTLS_VERSION_C - * - * Enable run-time version information. - * - * Module: library/version.c - * - * This module provides run-time version information. - */ -#define MBEDTLS_VERSION_C - -/** - * \def MBEDTLS_X509_USE_C - * - * Enable X.509 core for using certificates. - * - * Module: library/x509.c - * Caller: library/x509_crl.c - * library/x509_crt.c - * library/x509_csr.c - * - * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, - * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) - * - * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call - * psa_crypto_init() before doing any X.509 operation. - * - * This module is required for the X.509 parsing modules. - */ -#define MBEDTLS_X509_USE_C - -/** - * \def MBEDTLS_X509_CRT_PARSE_C - * - * Enable X.509 certificate parsing. - * - * Module: library/x509_crt.c - * Caller: library/ssl_tls.c - * library/ssl*_client.c - * library/ssl*_server.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 certificate parsing. - */ -#define MBEDTLS_X509_CRT_PARSE_C - -/** - * \def MBEDTLS_X509_CRL_PARSE_C - * - * Enable X.509 CRL parsing. - * - * Module: library/x509_crl.c - * Caller: library/x509_crt.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is required for X.509 CRL parsing. - */ -#define MBEDTLS_X509_CRL_PARSE_C - -/** - * \def MBEDTLS_X509_CSR_PARSE_C - * - * Enable X.509 Certificate Signing Request (CSR) parsing. - * - * Module: library/x509_csr.c - * Caller: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_USE_C - * - * This module is used for reading X.509 certificate request. - */ -#define MBEDTLS_X509_CSR_PARSE_C - -/** - * \def MBEDTLS_X509_CREATE_C - * - * Enable X.509 core for creating certificates. - * - * Module: library/x509_create.c - * - * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, - * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) - * - * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call - * psa_crypto_init() before doing any X.509 create operation. - * - * This module is the basis for creating X.509 certificates and CSRs. - */ -#define MBEDTLS_X509_CREATE_C - -/** - * \def MBEDTLS_X509_CRT_WRITE_C - * - * Enable creating X.509 certificates. - * - * Module: library/x509_crt_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate creation. - */ -#define MBEDTLS_X509_CRT_WRITE_C - -/** - * \def MBEDTLS_X509_CSR_WRITE_C - * - * Enable creating X.509 Certificate Signing Requests (CSR). - * - * Module: library/x509_csr_write.c - * - * Requires: MBEDTLS_X509_CREATE_C - * - * This module is required for X.509 certificate request writing. - */ -#define MBEDTLS_X509_CSR_WRITE_C - -/** \} name SECTION: mbed TLS modules */ - -/** - * \name SECTION: General configuration options - * - * This section contains Mbed TLS build settings that are not associated - * with a particular module. - * - * \{ - */ - -/** - * \def MBEDTLS_CONFIG_FILE - * - * If defined, this is a header which will be included instead of - * `"mbedtls/mbedtls_config.h"`. - * This header file specifies the compile-time configuration of Mbed TLS. - * Unlike other configuration options, this one must be defined on the - * compiler command line: a definition in `mbedtls_config.h` would have - * no effect. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -#define MBEDTLS_CONFIG_FILE "mbedtls/config.h" - -/** - * \def MBEDTLS_USER_CONFIG_FILE - * - * If defined, this is a header which will be included after - * `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE. - * This allows you to modify the default configuration, including the ability - * to undefine options that are enabled by default. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" - -/** - * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_config.h"`. - * This header file specifies which cryptographic mechanisms are available - * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and - * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" - -/** - * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE - * - * If defined, this is a header which will be included after - * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE. - * This allows you to modify the default configuration, including the ability - * to undefine options that are enabled by default. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" - -/** - * \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_platform.h"`. This file should declare the same identifiers - * as the one in Mbed TLS, but with definitions adapted to the platform on - * which the library code will run. - * - * \note The required content of this header can vary from one version of - * Mbed TLS to the next. Integrators who provide an alternative file - * should review the changes in the original file whenever they - * upgrade Mbed TLS. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_PLATFORM_FILE "psa/crypto_platform_alt.h" - -/** - * \def MBEDTLS_PSA_CRYPTO_STRUCT_FILE - * - * If defined, this is a header which will be included instead of - * `"psa/crypto_struct.h"`. This file should declare the same identifiers - * as the one in Mbed TLS, but with definitions adapted to the environment - * in which the library code will run. The typical use for this feature - * is to provide alternative type definitions on the client side in - * client-server integrations of PSA crypto, where operation structures - * contain handles instead of cryptographic data. - * - * \note The required content of this header can vary from one version of - * Mbed TLS to the next. Integrators who provide an alternative file - * should review the changes in the original file whenever they - * upgrade Mbed TLS. - * - * This macro is expanded after an \#include directive. This is a popular but - * non-standard feature of the C language, so this feature is only available - * with compilers that perform macro expansion on an \#include line. - * - * The value of this symbol is typically a path in double quotes, either - * absolute or relative to a directory on the include search path. - */ -//#define MBEDTLS_PSA_CRYPTO_STRUCT_FILE "psa/crypto_struct_alt.h" - -/** \} name SECTION: General configuration options */ - -/** - * \name SECTION: Module configuration options - * - * This section allows for the setting of module specific sizes and - * configuration options. The default values are already present in the - * relevant header files and should suffice for the regular use cases. - * - * Our advice is to enable options and change their values here - * only if you have a good reason and know the consequences. - * \{ - */ -/* The Doxygen documentation here is used when a user comments out a - * setting and runs doxygen themselves. On the other hand, when we typeset - * the full documentation including disabled settings, the documentation - * in specific modules' header files is used if present. When editing this - * file, make sure that each option is documented in exactly one place, - * plus optionally a same-line Doxygen comment here if there is a Doxygen - * comment in the specific module. */ - -/* MPI / BIGNUM options */ -//#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ -//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ - -/* CTR_DRBG options */ -//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with -// SHA-512, 32 with SHA-256) */ #define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is -// performed by default */ #define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input -// bytes */ #define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* HMAC_DRBG options */ -//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ -//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ -//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ -//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ - -/* ECP options */ -//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ -//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ - -/* Entropy options */ -//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ -//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ -//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware -// entropy source mbedtls_hardware_poll() before entropy is released */ - -/* Memory buffer allocator options */ -//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ - -/* Platform options */ -//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is -// defined. Don't define if no header is needed. */ #define MBEDTLS_PLATFORM_STD_CALLOC calloc /**< Default -// allocator to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_FREE free /**< Default free to use, can -// be undefined */ #define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must -// be enabled */ #define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ -//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to -// use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default -// nv_seed_write function to use, can be undefined */ #define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed -// file to read/write with default implementation */ - -/* To Use Function Macros MBEDTLS_PLATFORM_C must be enabled */ -/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ -//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. -// MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to -// use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ #define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< -// Default fprintf macro to use, can be undefined */ #define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default -// printf macro to use, can be undefined */ -/* Note: your snprintf must correctly zero-terminate the buffer! */ -//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ -//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to -// use, can be undefined */ #define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< -// Default nv_seed_write function to use, can be undefined */ - -/** \def MBEDTLS_CHECK_RETURN - * - * This macro is used at the beginning of the declaration of a function - * to indicate that its return value should be checked. It should - * instruct the compiler to emit a warning or an error if the function - * is called without checking its return value. - * - * There is a default implementation for popular compilers in platform_util.h. - * You can override the default implementation by defining your own here. - * - * If the implementation here is empty, this will effectively disable the - * checking of functions' return values. - */ -//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) - -/** \def MBEDTLS_IGNORE_RETURN - * - * This macro requires one argument, which should be a C function call. - * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this - * warning is suppressed. - */ -//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) - -/* PSA options */ -/** - * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the - * PSA crypto subsystem. - * - * If this option is unset: - * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG. - * - Otherwise, the PSA subsystem uses HMAC_DRBG with either - * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and - * on unspecified heuristics. - */ -//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 - -/** \def MBEDTLS_PSA_KEY_SLOT_COUNT - * Restrict the PSA library to supporting a maximum amount of simultaneously - * loaded keys. A loaded key is a key stored by the PSA Crypto core as a - * volatile key, or a persistent key which is loaded temporarily by the - * library as part of a crypto operation in flight. - * - * If this option is unset, the library will fall back to a default value of - * 32 keys. - */ -//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 - -/* SSL Cache options */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ -//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ - -/* SSL options */ - -/** \def MBEDTLS_SSL_IN_CONTENT_LEN - * - * Maximum length (in bytes) of incoming plaintext fragments. - * - * This determines the size of the incoming TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * \note When using a value less than the default of 16KB on the client, it is - * recommended to use the Maximum Fragment Length (MFL) extension to - * inform the server about this limitation. On the server, there - * is no supported, standardized way of informing the client about - * restriction on the maximum size of incoming messages, and unless - * the limitation has been communicated by other means, it is recommended - * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN - * while keeping the default value of 16KB for the incoming buffer. - * - * Uncomment to set the maximum plaintext size of the incoming I/O buffer. - */ -//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_CID_IN_LEN_MAX - * - * The maximum length of CIDs used for incoming DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX - * - * The maximum length of CIDs used for outgoing DTLS messages. - * - */ -//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 - -/** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY - * - * This option controls the use of record plaintext padding - * in TLS 1.3 and when using the Connection ID extension in DTLS 1.2. - * - * The padding will always be chosen so that the length of the - * padded plaintext is a multiple of the value of this option. - * - * Note: A value of \c 1 means that no padding will be used - * for outgoing records. - * - * Note: On systems lacking division instructions, - * a power of two should be preferred. - */ -//#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 - -/** \def MBEDTLS_SSL_OUT_CONTENT_LEN - * - * Maximum length (in bytes) of outgoing plaintext fragments. - * - * This determines the size of the outgoing TLS I/O buffer in such a way - * that it is capable of holding the specified amount of plaintext data, - * regardless of the protection mechanism used. - * - * It is possible to save RAM by setting a smaller outward buffer, while keeping - * the default inward 16384 byte buffer to conform to the TLS specification. - * - * The minimum required outward buffer size is determined by the handshake - * protocol's usage. Handshaking will fail if the outward buffer is too small. - * The specific size requirement depends on the configured ciphers and any - * certificate data which is sent during the handshake. - * - * Uncomment to set the maximum plaintext size of the outgoing I/O buffer. - */ -//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 - -/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING - * - * Maximum number of heap-allocated bytes for the purpose of - * DTLS handshake message reassembly and future message buffering. - * - * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN - * to account for a reassembled handshake message of maximum size, - * together with its reassembly bitmap. - * - * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) - * should be sufficient for all practical situations as it allows - * to reassembly a large handshake message (such as a certificate) - * while buffering multiple smaller handshake messages. - * - */ -//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 - -//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 or 384 bits) -//*/ #define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if -// HAVE_TIME, or in number of cookies issued */ - -/** - * Complete list of ciphersuites to use, in order of preference. - * - * \warning No dependency checking is done on that field! This option can only - * be used to restrict the set of available ciphersuites. It is your - * responsibility to make sure the needed modules are active. - * - * Use this to save a few hundred bytes of ROM (default ordering of all - * available ciphersuites) and a few to a few hundred bytes of RAM. - * - * The value below is only an example, not the default. - */ -//#define MBEDTLS_SSL_CIPHERSUITES -// MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - -/** - * \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE - * - * Maximum time difference in milliseconds tolerated between the age of a - * ticket from the server and client point of view. - * From the client point of view, the age of a ticket is the time difference - * between the time when the client proposes to the server to use the ticket - * (time of writing of the Pre-Shared Key Extension including the ticket) and - * the time the client received the ticket from the server. - * From the server point of view, the age of a ticket is the time difference - * between the time when the server receives a proposition from the client - * to use the ticket and the time when the ticket was created by the server. - * The server age is expected to be always greater than the client one and - * MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE defines the - * maximum difference tolerated for the server to accept the ticket. - * This is not used in TLS 1.2. - * - */ -#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000 - -/** - * \def MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH - * - * Size in bytes of a ticket nonce. This is not used in TLS 1.2. - * - * This must be less than 256. - */ -#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32 - -/** - * \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS - * - * Default number of NewSessionTicket messages to be sent by a TLS 1.3 server - * after handshake completion. This is not used in TLS 1.2 and relevant only if - * the MBEDTLS_SSL_SESSION_TICKETS option is enabled. - * - */ -#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1 - -/* X509 options */ -//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ -//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the -// null terminator character ('\0'). */ - -/** - * Uncomment the macro to let mbed TLS use your alternate implementation of - * mbedtls_platform_zeroize(). This replaces the default implementation in - * platform_util.c. - * - * mbedtls_platform_zeroize() is a widely used function across the library to - * zero a block of memory. The implementation is expected to be secure in the - * sense that it has been written to prevent the compiler from removing calls - * to mbedtls_platform_zeroize() as part of redundant code elimination - * optimizations. However, it is difficult to guarantee that calls to - * mbedtls_platform_zeroize() will not be optimized by the compiler as older - * versions of the C language standards do not provide a secure implementation - * of memset(). Therefore, MBEDTLS_PLATFORM_ZEROIZE_ALT enables users to - * configure their own implementation of mbedtls_platform_zeroize(), for - * example by using directives specific to their compiler, features from newer - * C standards (e.g using memset_s() in C11) or calling a secure memset() from - * their system (e.g explicit_bzero() in BSD). - */ -//#define MBEDTLS_PLATFORM_ZEROIZE_ALT - -/** - * Uncomment the macro to let Mbed TLS use your alternate implementation of - * mbedtls_platform_gmtime_r(). This replaces the default implementation in - * platform_util.c. - * - * gmtime() is not a thread-safe function as defined in the C standard. The - * library will try to use safer implementations of this function, such as - * gmtime_r() when available. However, if Mbed TLS cannot identify the target - * system, the implementation of mbedtls_platform_gmtime_r() will default to - * using the standard gmtime(). In this case, calls from the library to - * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex - * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the - * library are also guarded with this mutex to avoid race conditions. However, - * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will - * unconditionally use the implementation for mbedtls_platform_gmtime_r() - * supplied at compile time. - */ -//#define MBEDTLS_PLATFORM_GMTIME_R_ALT - -/** - * Enable the verified implementations of ECDH primitives from Project Everest - * (currently only Curve25519). This feature changes the layout of ECDH - * contexts and therefore is a compatibility break for applications that access - * fields of a mbedtls_ecdh_context structure directly. See also - * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. - */ -//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED - -/** \} name SECTION: Module configuration options */ diff --git a/include/ucall/ucall.h b/include/ucall/ucall.h index 866ec59..48ec63e 100644 --- a/include/ucall/ucall.h +++ b/include/ucall/ucall.h @@ -5,7 +5,7 @@ * * @addtogroup C * - * @brief Binary Interface for UCall. + * @brief UCall is fast JSON-RPC implementation using `io_uring` and SIMD on x86 and Arm. * * ## Basic Usage * @@ -44,15 +44,28 @@ extern "C" { #include // `size_t` #include // `int64_t` +/// @brief Opaque type-punned server handle. typedef void* ucall_server_t; + +/// @brief Opaque type-punned handle for a single Remote Procedure Call. typedef void* ucall_call_t; + +/// @brief Opaque type-punned handle for several batched Remote Procedure Calls. +typedef void* ucall_batch_call_t; + +/// @brief Opaque type-punned handle to identify dynamically defined endpoints. typedef void* ucall_callback_tag_t; + +/// @brief Type alias for immutable strings. typedef char const* ucall_str_t; typedef void (*ucall_callback_t)(ucall_call_t, ucall_callback_tag_t); +typedef void (*ucall_batch_callback_t)(ucall_batch_call_t, ucall_callback_tag_t); + /** - * @brief Configuration parameters for `ucall_init()`. + * @brief Configuration parameters for the UCall server. + * @see `ucall_init()` to initialize the server. */ typedef struct ucall_config_t { char const* hostname; @@ -65,6 +78,7 @@ typedef struct ucall_config_t { /// > STDOUT_FILENO: console output. /// > STDERR_FILENO: errors. int32_t logs_file_descriptor; + /// @brief Can be: /// > "human" will print human-readable unit-normalized lines. /// > "json" will output newline-delimited JSONs documents. @@ -75,19 +89,11 @@ typedef struct ucall_config_t { uint32_t max_lifetime_micro_seconds; uint32_t max_lifetime_exchanges; - /// @brief Enable SSL. - bool use_ssl; - /// @brief Private Key required for SSL. - char const* ssl_private_key_path; - /// @brief At least one certificate is required for SSL. - char const** ssl_certificates_paths; - /// @brief Certificates count. - size_t ssl_certificates_count; } ucall_config_t; /** * @brief Initializes the server state. - * + * * @param config Input and output argument, that will be updated to export set configuration. * @param server Output variable, which, on success, will be an initialized server. * Don't forget to free its memory with `ucall_free()` at the end. @@ -99,9 +105,10 @@ void ucall_free(ucall_server_t); /** * @brief Registers a function callback to be triggered by the server, * when a matching request arrives. - * + * * @param server Must be pre-initialized with `ucall_init()`. * @param name The string to be matched against "method" in every JSON request. + * Must be @b unique, and can't be reused in `ucall_add_batched_procedure`. * @param callback Function pointer to the callback. * @param callback_tag Optional payload/tag, often pointing to metadata about * expected "params", mostly used for higher-level runtimes, like CPython. @@ -113,42 +120,75 @@ void ucall_add_procedure( // ucall_callback_tag_t callback_tag); /** - * @brief Perform a single blocking round of polling on the current calling thread. + * @brief Perform a single blocking round of polling on the current calling thread. * * @param thread_idx Assuming that the `::server` itself has memory reserves for every - * thread, the caller must provide a `::thread_idx` uniquely identifying + * thread, the caller must provide a `::thread_idx` uniquely identifying * current thread with a number from zero to `::ucall_config_t::max_threads`. */ void ucall_take_call(ucall_server_t server, uint16_t thread_idx); /** - * @brief Blocks current thread, replying to requests in a potentially more efficient + * @brief Blocks current thread, replying to requests in a potentially more efficient * way, than just a `while` loop calling `ucall_take_call()`. * * @param thread_idx Assuming that the `::server` itself has memory reserves for every - * thread, the caller must provide a `::thread_idx` uniquely identifying current + * thread, the caller must provide a `::thread_idx` uniquely identifying current * thread with a number from zero to `::ucall_config_t::max_threads`. */ void ucall_take_calls(ucall_server_t server, uint16_t thread_idx); +/** + * @brief Extracts the named @b boolean parameter from the current request (call). + * @param call Encapsulates the context and the arguments of the current request. + * @param json_pointer A JSON Pointer to the parameter. + * @param json_pointer_length The length of the `::json_pointer`. + * @param output The output boolean. + * @return `true` if the parameter was found and successfully extracted. + */ bool ucall_param_named_bool( // ucall_call_t call, // ucall_str_t json_pointer, // size_t json_pointer_length, // bool* output); +/** + * @brief Extracts the named @b integral parameter from the current request (call). + * @param call Encapsulates the context and the arguments of the current request. + * @param json_pointer A JSON Pointer to the parameter. + * @param json_pointer_length The length of the `::json_pointer`. + * @param output The output 64-bit signed integer. + * @return `true` if the parameter was found and successfully extracted. + */ bool ucall_param_named_i64( // ucall_call_t call, // ucall_str_t json_pointer, // size_t json_pointer_length, // int64_t* output); +/** + * @brief Extracts the named @b floating-point parameter from the current request (call). + * @param call Encapsulates the context and the arguments of the current request. + * @param json_pointer A JSON Pointer to the parameter. + * @param json_pointer_length The length of the `::json_pointer`. + * @param output The output 64-bit double-precision float. + * @return `true` if the parameter was found and successfully extracted. + */ bool ucall_param_named_f64( // ucall_call_t call, // ucall_str_t json_pointer, // size_t json_pointer_length, // double* output); +/** + * @brief Extracts the named @b string parameter from the current request (call). + * @param call Encapsulates the context and the arguments of the current request. + * @param json_pointer A JSON Pointer to the parameter. + * @param json_pointer_length The length of the `::json_pointer`. + * @param output The output pointer for the string start. + * @param output_length The output length of the string. + * @return `true` if the parameter was found and successfully extracted. + */ bool ucall_param_named_str( // ucall_call_t call, // ucall_str_t json_pointer, // @@ -178,8 +218,63 @@ void ucall_call_reply_error_invalid_params(ucall_call_t); void ucall_call_reply_error_out_of_memory(ucall_call_t); void ucall_call_reply_error_unknown(ucall_call_t); -bool ucall_param_named_json(ucall_call_t, ucall_str_t, size_t, ucall_str_t*, size_t*); // TODO -bool ucall_param_positional_json(ucall_call_t, size_t, ucall_str_t*, size_t*); // TODO +/** + * @brief Extract the entire nested @b JSON object from the current request (call). + * @param call Encapsulates the context and the arguments of the current request. + * @param output The output buffer. + * @param output_length The length of the `::output`. + * @return `true` if the parameter was found and successfully extracted. + */ +bool ucall_param_named_json(ucall_call_t, ucall_str_t, size_t, ucall_str_t*, size_t*); + +/** + * @brief Extract the entire nested @b JSON object from the current request (call). + * @param call Encapsulates the context and the arguments of the current request. + * @param output The output buffer. + * @param output_length The length of the `::output`. + * @return `true` if the parameter was found and successfully extracted. + */ +bool ucall_param_positional_json(ucall_call_t, size_t, ucall_str_t*, size_t*); + +/** + * @brief Registers a function callback to be triggered by the server, adding an additional batching + * layer, which allows the server to collect multiple requests and process them in a single + * callback. Very handy for @b batch-processing, and high-latency opeations, like dispatching + * a GPU kernel for @b AI-inference. + * + * This function is different from the inherent ability of JSON-RPS to handle batched requests. + * In one case, the client is responsible for batching multiple requests into a single JSON array, + * and sending to the server. In this case, however, single or batch requests from different sources + * are packed together by the server, and dispatched to the callback when the batch is full. + * + * @param server Must be pre-initialized with `ucall_init()`. + * @param name The string to be matched against "method" in every JSON request. + * Must be @b unique, and can't be reused in `ucall_add_batched_procedure`. + * @param max_batch_size The maximum number of requests to batch together. + * @param max_latency_micro_seconds The maximum time to wait for the batch to fill up. + * If the batch is not full, the server will dispatch the callback after this time. + * + * @param callback Function pointer to the callback. + * @param callback_tag Optional payload/tag, often pointing to metadata about + * expected "params", mostly used for higher-level runtimes, like CPython. + * + * @see `ucall_batch_size` to extract the number of calls in the batch. + * @see `ucall_batch_unpack` to enumerate separate calls from within the batch. + */ +void ucall_batch_add_procedure( // + ucall_server_t server, // + ucall_str_t name, // + size_t max_batch_size, // + size_t max_latency_micro_seconds, // + ucall_batch_callback_t callback, // + ucall_callback_tag_t callback_tag); + +/** + * @brief Introspects the structure of the batch request. + */ +size_t ucall_batch_size(ucall_batch_call_t batch); + +void ucall_batch_unpack(ucall_batch_call_t batch, ucall_call_t* call); #ifdef __cplusplus } /* end extern "C" */ diff --git a/pyproject.toml b/pyproject.toml index 3fcd1d9..c8a1c89 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,11 @@ +# This file configures wheels compilation for `cibuilwheel` for StringZilla CPython bindings. +# On a good day it will produce: +# - `macos` wheels for x86_64, arm64, and universal2; +# - `windows` wheels for AMD64, and ARM64. But not x86. +# - `manylinux` and `musllinux` wheels for Linux on x86_64, aarch64. But not i686, ppc64le, s390x; +# * for Python versions from 3.7 to 3.12. +# * for PyPy versions 3.7 and 3.10. +# = meaning 7 platforms * 10 Python versions = 70 builds. [build-system] requires = ["setuptools>=42", "wheel", "cmake>=3.22"] build-backend = "setuptools.build_meta" @@ -8,31 +16,61 @@ addopts = ["-ra", "--showlocals", "--strict-markers", "--strict-config"] xfail_strict = true filterwarnings = ["error"] +# Avoid running tests, as everything is happening in a super slow container +# We have already run all the relavent Python tests in `prerelease.yml` +# test-requires = ["pytest"] +# test-command = "pytest {project}/python/scripts" [tool.cibuildwheel] +test-requires = [] +test-command = "" build-verbosity = 0 +skip = [] + +[tool.cibuildwheel.linux] +archs = ["x86_64", "aarch64"] before-build = [ - "rm -rf {project}/CMakeCache.txt {project}/build {project}/build_debug {project}/CMakeFiles.txt {project}/_deps", - "mkdir -p build/ucall", + "rm -rf {project}/CMakeCache.txt {project}/build {project}/build_debug {project}/CMakeFiles.txt {project}/_deps {project}/.pytest_cache", + "mkdir -p build/usearch", + "git submodule update --init --recursive", ] -skip = ["*musllinux*", "*i686*", "pp*", "cp36-*", "cp37-*", "cp38-*"] - -[tool.cibuildwheel.linux] +# Use more recent images for the most popular SIMD-capable CPU architectures, to have access to newer compilers. +# Otherwise, prepare yourself to all kinds of AVX-512 issues and other SIMD-related pain. +# You can keep track of the most recent images on Quay: +# - for `manylinux`: https://quay.io/search?q=manylinux +# - for `musllinux`: https://quay.io/search?q=musllinux manylinux-x86_64-image = "manylinux_2_28" manylinux-aarch64-image = "manylinux_2_28" +musllinux-x86_64-image = "musllinux_1_2" +musllinux-aarch64-image = "musllinux_1_2" -archs = ["x86_64", "aarch64"] -before-all = ["yum install -y glibc-devel wget python3-devel"] repair-wheel-command = "auditwheel repair --lib-sdir . -w {dest_dir} {wheel}" +# On CentOS we have to use `yum`. +# The healthy version would be: `apt-get update && apt-get install -y libc6-dev wget python3-dev`. +before-all = ["yum update -y && yum install -y glibc-devel wget python3-devel"] + +# With `musl` builds, we obviously don't need the `glibc` and can't use `yum`. +# This may also be handy for using custom dependencies for different Python versions: +# https://cibuildwheel.readthedocs.io/en/stable/options/#overrides +[[tool.cibuildwheel.overrides]] +select = "*-musllinux*" +before-all = "apk add --update wget python3-dev" + [tool.cibuildwheel.macos] archs = ["x86_64", "universal2", "arm64"] +before-build = [ + "rm -rf {project}/CMakeCache.txt {project}/build {project}/build_debug {project}/CMakeFiles.txt {project}/_deps {project}/.pytest_cache", + "mkdir -p build/usearch", + "git submodule update --init --recursive", +] repair-wheel-command = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}" + [tool.cibuildwheel.windows] +archs = ["AMD64", "ARM64"] before-build = [ - "rd /s /q {project}\\CMakeCache.txt {project}\\build {project}\\build_debug {project}\\CMakeFiles.txt {project}\\_deps || echo Done", - "md build\\ucall", + "rd /s /q {project}\\CMakeCache.txt {project}\\build {project}\\build_debug {project}\\CMakeFiles.txt {project}\\_deps {project}\\.pytest_cache || echo Done", + "md build\\usearch", + "git submodule update --init --recursive", ] -archs = ["x86", "AMD64"] -skip = ["*win32*", "pp*"] diff --git a/src/python.c b/python/lib.c similarity index 93% rename from src/python.c rename to python/lib.c index 3fa7c6f..166c593 100644 --- a/src/python.c +++ b/python/lib.c @@ -1,11 +1,11 @@ /** * @brief Pure CPython bindings for UCall. * @author Ash Vardanian - * @file python.c + * @file lib.c * @date 2023-01-30 - * + * * @copyright Copyright (c) 2023 - * + * * @see Reading Materials * https://pythoncapi.readthedocs.io/type_object.html * https://numpy.org/doc/stable/reference/c-api/types-and-structures.html @@ -44,7 +44,7 @@ typedef enum { } py_param_kind_t; typedef struct { - const char* name; // Name or NULL + char const* name; // Name or NULL Py_ssize_t name_len; // Name Length PyObject* value; // Any or NULL PyTypeObject* type; // Type or NULL @@ -402,7 +402,6 @@ static PyMappingMethods server_mapping_methods = { static void server_dealloc(py_server_t* self) { free(self->wrappers); - free(self->config.ssl_certificates_paths); ucall_free(self->server); Py_TYPE(self)->tp_free((PyObject*)self); } @@ -413,7 +412,7 @@ static PyObject* server_new(PyTypeObject* type, PyObject* args, PyObject* keywor } static int server_init(py_server_t* self, PyObject* args, PyObject* keywords) { - static const char const* keywords_list[] = { + static char const const* keywords_list[] = { "hostname", "port", "queue_depth", "max_callbacks", "max_threads", "count_threads", "quiet", "ssl_pk", "ssl_certs", NULL, }; @@ -429,20 +428,12 @@ static int server_init(py_server_t* self, PyObject* args, PyObject* keywords) { PyObject* certs_path = NULL; - if (!PyArg_ParseTupleAndKeywords(args, keywords, "|snnnnnpsO", (char**)keywords_list, // + if (!PyArg_ParseTupleAndKeywords(args, keywords, "|snnnnnp", (char**)keywords_list, // &self->config.hostname, &self->config.port, &self->config.queue_depth, &self->config.max_callbacks, &self->config.max_threads, &self->count_threads, - &self->quiet, &self->config.ssl_private_key_path, &certs_path)) + &self->quiet)) return -1; - if (self->config.ssl_private_key_path && certs_path && PySequence_Check(certs_path)) { - self->config.use_ssl = true; - self->config.ssl_certificates_count = PySequence_Length(certs_path); - self->config.ssl_certificates_paths = (char**)malloc(sizeof(char*) * self->config.ssl_certificates_count); - for (size_t i = 0; i < self->config.ssl_certificates_count; i++) - self->config.ssl_certificates_paths[i] = PyUnicode_AsUTF8AndSize(PySequence_GetItem(certs_path, i), NULL); - } - self->wrapper_capacity = 16; self->wrappers = (py_wrapper_t*)malloc(self->wrapper_capacity * sizeof(py_wrapper_t)); @@ -512,22 +503,28 @@ int main(int argc, char* argv[]) { exit(1); } - /* Add a built-in module, before Py_Initialize */ + // Add a built-in module, before Py_Initialize if (PyImport_AppendInittab("ucall." stringify_value_m(UCALL_PYTHON_MODULE_NAME), pyinit_f_m) == -1) { fprintf(stderr, "Error: could not extend in-built modules table\n"); exit(1); } - /* Pass argv[0] to the Python interpreter */ - Py_SetProgramName(program); + // Pass argv[0] to the Python interpreter + PyConfig config; + PyConfig_InitPythonConfig(&config); + config.program_name = program; - /* Initialize the Python interpreter. Required. - If this step fails, it will be a fatal error. */ - Py_Initialize(); + // Initialize the Python interpreter. Required. + // If this step fails, it will be a fatal error. + PyStatus status = Py_InitializeFromConfig(&config); + if (PyStatus_Exception(status)) { + fprintf(stderr, "Couldn't initialize from config\n"); + exit(1); + } + PyConfig_Clear(&config); - /* Optionally import the module; alternatively, - import can be deferred until the embedded script - imports it. */ + // Optionally import the module; alternatively, import can be deferred + // until the embedded script imports it. PyObject* pmodule = PyImport_ImportModule("ucall." stringify_value_m(UCALL_PYTHON_MODULE_NAME)); if (!pmodule) { PyErr_Print(); @@ -537,8 +534,7 @@ int main(int argc, char* argv[]) { // Add version metadata { char version_str[50]; - sprintf(version_str, "%d.%d.%d", UCALL_VERSION_MAJOR, UCALL_VERSION_MINOR, - UCALL_VERSION_PATCH); + sprintf(version_str, "%d.%d.%d", UCALL_VERSION_MAJOR, UCALL_VERSION_MINOR, UCALL_VERSION_PATCH); PyModule_AddStringConstant(pmodule, "__version__", version_str); } diff --git a/src/ucall/__init__.py b/python/ucall/__init__.py similarity index 100% rename from src/ucall/__init__.py rename to python/ucall/__init__.py diff --git a/src/ucall/_server.py b/python/ucall/_server.py similarity index 100% rename from src/ucall/_server.py rename to python/ucall/_server.py diff --git a/src/ucall/cli.py b/python/ucall/cli.py similarity index 100% rename from src/ucall/cli.py rename to python/ucall/cli.py diff --git a/src/ucall/client.py b/python/ucall/client.py similarity index 100% rename from src/ucall/client.py rename to python/ucall/client.py diff --git a/src/ucall/rich_posix.py b/python/ucall/rich_posix.py similarity index 100% rename from src/ucall/rich_posix.py rename to python/ucall/rich_posix.py diff --git a/src/ucall/rich_uring.py b/python/ucall/rich_uring.py similarity index 100% rename from src/ucall/rich_uring.py rename to python/ucall/rich_uring.py diff --git a/setup.py b/setup.py index e42c3f7..02feabc 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,13 @@ +# Uses CMake to compile UCall with `io_uring` and other CPython bindings. +# That is a multi-step process, that involves: +# 1. Build the C server as one library, like `libucall_server_posix.a` +# 2. Build the C binding, where target `py_ucall_posix` produces `py_ucall_posix.so` +# 3. Rename binding to `posix.cpython-312-x86_64-linux-gnu.so` import os import sys +import sysconfig import re +import glob import platform from os.path import dirname import multiprocessing @@ -17,6 +24,24 @@ long_description = f.read() +def print_dir_tree(startpath): + for root, dirs, files in os.walk(startpath): + level = root.replace(startpath, "").count(os.sep) + indent = " " * 4 * (level) + print(f"{indent}{os.path.basename(root)}/") + subindent = " " * 4 * (level + 1) + for f in files: + print(f"{subindent}{f}") + + +def get_expected_module_name(module_name): + # Get the suffix for shared object files (includes Python version and platform) + so_suffix = sysconfig.get_config_var("EXT_SUFFIX") + # Construct the expected module filename + expected_filename = f"{module_name}{so_suffix}" + return expected_filename + + class CMakeExtension(Extension): def __init__(self, name, source_dir=""): Extension.__init__(self, name, sources=[]) @@ -25,7 +50,11 @@ def __init__(self, name, source_dir=""): class CMakeBuild(build_ext): def build_extension(self, ext): - if "uring" in ext.name and platform.system() != "Linux": + package_name, _, module_name = ext.name.partition(".") + assert package_name == __lib_name__ + assert module_name in ["uring", "posix"] + + if module_name == "uring" and platform.system() != "Linux": return self.parallel = multiprocessing.cpu_count() // 2 @@ -52,23 +81,65 @@ def build_extension(self, ext): if archs: cmake_args += ["-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))] - # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level - # across all generators. build_args = [] if sys.platform.startswith("win32"): build_args += ["--config", "Release"] + # Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level + # across all generators. if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ: # self.parallel is a Python 3 only way to set parallel jobs by hand # using -j in the build_ext call, not supported by pip or PyPA-build. if hasattr(self, "parallel") and self.parallel: build_args += [f"-j{self.parallel}"] - subprocess.check_call(["cmake", ext.source_dir] + cmake_args) - subprocess.check_call( - ["cmake", "--build", ".", "--target", "py_" + ext.name.replace(".", "_")] - + build_args - ) + # Configure CMake + try: + subprocess.check_call(["cmake", ext.source_dir] + cmake_args) + except subprocess.CalledProcessError as e: + print(f"CMake for {ext.name} in {ext.source_dir} with args: {cmake_args}") + print(f"Resulted in error: {e}") + raise + + # Build with CMake + try: + binding_name = "py_ucall_" + module_name + expected_name = get_expected_module_name(module_name) + subprocess.check_call( + [ + "cmake", + "--build", + ".", + "--target", + binding_name, + ] + + build_args, + ) + + print( + f"Directory for `{ext.name}` extension should contain `{package_name}` / `{binding_name}`" + ) + print_dir_tree(self.build_lib) + + # Match a file in the build directory, that is named like the `binding_name`, + # regardless of the extension, and rename it to the `expected_name` with the same extension. + compiled_files_pattern = f"{self.build_lib}/{package_name}/{binding_name}.*" + compiled_files = list(glob.glob(compiled_files_pattern)) + assert ( + len(compiled_files) == 1 + ), f"Expected to find one file, but found {len(compiled_files)}: {compiled_files}" + + old_name = compiled_files[0] + new_name = os.path.join(os.path.dirname(old_name), expected_name) + os.rename(old_name, new_name) + + except subprocess.CalledProcessError as e: + print(f"Building {ext.name} with arguments: {build_args}") + print(f"Resulted in error: {e}") + raise + + print(f"Directory for `{ext.name}` extension should contain `{expected_name}`") + print_dir_tree(self.build_lib) def run(self): build_ext.run(self) @@ -97,6 +168,7 @@ def run(self): "Operating System :: POSIX", "Operating System :: POSIX :: Linux", "Operating System :: MacOS", + "Operating System :: Windows", "Programming Language :: C", "Programming Language :: C++", "Programming Language :: Python :: Implementation :: CPython", @@ -110,7 +182,7 @@ def run(self): "Topic :: System :: Networking", ], packages=["ucall"], - package_dir={"": "src"}, + package_dir={"": "python"}, ext_modules=[ CMakeExtension("ucall.uring"), CMakeExtension("ucall.posix"), diff --git a/src/engine_posix.cpp b/src/engine_posix.cpp index 70a80fb..cedc7f5 100644 --- a/src/engine_posix.cpp +++ b/src/engine_posix.cpp @@ -1,6 +1,6 @@ /** - * @brief JSON-RPC implementation for TCP/IP stack with POSIX calls. - * @author Ashot Vardanian + * @brief JSON-RPC implementation for TCP/IP stack with POSIX calls. + * @author Ash Vardanian */ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) @@ -38,13 +38,6 @@ #include // `std::to_chars` #include // `std::chrono` -#include "mbedtls/config.h" -#include -#include -#include -#include -#include - #include "ucall/ucall.h" #include "helpers/log.hpp" @@ -59,80 +52,11 @@ using time_point_t = std::chrono::time_point; static constexpr std::size_t initial_buffer_size_k = ram_page_size_k * 4; -struct ucall_ssl_context_t { - - ~ucall_ssl_context_t() noexcept { - mbedtls_x509_crt_free(&srvcert); - mbedtls_pk_free(&pkey); - mbedtls_ssl_free(&ssl); - mbedtls_ssl_config_free(&conf); - mbedtls_ssl_cache_free(&cache); - mbedtls_ctr_drbg_free(&ctr_drbg); - mbedtls_entropy_free(&entropy); - } - - int init(const char* pk_path, const char** crts_path, size_t crts_cnt) { - mbedtls_ssl_init(&ssl); - mbedtls_ssl_config_init(&conf); - mbedtls_ssl_cache_init(&cache); - mbedtls_x509_crt_init(&srvcert); - mbedtls_pk_init(&pkey); - mbedtls_entropy_init(&entropy); - mbedtls_ctr_drbg_init(&ctr_drbg); - int ret = 0; - - // Seed the RNG - if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) - // TODO Use personalization string. Required or Optional ? - return ret; - - // Load Private Key - if ((ret = mbedtls_pk_parse_keyfile(&pkey, pk_path, NULL, NULL, &ctr_drbg)) != 0) - // TODO Use Password. Required or Optional ? - return ret; - - // Load Certificates - for (size_t i = 0; i < crts_cnt; ++i) - if ((ret = mbedtls_x509_crt_parse_file(&srvcert, crts_path[i])) != 0) - // TODO Notify which certificate was invalid ? - return ret; - - if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT)) != 0) - return ret; - - mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg); - - mbedtls_ssl_conf_session_cache(&conf, &cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); - mbedtls_ssl_conf_renegotiation(&conf, MBEDTLS_SSL_RENEGOTIATION_DISABLED); - - mbedtls_ssl_conf_ca_chain(&conf, srvcert.next, NULL); - if ((ret = mbedtls_ssl_conf_own_cert(&conf, &srvcert, &pkey)) != 0) - return ret; - - if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) - return ret; - - return 0; - } - - mbedtls_ssl_context ssl{}; - mbedtls_ssl_config conf{}; - mbedtls_pk_context pkey{}; - mbedtls_x509_crt srvcert{}; - mbedtls_entropy_context entropy{}; - mbedtls_ssl_cache_context cache{}; - mbedtls_ctr_drbg_context ctr_drbg{}; -}; - struct engine_t { - ~engine_t() noexcept { delete ssl_ctx; } + ~engine_t() noexcept {} descriptor_t socket{}; - /// @brief Establishes an SSL connection if SSL is enabled, otherwise the `ssl_ctx` is unused and uninitialized. - ucall_ssl_context_t* ssl_ctx = nullptr; - /// @brief The file descriptor of the stateful connection over TCP. descriptor_t connection{}; /// @brief A small memory buffer to store small requests. @@ -169,13 +93,8 @@ void send_message(engine_t& engine, array_gt const& message) noexcept { long idx = 0; long res = 0; - if (engine.ssl_ctx) - while (idx < len && (res = mbedtls_ssl_write(&engine.ssl_ctx->ssl, reinterpret_cast(buf + idx), - (len - idx))) > 0) - idx += res; - else - while (idx < len && (res = send(engine.connection, buf + idx, len - idx, 0)) > 0) - idx += res; + while (idx < len && (res = send(engine.connection, buf + idx, len - idx, 0)) > 0) + idx += res; if (res < 0) { if (errno == EMSGSIZE) @@ -264,29 +183,12 @@ void forward_packet(engine_t& engine) noexcept { return forward_call_or_calls(engine); } -int ssl_send(void* ctx, const unsigned char* buf, size_t len) { - mbedtls_net_context* conn = reinterpret_cast(ctx); - ssize_t ret = send(conn->fd, reinterpret_cast(buf), len, 0); - return ret; -} - -int ssl_recv(void* ctx, unsigned char* buf, size_t len) { - mbedtls_net_context* conn = reinterpret_cast(ctx); - ssize_t ret = recv(conn->fd, reinterpret_cast(buf), len, 0); - return ret; -} - int recv_all(engine_t& engine, char* buf, size_t len) { size_t idx = 0; int res = 0; - if (engine.ssl_ctx) - while (idx < len && - (res = mbedtls_ssl_read(&engine.ssl_ctx->ssl, reinterpret_cast(buf + idx), (len - idx))) > 0) - idx += res; - else - while (idx < len && (res = recv(engine.connection, buf + idx, len - idx, 0)) > 0) - idx += res; + while (idx < len && (res = recv(engine.connection, buf + idx, len - idx, 0)) > 0) + idx += res; return idx; } @@ -320,20 +222,6 @@ void ucall_take_call(ucall_server_t server, uint16_t) { return; } - mbedtls_net_context client_ctx; - - if (engine.ssl_ctx) { - client_ctx.fd = connection_fd; - mbedtls_ssl_set_bio(&engine.ssl_ctx->ssl, &client_ctx, ssl_send, ssl_recv, NULL); - int ret = 0; - while ((ret = mbedtls_ssl_handshake(&engine.ssl_ctx->ssl)) != 0) - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - mbedtls_net_free(&client_ctx); - mbedtls_ssl_session_reset(&engine.ssl_ctx->ssl); - return; - } - } - // Wait until we have input. engine.connection = descriptor_t{connection_fd}; engine.stats.added_connections++; @@ -341,11 +229,7 @@ void ucall_take_call(ucall_server_t server, uint16_t) { char* buffer_ptr = &engine.packet_buffer[0]; size_t bytes_received = 0, bytes_expected = 0; - if (engine.ssl_ctx) - bytes_received = - mbedtls_ssl_read(&engine.ssl_ctx->ssl, reinterpret_cast(buffer_ptr), http_head_max_size_k); - else - bytes_received = recv(engine.connection, buffer_ptr, http_head_max_size_k, 0); + bytes_received = recv(engine.connection, buffer_ptr, http_head_max_size_k, 0); auto json_or_error = split_body_headers(std::string_view(buffer_ptr, bytes_received)); if (auto error_ptr = std::get_if(&json_or_error); error_ptr) @@ -401,14 +285,6 @@ void ucall_take_call(ucall_server_t server, uint16_t) { buffer_ptr = nullptr; } - if (engine.ssl_ctx) { - int ret = 0; - while ((ret = mbedtls_ssl_close_notify(&engine.ssl_ctx->ssl)) < 0) - if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) - break; - - mbedtls_ssl_session_reset(&engine.ssl_ctx->ssl); - } shutdown(connection_fd, SHUT_WR); // If later on some UB is detected for client not recieving full data, // then it may be required to put a `recv` with timeout between `shutdown` and `close` @@ -431,9 +307,6 @@ void ucall_init(ucall_config_t* config_inout, ucall_server_t* server_out) { config.max_callbacks = 128u; if (!config.hostname) config.hostname = "0.0.0.0"; - if (config.use_ssl && - !(config.ssl_private_key_path || config.ssl_certificates_paths || config.ssl_certificates_count)) - return; // Some limitations are hard-coded for this non-concurrent implementation config.max_threads = 1u; @@ -447,7 +320,6 @@ void ucall_init(ucall_config_t* config_inout, ucall_server_t* server_out) { engine_t* server_ptr = nullptr; array_gt buffer; array_gt embedded_callbacks; - ucall_ssl_context_t* ssl_context = nullptr; sjd::parser parser; // By default, let's open TCP port for IPv4. @@ -475,12 +347,6 @@ void ucall_init(ucall_config_t* config_inout, ucall_server_t* server_out) { goto cleanup; if (listen(socket_descriptor, config.queue_depth) < 0) goto cleanup; - if (config.use_ssl) { - ssl_context = new ucall_ssl_context_t(); - if (ssl_context->init(config.ssl_private_key_path, config.ssl_certificates_paths, - config.ssl_certificates_count) != 0) - goto cleanup; - } if (parser.allocate(ram_page_size_k, ram_page_size_k / 2) != sj::SUCCESS) goto cleanup; @@ -493,7 +359,6 @@ void ucall_init(ucall_config_t* config_inout, ucall_server_t* server_out) { server_ptr->logs_file_descriptor = config.logs_file_descriptor; server_ptr->logs_format = config.logs_format ? std::string_view(config.logs_format) : std::string_view(); server_ptr->log_last_time = time_clock_t::now(); - server_ptr->ssl_ctx = ssl_context; *server_out = (ucall_server_t)server_ptr; return; @@ -503,7 +368,6 @@ void ucall_init(ucall_config_t* config_inout, ucall_server_t* server_out) { close(socket_descriptor); std::free(server_ptr); *server_out = nullptr; - delete ssl_context; } void ucall_add_procedure(ucall_server_t server, ucall_str_t name, ucall_callback_t callback, @@ -705,4 +569,4 @@ bool ucall_param_positional_str(ucall_call_t call, size_t position, ucall_str_t* return true; } else return false; -} \ No newline at end of file +} diff --git a/src/engine_uring.cpp b/src/engine_uring.cpp index 7650786..bbccba8 100644 --- a/src/engine_uring.cpp +++ b/src/engine_uring.cpp @@ -35,7 +35,7 @@ * - `IORING_SETUP_COOP_TASKRUN` > 5.19. * - `IORING_SETUP_SINGLE_ISSUER` > 6.0. * - * @author Ashot Vardanian + * @author Ash Vardanian * * @see Notable links: * https://man7.org/linux/man-pages/dir_by_project.html#liburing @@ -487,7 +487,7 @@ void ucall_call_reply_content(ucall_call_t call, ucall_str_t body, size_t body_l return; body_len = string_length(body, body_len); - struct iovec iovecs[iovecs_for_content_k] {}; + struct iovec iovecs[iovecs_for_content_k]{}; fill_with_content(iovecs, scratch.dynamic_id, std::string_view(body, body_len), true); connection.pipes.append_outputs(iovecs); } @@ -507,7 +507,7 @@ void ucall_call_reply_error(ucall_call_t call, int code_int, ucall_str_t note, s if (res.ec != std::error_code()) return ucall_call_reply_error_unknown(call); - struct iovec iovecs[iovecs_for_error_k] {}; + struct iovec iovecs[iovecs_for_error_k]{}; fill_with_error(iovecs, scratch.dynamic_id, std::string_view(code, code_len), std::string_view(note, note_len), true); if (!connection.pipes.append_outputs(iovecs)) diff --git a/src/helpers/py_to_json.h b/src/helpers/py_to_json.h index 33836a3..7d0173b 100644 --- a/src/helpers/py_to_json.h +++ b/src/helpers/py_to_json.h @@ -5,7 +5,7 @@ #include -static const char int_to_hex_k[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; +static char const int_to_hex_k[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; static void char_to_hex(uint8_t const c, uint8_t* hex) { hex[0] = int_to_hex_k[c >> 4]; @@ -32,7 +32,7 @@ static int to_string(PyObject* obj, char* data, size_t* len) { *len = begin - data; } else if (PyUnicode_Check(obj)) { Py_ssize_t size; - const char* char_ptr = PyUnicode_AsUTF8AndSize(obj, &size); + char const* char_ptr = PyUnicode_AsUTF8AndSize(obj, &size); char* begin = data; *(begin++) = '"'; for (size_t i = 0; i != size; ++i) {