diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 69921a1..b800d44 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-22.04 strategy: matrix: - distro: [bullseye, bookworm] + distro: [bookworm] env: FORCE_COLOR: 1 steps: @@ -37,7 +37,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Build dependencies run: ceedling project:linux verbosity[4] clobber dependencies:make - name: Run wolfSSL Tests @@ -46,12 +46,26 @@ jobs: ./wolfcrypt/test/testwolfcrypt - name: Run build and test run: ceedling project:linux verbosity[4] test:all + linux-multithread: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + - name: Install Ceedling + run: sudo gem install ceedling -v 0.31.1 --no-user-install + - name: Build dependencies + run: ceedling project:linux_multithread verbosity[4] clobber dependencies:make + - name: Run wolfSSL Tests + run: | + cd third_party/wolfssl + ./wolfcrypt/test/testwolfcrypt + - name: Run build and test + run: ceedling project:linux_multithread verbosity[4] test:all linux-386: runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install gcc multi lib run: | sudo apt update @@ -69,7 +83,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install ARM Tools run: | sudo apt update @@ -87,7 +101,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install ARM Tools run: | sudo apt update @@ -105,7 +119,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install ARM Tools run: | sudo apt update @@ -123,7 +137,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install RISC-V Toolchain run: | sudo apt update @@ -141,7 +155,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install automake run: HOMEBREW_NO_AUTO_UPDATE=1 brew install autoconf automake libtool - name: Build dependencies @@ -153,7 +167,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install automake run: HOMEBREW_NO_AUTO_UPDATE=1 brew install autoconf automake libtool - name: Build dependencies @@ -168,20 +182,21 @@ jobs: config: [ { project: windows_64, arch: x64 }, + { project: windows_64_multithread, arch: x64 }, { project: windows_32, arch: x86 }, { project: windows_arm64, arch: amd64_arm64 }, ] steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: gem install ceedling --no-user-install + run: gem install ceedling -v 0.31.1 --no-user-install - name: Check Ceedling version run: ceedling version - name: Set up Visual Studio shell uses: TheMrMilchmann/setup-msvc-dev@v3 with: arch: ${{ matrix.config.arch }} - - if: ${{ matrix.config.project != 'windows_arm64' }} + - if: ${{ matrix.config.project != 'windows_arm64' }} # Skip making dependencies for ARM64 as we can only apply git patch once for WolfSSL name: Build dependencies run: ceedling project:${{ matrix.config.project }} verbosity[4] clobber dependencies:make @@ -196,7 +211,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install automake run: HOMEBREW_NO_AUTO_UPDATE=1 brew install autoconf automake libtool - name: Run build @@ -212,7 +227,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Install automake run: HOMEBREW_NO_AUTO_UPDATE=1 brew install autoconf automake libtool - name: Run build @@ -226,7 +241,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Install Ceedling - run: sudo gem install ceedling --no-user-install + run: sudo gem install ceedling -v 0.31.1 --no-user-install - name: Run build run: | source android/android_env.sh ${{ matrix.arch }} diff --git a/3rd_party_deps.yml b/3rd_party_deps.yml index c73ac9c..f6eddd4 100644 --- a/3rd_party_deps.yml +++ b/3rd_party_deps.yml @@ -16,7 +16,7 @@ --enable-dtls-frag-ch --enable-dtls-mtu --enable-secure-renegotiation - --enable-singlethreaded + --disable-singlethreaded --enable-sni --enable-sp=yes,4096 --enable-static diff --git a/Earthfile b/Earthfile index b2f6fd7..7cb241d 100644 --- a/Earthfile +++ b/Earthfile @@ -8,7 +8,7 @@ debian-deps: RUN apt-get -y install --no-install-recommends build-essential git automake m4 libtool-bin cmake ruby-full python3-pip # Not including colrm seems to give an error when configuring wolfssl RUN apt-get -y install --no-install-recommends bsdmainutils - RUN gem install ceedling --no-user-install + RUN gem install ceedling -v 0.31.1 --no-user-install RUN apt-get -y install --no-install-recommends gcovr libhelium-deps: diff --git a/linux_multithread.yml b/linux_multithread.yml new file mode 100644 index 0000000..a020a85 --- /dev/null +++ b/linux_multithread.yml @@ -0,0 +1,12 @@ +--- # ceedling project file for Linux +:import: + - linux.yml + +:defines: + :test: + - HE_ENABLE_MULTITHREADED + +:tools_test_linker: + :arguments: + - -latomic + diff --git a/src/he/conn.c b/src/he/conn.c index 7d9abb2..87ea70b 100644 --- a/src/he/conn.c +++ b/src/he/conn.c @@ -473,7 +473,7 @@ he_return_code_t he_internal_send_message(he_conn_t *conn, uint8_t *message, uin if(res == 0) { return HE_ERR_CONNECTION_WAS_CLOSED; } else { - conn->wolf_error = error; + he_conn_set_ssl_error(conn, error); return HE_ERR_SSL_ERROR; } } @@ -536,7 +536,7 @@ bool he_internal_is_valid_state_for_server_config(he_conn_t *conn) { } // The server config message is only valid after the TLS link is established - switch(conn->state) { + switch((int)conn->state) { case HE_STATE_LINK_UP: case HE_STATE_AUTHENTICATING: case HE_STATE_CONFIGURING: @@ -746,7 +746,7 @@ he_return_code_t he_internal_renegotiate_ssl(he_conn_t *conn) { case SECURE_RENEGOTIATION_E: return HE_ERR_SECURE_RENEGOTIATION_ERROR; default: - conn->wolf_error = error; + he_conn_set_ssl_error(conn, error); return HE_ERR_SSL_ERROR; } } @@ -1213,7 +1213,7 @@ he_return_code_t he_conn_start_pmtu_discovery(he_conn_t *conn) { if(conn->pmtud_state_change_cb == NULL || conn->pmtud_time_cb == NULL) { return HE_ERR_PMTUD_CALLBACKS_NOT_SET; } - if(conn->pmtud_state != HE_PMTUD_STATE_DISABLED) { + if(conn->pmtud.state != HE_PMTUD_STATE_DISABLED) { // PMTUD is already started return HE_SUCCESS; } @@ -1223,10 +1223,10 @@ he_return_code_t he_conn_start_pmtu_discovery(he_conn_t *conn) { } uint16_t he_conn_get_effective_pmtu(he_conn_t *conn) { - if(!conn || conn->effective_pmtu == 0) { + if(!conn || conn->pmtud.effective_pmtu == 0 || conn->pmtud.state != HE_PMTUD_STATE_SEARCH_COMPLETE) { return HE_MAX_MTU; } - return conn->effective_pmtu; + return conn->pmtud.effective_pmtu; } he_return_code_t he_conn_pmtud_probe_timeout(he_conn_t *conn) { @@ -1236,6 +1236,25 @@ he_return_code_t he_conn_pmtud_probe_timeout(he_conn_t *conn) { return he_internal_pmtud_handle_probe_timeout(conn); } +#ifdef HE_ENABLE_MULTITHREADED +// wolf_error as thread local variable, so it can be used +// from multiple threads without collision +HE_THREAD_LOCAL int wolf_error = 0; +#endif + +void he_conn_set_ssl_error(he_conn_t *conn, int error) { +#ifdef HE_ENABLE_MULTITHREADED + (void) conn; + wolf_error = error; +#else + conn->wolf_error = error; +#endif +} + int he_conn_get_ssl_error(he_conn_t *conn) { +#ifdef HE_ENABLE_MULTITHREADED + return wolf_error; +#else return conn->wolf_error; +#endif } diff --git a/src/he/conn.h b/src/he/conn.h index 9922765..58d8f24 100644 --- a/src/he/conn.h +++ b/src/he/conn.h @@ -517,4 +517,7 @@ he_return_code_t he_conn_pmtud_probe_timeout(he_conn_t *conn); */ int he_conn_get_ssl_error(he_conn_t* conn); + +void he_conn_set_ssl_error(he_conn_t *conn, int error); + #endif // CONN_H diff --git a/src/he/core.c b/src/he/core.c index 69d0cb9..a763cf0 100644 --- a/src/he/core.c +++ b/src/he/core.c @@ -18,12 +18,13 @@ */ #include "core.h" +#include "conn.h" he_return_code_t he_internal_setup_stream_state(he_conn_t *conn, uint8_t *data, size_t length) { if(conn->incoming_data_left_to_read != 0) { // Somehow this function was called without reading all data from a previous buffer // This is bad - conn->wolf_error = 0; + he_conn_set_ssl_error(conn, 0); return HE_ERR_SSL_ERROR; } // Set up the location of the buffer and its length diff --git a/src/he/flow.c b/src/he/flow.c index 530d193..99e950d 100644 --- a/src/he/flow.c +++ b/src/he/flow.c @@ -35,8 +35,7 @@ #include bool he_internal_flow_should_fragment(he_conn_t *conn, uint16_t effective_pmtu, uint16_t length) { - return conn->connection_type == HE_CONNECTION_TYPE_DATAGRAM && - conn->pmtud_state == HE_PMTUD_STATE_SEARCH_COMPLETE && length > effective_pmtu; + return conn->connection_type == HE_CONNECTION_TYPE_DATAGRAM && length > effective_pmtu; } he_return_code_t he_conn_inside_packet_received(he_conn_t *conn, uint8_t *packet, size_t length) { @@ -70,11 +69,9 @@ he_return_code_t he_conn_inside_packet_received(he_conn_t *conn, uint8_t *packet // Clamp the MSS if PMTU has been fixed he_return_code_t ret = HE_SUCCESS; uint16_t effective_pmtu = he_conn_get_effective_pmtu(conn); - if(conn->pmtud_state == HE_PMTUD_STATE_SEARCH_COMPLETE) { - ret = he_internal_clamp_mss(packet, length, effective_pmtu - HE_MSS_OVERHEAD); - if(ret != HE_SUCCESS) { - return ret; - } + ret = he_internal_clamp_mss(packet, length, effective_pmtu - HE_MSS_OVERHEAD); + if(ret != HE_SUCCESS) { + return ret; } // Process the packet with plugins. @@ -144,26 +141,24 @@ he_return_code_t he_conn_inside_packet_received(he_conn_t *conn, uint8_t *packet return ret; } -he_return_code_t he_internal_flow_process_message(he_conn_t *conn) { +he_return_code_t he_internal_flow_process_message(he_conn_t *conn, he_packet_buffer_t *read_packet) { // Return if conn is null - if(!conn) { + if(!conn || !read_packet) { return HE_ERR_NULL_POINTER; } // If the packet is too small then either the client is sending corrupted data or something is // very wrong with the SSL connection - if(conn->read_packet.packet_size < sizeof(he_msg_hdr_t)) { - conn->read_packet.has_packet = false; - conn->wolf_error = 0; + if(read_packet->packet_size < sizeof(he_msg_hdr_t)) { + read_packet->has_packet = false; + he_conn_set_ssl_error(conn, 0); return HE_ERR_SSL_ERROR; } - he_packet_buffer_t *pkt_buff = &conn->read_packet; - // Cast the header - he_msg_hdr_t *msg_hdr = (he_msg_hdr_t *)&pkt_buff->packet; - uint8_t *buf = pkt_buff->packet; - int buf_len = pkt_buff->packet_size; + he_msg_hdr_t *msg_hdr = (he_msg_hdr_t *)&read_packet->packet; + uint8_t *buf = read_packet->packet; + int buf_len = read_packet->packet_size; switch(msg_hdr->msgid) { case HE_MSGID_NOOP: @@ -218,19 +213,19 @@ he_return_code_t he_internal_flow_process_message(he_conn_t *conn) { return HE_SUCCESS; } -he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn) { +he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn, he_packet_buffer_t *read_packet) { // Return if conn is null - if(!conn) { + if(!conn || !read_packet) { return HE_ERR_NULL_POINTER; } // Try to read out a packet int res = - wolfSSL_read(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet)); + wolfSSL_read(conn->wolf_ssl, read_packet->packet, sizeof(read_packet->packet)); if(res <= 0) { - conn->read_packet.has_packet = false; - conn->read_packet.packet_size = 0; + read_packet->has_packet = false; + read_packet->packet_size = 0; int error = wolfSSL_get_error(conn->wolf_ssl, res); switch(error) { @@ -239,7 +234,7 @@ he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn) { return HE_SUCCESS; case APP_DATA_READY: - return he_internal_flow_fetch_message(conn); + return he_internal_flow_fetch_message(conn, read_packet); case SSL_ERROR_WANT_READ: case SSL_ERROR_WANT_WRITE: @@ -251,7 +246,7 @@ he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn) { if(res == 0) { return HE_ERR_CONNECTION_WAS_CLOSED; } else { - conn->wolf_error = error; + he_conn_set_ssl_error(conn, error); // if this is TCP then any SSL error is fatal (stream corruption). // If this is D/TLS we can actually ignore corrupted packets. if(conn->connection_type == HE_CONNECTION_TYPE_STREAM) { @@ -262,8 +257,8 @@ he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn) { } } } else { - conn->read_packet.has_packet = true; - conn->read_packet.packet_size = res; + read_packet->has_packet = true; + read_packet->packet_size = res; } return HE_SUCCESS; @@ -340,6 +335,12 @@ he_return_code_t he_conn_outside_data_received(he_conn_t *conn, uint8_t *buffer, } } +#ifdef HE_ENABLE_MULTITHREADED +HE_THREAD_LOCAL uint8_t *cur_packet = NULL; +HE_THREAD_LOCAL size_t cur_packet_length = 0; +HE_THREAD_LOCAL bool packet_seen = false; +#endif + he_return_code_t he_internal_flow_outside_packet_received(he_conn_t *conn, uint8_t *packet, size_t length) { // Return if packet or conn is null @@ -380,11 +381,10 @@ he_return_code_t he_internal_flow_outside_packet_received(he_conn_t *conn, uint8 // Update pointer and length in our connection state // We need to pull the wire header off first - conn->incoming_data_length = length - sizeof(he_wire_hdr_t); - conn->incoming_data = packet + sizeof(he_wire_hdr_t); + he_internal_set_packet(conn, packet + sizeof(he_wire_hdr_t), length - sizeof(he_wire_hdr_t)); // Make sure that this packet is marked as unseen - conn->packet_seen = false; + he_internal_set_packet_seen(conn, false); return HE_DISPATCH(he_internal_flow_outside_data_verify_connection, conn); } @@ -410,8 +410,13 @@ he_return_code_t he_internal_flow_outside_data_verify_connection(he_conn_t *conn } // Check to see if this is our first message and trigger an event change if it is - if(!conn->first_message_received) { +#ifdef HE_ENABLE_MULTITHREADED + bool expected = false; + if (atomic_compare_exchange_strong(&conn->first_message_received, &expected, true)) { +#else + if (!conn->first_message_received) { conn->first_message_received = true; +#endif he_internal_generate_event(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); } @@ -434,7 +439,7 @@ he_return_code_t he_internal_flow_outside_data_verify_connection(he_conn_t *conn } // We can't recover from any other errors - conn->wolf_error = error; + he_conn_set_ssl_error(conn, error); return HE_ERR_SSL_ERROR; } @@ -456,6 +461,8 @@ he_return_code_t he_internal_flow_outside_data_verify_connection(he_conn_t *conn } he_return_code_t he_internal_flow_outside_data_handle_messages(he_conn_t *conn) { + he_packet_buffer_t read_packet = { 0 }; + // Return if conn is null if(!conn) { return HE_ERR_NULL_POINTER; @@ -464,18 +471,18 @@ he_return_code_t he_internal_flow_outside_data_handle_messages(he_conn_t *conn) // Handle messages while(true) { // Do we have a message? - he_return_code_t ret = he_internal_flow_fetch_message(conn); + he_return_code_t ret = he_internal_flow_fetch_message(conn, &read_packet); if(ret != HE_SUCCESS) { return ret; } - if(!conn->read_packet.has_packet) { + if(!read_packet.has_packet) { break; } // Process the message - ret = he_internal_flow_process_message(conn); + ret = he_internal_flow_process_message(conn, &read_packet); if(ret != HE_SUCCESS) return ret; } @@ -498,7 +505,7 @@ he_return_code_t he_internal_flow_outside_data_handle_messages(he_conn_t *conn) // D/TLS 1.3 int wolf_rc = 0; if((wolf_rc = wolfSSL_key_update_response(conn->wolf_ssl, &resp_pending)) != 0) { - conn->wolf_error = wolfSSL_get_error(conn->wolf_ssl, wolf_rc); + he_conn_set_ssl_error(conn, wolfSSL_get_error(conn->wolf_ssl, wolf_rc)); return HE_ERR_SSL_ERROR; } } @@ -513,10 +520,6 @@ he_return_code_t he_internal_flow_outside_data_handle_messages(he_conn_t *conn) he_internal_update_timeout(conn); } - // Zero out the packet, ensures that if the connection is unused - // for extended periods the old outdated data is cleared from memory - memset(&conn->read_packet, 0, sizeof(conn->read_packet)); - // All went well return HE_SUCCESS; } diff --git a/src/he/flow.h b/src/he/flow.h index d73c60e..e03ed7c 100644 --- a/src/he/flow.h +++ b/src/he/flow.h @@ -27,6 +27,7 @@ #define FLOW_H #include "he.h" +#include "he_internal.h" /** * @brief Called when the host application needs to deliver an inside packet to Helium. @@ -68,8 +69,8 @@ he_return_code_t he_conn_inside_packet_received(he_conn_t *conn, uint8_t *packet */ he_return_code_t he_conn_outside_data_received(he_conn_t *conn, uint8_t *buffer, size_t length); -he_return_code_t he_internal_flow_process_message(he_conn_t *conn); -he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn); +he_return_code_t he_internal_flow_process_message(he_conn_t *conn, he_packet_buffer_t *read_packet); +he_return_code_t he_internal_flow_fetch_message(he_conn_t *conn, he_packet_buffer_t *read_packet); he_return_code_t he_internal_update_session_incoming(he_conn_t *conn, he_wire_hdr_t *hdr); he_return_code_t he_internal_flow_outside_packet_received(he_conn_t *conn, uint8_t *packet, @@ -81,4 +82,64 @@ he_return_code_t he_internal_flow_outside_data_handle_messages(he_conn_t *conn); bool he_internal_flow_should_fragment(he_conn_t *conn, uint16_t effective_pmtu, uint16_t length); +#ifdef HE_ENABLE_MULTITHREADED +extern HE_THREAD_LOCAL uint8_t *cur_packet; +extern HE_THREAD_LOCAL size_t cur_packet_length; +extern HE_THREAD_LOCAL bool packet_seen; + +static inline void he_internal_set_packet(he_conn_t *conn, uint8_t *packet, size_t len) { + cur_packet_length = len; + cur_packet = packet; +} + +static inline void he_internal_set_packet_seen(he_conn_t *conn, bool value) { + packet_seen = value; +} + +static inline bool he_internal_is_packet_seen(he_conn_t *conn) { + return packet_seen; +} + +static inline bool he_internal_is_pkt_available(he_conn_t *conn) { + return !packet_seen && cur_packet; +} + +static inline size_t he_internal_copy_packet(he_conn_t *conn, char *buf) { + memcpy(buf, cur_packet, cur_packet_length); + return cur_packet_length; +} + +static inline size_t he_internal_get_packet_length(he_conn_t *conn) { + return cur_packet_length; +} + +#else // HE_ENABLE_MULTITHREADED + +static inline void he_internal_set_packet(he_conn_t *conn, uint8_t *packet, size_t len) { + conn->incoming_data_length = len; + conn->incoming_data = packet; +} + +static inline void he_internal_set_packet_seen(he_conn_t *conn, bool value) { + conn->packet_seen = value; +} + +static inline bool he_internal_is_packet_seen(he_conn_t *conn) { + return conn->packet_seen; +} + +static inline bool he_internal_is_pkt_available(he_conn_t *conn) { + return !!conn->incoming_data; +} + +static inline size_t he_internal_copy_packet(he_conn_t *conn, char *buf) { + memcpy(buf, conn->incoming_data, conn->incoming_data_length); + return conn->incoming_data_length; +} + +static inline size_t he_internal_get_packet_length(he_conn_t *conn) { + return conn->incoming_data_length; +} +#endif // HE_ENABLE_MULTITHREADED + #endif // FLOW_H diff --git a/src/he/he_internal.h b/src/he/he_internal.h index 92c0d5e..bf1c2b4 100644 --- a/src/he/he_internal.h +++ b/src/he/he_internal.h @@ -34,6 +34,10 @@ #include #include +#ifdef HE_ENABLE_MULTITHREADED +#include +#endif + // Network headers #include "he_plugin.h" @@ -48,8 +52,26 @@ #include #include +#ifdef HE_ENABLE_MULTITHREADED +# define HE_ATOMIC _Atomic +#else +# define HE_ATOMIC +#endif + #pragma pack(1) +#ifndef HE_THREAD_LOCAL +# if __STDC_VERSION__ >= 201112 && !defined __STDC_NO_THREADS__ +# define HE_THREAD_LOCAL _Thread_local +# elif defined _WIN32 +# define HE_THREAD_LOCAL __declspec(thread) +# elif defined __APPLE__ +# define HE_THREAD_LOCAL __thread +# else +# error "Cannot define HE_THREAD_LOCAL" +# endif +#endif + typedef struct he_packet_buffer { // Buffer has data bool has_packet; @@ -128,47 +150,31 @@ struct he_ssl_ctx { size_t max_frag_entries; }; +typedef struct he_internal_pmtud_ { + /// Path MTU Discovery state + he_pmtud_state_t state; + + /// Current effective PMTU + HE_ATOMIC uint16_t effective_pmtu; + + /// PMTUD internal data + uint16_t base; + uint8_t probe_count; + uint16_t probing_size; + bool is_using_big_step; + uint16_t probe_pending_id; +} he_internal_pmtud_t; + typedef struct he_fragment_table he_fragment_table_t; struct he_conn { + // -------------- Configs (Immutable) ----------------- + /// Internal Structure Member for client/server determination /// No explicit setter or getter, we internally set this in /// either client or server connect functions bool is_server; - /// Client State - he_conn_state_t state; - - /// Pointer to incoming data buffer - uint8_t *incoming_data; - /// Length of the data in the - size_t incoming_data_length; - // WolfSSL stuff - WOLFSSL *wolf_ssl; - /// Wolf Timeout - int wolf_timeout; - /// Write buffer - uint8_t write_buffer[HE_MAX_WIRE_MTU]; - /// Packet seen - bool packet_seen; - /// Session ID - uint64_t session_id; - uint64_t pending_session_id; - /// Read packet buffers - he_packet_buffer_t read_packet; - /// Has the first message been received? - bool first_message_received; - /// Bytes left to read in the packet buffer (Streaming only) - size_t incoming_data_left_to_read; - /// Index into the incoming data buffer - uint8_t *incoming_data_read_offset_ptr; - - bool renegotiation_in_progress; - bool renegotiation_due; - - /// Do we already have a timer running? If so, we don't want to generate new callbacks - bool is_nudge_timer_running; - he_plugin_chain_t *inside_plugins; he_plugin_chain_t *outside_plugins; @@ -233,30 +239,59 @@ struct he_conn { /// Random number generator RNG wolf_rng; + /// WolfSSL stuff + WOLFSSL *wolf_ssl; + + // -------------- State (Mutable) ----------------- + + /// Client State + HE_ATOMIC he_conn_state_t state; + + /// Wolf Timeout + HE_ATOMIC int wolf_timeout; + + /// Pointer to incoming data buffer + uint8_t *incoming_data; + /// Length of the data in the + size_t incoming_data_length; + /// Packet seen + bool packet_seen; + /// Bytes left to read in the packet buffer (Streaming only) + size_t incoming_data_left_to_read; + /// Index into the incoming data buffer + uint8_t *incoming_data_read_offset_ptr; + + /// Write buffer + uint8_t write_buffer[HE_MAX_WIRE_MTU]; + + /// Session ID + HE_ATOMIC uint64_t session_id; + HE_ATOMIC uint64_t pending_session_id; + + /// Has the first message been received? + HE_ATOMIC bool first_message_received; + + /// Do we already have a timer running? If so, we don't want to generate new callbacks + HE_ATOMIC bool is_nudge_timer_running; + + bool renegotiation_in_progress; + bool renegotiation_due; + /// Identifier of the next ping message uint16_t ping_next_id; /// Identifier of the ping message pending reply uint16_t ping_pending_id; - /// Path MTU Discovery state - he_pmtud_state_t pmtud_state; - - /// Current effective PMTU - uint16_t effective_pmtu; - - /// PMTUD internal data - uint16_t pmtud_base; - uint8_t pmtud_probe_count; - uint16_t pmtud_probing_size; - bool pmtud_is_using_big_step; - uint16_t pmtud_probe_pending_id; + he_internal_pmtud_t pmtud; /// UDP Fragmentation - uint16_t frag_next_id; + HE_ATOMIC uint16_t frag_next_id; he_fragment_table_t *frag_table; +#ifndef HE_ENABLE_MULTITHREADED /// Last wolfssl error int wolf_error; +#endif }; struct he_plugin_chain { diff --git a/src/he/msg_handlers.c b/src/he/msg_handlers.c index c968932..d5ab9e9 100644 --- a/src/he/msg_handlers.c +++ b/src/he/msg_handlers.c @@ -81,12 +81,9 @@ he_return_code_t he_handle_msg_pong(he_conn_t *conn, uint8_t *packet, int length if(id == conn->ping_pending_id) { // Tell the host application that we received a PONG he_internal_generate_event(conn, HE_EVENT_PONG); - return HE_SUCCESS; - } - if(id == conn->pmtud_probe_pending_id) { + } else { // Received ack of a pmtud probe he_internal_pmtud_handle_probe_ack(conn, id); - return HE_SUCCESS; } // Ignore the pong message diff --git a/src/he/pmtud.c b/src/he/pmtud.c index d04a3d5..5acee69 100644 --- a/src/he/pmtud.c +++ b/src/he/pmtud.c @@ -41,7 +41,7 @@ static void he_internal_pmtud_change_state(he_conn_t *conn, he_pmtud_state_t sta if(conn->pmtud_state_change_cb) { conn->pmtud_state_change_cb(conn, state, conn->data); } - conn->pmtud_state = state; + conn->pmtud.state = state; } he_return_code_t he_internal_pmtud_send_probe(he_conn_t *conn, uint16_t probe_mtu) { @@ -70,8 +70,8 @@ he_return_code_t he_internal_pmtud_send_probe(he_conn_t *conn, uint16_t probe_mt uint16_t payload_size = probe_mtu + sizeof(he_msg_data_t) - sizeof(he_msg_ping_t); probe->length = htons(payload_size); - conn->pmtud_probe_count++; - conn->pmtud_probing_size = probe_mtu; + conn->pmtud.probe_count++; + conn->pmtud.probing_size = probe_mtu; // Send it he_return_code_t res = he_internal_send_message(conn, buf, sizeof(he_msg_ping_t) + payload_size); @@ -82,7 +82,7 @@ he_return_code_t he_internal_pmtud_send_probe(he_conn_t *conn, uint16_t probe_mt timeout_ms = 10; } else { // Set the probe pending id for verifying the ack message - conn->pmtud_probe_pending_id = id; + conn->pmtud.probe_pending_id = id; } // Start the probe timer @@ -97,7 +97,7 @@ he_return_code_t he_internal_pmtud_handle_probe_ack(he_conn_t *conn, uint16_t pr if(!conn) { return HE_ERR_NULL_POINTER; } - if(conn->pmtud_probe_pending_id != probe_id) { + if(conn->pmtud.probe_pending_id != probe_id) { // Receives an outdated probe id, ignore. return HE_SUCCESS; } @@ -108,26 +108,26 @@ he_return_code_t he_internal_pmtud_handle_probe_ack(he_conn_t *conn, uint16_t pr } // Reset the pending probe id - conn->pmtud_probe_pending_id = 0; + conn->pmtud.probe_pending_id = 0; // Reset the probe count for each ack - conn->pmtud_probe_count = 0; + conn->pmtud.probe_count = 0; // Handle the ack based on current state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_BASE: // Base MTU confirmed return he_internal_pmtud_base_confirmed(conn); case HE_PMTUD_STATE_SEARCHING: // Current probe acked - if(conn->pmtud_probing_size >= MAX_PLPMTU) { + if(conn->pmtud.probing_size >= MAX_PLPMTU) { // Search completed if the MAX_PLPMTU acked return he_internal_pmtud_search_completed(conn); } else { // Increment probing size and send next probe - uint16_t probe_size = conn->pmtud_probing_size; + uint16_t probe_size = conn->pmtud.probing_size; probe_size += - (conn->pmtud_is_using_big_step) ? PMTUD_PROBE_BIG_STEP : PMTUD_PROBE_SMALL_STEP; + (conn->pmtud.is_using_big_step) ? PMTUD_PROBE_BIG_STEP : PMTUD_PROBE_SMALL_STEP; probe_size = MIN(probe_size, MAX_PLPMTU); he_internal_pmtud_send_probe(conn, probe_size); } @@ -151,18 +151,18 @@ he_return_code_t he_internal_pmtud_handle_probe_timeout(he_conn_t *conn) { } // Try again with the same probe size - if(conn->pmtud_probe_count < MAX_PROBES) { - return he_internal_pmtud_send_probe(conn, conn->pmtud_probing_size); + if(conn->pmtud.probe_count < MAX_PROBES) { + return he_internal_pmtud_send_probe(conn, conn->pmtud.probing_size); } // Reset probe count - conn->pmtud_probe_pending_id = 0; - conn->pmtud_probe_count = 0; + conn->pmtud.probe_pending_id = 0; + conn->pmtud.probe_count = 0; // PROBE_COUNT reaches MAX_PROBES, decide what to do based on state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_BASE: - if(conn->pmtud_probing_size == INITIAL_PLPMTU) { + if(conn->pmtud.probing_size == INITIAL_PLPMTU) { // Try again using MIN_PLPMTU return he_internal_pmtud_send_probe(conn, MIN_PLPMTU); } else { @@ -171,18 +171,18 @@ he_return_code_t he_internal_pmtud_handle_probe_timeout(he_conn_t *conn) { } break; case HE_PMTUD_STATE_SEARCHING: - if(conn->pmtud_is_using_big_step) { + if(conn->pmtud.is_using_big_step) { // Try probing with small step - conn->pmtud_is_using_big_step = false; - uint16_t probe_size = conn->pmtud_probing_size; + conn->pmtud.is_using_big_step = false; + uint16_t probe_size = conn->pmtud.probing_size; probe_size -= PMTUD_PROBE_BIG_STEP; probe_size += PMTUD_PROBE_SMALL_STEP; return he_internal_pmtud_send_probe(conn, probe_size); } else { // Search completed // Set the probing size to the previous successful one - assert(conn->pmtud_probing_size > conn->pmtud_base); - conn->pmtud_probing_size -= PMTUD_PROBE_SMALL_STEP; + assert(conn->pmtud.probing_size > conn->pmtud.base); + conn->pmtud.probing_size -= PMTUD_PROBE_SMALL_STEP; return he_internal_pmtud_search_completed(conn); } break; @@ -205,7 +205,7 @@ he_return_code_t he_internal_pmtud_start_base_probing(he_conn_t *conn) { } // Check current state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_DISABLED: case HE_PMTUD_STATE_SEARCHING: case HE_PMTUD_STATE_SEARCH_COMPLETE: @@ -223,11 +223,11 @@ he_return_code_t he_internal_pmtud_start_base_probing(he_conn_t *conn) { he_internal_pmtud_change_state(conn, HE_PMTUD_STATE_BASE); // Initialize PMTUD internal state - conn->pmtud_base = INITIAL_PLPMTU; - conn->pmtud_probe_count = 0; + conn->pmtud.base = INITIAL_PLPMTU; + conn->pmtud.probe_count = 0; // Start probing base mtu - return he_internal_pmtud_send_probe(conn, conn->pmtud_base); + return he_internal_pmtud_send_probe(conn, conn->pmtud.base); } he_return_code_t he_internal_pmtud_base_confirmed(he_conn_t *conn) { @@ -235,7 +235,7 @@ he_return_code_t he_internal_pmtud_base_confirmed(he_conn_t *conn) { return HE_ERR_NULL_POINTER; } // Check current state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_BASE: case HE_PMTUD_STATE_ERROR: // Valid states @@ -249,9 +249,9 @@ he_return_code_t he_internal_pmtud_base_confirmed(he_conn_t *conn) { he_internal_pmtud_change_state(conn, HE_PMTUD_STATE_SEARCHING); // Start searching - conn->pmtud_probe_count = 0; - conn->pmtud_is_using_big_step = true; - uint16_t probe_size = conn->pmtud_base + PMTUD_PROBE_BIG_STEP; + conn->pmtud.probe_count = 0; + conn->pmtud.is_using_big_step = true; + uint16_t probe_size = conn->pmtud.base + PMTUD_PROBE_BIG_STEP; return he_internal_pmtud_send_probe(conn, probe_size); } @@ -261,7 +261,7 @@ he_return_code_t he_internal_pmtud_confirm_base_failed(he_conn_t *conn) { return HE_ERR_NULL_POINTER; } // Check current state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_BASE: // Valid states break; @@ -281,7 +281,7 @@ he_return_code_t he_internal_pmtud_search_completed(he_conn_t *conn) { return HE_ERR_NULL_POINTER; } // Check current state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_SEARCHING: // Valid states break; @@ -291,7 +291,7 @@ he_return_code_t he_internal_pmtud_search_completed(he_conn_t *conn) { } // Set the effective pmtu - conn->effective_pmtu = MIN(conn->pmtud_probing_size, MAX_PLPMTU); + conn->pmtud.effective_pmtu = MIN(conn->pmtud.probing_size, MAX_PLPMTU); // Change state he_internal_pmtud_change_state(conn, HE_PMTUD_STATE_SEARCH_COMPLETE); @@ -305,7 +305,7 @@ he_return_code_t he_internal_pmtud_blackhole_detected(he_conn_t *conn) { return HE_ERR_NULL_POINTER; } // Check current state - switch(conn->pmtud_state) { + switch(conn->pmtud.state) { case HE_PMTUD_STATE_SEARCHING: case HE_PMTUD_STATE_SEARCH_COMPLETE: // Valid states @@ -319,11 +319,11 @@ he_return_code_t he_internal_pmtud_blackhole_detected(he_conn_t *conn) { he_internal_pmtud_change_state(conn, HE_PMTUD_STATE_BASE); // Set the base pmtu - conn->pmtud_base = MIN_PLPMTU; - conn->pmtud_probe_count = 0; + conn->pmtud.base = MIN_PLPMTU; + conn->pmtud.probe_count = 0; // Start probing base mtu - return he_internal_pmtud_send_probe(conn, conn->pmtud_base); + return he_internal_pmtud_send_probe(conn, conn->pmtud.base); } he_return_code_t he_internal_pmtud_retry_probe(he_conn_t *conn, int delay_ms) { @@ -334,6 +334,6 @@ he_return_code_t he_internal_pmtud_retry_probe(he_conn_t *conn, int delay_ms) { ret = conn->pmtud_time_cb(conn, delay_ms, conn->data); } - conn->pmtud_probe_count = 0; + conn->pmtud.probe_count = 0; return ret; } diff --git a/src/he/wolf.c b/src/he/wolf.c index 21e3a35..13a38dd 100644 --- a/src/he/wolf.c +++ b/src/he/wolf.c @@ -20,6 +20,7 @@ #include "he.h" #include "wolf.h" +#include "flow.h" #include "plugin_chain.h" int he_wolf_dtls_read(WOLFSSL *ssl, char *buf, int sz, void *ctx) { @@ -39,7 +40,7 @@ int he_wolf_dtls_read(WOLFSSL *ssl, char *buf, int sz, void *ctx) { he_conn_t *conn = (he_conn_t *)ctx; // This can be null if no data has been received yet, tell wolfSSL to stop asking - if(!conn->incoming_data) { + if(!he_internal_is_pkt_available(conn)) { return WOLFSSL_CBIO_ERR_WANT_READ; } @@ -48,25 +49,26 @@ int he_wolf_dtls_read(WOLFSSL *ssl, char *buf, int sz, void *ctx) { // any time it wants to read, it doesn't know there's only ever one, so we need to // check and send the equivalent of "would block" if we've already processed the // provided packet. - if(conn->packet_seen) { + if(he_internal_is_packet_seen(conn)) { // We've already processed this packet, tell WolfSSL to stop asking return WOLFSSL_CBIO_ERR_WANT_READ; } // Check that we have enough space to write the packet - if(conn->incoming_data_length > sz) { + if(he_internal_get_packet_length(conn) > sz) { // We can't write this packet and split it - have to drop - conn->packet_seen = true; + he_internal_set_packet_seen(conn, true); return 0; } // Copy the data out of the packet into WolfSSL's buffer - memcpy(buf, conn->incoming_data, conn->incoming_data_length); + he_internal_copy_packet(conn, buf); + // Set flag so we can ignore this packet next time - conn->packet_seen = true; + he_internal_set_packet_seen(conn, true); // The amount of data we copied into WolfSSL's buffer - return (int)conn->incoming_data_length; + return (int)he_internal_get_packet_length(conn); } int he_internal_write_packet_header(he_conn_t *conn, he_wire_hdr_t *hdr) { @@ -102,6 +104,11 @@ int he_internal_write_packet_header(he_conn_t *conn, he_wire_hdr_t *hdr) { } int he_wolf_dtls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { + he_internal_write_buf_t write_buffer = {0}; + return he_wolf_dtls_write_internal(ssl, buf, sz, ctx, &write_buffer); +} + +int he_wolf_dtls_write_internal(WOLFSSL *ssl, char *buf, int sz, void *ctx, he_internal_write_buf_t *write_buffer) { (void)ssl; /* will not need ssl context */ if(sz < 0) { @@ -110,7 +117,7 @@ int he_wolf_dtls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { } // Abort if any of the IO buffers are null pointers - if(!buf || !ctx) { + if(!buf || !ctx || !write_buffer) { return WOLFSSL_CBIO_ERR_GENERAL; } @@ -119,36 +126,36 @@ int he_wolf_dtls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { // Check we have enough space // @TODO: Take MTU settings into account - if(sz + sizeof(he_wire_hdr_t) > sizeof(conn->write_buffer)) { + if(sz + sizeof(he_wire_hdr_t) > sizeof(write_buffer->buf)) { // We have to drop the packet as we can never send it (in theory this should never happen // due to earlier constraints) return WOLFSSL_CBIO_ERR_GENERAL; } // Initialise the write buffer - he_internal_write_packet_header(conn, (he_wire_hdr_t *)conn->write_buffer); + he_internal_write_packet_header(conn, (he_wire_hdr_t *)write_buffer->buf); // Copy in the data behind the header - // TODO Actively investigating why the analyzer thinks that conn->write_buffer is not the same - // as &conn->write_buffer[0] - memcpy((&conn->write_buffer[0]) + sizeof(he_wire_hdr_t), buf, sz); + // TODO Actively investigating why the analyzer thinks that write_buffer->buf is not the same + // as &write_buffer->buf[0] + memcpy((&write_buffer->buf[0]) + sizeof(he_wire_hdr_t), buf, sz); // Note that the parallel call to ingress is in conn.c:he_internal_outside_data_received size_t post_plugin_length = sz + sizeof(he_wire_hdr_t); - he_return_code_t res = he_plugin_egress(conn->outside_plugins, &conn->write_buffer[0], - &post_plugin_length, sizeof(conn->write_buffer)); + he_return_code_t res = he_plugin_egress(conn->outside_plugins, &write_buffer->buf[0], + &post_plugin_length, sizeof(write_buffer->buf)); if(res == HE_ERR_PLUGIN_DROP) { // Plugin said to drop it, we drop it // Parallel to returning HE_SUCCESS on ingress return sz; - } else if(res != HE_SUCCESS || post_plugin_length > sizeof(conn->write_buffer)) { + } else if(res != HE_SUCCESS || post_plugin_length > sizeof(write_buffer->buf)) { return WOLFSSL_CBIO_ERR_GENERAL; } // Call the write callback if set if(conn->outside_write_cb) { - res = conn->outside_write_cb(conn, conn->write_buffer, post_plugin_length, conn->data); + res = conn->outside_write_cb(conn, write_buffer->buf, post_plugin_length, conn->data); if(res != HE_SUCCESS) { return WOLFSSL_CBIO_ERR_GENERAL; } @@ -156,12 +163,12 @@ int he_wolf_dtls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { // If we're not yet connected, be aggressive and send two more packets. If aggressive mode // is set, always be aggressive and send two more. if(conn->state != HE_STATE_ONLINE || conn->use_aggressive_mode) { - res = conn->outside_write_cb(conn, conn->write_buffer, post_plugin_length, conn->data); + res = conn->outside_write_cb(conn, write_buffer->buf, post_plugin_length, conn->data); if(res != HE_SUCCESS) { return WOLFSSL_CBIO_ERR_GENERAL; } - res = conn->outside_write_cb(conn, conn->write_buffer, post_plugin_length, conn->data); + res = conn->outside_write_cb(conn, write_buffer->buf, post_plugin_length, conn->data); if(res != HE_SUCCESS) { return WOLFSSL_CBIO_ERR_GENERAL; } @@ -221,6 +228,11 @@ int he_wolf_tls_read(WOLFSSL *ssl, char *buf, int sz, void *ctx) { } int he_wolf_tls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { + he_internal_write_buf_t write_buffer = {0}; + return he_wolf_tls_write_internal(ssl, buf, sz, ctx, &write_buffer); +} + +int he_wolf_tls_write_internal(WOLFSSL *ssl, char *buf, int sz, void *ctx, he_internal_write_buf_t *write_buffer) { (void)ssl; /* will not need ssl context */ if(sz < 0) { @@ -229,7 +241,7 @@ int he_wolf_tls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { } // Abort if any of the IO buffers are null pointers - if(!buf || !ctx) { + if(!buf || !ctx || !write_buffer) { return WOLFSSL_CBIO_ERR_GENERAL; } @@ -241,31 +253,31 @@ int he_wolf_tls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx) { size_t number_of_bytes_to_copy = 0; // Figure out how much to copy - if(sz < sizeof(conn->write_buffer)) { + if(sz < sizeof(write_buffer->buf)) { number_of_bytes_to_copy = sz; } else { - number_of_bytes_to_copy = sizeof(conn->write_buffer); + number_of_bytes_to_copy = sizeof(write_buffer->buf); } // Copy in the data - memcpy((&conn->write_buffer[0]), buf, number_of_bytes_to_copy); + memcpy((&write_buffer->buf[0]), buf, number_of_bytes_to_copy); // Note that the parallel call to ingress is in conn.t.c:he_conn_outside_data_received size_t post_plugin_length = number_of_bytes_to_copy; - he_return_code_t res = he_plugin_egress(conn->outside_plugins, &conn->write_buffer[0], - &post_plugin_length, sizeof(conn->write_buffer)); + he_return_code_t res = he_plugin_egress(conn->outside_plugins, &write_buffer->buf[0], + &post_plugin_length, sizeof(write_buffer->buf)); if(res == HE_ERR_PLUGIN_DROP) { // Plugin said to drop it, we drop it // Parallel to returning HE_SUCCESS on ingress return sz; - } else if(res != HE_SUCCESS || post_plugin_length > sizeof(conn->write_buffer)) { + } else if(res != HE_SUCCESS || post_plugin_length > sizeof(write_buffer->buf)) { return WOLFSSL_CBIO_ERR_GENERAL; } // Call the write callback if set if(conn->outside_write_cb) { - res = conn->outside_write_cb(conn, conn->write_buffer, post_plugin_length, conn->data); + res = conn->outside_write_cb(conn, write_buffer->buf, post_plugin_length, conn->data); if(res != HE_SUCCESS) { return WOLFSSL_CBIO_ERR_GENERAL; } diff --git a/src/he/wolf.h b/src/he/wolf.h index 2a4f989..49f2c3d 100644 --- a/src/he/wolf.h +++ b/src/he/wolf.h @@ -105,4 +105,11 @@ int he_wolf_tls_read(WOLFSSL *ssl, char *buf, int sz, void *ctx); // Todo document this int he_wolf_tls_write(WOLFSSL *ssl, char *buf, int sz, void *ctx); +typedef struct he_internal_write_buf_ { + uint8_t buf[HE_MAX_WIRE_MTU]; +} he_internal_write_buf_t; + +int he_wolf_dtls_write_internal(WOLFSSL *ssl, char *buf, int sz, void *ctx, he_internal_write_buf_t *write_buffer); +int he_wolf_tls_write_internal(WOLFSSL *ssl, char *buf, int sz, void *ctx, he_internal_write_buf_t *write_buffer); + #endif // WOLF_H diff --git a/test/he/test_conn.c b/test/he/test_conn.c index 788d551..a0c694c 100644 --- a/test/he/test_conn.c +++ b/test/he/test_conn.c @@ -793,7 +793,7 @@ void test_he_internal_send_message_ssl_error(void) { wolfSSL_get_error_ExpectAndReturn(conn.wolf_ssl, -1, SSL_FATAL_ERROR); int rc = he_internal_send_message(&conn, fake_ipv4_packet, sizeof(fake_ipv4_packet)); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR, rc); - TEST_ASSERT_EQUAL(SSL_FATAL_ERROR, conn.wolf_error); + TEST_ASSERT_EQUAL(SSL_FATAL_ERROR, he_conn_get_ssl_error(&conn)); } void test_he_internal_update_timeout_with_cb_multiple_calls(void) { @@ -1254,7 +1254,7 @@ void test_he_internal_renegotiate_ssl_error_fatal(void) { he_return_code_t res = he_internal_renegotiate_ssl(&conn); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR, res); - TEST_ASSERT_EQUAL(SSL_FATAL_ERROR, conn.wolf_error); + TEST_ASSERT_EQUAL(SSL_FATAL_ERROR, he_conn_get_ssl_error(&conn)); } void test_he_internal_renegotiate_ssl_secure_renegotiation_error(void) { @@ -1728,7 +1728,7 @@ void test_he_conn_start_pmtu_discovery_do_nothing_when_already_started(void) { conn.pmtud_time_cb = pmtud_time_cb; // Do nothing if the pmtud is already started - conn.pmtud_state = HE_PMTUD_STATE_BASE; + conn.pmtud.state = HE_PMTUD_STATE_BASE; TEST_ASSERT_EQUAL(HE_SUCCESS, he_conn_start_pmtu_discovery(&conn)); } @@ -1759,14 +1759,22 @@ void test_he_conn_start_pmtu_discovery_callback_not_set(void) { TEST_ASSERT_EQUAL(HE_ERR_PMTUD_CALLBACKS_NOT_SET, he_conn_start_pmtu_discovery(&conn)); } -void test_he_conn_get_effective_pmtu(void) { +void test_he_conn_get_effective_pmtu_after_complete(void) { TEST_ASSERT_EQUAL(HE_MAX_MTU, he_conn_get_effective_pmtu(NULL)); TEST_ASSERT_EQUAL(HE_MAX_MTU, he_conn_get_effective_pmtu(&conn)); - conn.effective_pmtu = 1212; + conn.pmtud.state = HE_PMTUD_STATE_SEARCH_COMPLETE; + conn.pmtud.effective_pmtu = 1212; TEST_ASSERT_EQUAL(1212, he_conn_get_effective_pmtu(&conn)); } +void test_he_conn_get_effective_pmtu_before_complete(void) { + TEST_ASSERT_EQUAL(HE_MAX_MTU, he_conn_get_effective_pmtu(NULL)); + TEST_ASSERT_EQUAL(HE_MAX_MTU, he_conn_get_effective_pmtu(&conn)); + + conn.pmtud.effective_pmtu = 1212; + TEST_ASSERT_EQUAL(1350, he_conn_get_effective_pmtu(&conn)); +} void test_he_conn_pmtud_probe_timeout(void) { TEST_ASSERT_EQUAL(HE_ERR_NULL_POINTER, he_conn_pmtud_probe_timeout(NULL)); @@ -1775,8 +1783,8 @@ void test_he_conn_pmtud_probe_timeout(void) { } void test_he_conn_get_ssl_error(void) { - conn.wolf_error = -1; + he_conn_set_ssl_error(&conn, -1); TEST_ASSERT_EQUAL(-1, he_conn_get_ssl_error(&conn)); - conn.wolf_error = -2; + he_conn_set_ssl_error(&conn, -2); TEST_ASSERT_EQUAL(-2, he_conn_get_ssl_error(&conn)); } diff --git a/test/he/test_core.c b/test/he/test_core.c index ad20d9b..3c90815 100644 --- a/test/he/test_core.c +++ b/test/he/test_core.c @@ -23,6 +23,8 @@ #include #include "test_defs.h" +#include "mock_conn.h" + // Unit under test #include "core.h" @@ -37,9 +39,10 @@ void tearDown(void) { } void test_he_internal_stream_setup_state_overwrite(void) { + he_conn_set_ssl_error_Expect(conn, 0); + conn->incoming_data_left_to_read = 42; int res = he_internal_setup_stream_state(conn, empty_data, sizeof(empty_data)); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR, res); - TEST_ASSERT_EQUAL(0, conn->wolf_error); } diff --git a/test/he/test_flow.c b/test/he/test_flow.c index 15ee9f0..e14d7f1 100644 --- a/test/he/test_flow.c +++ b/test/he/test_flow.c @@ -145,6 +145,8 @@ void test_inside_pkt_good_packet(void) { he_internal_is_ipv4_packet_valid_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), true); he_conn_get_effective_pmtu_ExpectAndReturn(conn, 1350); + he_internal_clamp_mss_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), + 1350 - HE_MSS_OVERHEAD, HE_SUCCESS); he_plugin_ingress_ExpectAnyArgsAndReturn(HE_SUCCESS); he_internal_calculate_data_packet_length_ExpectAndReturn(conn, sizeof(fake_ipv4_packet), 1242); he_internal_send_message_ExpectAndReturn(conn, NULL, 1242 + sizeof(he_msg_data_t), HE_SUCCESS); @@ -164,6 +166,8 @@ void test_inside_pkt_good_packet_with_legacy_behaviour(void) { conn->protocol_version.minor_version = 0; he_conn_get_effective_pmtu_ExpectAndReturn(conn, 1350); + he_internal_clamp_mss_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), + 1350 - HE_MSS_OVERHEAD, HE_SUCCESS); he_internal_calculate_data_packet_length_ExpectAndReturn(conn, sizeof(fake_ipv4_packet), 1242); he_internal_send_message_ExpectAndReturn(conn, NULL, 1242 + sizeof(he_msg_data_t), HE_SUCCESS); he_internal_send_message_IgnoreArg_message(); @@ -178,14 +182,9 @@ void test_he_internal_flow_should_fragment(void) { conn->connection_type = HE_CONNECTION_TYPE_STREAM; TEST_ASSERT_FALSE(he_internal_flow_should_fragment(conn, 1200, 1350)); - // Don't frag if PMTUD search hasn't completed - conn->connection_type = HE_CONNECTION_TYPE_DATAGRAM; - conn->pmtud_state = HE_PMTUD_STATE_SEARCHING; - TEST_ASSERT_FALSE(he_internal_flow_should_fragment(conn, 1200, 1350)); - // Don't frag if the packet length is exactly effective_pmtu conn->connection_type = HE_CONNECTION_TYPE_DATAGRAM; - conn->pmtud_state = HE_PMTUD_STATE_SEARCH_COMPLETE; + conn->pmtud.state = HE_PMTUD_STATE_SEARCH_COMPLETE; TEST_ASSERT_FALSE(he_internal_flow_should_fragment(conn, 1200, 1200)); // Should frag if packet length is greater than effective_pmtu @@ -194,7 +193,7 @@ void test_he_internal_flow_should_fragment(void) { void test_inside_pkt_good_packet_clamp_mss_success(void) { conn->state = HE_STATE_ONLINE; - conn->pmtud_state = HE_PMTUD_STATE_SEARCH_COMPLETE; + conn->pmtud.state = HE_PMTUD_STATE_SEARCH_COMPLETE; he_internal_is_ipv4_packet_valid_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), true); he_conn_get_effective_pmtu_ExpectAndReturn(conn, 100); @@ -211,7 +210,7 @@ void test_inside_pkt_good_packet_clamp_mss_success(void) { void test_inside_pkt_good_packet_clamp_mss_failed(void) { conn->state = HE_STATE_ONLINE; - conn->pmtud_state = HE_PMTUD_STATE_SEARCH_COMPLETE; + conn->pmtud.state = HE_PMTUD_STATE_SEARCH_COMPLETE; he_internal_is_ipv4_packet_valid_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), true); he_conn_get_effective_pmtu_ExpectAndReturn(conn, 100); @@ -227,6 +226,8 @@ void test_inside_pkt_plugin_drop(void) { he_internal_is_ipv4_packet_valid_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), true); he_conn_get_effective_pmtu_ExpectAndReturn(conn, 1350); + he_internal_clamp_mss_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), + 1350 - HE_MSS_OVERHEAD, HE_SUCCESS); he_plugin_ingress_ExpectAnyArgsAndReturn(HE_ERR_PLUGIN_DROP); he_return_code_t res1 = @@ -241,6 +242,8 @@ void test_inside_pkt_plugin_fail(void) { he_internal_is_ipv4_packet_valid_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), true); he_conn_get_effective_pmtu_ExpectAndReturn(conn, 1350); + he_internal_clamp_mss_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), + 1350 - HE_MSS_OVERHEAD, HE_SUCCESS); he_plugin_ingress_ExpectAnyArgsAndReturn(HE_ERR_FAILED); he_return_code_t res1 = @@ -255,6 +258,8 @@ void test_inside_pkt_plugin_overflow_fail(void) { he_internal_is_ipv4_packet_valid_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), true); he_conn_get_effective_pmtu_ExpectAndReturn(conn, 1350); + he_internal_clamp_mss_ExpectAndReturn(fake_ipv4_packet, sizeof(fake_ipv4_packet), + 1350 - HE_MSS_OVERHEAD, HE_SUCCESS); he_plugin_ingress_Stub(stub_overflow_plugin); he_return_code_t res1 = @@ -269,7 +274,9 @@ void test_inside_pkt_plugin_large_mtu(void) { conn->outside_mtu = 9000; he_internal_is_ipv4_packet_valid_ExpectAndReturn(buffer, sizeof(buffer), true); - he_conn_get_effective_pmtu_ExpectAndReturn(conn, 1350); + he_conn_get_effective_pmtu_ExpectAndReturn(conn, 9000); + he_internal_clamp_mss_ExpectAndReturn(buffer, sizeof(buffer), + 9000 - HE_MSS_OVERHEAD, HE_SUCCESS); he_plugin_ingress_ExpectAnyArgsAndReturn(HE_SUCCESS); he_return_code_t res1 = he_conn_inside_packet_received(conn, buffer, sizeof(buffer)); @@ -317,8 +324,7 @@ void test_outside_pktrcv_good_packet(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_verify_connection", HE_SUCCESS); he_internal_generate_event_Expect(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, &conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); he_return_code_t res1 = @@ -363,6 +369,7 @@ void test_outside_pktrcv_good_packet_in_connecting_actual_error(void) { he_internal_generate_event_Expect(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); wolfSSL_negotiate_ExpectAndReturn(conn->wolf_ssl, FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, FATAL_ERROR, SSL_FATAL_ERROR); + he_conn_set_ssl_error_Expect(conn, SSL_FATAL_ERROR); conn->state = HE_STATE_CONNECTING; he_return_code_t res1 = he_internal_flow_outside_packet_received(conn, packet, test_buffer_length); @@ -379,8 +386,7 @@ void test_outside_pktrcv_good_packet_in_connecting_all_good(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); conn->state = HE_STATE_CONNECTING; - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, &conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); @@ -483,12 +489,9 @@ void test_handle_process_packet_wants_read(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_verify_connection", HE_SUCCESS); he_internal_generate_event_Expect(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1200); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1000); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(1200); + wolfSSL_read_IgnoreAndReturn(1000); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); he_return_code_t res = he_internal_flow_outside_packet_received(conn, packet, packet_max_length); @@ -497,21 +500,15 @@ void test_handle_process_packet_wants_read(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, res2); he_return_code_t res3 = he_internal_flow_outside_data_handle_messages(conn); TEST_ASSERT_EQUAL(HE_SUCCESS, res3); - - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); } void test_handle_process_packet_wants_write(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_verify_connection", HE_SUCCESS); he_internal_generate_event_Expect(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1200); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1000); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(1200); + wolfSSL_read_IgnoreAndReturn(1000); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_WRITE); he_return_code_t res = he_internal_flow_outside_packet_received(conn, packet, packet_max_length); @@ -520,22 +517,17 @@ void test_handle_process_packet_wants_write(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, res2); he_return_code_t res3 = he_internal_flow_outside_data_handle_messages(conn); TEST_ASSERT_EQUAL(HE_SUCCESS, res3); - - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); } void test_handle_process_packet_other_error(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_verify_connection", HE_SUCCESS); he_internal_generate_event_Expect(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1200); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1000); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(1200); + wolfSSL_read_IgnoreAndReturn(1000); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_FATAL_ERROR); + he_conn_set_ssl_error_Expect(conn, SSL_FATAL_ERROR); he_return_code_t res = he_internal_flow_outside_packet_received(conn, packet, packet_max_length); TEST_ASSERT_EQUAL(HE_SUCCESS, res); @@ -543,19 +535,14 @@ void test_handle_process_packet_other_error(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, res2); he_return_code_t res3 = he_internal_flow_outside_data_handle_messages(conn); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR_NONFATAL, res3); - - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); } void test_handle_process_packet_connection_closed(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_verify_connection", HE_SUCCESS); he_internal_generate_event_Expect(conn, HE_EVENT_FIRST_MESSAGE_RECEIVED); dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1200); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 0); + wolfSSL_read_IgnoreAndReturn(1200); + wolfSSL_read_IgnoreAndReturn(0); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, 0, SSL_ERROR_SSL); he_return_code_t res = he_internal_flow_outside_packet_received(conn, packet, packet_max_length); @@ -564,9 +551,6 @@ void test_handle_process_packet_connection_closed(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, res2); he_return_code_t res3 = he_internal_flow_outside_data_handle_messages(conn); TEST_ASSERT_EQUAL(HE_ERR_CONNECTION_WAS_CLOSED, res3); - - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); } void test_dnsmismatch_gets_returned(void) { @@ -605,17 +589,13 @@ void test_handle_process_packet_app_data_ready(void) { dispatch_ExpectAndReturn("he_internal_flow_outside_data_handle_messages", HE_SUCCESS); // Trigger the APP_DATA_READY error - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, APP_DATA_READY); // We should then immediately try again to read a message - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1200); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), 1000); - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(1200); + wolfSSL_read_IgnoreAndReturn(1000); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); he_return_code_t res = he_internal_flow_outside_packet_received(conn, packet, packet_max_length); @@ -624,9 +604,6 @@ void test_handle_process_packet_app_data_ready(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, res2); he_return_code_t res3 = he_internal_flow_outside_data_handle_messages(conn); TEST_ASSERT_EQUAL(HE_SUCCESS, res3); - - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); } void test_outside_datarcv_good_packet_datagram(void) { @@ -692,149 +669,167 @@ void test_outside_data_received_disconnected(void) { } void test_he_internal_flow_process_message_too_small(void) { - conn->read_packet.packet_size = 0; + he_packet_buffer_t read_packet = { 0 }; + read_packet.packet_size = 0; + he_conn_set_ssl_error_Expect(conn, 0); - he_return_code_t res = he_internal_flow_process_message(conn); + he_return_code_t res = he_internal_flow_process_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->wolf_error); + TEST_ASSERT_FALSE(read_packet.has_packet); } -void test_he_internal_flow_process_message_null_conn(void) { - he_return_code_t res = he_internal_flow_process_message(NULL); +void test_he_internal_flow_process_message_null_arg(void) { + he_packet_buffer_t read_packet = { 0 }; + he_return_code_t res = he_internal_flow_process_message(NULL, &read_packet); + TEST_ASSERT_EQUAL(HE_ERR_NULL_POINTER, res); + res = he_internal_flow_process_message(conn, NULL); TEST_ASSERT_EQUAL(HE_ERR_NULL_POINTER, res); } -void test_he_internal_flow_fetch_message_null_conn(void) { - he_return_code_t res = he_internal_flow_fetch_message(NULL); +void test_he_internal_flow_fetch_message_null_arg(void) { + he_packet_buffer_t read_packet = { 0 }; + he_return_code_t res = he_internal_flow_fetch_message(NULL, &read_packet); + TEST_ASSERT_EQUAL(HE_ERR_NULL_POINTER, res); + res = he_internal_flow_fetch_message(conn, NULL); TEST_ASSERT_EQUAL(HE_ERR_NULL_POINTER, res); } void test_he_internal_flow_fetch_message_success(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), 10); - int res = he_internal_flow_fetch_message(conn); + wolfSSL_read_IgnoreAndReturn(10); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_SUCCESS, res); - TEST_ASSERT_TRUE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(10, conn->read_packet.packet_size); + TEST_ASSERT_TRUE(read_packet.has_packet); + TEST_ASSERT_EQUAL(10, read_packet.packet_size); } void test_he_internal_flow_fetch_message_error_none(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), 0); + wolfSSL_read_IgnoreAndReturn(0); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, 0, SSL_ERROR_NONE); - int res = he_internal_flow_fetch_message(conn); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_SUCCESS, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); + TEST_ASSERT_FALSE(read_packet.has_packet); + TEST_ASSERT_EQUAL(0, read_packet.packet_size); } void test_he_internal_flow_fetch_message_error_want_read(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), 0); + wolfSSL_read_IgnoreAndReturn(0); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, 0, SSL_ERROR_WANT_READ); - int res = he_internal_flow_fetch_message(conn); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_SUCCESS, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); + TEST_ASSERT_FALSE(read_packet.has_packet); + TEST_ASSERT_EQUAL(0, read_packet.packet_size); } void test_he_internal_flow_fetch_message_error_want_write(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), 0); + wolfSSL_read_IgnoreAndReturn(0); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, 0, SSL_ERROR_WANT_WRITE); - int res = he_internal_flow_fetch_message(conn); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_SUCCESS, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); + TEST_ASSERT_FALSE(read_packet.has_packet); + TEST_ASSERT_EQUAL(0, read_packet.packet_size); } void test_he_internal_flow_fetch_message_error_conn_closed(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), 0); + wolfSSL_read_IgnoreAndReturn(0); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, 0, SSL_ERROR_SSL); - int res = he_internal_flow_fetch_message(conn); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_ERR_CONNECTION_WAS_CLOSED, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); + TEST_ASSERT_FALSE(read_packet.has_packet); + TEST_ASSERT_EQUAL(0, read_packet.packet_size); } void test_he_internal_flow_fetch_message_error_non_fatal(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), -1); + wolfSSL_read_IgnoreAndReturn(-1); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, -1, SSL_ERROR_SSL); + he_conn_set_ssl_error_Expect(conn, SSL_ERROR_SSL); conn->connection_type = HE_CONNECTION_TYPE_DATAGRAM; - int res = he_internal_flow_fetch_message(conn); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR_NONFATAL, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); + TEST_ASSERT_FALSE(read_packet.has_packet); + TEST_ASSERT_EQUAL(0, read_packet.packet_size); } void test_he_internal_flow_fetch_message_error_fatal(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, sizeof(conn->read_packet.packet), -1); + wolfSSL_read_IgnoreAndReturn(-1); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, -1, SSL_ERROR_SSL); + he_conn_set_ssl_error_Expect(conn, SSL_ERROR_SSL); conn->connection_type = HE_CONNECTION_TYPE_STREAM; - int res = he_internal_flow_fetch_message(conn); + he_packet_buffer_t read_packet = { 0 }; + int res = he_internal_flow_fetch_message(conn, &read_packet); TEST_ASSERT_EQUAL(HE_ERR_SSL_ERROR, res); - TEST_ASSERT_FALSE(conn->read_packet.has_packet); - TEST_ASSERT_EQUAL(0, conn->read_packet.packet_size); - TEST_ASSERT_EQUAL(SSL_ERROR_SSL, conn->wolf_error); + TEST_ASSERT_FALSE(read_packet.has_packet); + TEST_ASSERT_EQUAL(0, read_packet.packet_size); } // In general we try to avoid complex macros in libhelium, but these tests are so repetitive the // value of capturing these lines -#define HE_MSG_SWITCH_TEST(test_msgid) \ +#define HE_MSG_SWITCH_TEST(test_msgid, read_packet) \ msg->msgid = (test_msgid); \ - res = he_internal_flow_process_message(conn); \ + res = he_internal_flow_process_message(conn, &read_packet); \ TEST_ASSERT_EQUAL(HE_SUCCESS, res); -#define HE_MSG_SWITCH_TEST_EXPECT(test_msg_id, msg_fn) \ - msg_fn##_ExpectAndReturn(conn, conn->read_packet.packet, conn->read_packet.packet_size, \ + +#define HE_MSG_SWITCH_TEST_EXPECT(test_msg_id, msg_fn, read_packet) \ + msg_fn##_ExpectAndReturn(conn, read_packet.packet, read_packet.packet_size, \ HE_SUCCESS); \ - HE_MSG_SWITCH_TEST(test_msg_id); + HE_MSG_SWITCH_TEST(test_msg_id, read_packet); void test_he_internal_flow_process_message_switch(void) { - conn->read_packet.packet_size = 1; - he_msg_hdr_t *msg = (he_msg_hdr_t *)conn->read_packet.packet; + he_packet_buffer_t read_packet = { 0 }; + read_packet.packet_size = 1; + he_msg_hdr_t *msg = (he_msg_hdr_t *)read_packet.packet; he_return_code_t res = HE_ERR_FAILED; - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_NOOP, he_handle_msg_noop); - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_PING, he_handle_msg_ping); - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_PONG, he_handle_msg_pong); - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_DATA, he_handle_msg_data); - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_GOODBYE, he_handle_msg_goodbye); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_NOOP, he_handle_msg_noop, read_packet); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_PING, he_handle_msg_ping, read_packet); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_PONG, he_handle_msg_pong, read_packet); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_DATA, he_handle_msg_data, read_packet); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_GOODBYE, he_handle_msg_goodbye, read_packet); - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_DEPRECATED_13, he_handle_msg_deprecated_13); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_DEPRECATED_13, he_handle_msg_deprecated_13, read_packet); - HE_MSG_SWITCH_TEST(HE_MSGID_AUTH_RESPONSE_WITH_CONFIG); - HE_MSG_SWITCH_TEST(HE_MSGID_EXTENSION); + HE_MSG_SWITCH_TEST(HE_MSGID_AUTH_RESPONSE_WITH_CONFIG, read_packet); + HE_MSG_SWITCH_TEST(HE_MSGID_EXTENSION, read_packet); } void test_he_internal_flow_process_message_switch_client(void) { - conn->read_packet.packet_size = 1; - he_msg_hdr_t *msg = (he_msg_hdr_t *)conn->read_packet.packet; + he_packet_buffer_t read_packet = { 0 }; + read_packet.packet_size = 1; + he_msg_hdr_t *msg = (he_msg_hdr_t *)read_packet.packet; he_return_code_t res = HE_ERR_FAILED; // This is false by default but just to make this explicit conn->is_server = false; - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_CONFIG_IPV4, he_handle_msg_config_ipv4); - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_AUTH_RESPONSE, he_handle_msg_auth_response); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_CONFIG_IPV4, he_handle_msg_config_ipv4, read_packet); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_AUTH_RESPONSE, he_handle_msg_auth_response, read_packet); // No expectation of call here - HE_MSG_SWITCH_TEST(HE_MSGID_AUTH); + HE_MSG_SWITCH_TEST(HE_MSGID_AUTH, read_packet); } void test_he_internal_flow_process_message_switch_server(void) { - conn->read_packet.packet_size = 1; - he_msg_hdr_t *msg = (he_msg_hdr_t *)conn->read_packet.packet; + he_packet_buffer_t read_packet = { 0 }; + read_packet.packet_size = 1; + he_msg_hdr_t *msg = (he_msg_hdr_t *)read_packet.packet; he_return_code_t res = HE_ERR_FAILED; conn->is_server = true; - HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_AUTH, he_handle_msg_auth); + HE_MSG_SWITCH_TEST_EXPECT(HE_MSGID_AUTH, he_handle_msg_auth, read_packet); - HE_MSG_SWITCH_TEST(HE_MSGID_CONFIG_IPV4); - HE_MSG_SWITCH_TEST(HE_MSGID_AUTH_RESPONSE); + HE_MSG_SWITCH_TEST(HE_MSGID_CONFIG_IPV4, read_packet); + HE_MSG_SWITCH_TEST(HE_MSGID_AUTH_RESPONSE, read_packet); } void test_outside_data_handle_messages_triggers_renegotiation(void) { conn->renegotiation_due = true; - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); he_internal_renegotiate_ssl_ExpectAndReturn(conn, HE_SUCCESS); @@ -844,8 +839,7 @@ void test_outside_data_handle_messages_triggers_renegotiation(void) { void test_outside_data_handle_messages_triggers_renegotiation_error(void) { conn->renegotiation_due = true; - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); he_internal_renegotiate_ssl_ExpectAndReturn(conn, HE_ERR_SSL_ERROR); @@ -857,16 +851,14 @@ void test_outside_data_handle_messages_triggers_renegotiation_error(void) { void test_outside_data_handle_messages_skips_postprocessing_for_stream(void) { conn->connection_type = HE_CONNECTION_TYPE_STREAM; - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); he_internal_flow_outside_data_handle_messages(conn); } void test_outside_data_handle_messages_generates_renegotiation_event(void) { - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); // Renegotiation in process, conn does not expect renegotiation, no event @@ -878,8 +870,7 @@ void test_outside_data_handle_messages_generates_renegotiation_event(void) { TEST_ASSERT_TRUE(conn->renegotiation_in_progress); // Reset expectations - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); // Renegotiation in process, and conn expects renegotiation, no event, no change @@ -891,8 +882,7 @@ void test_outside_data_handle_messages_generates_renegotiation_event(void) { TEST_ASSERT_TRUE(conn->renegotiation_in_progress); // Reset expectations - wolfSSL_read_ExpectAndReturn(conn->wolf_ssl, conn->read_packet.packet, - sizeof(conn->read_packet.packet), SSL_FATAL_ERROR); + wolfSSL_read_IgnoreAndReturn(SSL_FATAL_ERROR); wolfSSL_get_error_ExpectAndReturn(conn->wolf_ssl, SSL_FATAL_ERROR, SSL_ERROR_WANT_READ); // Renegotiation completed, conn expects renegotiation, expect event and conn reset diff --git a/test/he/test_msg_handlers.c b/test/he/test_msg_handlers.c index a04d787..c883661 100644 --- a/test/he/test_msg_handlers.c +++ b/test/he/test_msg_handlers.c @@ -193,7 +193,7 @@ void test_msg_handler_pong(void) { void test_msg_handler_pong_pmtud_ack(void) { conn->ping_pending_id = 42; - conn->pmtud_probe_pending_id = 999; + conn->pmtud.probe_pending_id = 999; he_internal_pmtud_handle_probe_ack_ExpectAndReturn(conn, 999, HE_SUCCESS); @@ -206,6 +206,8 @@ void test_msg_handler_pong_pmtud_ack(void) { void test_msg_handler_pong_mismatch_id(void) { conn->ping_pending_id = 42; + he_internal_pmtud_handle_probe_ack_ExpectAndReturn(conn, 999, HE_SUCCESS); + he_msg_pong_t *pong = (he_msg_pong_t *)empty_data; pong->id = htons(999); ret = he_handle_msg_pong(conn, (uint8_t *)pong, sizeof(he_msg_pong_t)); diff --git a/test/he/test_pmtud.c b/test/he/test_pmtud.c index 65d7dfd..79bc0f0 100644 --- a/test/he/test_pmtud.c +++ b/test/he/test_pmtud.c @@ -49,7 +49,7 @@ void tearDown(void) { void test_he_internal_pmtud_send_probe(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; + conn.pmtud.state = HE_PMTUD_STATE_BASE; conn.pmtud_time_cb = pmtud_time_cb; conn.ping_next_id = 42; @@ -64,13 +64,13 @@ void test_he_internal_pmtud_send_probe(void) { he_return_code_t res = he_internal_pmtud_send_probe(&conn, probe_mtu); TEST_ASSERT_EQUAL(HE_SUCCESS, res); TEST_ASSERT_EQUAL(1, call_counter); - TEST_ASSERT_EQUAL(probe_mtu, conn.pmtud_probing_size); - TEST_ASSERT_EQUAL(42, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(probe_mtu, conn.pmtud.probing_size); + TEST_ASSERT_EQUAL(42, conn.pmtud.probe_pending_id); } void test_he_internal_pmtud_send_probe_failed(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; + conn.pmtud.state = HE_PMTUD_STATE_BASE; conn.pmtud_time_cb = pmtud_time_cb; conn.ping_next_id = 42; @@ -85,8 +85,8 @@ void test_he_internal_pmtud_send_probe_failed(void) { he_return_code_t res = he_internal_pmtud_send_probe(&conn, probe_mtu); TEST_ASSERT_EQUAL(HE_SUCCESS, res); TEST_ASSERT_EQUAL(1, call_counter); - TEST_ASSERT_EQUAL(probe_mtu, conn.pmtud_probing_size); - TEST_ASSERT_EQUAL(0, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(probe_mtu, conn.pmtud.probing_size); + TEST_ASSERT_EQUAL(0, conn.pmtud.probe_pending_id); } void test_he_internal_pmtud_send_probe_nulls(void) { @@ -99,80 +99,80 @@ void test_he_internal_pmtud_send_probe_invalid_conn_state(void) { void test_he_internal_pmtud_send_probe_when_probe_mtu_too_small(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; + conn.pmtud.state = HE_PMTUD_STATE_BASE; TEST_ASSERT_EQUAL(1416, MAX_PLPMTU); TEST_ASSERT_EQUAL(HE_ERR_INVALID_MTU_SIZE, he_internal_pmtud_send_probe(&conn, 120)); } void test_he_internal_pmtud_send_probe_when_probe_mtu_too_large(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; + conn.pmtud.state = HE_PMTUD_STATE_BASE; TEST_ASSERT_EQUAL(HE_ERR_INVALID_MTU_SIZE, he_internal_pmtud_send_probe(&conn, HE_MAX_WIRE_MTU)); } void test_he_internal_pmtud_handle_probe_ack_invalid_id(void) { // ignore invalid probe id - conn.pmtud_probe_pending_id = 123; + conn.pmtud.probe_pending_id = 123; TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_ack(&conn, 199)); } void test_he_internal_pmtud_handle_probe_ack_from_base(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; - conn.pmtud_probe_pending_id = 123; + conn.pmtud.state = HE_PMTUD_STATE_BASE; + conn.pmtud.probe_pending_id = 123; conn.pmtud_state_change_cb = pmtud_state_change_cb; conn.pmtud_time_cb = pmtud_time_cb; - conn.pmtud_base = HE_MAX_MTU; + conn.pmtud.base = HE_MAX_MTU; EXPECT_HE_INTERNAL_SEND_MESSAGE(HE_SUCCESS); TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_ack(&conn, 123)); // New state should be searching - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCHING, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCHING, conn.pmtud.state); // Should be using big step when first entering searching state - TEST_ASSERT_TRUE(conn.pmtud_is_using_big_step); + TEST_ASSERT_TRUE(conn.pmtud.is_using_big_step); // Current probing size should be BASE_PMTU + BIG_STEP - TEST_ASSERT_EQUAL(conn.pmtud_base + PMTUD_PROBE_BIG_STEP, conn.pmtud_probing_size); + TEST_ASSERT_EQUAL(conn.pmtud.base + PMTUD_PROBE_BIG_STEP, conn.pmtud.probing_size); // Both callbacks should be called TEST_ASSERT_EQUAL(2, call_counter); // Probe count should be reset - TEST_ASSERT_EQUAL(1, conn.pmtud_probe_count); + TEST_ASSERT_EQUAL(1, conn.pmtud.probe_count); } void test_he_internal_pmtud_handle_probe_ack_from_error(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_ERROR; - conn.pmtud_probe_pending_id = 123; + conn.pmtud.state = HE_PMTUD_STATE_ERROR; + conn.pmtud.probe_pending_id = 123; conn.pmtud_state_change_cb = pmtud_state_change_cb; conn.pmtud_time_cb = pmtud_time_cb; - conn.pmtud_base = HE_MAX_MTU; + conn.pmtud.base = HE_MAX_MTU; EXPECT_HE_INTERNAL_SEND_MESSAGE(HE_SUCCESS); TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_ack(&conn, 123)); // New state should be searching - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCHING, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCHING, conn.pmtud.state); // Should be using big step when first entering searching state - TEST_ASSERT_TRUE(conn.pmtud_is_using_big_step); + TEST_ASSERT_TRUE(conn.pmtud.is_using_big_step); // Current probing size should be BASE_PMTU + BIG_STEP - TEST_ASSERT_EQUAL(conn.pmtud_base + PMTUD_PROBE_BIG_STEP, conn.pmtud_probing_size); + TEST_ASSERT_EQUAL(conn.pmtud.base + PMTUD_PROBE_BIG_STEP, conn.pmtud.probing_size); // Both callbacks should be called TEST_ASSERT_EQUAL(2, call_counter); // Probe count should be reset - TEST_ASSERT_EQUAL(1, conn.pmtud_probe_count); + TEST_ASSERT_EQUAL(1, conn.pmtud.probe_count); } static void test_handle_probe_ack_from_searching(uint16_t probe_size, bool use_big_step) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_SEARCHING; - conn.pmtud_probe_pending_id = 123; + conn.pmtud.state = HE_PMTUD_STATE_SEARCHING; + conn.pmtud.probe_pending_id = 123; conn.pmtud_state_change_cb = pmtud_state_change_cb; conn.pmtud_time_cb = pmtud_time_cb; - conn.pmtud_base = MIN_PLPMTU; - conn.pmtud_probing_size = probe_size; - conn.pmtud_is_using_big_step = use_big_step; + conn.pmtud.base = MIN_PLPMTU; + conn.pmtud.probing_size = probe_size; + conn.pmtud.is_using_big_step = use_big_step; if(probe_size < MAX_PLPMTU) { EXPECT_HE_INTERNAL_SEND_MESSAGE(HE_SUCCESS); @@ -182,20 +182,20 @@ static void test_handle_probe_ack_from_searching(uint16_t probe_size, bool use_b if(probe_size >= MAX_PLPMTU) { // State should enter search complete - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCH_COMPLETE, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCH_COMPLETE, conn.pmtud.state); // Effective PMTU should be set - TEST_ASSERT_EQUAL(MAX_PLPMTU, conn.effective_pmtu); + TEST_ASSERT_EQUAL(MAX_PLPMTU, conn.pmtud.effective_pmtu); // pmtud_state_change_cb callback should be called twice, once to cancel the timer // and once more to retry probing TEST_ASSERT_EQUAL(2, call_counter); } else { // State should still be searching if the probed size is smaller than MAX_PLPMTU - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCHING, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCHING, conn.pmtud.state); // Probe size should be incremented if(use_big_step) { - TEST_ASSERT_EQUAL(probe_size + PMTUD_PROBE_BIG_STEP, conn.pmtud_probing_size); + TEST_ASSERT_EQUAL(probe_size + PMTUD_PROBE_BIG_STEP, conn.pmtud.probing_size); } else { - TEST_ASSERT_EQUAL(probe_size + PMTUD_PROBE_SMALL_STEP, conn.pmtud_probing_size); + TEST_ASSERT_EQUAL(probe_size + PMTUD_PROBE_SMALL_STEP, conn.pmtud.probing_size); } // Only the pmtud_time_cb callback should be called TEST_ASSERT_EQUAL(1, call_counter); @@ -216,8 +216,8 @@ void test_he_internal_pmtud_handle_probe_ack_from_searching_to_search_complete(v void test_he_internal_pmtud_handle_probe_ack_completed_retries(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_SEARCH_COMPLETE; - conn.pmtud_probe_pending_id = 123; + conn.pmtud.state = HE_PMTUD_STATE_SEARCH_COMPLETE; + conn.pmtud.probe_pending_id = 123; conn.pmtud_state_change_cb = pmtud_state_change_cb; conn.pmtud_time_cb = pmtud_time_cb; @@ -229,28 +229,28 @@ void test_he_internal_pmtud_handle_probe_ack_completed_retries(void) { void test_he_internal_pmtud_handle_probe_timeout_try_again(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_SEARCHING; - conn.pmtud_probe_count = 1; + conn.pmtud.state = HE_PMTUD_STATE_SEARCHING; + conn.pmtud.probe_count = 1; + conn.pmtud.probing_size = MAX_PLPMTU - 120; conn.pmtud_time_cb = pmtud_time_cb; conn.ping_next_id = 43; - conn.pmtud_probing_size = MAX_PLPMTU - 120; // It should send probe again when probe count hasn't reached MAX_PROBES EXPECT_HE_INTERNAL_SEND_MESSAGE(HE_SUCCESS); TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_timeout(&conn)); - TEST_ASSERT_EQUAL(2, conn.pmtud_probe_count); - TEST_ASSERT_EQUAL(43, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(2, conn.pmtud.probe_count); + TEST_ASSERT_EQUAL(43, conn.pmtud.probe_pending_id); TEST_ASSERT_EQUAL(44, conn.ping_next_id); } void test_he_internal_pmtud_handle_probe_timeout_confirm_base_failed(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; - conn.pmtud_probe_count = MAX_PROBES; + conn.pmtud.state = HE_PMTUD_STATE_BASE; + conn.pmtud.probe_count = MAX_PROBES; conn.pmtud_time_cb = pmtud_time_cb; - conn.pmtud_probing_size = MIN_PLPMTU; + conn.pmtud.probing_size = MIN_PLPMTU; // Probe count reached MAX_PROBES, // it should call he_internal_pmtud_confirm_base_failed if current state is BASE @@ -258,11 +258,11 @@ void test_he_internal_pmtud_handle_probe_timeout_confirm_base_failed(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_timeout(&conn)); // The new state should be Error - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_ERROR, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_ERROR, conn.pmtud.state); // The probe count and pending id should be reset to 0 - TEST_ASSERT_EQUAL(0, conn.pmtud_probe_count); - TEST_ASSERT_EQUAL(0, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(0, conn.pmtud.probe_count); + TEST_ASSERT_EQUAL(0, conn.pmtud.probe_pending_id); // pmtud_time_cb should be called to retry the error TEST_ASSERT_EQUAL(1, call_counter); @@ -270,10 +270,10 @@ void test_he_internal_pmtud_handle_probe_timeout_confirm_base_failed(void) { void test_he_internal_pmtud_handle_probe_timeout_confirm_base_retry_with_min_plpmtu(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_BASE; - conn.pmtud_probe_count = MAX_PROBES; + conn.pmtud.state = HE_PMTUD_STATE_BASE; + conn.pmtud.probe_count = MAX_PROBES; conn.pmtud_time_cb = pmtud_time_cb; - conn.pmtud_probing_size = INITIAL_PLPMTU; + conn.pmtud.probing_size = INITIAL_PLPMTU; conn.ping_next_id = 42; EXPECT_HE_INTERNAL_SEND_MESSAGE(HE_SUCCESS); @@ -283,14 +283,14 @@ void test_he_internal_pmtud_handle_probe_timeout_confirm_base_retry_with_min_plp TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_timeout(&conn)); // The new state should still be BASE - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_BASE, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_BASE, conn.pmtud.state); // The probe count and pending id should be set - TEST_ASSERT_EQUAL(1, conn.pmtud_probe_count); - TEST_ASSERT_EQUAL(42, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(1, conn.pmtud.probe_count); + TEST_ASSERT_EQUAL(42, conn.pmtud.probe_pending_id); // The new probe size should be MIN_PLPMTU - TEST_ASSERT_EQUAL(MIN_PLPMTU, conn.pmtud_probing_size); + TEST_ASSERT_EQUAL(MIN_PLPMTU, conn.pmtud.probing_size); // pmtud_time_cb should be called to retry the error TEST_ASSERT_EQUAL(1, call_counter); @@ -298,7 +298,7 @@ void test_he_internal_pmtud_handle_probe_timeout_confirm_base_retry_with_min_plp void test_he_internal_pmtud_start_base_probing(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_DISABLED; + conn.pmtud.state = HE_PMTUD_STATE_DISABLED; conn.pmtud_time_cb = pmtud_time_cb; conn.ping_next_id = 42; @@ -307,14 +307,14 @@ void test_he_internal_pmtud_start_base_probing(void) { he_return_code_t rc = he_internal_pmtud_start_base_probing(&conn); // The new state should be BASE - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_BASE, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_BASE, conn.pmtud.state); // The probe count and pending id should be set - TEST_ASSERT_EQUAL(1, conn.pmtud_probe_count); - TEST_ASSERT_EQUAL(42, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(1, conn.pmtud.probe_count); + TEST_ASSERT_EQUAL(42, conn.pmtud.probe_pending_id); // The probe size should be INITIAL_PLPMTU - TEST_ASSERT_EQUAL(INITIAL_PLPMTU, conn.pmtud_probing_size); + TEST_ASSERT_EQUAL(INITIAL_PLPMTU, conn.pmtud.probing_size); // pmtud_time_cb should be called to retry the error TEST_ASSERT_EQUAL(1, call_counter); @@ -324,24 +324,24 @@ void test_he_internal_pmtud_start_base_probing(void) { void test_he_internal_pmtud_handle_probe_timeout_search_completed(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_SEARCHING; - conn.pmtud_probe_count = 3; - conn.pmtud_probing_size = MAX_PLPMTU - 120; - conn.pmtud_is_using_big_step = false; + conn.pmtud.state = HE_PMTUD_STATE_SEARCHING; + conn.pmtud.probe_count = 3; + conn.pmtud.probing_size = MAX_PLPMTU - 120; + conn.pmtud.is_using_big_step = false; conn.pmtud_time_cb = pmtud_time_cb; // Probe count reached MAX_PROBES, TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_timeout(&conn)); // The new state should be Search Complete - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCH_COMPLETE, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_SEARCH_COMPLETE, conn.pmtud.state); // The effective mtu should be set - TEST_ASSERT_EQUAL(MAX_PLPMTU - 120 - PMTUD_PROBE_SMALL_STEP, conn.effective_pmtu); + TEST_ASSERT_EQUAL(MAX_PLPMTU - 120 - PMTUD_PROBE_SMALL_STEP, conn.pmtud.effective_pmtu); // The probe count and pending id should be reset to 0 - TEST_ASSERT_EQUAL(0, conn.pmtud_probe_count); - TEST_ASSERT_EQUAL(0, conn.pmtud_probe_pending_id); + TEST_ASSERT_EQUAL(0, conn.pmtud.probe_count); + TEST_ASSERT_EQUAL(0, conn.pmtud.probe_pending_id); // pmtud_time_cb should be called to schedule a retest TEST_ASSERT_EQUAL(1, call_counter); @@ -349,10 +349,10 @@ void test_he_internal_pmtud_handle_probe_timeout_search_completed(void) { void test_he_internal_pmtud_handle_probe_timeout_blackhole_detected(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_SEARCH_COMPLETE; - conn.pmtud_probe_count = MAX_PROBES; - conn.pmtud_probing_size = MAX_PLPMTU - 120; - conn.pmtud_is_using_big_step = false; + conn.pmtud.state = HE_PMTUD_STATE_SEARCH_COMPLETE; + conn.pmtud.probe_count = MAX_PROBES; + conn.pmtud.probing_size = MAX_PLPMTU - 120; + conn.pmtud.is_using_big_step = false; conn.pmtud_time_cb = pmtud_time_cb; EXPECT_HE_INTERNAL_SEND_MESSAGE(HE_SUCCESS); @@ -361,13 +361,13 @@ void test_he_internal_pmtud_handle_probe_timeout_blackhole_detected(void) { TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_timeout(&conn)); // The new state should be Base - TEST_ASSERT_EQUAL(HE_PMTUD_STATE_BASE, conn.pmtud_state); + TEST_ASSERT_EQUAL(HE_PMTUD_STATE_BASE, conn.pmtud.state); // The base mtu should be set to MIN_PLPMTU - TEST_ASSERT_EQUAL(MIN_PLPMTU, conn.pmtud_base); + TEST_ASSERT_EQUAL(MIN_PLPMTU, conn.pmtud.base); // The probe count should be reset to 1 - TEST_ASSERT_EQUAL(1, conn.pmtud_probe_count); + TEST_ASSERT_EQUAL(1, conn.pmtud.probe_count); // pmtud_time_cb should be called TEST_ASSERT_EQUAL(1, call_counter); @@ -375,13 +375,13 @@ void test_he_internal_pmtud_handle_probe_timeout_blackhole_detected(void) { void test_he_internal_pmtud_handle_probe_timeout_on_error_try_again(void) { conn.state = HE_STATE_ONLINE; - conn.pmtud_state = HE_PMTUD_STATE_ERROR; - conn.pmtud_probe_count = MAX_PROBES; + conn.pmtud.state = HE_PMTUD_STATE_ERROR; + conn.pmtud.probe_count = MAX_PROBES; conn.pmtud_time_cb = pmtud_time_cb; TEST_ASSERT_EQUAL(HE_SUCCESS, he_internal_pmtud_handle_probe_timeout(&conn)); - TEST_ASSERT_EQUAL(0, conn.pmtud_probe_count); + TEST_ASSERT_EQUAL(0, conn.pmtud.probe_count); // pmtud_time_cb should be called to start a new timer TEST_ASSERT_EQUAL(1, call_counter); diff --git a/test/he/test_wolf.c b/test/he/test_wolf.c index e2b5014..04a4084 100644 --- a/test/he/test_wolf.c +++ b/test/he/test_wolf.c @@ -31,6 +31,8 @@ // Internal Mocks #include "mock_plugin_chain.h" +#include "mock_flow.h" +#include "mock_conn.h" uint8_t *packet = NULL; uint8_t *buffer = NULL; @@ -114,22 +116,30 @@ he_return_code_t outside_write_return_failure_on_third_call(he_conn_t *conn1, ui } } -void assert_standard_header(uint8_t write_buffer[]) { - TEST_ASSERT_EQUAL_CHAR('H', write_buffer[0]); - TEST_ASSERT_EQUAL_CHAR('e', write_buffer[1]); +void assert_standard_header(he_internal_write_buf_t *wbuffer) { + TEST_ASSERT_EQUAL_CHAR('H', wbuffer->buf[0]); + TEST_ASSERT_EQUAL_CHAR('e', wbuffer->buf[1]); } -void assert_standard_version(uint8_t write_buffer[]) { - TEST_ASSERT_EQUAL(HE_WIRE_MAXIMUM_PROTOCOL_MAJOR_VERSION, write_buffer[2]); - TEST_ASSERT_EQUAL(HE_WIRE_MAXIMUM_PROTOCOL_MINOR_VERSION, write_buffer[3]); +void assert_standard_version(he_internal_write_buf_t *wbuffer) { + TEST_ASSERT_EQUAL(HE_WIRE_MAXIMUM_PROTOCOL_MAJOR_VERSION, wbuffer->buf[2]); + TEST_ASSERT_EQUAL(HE_WIRE_MAXIMUM_PROTOCOL_MINOR_VERSION, wbuffer->buf[3]); } -void assert_standard_reserved_section(uint8_t write_buffer[]) { - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[5]); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[6]); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[7]); +void assert_standard_reserved_section(he_internal_write_buf_t *wbuffer) { + TEST_ASSERT_EQUAL(0x00, wbuffer->buf[5]); + TEST_ASSERT_EQUAL(0x00, wbuffer->buf[6]); + TEST_ASSERT_EQUAL(0x00, wbuffer->buf[7]); } +#ifdef HE_ENABLE_MULTITHREADED +HE_THREAD_LOCAL uint8_t* cur_packet; +HE_THREAD_LOCAL size_t cur_packet_length; +HE_THREAD_LOCAL bool packet_seen; +#endif + +he_internal_write_buf_t write_buffer; + void setUp(void) { srand(time(NULL)); @@ -137,9 +147,9 @@ void setUp(void) { buffer = calloc(1, buffer_max_length); conn = calloc(1, sizeof(he_conn_t)); - conn->packet_seen = false; - conn->incoming_data = packet; - conn->incoming_data_length = packet_max_length; + he_internal_set_packet(conn, packet, packet_max_length); + he_internal_set_packet_seen(conn, false); + conn->outside_write_cb = outside_write_test; conn->protocol_version.major_version = HE_WIRE_MAXIMUM_PROTOCOL_MAJOR_VERSION; conn->protocol_version.minor_version = HE_WIRE_MAXIMUM_PROTOCOL_MINOR_VERSION; @@ -150,6 +160,7 @@ void setUp(void) { } write_callback_count = 0; + memset(&write_buffer, 0, sizeof(write_buffer)); he_plugin_egress_IgnoreAndReturn(HE_SUCCESS); } @@ -161,6 +172,7 @@ void tearDown(void) { } void test_read_raw_buffer_pass_to_read(void) { + int res1 = he_wolf_dtls_read(ssl, (char *)buffer, packet_max_length, conn); TEST_ASSERT_EQUAL(packet_max_length, res1); @@ -169,11 +181,11 @@ void test_read_raw_buffer_pass_to_read(void) { } void test_read_no_data_error_triggered_on_second_read(void) { - TEST_ASSERT_FALSE(conn->packet_seen); + TEST_ASSERT_FALSE(he_internal_is_packet_seen(conn)); int res1 = he_wolf_dtls_read(ssl, (char *)packet, packet_max_length, conn); - TEST_ASSERT_TRUE(conn->packet_seen); + TEST_ASSERT_TRUE(he_internal_is_packet_seen(conn)); int res2 = he_wolf_dtls_read(ssl, (char *)packet, packet_max_length, conn); @@ -192,79 +204,79 @@ void test_read_buffer_too_small(void) { } void test_read_null_incoming_data(void) { - conn->incoming_data = NULL; + he_internal_set_packet(conn, NULL, 0); int res = he_wolf_dtls_read(ssl, (char *)packet, packet_max_length, conn); TEST_ASSERT_EQUAL(WOLFSSL_CBIO_ERR_WANT_READ, res); } void test_write_create_packet(void) { - int res1 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Checks that the data written is what WolfSSL expects - Helium headers are extra and not covered // here TEST_ASSERT_EQUAL(test_packet_size, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_version(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_version(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &conn->write_buffer[8], sizeof(conn->session_id)); + TEST_ASSERT_EQUAL(0x00, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &write_buffer.buf[8], sizeof(conn->session_id)); // Test packet is unchanged - TEST_ASSERT_EQUAL_MEMORY(packet, conn->write_buffer + sizeof(he_wire_hdr_t), test_packet_size); + TEST_ASSERT_EQUAL_MEMORY(packet, write_buffer.buf + sizeof(he_wire_hdr_t), test_packet_size); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); } void test_write_packet_too_big(void) { size_t test_packet_size = 4000; - int res1 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Make sure it returns an error correctly TEST_ASSERT_EQUAL(WOLFSSL_CBIO_ERR_GENERAL, res1); // Ensure the write buffer wasn't touched - TEST_ASSERT_EQUAL(0, conn->write_buffer[0]); + TEST_ASSERT_EQUAL(0, write_buffer.buf[0]); } void test_write_context_gets_passed(void) { conn->data = conn; conn->outside_write_cb = outside_write_test_with_context; - int res1 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); TEST_ASSERT_EQUAL(test_packet_size, res1); } void test_internal_pkt_header_writer(void) { conn->session_id = 0x1234567891234567; - int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)conn->write_buffer); + int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)&write_buffer.buf); TEST_ASSERT_EQUAL(HE_SUCCESS, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_version(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_version(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &conn->write_buffer[8], sizeof(conn->session_id)); + TEST_ASSERT_EQUAL(0x00, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &write_buffer.buf[8], sizeof(conn->session_id)); } void test_internal_pkt_header_writer_aggressive_mode(void) { conn->session_id = 0x1234567891234567; conn->use_aggressive_mode = true; - int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)conn->write_buffer); + int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)&write_buffer.buf); TEST_ASSERT_EQUAL(HE_SUCCESS, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_version(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_version(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0x01, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &conn->write_buffer[8], sizeof(conn->session_id)); + TEST_ASSERT_EQUAL(0x01, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &write_buffer.buf[8], sizeof(conn->session_id)); } void test_internal_pkt_header_writer_disabled_roaming_sessions(void) { @@ -273,19 +285,19 @@ void test_internal_pkt_header_writer_disabled_roaming_sessions(void) { // Setting this manually so that these tests don't have a dependency on conn conn->disable_roaming_connections = true; - int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)conn->write_buffer); + int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)&write_buffer.buf); TEST_ASSERT_EQUAL(HE_SUCCESS, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_version(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_version(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&temp_session, &conn->write_buffer[8], sizeof(conn->session_id)); + TEST_ASSERT_EQUAL(0x00, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&temp_session, &write_buffer.buf[8], sizeof(conn->session_id)); } void test_internal_pkt_header_various_nulls(void) { - int res1 = he_internal_write_packet_header(NULL, (he_wire_hdr_t *)conn->write_buffer); + int res1 = he_internal_write_packet_header(NULL, (he_wire_hdr_t *)&write_buffer.buf); int res2 = he_internal_write_packet_header(conn, NULL); int res3 = he_internal_write_packet_header(NULL, NULL); @@ -297,16 +309,16 @@ void test_internal_pkt_header_various_nulls(void) { void test_internal_pkt_header_writer_pending_session(void) { conn->session_id = 0x1234567891234567; conn->pending_session_id = 0x9876543219876543; - int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)conn->write_buffer); + int res1 = he_internal_write_packet_header(conn, (he_wire_hdr_t *)&write_buffer.buf); TEST_ASSERT_EQUAL(HE_SUCCESS, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_version(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_version(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&conn->pending_session_id, &conn->write_buffer[8], + TEST_ASSERT_EQUAL(0x00, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&conn->pending_session_id, &write_buffer.buf[8], sizeof(conn->session_id)); } @@ -314,22 +326,22 @@ void test_write_dont_explode_if_not_write_cb_set(void) { // Unset the callback conn->outside_write_cb = NULL; - int res1 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Checks that the data written is what WolfSSL expects - Helium headers are extra and not covered // here TEST_ASSERT_EQUAL(test_packet_size, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_version(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_version(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &conn->write_buffer[8], sizeof(conn->session_id)); + TEST_ASSERT_EQUAL(0x00, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &write_buffer.buf[8], sizeof(conn->session_id)); // Test packet is unchanged - TEST_ASSERT_EQUAL_MEMORY(packet, conn->write_buffer + sizeof(he_wire_hdr_t), test_packet_size); + TEST_ASSERT_EQUAL_MEMORY(packet, write_buffer.buf + sizeof(he_wire_hdr_t), test_packet_size); // Test that the callback is set correctly TEST_ASSERT_NULL(conn->outside_write_cb); @@ -339,24 +351,24 @@ void test_write_accepts_conn_version(void) { conn->protocol_version.major_version = 0xFF; conn->protocol_version.minor_version = 0x99; - int res1 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Checks that the data written is what WolfSSL expects - Helium headers are extra and not covered // here TEST_ASSERT_EQUAL(test_packet_size, res1); // Test we have a valid helium header - assert_standard_header(conn->write_buffer); - assert_standard_reserved_section(conn->write_buffer); + assert_standard_header(&write_buffer); + assert_standard_reserved_section(&write_buffer); - TEST_ASSERT_EQUAL(0xFF, conn->write_buffer[2]); - TEST_ASSERT_EQUAL(0x99, conn->write_buffer[3]); + TEST_ASSERT_EQUAL(0xFF, write_buffer.buf[2]); + TEST_ASSERT_EQUAL(0x99, write_buffer.buf[3]); - TEST_ASSERT_EQUAL(0x00, conn->write_buffer[4]); - TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &conn->write_buffer[8], sizeof(conn->session_id)); + TEST_ASSERT_EQUAL(0x00, write_buffer.buf[4]); + TEST_ASSERT_EQUAL_MEMORY(&conn->session_id, &write_buffer.buf[8], sizeof(conn->session_id)); // Test packet is unchanged - TEST_ASSERT_EQUAL_MEMORY(packet, conn->write_buffer + sizeof(he_wire_hdr_t), test_packet_size); + TEST_ASSERT_EQUAL_MEMORY(packet, write_buffer.buf + sizeof(he_wire_hdr_t), test_packet_size); } void test_aggressive_mode_is_off_write_callback_called_once_when_online(void) { @@ -364,7 +376,7 @@ void test_aggressive_mode_is_off_write_callback_called_once_when_online(void) { conn->state = HE_STATE_ONLINE; // Call a write - he_return_code_t res1 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res1 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -378,7 +390,7 @@ void test_aggressive_mode_is_on_write_callback_called_three_times_when_online(vo conn->use_aggressive_mode = true; // Call a write - he_return_code_t res2 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -393,7 +405,7 @@ void test_aggressive_mode_is_on_write_callback_checks_result_on_second_callback_ conn->outside_write_cb = outside_write_return_failure_on_second_call; // Call a write - he_return_code_t res2 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback errors on the second attempt TEST_ASSERT_EQUAL(1, write_callback_count); @@ -406,7 +418,7 @@ void test_aggressive_mode_is_on_write_callback_checks_result_on_third_callback_t conn->outside_write_cb = outside_write_return_failure_on_third_call; // Call a write - he_return_code_t res2 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback errors on the 3rd attempt TEST_ASSERT_EQUAL(2, write_callback_count); @@ -415,7 +427,7 @@ void test_aggressive_mode_is_on_write_callback_checks_result_on_third_callback_t void test_aggressive_mode_on_before_online(void) { // Call a write - he_return_code_t res2 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -429,7 +441,7 @@ void test_plugin_drop_results_in_no_write(void) { he_plugin_egress_ExpectAnyArgsAndReturn(HE_ERR_PLUGIN_DROP); // Call a write - he_return_code_t res2 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -443,7 +455,7 @@ void test_plugin_error_results_in_no_write(void) { he_plugin_egress_ExpectAnyArgsAndReturn(HE_ERR_FAILED); // Call a write - he_return_code_t res2 = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -454,7 +466,7 @@ void test_plugin_error_results_in_no_write(void) { void test_outside_write_failure_returns_failure(void) { conn->outside_write_cb = outside_write_return_failure; - int res = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); TEST_ASSERT_EQUAL(WOLFSSL_CBIO_ERR_GENERAL, res); } @@ -463,7 +475,7 @@ void test_dtls_overflow_plugin_egress_returns_failure(void) { he_plugin_egress_StopIgnore(); he_plugin_egress_Stub(stub_overflow_plugin); - int res = he_wolf_dtls_write(ssl, (char *)packet, test_packet_size, conn); + int res = he_wolf_dtls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); TEST_ASSERT_EQUAL(WOLFSSL_CBIO_ERR_GENERAL, res); } @@ -505,11 +517,11 @@ void test_tls_write_simple(void) { conn->data = conn; conn->outside_write_cb = outside_write_test_for_streaming; - int res1 = he_wolf_tls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_tls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Make sure it sent all the data TEST_ASSERT_EQUAL(test_packet_size, res1); - TEST_ASSERT_EQUAL_MEMORY(packet, &conn->write_buffer[0], test_packet_size); + TEST_ASSERT_EQUAL_MEMORY(packet, &write_buffer.buf[0], test_packet_size); } void test_tls_write_attemps_lots_of_data_but_only_write_our_buffer_size(void) { @@ -517,11 +529,11 @@ void test_tls_write_attemps_lots_of_data_but_only_write_our_buffer_size(void) { conn->data = conn; conn->outside_write_cb = outside_write_test_for_streaming_large; - int res1 = he_wolf_tls_write(ssl, (char *)packet, HE_MAX_WIRE_MTU * 2, conn); + int res1 = he_wolf_tls_write_internal(ssl, (char *)packet, HE_MAX_WIRE_MTU * 2, conn, &write_buffer); // Make sure it sent only HE_MAX_WIRE_MTU worth of data and told wolf just that many TEST_ASSERT_EQUAL(HE_MAX_WIRE_MTU, res1); - TEST_ASSERT_EQUAL_MEMORY(packet, &conn->write_buffer[0], HE_MAX_WIRE_MTU); + TEST_ASSERT_EQUAL_MEMORY(packet, &write_buffer.buf[0], HE_MAX_WIRE_MTU); } void test_plugin_drop_results_in_no_write_tls(void) { @@ -529,7 +541,7 @@ void test_plugin_drop_results_in_no_write_tls(void) { he_plugin_egress_ExpectAnyArgsAndReturn(HE_ERR_PLUGIN_DROP); // Call a write - he_return_code_t res2 = he_wolf_tls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_tls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -543,7 +555,7 @@ void test_plugin_error_results_in_no_write_tls(void) { he_plugin_egress_ExpectAnyArgsAndReturn(HE_ERR_FAILED); // Call a write - he_return_code_t res2 = he_wolf_tls_write(ssl, (char *)packet, test_packet_size, conn); + he_return_code_t res2 = he_wolf_tls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); // Test that the callback is set correctly TEST_ASSERT_EQUAL(outside_write_test, conn->outside_write_cb); @@ -556,7 +568,7 @@ void test_tls_write_dont_explode_if_not_write_cb_set(void) { // Unset the callback conn->outside_write_cb = NULL; - int res1 = he_wolf_tls_write(ssl, (char *)packet, test_packet_size, conn); + int res1 = he_wolf_tls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); TEST_ASSERT_EQUAL(test_packet_size, res1); @@ -566,7 +578,7 @@ void test_tls_write_dont_explode_if_not_write_cb_set(void) { void test_tls_write_outside_cb_cb_returns_failure(void) { conn->outside_write_cb = outside_write_return_failure; - int res = he_wolf_tls_write(ssl, (char *)packet, test_packet_size, conn); + int res = he_wolf_tls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); TEST_ASSERT_EQUAL(WOLFSSL_CBIO_ERR_GENERAL, res); } @@ -575,7 +587,7 @@ void test_tls_overflow_plugin_egress_returns_failure(void) { he_plugin_egress_StopIgnore(); he_plugin_egress_Stub(stub_overflow_plugin); - int res = he_wolf_tls_write(ssl, (char *)packet, test_packet_size, conn); + int res = he_wolf_tls_write_internal(ssl, (char *)packet, test_packet_size, conn, &write_buffer); TEST_ASSERT_EQUAL(WOLFSSL_CBIO_ERR_GENERAL, res); } @@ -583,10 +595,10 @@ void test_tls_overflow_plugin_egress_returns_failure(void) { void test_impossible_sizes(void) { int res = he_wolf_dtls_read(ssl, (char *)packet, -1, conn); TEST_ASSERT_EQUAL(res, -1); - res = he_wolf_dtls_write(ssl, (char *)packet, -1, conn); + res = he_wolf_dtls_write_internal(ssl, (char *)packet, -1, conn, &write_buffer); TEST_ASSERT_EQUAL(res, -1); res = he_wolf_tls_read(ssl, (char *)packet, -1, conn); TEST_ASSERT_EQUAL(res, -1); - res = he_wolf_tls_write(ssl, (char *)packet, -1, conn); + res = he_wolf_tls_write_internal(ssl, (char *)packet, -1, conn, &write_buffer); TEST_ASSERT_EQUAL(res, -1); } diff --git a/windows.yml b/windows.yml index a82d908..4c21a5a 100644 --- a/windows.yml +++ b/windows.yml @@ -10,6 +10,7 @@ - HAVE_SECURE_RENEGOTIATION - WOLFSSL_DTLS_CH_FRAG - WOLFSSL_TLS13_MIDDLEBOX_COMPAT + - WOLFSSL_RW_THREADED :test_preprocess: - WOLFSSL_USER_SETTINGS - WOLFSSL_MIN_RSA_BITS=2048 @@ -17,6 +18,7 @@ - HAVE_SECURE_RENEGOTIATION - WOLFSSL_DTLS_CH_FRAG - WOLFSSL_TLS_MIDDLEBOX_COMPAT + - WOLFSSL_RW_THREADED #- USE_WINDOWS_API # avoids use of unistd.h :release: - WOLFSSL_USER_SETTINGS @@ -25,6 +27,7 @@ - HAVE_SECURE_RENEGOTIATION - WOLFSSL_DTLS_CH_FRAG - WOLFSSL_TLS13_MIDDLEBOX_COMPAT + - WOLFSSL_RW_THREADED :libraries: :path_flag: /LIBPATH:${1} diff --git a/windows/wolfssl-user_settings-32.h b/windows/wolfssl-user_settings-32.h index 12343e4..6be8974 100644 --- a/windows/wolfssl-user_settings-32.h +++ b/windows/wolfssl-user_settings-32.h @@ -37,7 +37,6 @@ #define WOLFSSL_SEND_HRR_COOKIE #undef SINGLE_THREADED -#define SINGLE_THREADED #undef HAVE_THREAD_LS #define HAVE_THREAD_LS @@ -221,4 +220,7 @@ #undef WOLFSSL_SHAKE256 #define WOLFSSL_SHAKE256 +#undef WOLFSSL_RW_THREADED +#define WOLFSSL_RW_THREADED + #endif /* _WIN_USER_SETTINGS_H_ */ diff --git a/windows/wolfssl-user_settings-64.h b/windows/wolfssl-user_settings-64.h index 51a362a..aa0f14c 100644 --- a/windows/wolfssl-user_settings-64.h +++ b/windows/wolfssl-user_settings-64.h @@ -37,7 +37,6 @@ #define WOLFSSL_SEND_HRR_COOKIE #undef SINGLE_THREADED -#define SINGLE_THREADED #undef HAVE_THREAD_LS #define HAVE_THREAD_LS @@ -221,4 +220,7 @@ #undef WOLFSSL_SHAKE256 #define WOLFSSL_SHAKE256 +#undef WOLFSSL_RW_THREADED +#define WOLFSSL_RW_THREADED + #endif /* _WIN_USER_SETTINGS_H_ */ diff --git a/windows/wolfssl-user_settings-arm-64.h b/windows/wolfssl-user_settings-arm-64.h index 0d9508a..facd935 100644 --- a/windows/wolfssl-user_settings-arm-64.h +++ b/windows/wolfssl-user_settings-arm-64.h @@ -37,7 +37,6 @@ #define WOLFSSL_SEND_HRR_COOKIE #undef SINGLE_THREADED -#define SINGLE_THREADED #undef HAVE_THREAD_LS #define HAVE_THREAD_LS @@ -221,4 +220,7 @@ #undef WOLFSSL_SHAKE256 #define WOLFSSL_SHAKE256 +#undef WOLFSSL_RW_THREADED +#define WOLFSSL_RW_THREADED + #endif /* _WIN_USER_SETTINGS_H_ */ diff --git a/windows/wolfssl.vcxproj b/windows/wolfssl.vcxproj index 98c9c99..4133454 100644 --- a/windows/wolfssl.vcxproj +++ b/windows/wolfssl.vcxproj @@ -202,7 +202,7 @@ Disabled ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -216,7 +216,7 @@ Disabled ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -237,7 +237,7 @@ Disabled ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -251,7 +251,7 @@ Disabled ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -270,7 +270,7 @@ Disabled ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -284,7 +284,7 @@ Disabled ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL @@ -304,7 +304,7 @@ MaxSpeed true ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -317,7 +317,7 @@ MaxSpeed true ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -335,7 +335,7 @@ MaxSpeed true ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_LIB;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -349,7 +349,7 @@ MaxSpeed true ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -367,7 +367,7 @@ MaxSpeed true ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_LIB;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_LIB;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -381,7 +381,7 @@ MaxSpeed true ./;./IDE/WIN;%(AdditionalIncludeDirectories) - WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) + WOLFSSL_MIN_RSA_BITS=2048;WOLFSSL_MIN_ECC_BITS=256;HAVE_SECURE_RENEGOTIATION;WOLFSSL_DTLS_CH_FRAG;WOLFSSL_TLS13_MIDDLEBOX_COMPAT;WOLFSSL_LIB;BUILDING_WOLFSSL;WOLFSSL_DLL;WOLFSSL_RW_THREADED;WOLFSSL_USER_SETTINGS;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -574,4 +574,4 @@ - \ No newline at end of file + diff --git a/windows_64_multithread.yml b/windows_64_multithread.yml new file mode 100644 index 0000000..4ee1f9c --- /dev/null +++ b/windows_64_multithread.yml @@ -0,0 +1,113 @@ +--- # ceedling project file for Windows +:import: + - 3rd_party_deps.yml + - windows.yml + +:dependencies: + :libraries: + - :name: WolfSSL + :source_path: third_party/wolfssl + :fetch: + :method: :git + :source: "%HE_WOLFSSL_SOURCE%" + :tag: "%HE_WOLFSSL_TAG%" + :build: + - git apply ../../wolfssl/0001-fix-poly1305-aarch64-corner-case.patch + - git apply ../../wolfssl/0002-include-private-key-fields-for-kyber.patch + - git apply ../../wolfssl/0003-make-kyber-mlkem-available.patch + - git apply ../../wolfssl/0004-fix-kyber-mlkem-benchmark.patch + - git apply ../../wolfssl/0005-fix-mlkem-get-curve-name.patch + - git apply ../../wolfssl/0006-fix-kyber-get-curve-name.patch + - git apply ../../wolfssl/0007-fix-kyber-prf-non-avx2.patch + - "cp ../../windows/wolfssl-user_settings-64.h wolfssl/user_settings.h" + - "cp -f ../../windows/wolfssl-user_settings-64.h IDE/WIN/user_settings.h" + - "cp -f ../../windows/wolfssl.vcxproj ./wolfssl.vcxproj" + - "MSBuild.exe wolfssl.vcxproj -verbosity:detailed -t:Build -p:Configuration=Release -p:Platform=x64 -p:PlatformToolset=v143" + :artifacts: + :includes: + - / + - /wolfssl # needed e.g. for mock_ssl.h to find wolfssl/ssl.h + :static_libraries: + - Release/x64/wolfssl.lib + +# https://github.com/ThrowTheSwitch/Ceedling/issues/210 -> https://github.com/ThrowTheSwitch/Ceedling/files/1360977/project.txt +:tools: +# Ceedling defaults to using gcc for compiling, linking, etc. +# As [:tools] is blank, gcc will be used (so long as it's in your system path) +# See documentation to configure a given toolchain for use + :test_compiler: + :executable: cl + :name: 'msvc' + :arguments: + - /std:c11 + - /experimental:c11atomics + - /D"HE_ENABLE_MULTITHREADED" + - /c + - /nologo + - /MT + - /GL + - /I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - /I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - /D"$": COLLECTION_DEFINES_TEST_AND_VENDOR + - /Fo"${2}" + - "${1}" + :test_linker: + :executable: link + :name: 'msvc' + :arguments: + - /MACHINE:X64 + - "${1}" + - /FORCE:MULTIPLE # /IGNORE:LNK4006 # mocks deliberately duplicate symbols + - /LTCG + - "${5}" + - "${4}" + - /OUT:"${2}" + :test_file_preprocessor: + :executable: cl + :name: 'msvc' + :arguments: + - /P + - /C + - /I test_file_preprocessor + - /I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + - /I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + - /D"$": COLLECTION_DEFINES_TEST_AND_VENDOR + - /D"$": DEFINES_TEST_PREPROCESS + - /Fi"${2}" + - "${1}" + # This is `gcc -E -MM -MG` which outputs a make dependency rule. + # Unsure how to coax cl.exe into doing this, so just stick with gcc. + #:test_includes_preprocessor: + # :executable: cl + # :name: 'msvc' + # :arguments: + # - /P + # - /I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR + # - /I"$": COLLECTION_PATHS_TEST_TOOLCHAIN_INCLUDE + # - /D"$": COLLECTION_DEFINES_TEST_AND_VENDOR + # - /D"$": DEFINES_TEST_PREPROCESS + # - "${1}" + :release_compiler: + :executable: cl + :name: 'msvc' + :arguments: + - /std:c11 + - /experimental:c11atomics + - /D"HE_ENABLE_MULTITHREADED" + - /c + - /MT + - /I"$": COLLECTION_PATHS_SOURCE_INCLUDE_VENDOR + - /I"$": COLLECTION_PATHS_RELEASE_TOOLCHAIN_INCLUDE + - /D"$": COLLECTION_DEFINES_RELEASE_AND_VENDOR + - /Fo"${2}" + - "${1}" + :release_linker: + #:executable: link + :executable: lib + :name: 'msvc' + :arguments: + - /MACHINE:X64 + - "${1}" + - /OUT:"${2}" + +...