From 0fc181dfac5ff5ba13e24fcec389253fa235d1fc Mon Sep 17 00:00:00 2001 From: Khoi Hoang <57012152+khoih-prog@users.noreply.github.com> Date: Sun, 4 Sep 2022 19:53:47 -0400 Subject: [PATCH] v1.3.0 to add `ESP32_S3` support. etc. ### Releases v1.3.0 1. Remove hard-code if possible 2. Improve debug messages by adding functions to display `error/state messages` instead of `cryptic error/state number` 3. Clean up 4. Add support to `ESP32_S3`, using ESP32 core `v2.0.3`. **Don't use `ESP32_S3` with core v2.0.4**. Check [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165) --- CONTRIBUTING.md | 10 +- README.md | 190 +++++--- changelog.md | 8 + .../multiFileProject/multiFileProject.ino | 12 +- library.json | 4 +- library.properties | 4 +- platformio/platformio.ini | 2 + src/AsyncTCP_SSL.h | 3 +- src/AsyncTCP_SSL.hpp | 223 ++++----- src/AsyncTCP_SSL_Debug.h | 15 +- src/AsyncTCP_SSL_Impl.h | 435 +++++++++--------- src/tcp_mbedtls.c | 279 +++++------ src/tcp_mbedtls.h | 7 +- 13 files changed, 602 insertions(+), 590 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f87e9a1..0568082 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,12 +15,12 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p Please ensure to specify the following: * Arduino IDE version (e.g. 1.8.19) or Platform.io version -* `ESP32` Core Version (e.g. ESP32 core v2.0.2) -* `ESP32` Board type (e.g. ESP32_DEV, ESP32S2_DEV Module, ESP32_S2_Saola, etc.) +* `ESP32` Core Version (e.g. ESP32 core v2.0.4) +* `ESP32` Board type (e.g. ESP32_DEV, ESP32_S2, ESP32_S3, ESP32_C3, etc.) * Contextual information (e.g. what you were trying to achieve) * Simplest possible steps to reproduce * Anything that might be relevant in your opinion, such as: - * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` + * Operating system (Windows, Ubuntu, etc.) and the output of `uname -a` for Linux / Ubuntu * Network configuration @@ -28,10 +28,10 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.19 -ESP32 core v2.0.2 +ESP32 core v2.0.4 ESP32_DEV Module OS: Ubuntu 20.04 LTS -Linux xy-Inspiron-3593 5.4.0-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux +Linux xy-Inspiron-3593 5.15.0-46-generic #49~20.04.1-Ubuntu SMP Thu Aug 4 19:15:44 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux Context: I encountered a crash while using TimerInterrupt. diff --git a/README.md b/README.md index f32524f..0fa50c2 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,15 @@ [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/AsyncTCP_SSL.svg)](http://github.com/khoih-prog/AsyncTCP_SSL/issues) - - -Buy Me A Coffee - +Donate to my libraries using BuyMeACoffee + --- --- ## Table of contents +* [Important Note for ESP32_S3](#Important-Note-for-ESP32_S3) * [Important Change from v1.2.0](#Important-Change-from-v120) * [Why do we need this AsyncTCP_SSL library](#why-do-we-need-this-AsyncTCP_SSL-library) * [Features](#features) @@ -42,6 +41,7 @@ * [2. AsyncHTTPSRequest_ESP on ESP32S2_DEV](#2-AsyncHTTPSRequest_ESP-on-ESP32S2_DEV) * [3. AsyncHTTPSRequest_ESP on ESP32C3_DEV](#3-AsyncHTTPSRequest_ESP-on-ESP32C3_DEV) * [4. AsyncHTTPSRequest_ESP_WiFiManager on ESP32_DEV](#4-AsyncHTTPSRequest_ESP_WiFiManager-on-ESP32_DEV) + * [5. AsyncHTTPSRequest_ESP_Multi on ESP32S3_DEV](#5-AsyncHTTPSRequest_ESP_Multi-on-ESP32S3_DEV) * [Debug](#debug) * [Troubleshooting](#troubleshooting) * [Issues](#issues) @@ -55,10 +55,18 @@ --- --- +### Important Note for ESP32_S3 + +**Don't use `ESP32_S3` with core v2.0.4**. Check [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165) + +--- + ### Important Change from v1.2.0 Please have a look at [HOWTO Fix `Multiple Definitions` Linker Error](#howto-fix-multiple-definitions-linker-error) +--- + ### Why do we need this [AsyncTCP_SSL library](https://github.com/khoih-prog/AsyncTCP_SSL) #### Features @@ -90,9 +98,10 @@ to apply the better and faster **asynchronous** feature of the **powerful** [Asy ### Currently supported Boards -1. ESP32 boards, such as ESP32_DEV, etc. -2. ESP32S2-based boards, such as ESP32S2_DEV, ESP32_S2 Saola, etc. -3. ESP32C3-based boards, such as ESP32C3_DEV, etc. +1. `ESP32` boards, such as ESP32_DEV, etc. +2. `ESP32_S2`-based boards, such as ESP32S2_DEV, ESP32_S2 Saola, etc. +3. `ESP32_C3`-based boards, such as ESP32C3_DEV, etc. +4. `ESP32_S3`-based boards, such as ESP32S3_DEV, etc., using ESP32 core `v2.0.3` --- @@ -101,7 +110,8 @@ to apply the better and faster **asynchronous** feature of the **powerful** [Asy ## Prerequisites 1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest) - 2. [`ESP32 Core 2.0.2+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) + 2. [`ESP32 Core 2.0.4+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) for ESP32, ESP32_S2, ESP32_C3 + 3. [`ESP32 Core 2.0.3`](https://github.com/espressif/arduino-esp32) for ESP32_S3-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/) for ESP32_S3 until [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165) is fixed. --- --- @@ -118,9 +128,9 @@ You can also use this link [![arduino-library-badge](https://www.ardu-badge.com/ Another way to install is to: 1. Navigate to [**AsyncTCP_SSL**](https://github.com/khoih-prog/AsyncTCP_SSL) page. -2. Download the latest release `AsyncTCP_SSL-master.zip`. -3. Extract the zip file to `AsyncTCP_SSL-master` directory -4. Copy whole `AsyncTCP_SSL-master` folder to Arduino libraries' directory such as `~/Arduino/libraries/`. +2. Download the latest release `AsyncTCP_SSL-main.zip`. +3. Extract the zip file to `AsyncTCP_SSL-main` directory +4. Copy whole `AsyncTCP_SSL-main` folder to Arduino libraries' directory such as `~/Arduino/libraries/`. ### VS Code & PlatformIO @@ -270,8 +280,8 @@ Following is the debug terminal when running example [AsyncHTTPSRequest_ESP](htt ``` Starting AsyncHTTPSRequest_ESP using ESP32_DEV -AsyncTCP_SSL v1.2.0 -AsyncHTTPSRequest_Generic v1.3.0 +AsyncTCP_SSL v1.3.0 +AsyncHTTPSRequest_Generic v2.1.0 Connecting to WiFi SSID: HueNet1 ....... AsyncHTTPSRequest @ IP : 192.168.2.133 @@ -319,8 +329,8 @@ Following is the debug terminal when running example [AsyncHTTPSRequest_ESP](htt ``` Starting AsyncHTTPSRequest_ESP using ESP32S2_DEV -AsyncTCP_SSL v1.2.0 -AsyncHTTPSRequest_Generic v1.3.0 +AsyncTCP_SSL v1.3.0 +AsyncHTTPSRequest_Generic v2.1.0 Connecting to WiFi SSID: HueNet1 ....... AsyncHTTPSRequest @ IP : 192.168.2.79 @@ -349,21 +359,21 @@ AsyncHTTPSRequest @ IP : 192.168.2.79 [ATCP] _handle_async_event: LWIP_TCP_RECV = 0x3FFE5024 [ATCP] _recv: tot_len = 1016 ************************************** -abbreviation: EST +abbreviation: EDT client_ip: aaa.bbb.ccc.ddd -datetime: 2022-01-23T21:21:03.766116-05:00 +datetime: 2022-09-04T19:27:33.745787-04:00 day_of_week: 0 -day_of_year: 23 -dst: false -dst_from: -dst_offset: 0 -dst_until: +day_of_year: 247 +dst: true +dst_from: 2022-03-13T07:00:00+00:00 +dst_offset: 3600 +dst_until: 2022-11-06T06:00:00+00:00 raw_offset: -18000 timezone: America/Toronto -unixtime: 1642990863 -utc_datetime: 2022-01-24T02:21:03.766116+00:00 -utc_offset: -05:00 -week_number: 3 +unixtime: 1662334053 +utc_datetime: 2022-09-04T23:27:33.745787+00:00 +utc_offset: -04:00 +week_number: 35 ************************************** ``` @@ -375,27 +385,27 @@ Following is the debug terminal when running example [AsyncHTTPSRequest_ESP](htt ``` Starting AsyncHTTPSRequest_ESP using ESP32C3_DEV -AsyncTCP_SSL v1.2.0 -AsyncHTTPSRequest_Generic v1.3.0 +AsyncTCP_SSL v1.3.0 +AsyncHTTPSRequest_Generic v2.1.0 Connecting to WiFi SSID: HueNet1 ......... AsyncHTTPSRequest @ IP : 192.168.2.80 ************************************** -abbreviation: EST +abbreviation: EDT client_ip: aaa.bbb.ccc.ddd -datetime: 2022-01-23T21:24:07.839337-05:00 +datetime: 2022-09-04T19:27:33.745787-04:00 day_of_week: 0 -day_of_year: 23 -dst: false -dst_from: -dst_offset: 0 -dst_until: +day_of_year: 247 +dst: true +dst_from: 2022-03-13T07:00:00+00:00 +dst_offset: 3600 +dst_until: 2022-11-06T06:00:00+00:00 raw_offset: -18000 timezone: America/Toronto -unixtime: 1642991047 -utc_datetime: 2022-01-24T02:24:07.839337+00:00 -utc_offset: -05:00 -week_number: 3 +unixtime: 1662334053 +utc_datetime: 2022-09-04T23:27:33.745787+00:00 +utc_offset: -04:00 +week_number: 35 ************************************** ``` @@ -408,33 +418,106 @@ Following is the debug terminal when running example [AsyncHTTPSRequest_ESP_WiFi ``` Starting AsyncHTTPSRequest_ESP_WiFiManager using LittleFS on ESP32_DEV ESPAsync_WiFiManager v1.11.0 -AsyncTCP_SSL v1.2.0 -AsyncHTTPSRequest_Generic v1.3.0 +AsyncTCP_SSL v1.3.0 +AsyncHTTPSRequest_Generic v2.1.0 Stored: SSID = HueNet1, Pass = 12345678 Got stored Credentials. Timeout 120s ConnectMultiWiFi in setup After waiting 11.38 secs more in setup(), connection result is connected. Local IP: 192.168.2.232 H ************************************** -abbreviation: EST +abbreviation: EDT client_ip: aaa.bbb.ccc.ddd -datetime: 2022-01-23T21:18:03.759271-05:00 +datetime: 2022-09-04T19:41:10.727385-04:00 day_of_week: 0 -day_of_year: 23 -dst: false -dst_from: -dst_offset: 0 -dst_until: +day_of_year: 247 +dst: true +dst_from: 2022-03-13T07:00:00+00:00 +dst_offset: 3600 +dst_until: 2022-11-06T06:00:00+00:00 raw_offset: -18000 timezone: America/Toronto -unixtime: 1642990683 -utc_datetime: 2022-01-24T02:18:03.759271+00:00 -utc_offset: -05:00 -week_number: 3 +unixtime: 1662334870 +utc_datetime: 2022-09-04T23:41:10.727385+00:00 +utc_offset: -04:00 +week_number: 35 ************************************** H ``` +--- + +#### 5. AsyncHTTPSRequest_ESP_Multi on ESP32S3_DEV + +Following is the debug terminal when running example [AsyncHTTPSRequest_ESP_Multi](https://github.com/khoih-prog/AsyncHTTPSRequest_Generic/tree/main/examples/AsyncHTTPSRequest_ESP_Multi) on **ESP32S3_DEV on ESP32 core v2.0.3** to demonstrate the operation of SSL Async HTTPS request, using [AsyncTCP_SSL Library](https://github.com/khoih-prog/AsyncTCP_SSL) + + +``` +Starting AsyncHTTPSRequest_ESP_Multi on ESP32S3_DEV +AsyncTCP_SSL v1.3.0 +AsyncHTTPSRequest_Generic v2.1.0 +Connecting to WiFi SSID: HueNet1 +... +AsyncHTTPSRequest @ IP : 192.168.2.187 + +Sending request: https://worldtimeapi.org/api/timezone/Europe/Prague.txt + +Sending request: https://www.myexternalip.com/raw +[AHTTPS] _onError handler SSL error = OK + +************************************** +[AHTTPS] Response Code = HTTP OK + +************************************** +abbreviation: CEST +client_ip: aaa.bbb.ccc.ddd +datetime: 2022-09-05T01:27:33.313946+02:00 +day_of_week: 1 +day_of_year: 248 +dst: true +dst_from: 2022-03-27T01:00:00+00:00 +dst_offset: 3600 +dst_until: 2022-10-30T01:00:00+00:00 +raw_offset: 3600 +timezone: Europe/Prague +unixtime: 1662334053 +utc_datetime: 2022-09-04T23:27:33.313946+00:00 +utc_offset: +02:00 +week_number: 36 +************************************** + +Sending request: [AHTTPS] _onError handler SSL error = OK +https://worldtimeapi.org/api/timezone/America/Toronto.txt + +************************************** +[AHTTPS] Response Code = HTTP OK + +************************************** +abbreviation: EDT +client_ip: aaa.bbb.ccc.ddd +datetime: 2022-09-04T19:27:33.745787-04:00 +day_of_week: 0 +day_of_year: 247 +dst: true +dst_from: 2022-03-13T07:00:00+00:00 +dst_offset: 3600 +dst_until: 2022-11-06T06:00:00+00:00 +raw_offset: -18000 +timezone: America/Toronto +unixtime: 1662334053 +utc_datetime: 2022-09-04T23:27:33.745787+00:00 +utc_offset: -04:00 +week_number: 35 +************************************** + +************************************** +[AHTTPS] Response Code = HTTP OK + +************************************** +aaa.bbb.ccc.ddd +************************************** +``` + --- --- @@ -481,6 +564,9 @@ Submit issues to: [AsyncTCP_SSL issues](https://github.com/khoih-prog/AsyncTCP_S 3. Add debug feature 4. Fix `multiple-definitions` linker error 5. Add example +6. Remove hard-code if possible +7. Improve debug messages by adding functions to display `error/state messages` instead of `cryptic error/state number` +8. Add support to `ESP32_S3`, using ESP32 core `v2.0.3`. **Don't use `ESP32_S3` with core v2.0.4**. Check [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165) --- --- diff --git a/changelog.md b/changelog.md index 607a9df..923b605 100644 --- a/changelog.md +++ b/changelog.md @@ -11,6 +11,7 @@ ## Table of Contents * [Changelog](#changelog) + * [Releases v1.3.0](#Releases-v130) * [Releases v1.2.0](#Releases-v120) * [Releases v1.1.0](#Releases-v110) * [Initial Releases v1.0.0](#Initial-Releases-v100) @@ -20,6 +21,13 @@ ## Changelog +### Releases v1.3.0 + +1. Remove hard-code if possible +2. Improve debug messages by adding functions to display `error/state messages` instead of `cryptic error/state number` +3. Clean up +4. Add support to `ESP32_S3`, using ESP32 core `v2.0.3`. **Don't use `ESP32_S3` with core v2.0.4**. Check [ESP32-S3 Powercycling right after uploading a sketch using Arduino IDE and Arduino Core 2.0.4 #7165](https://github.com/espressif/arduino-esp32/issues/7165) + ### Releases v1.2.0 1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories diff --git a/examples/multiFileProject/multiFileProject.ino b/examples/multiFileProject/multiFileProject.ino index 90b9814..6da5c14 100644 --- a/examples/multiFileProject/multiFileProject.ino +++ b/examples/multiFileProject/multiFileProject.ino @@ -14,24 +14,22 @@ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting. #endif -#define ASYNC_TCP_SSL_VERSION_MIN_TARGET "AsyncTCP_SSL v1.2.0" -#define ASYNC_TCP_SSL_VERSION_MIN 1002000 +#define ASYNC_TCP_SSL_VERSION_MIN_TARGET "AsyncTCP_SSL v1.3.0" +#define ASYNC_TCP_SSL_VERSION_MIN 1003000 #include "multiFileProject.h" #include -// Can be included as many times as necessary, without `Multiple Definitions` Linker Error +// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "AsyncTCP_SSL.h" void setup() { Serial.begin(115200); - while (!Serial); - - delay(500); + while (!Serial && millis() < 5000); - Serial.println("\nStart multiFileProject"); + Serial.println("\nStart multiFileProject on "); Serial.println(ARDUINO_BOARD); Serial.println(ASYNC_TCP_SSL_VERSION); #if defined(ASYNC_TCP_SSL_VERSION_MIN) diff --git a/library.json b/library.json index 16298f0..0a8e086 100644 --- a/library.json +++ b/library.json @@ -1,8 +1,8 @@ { "name":"AsyncTCP_SSL", - "version": "1.2.0", + "version": "1.3.0", "keywords":"communication, async, tcp, ssl, tls, mbed, free-rtos", - "description":"Asynchronous SSL TCP Library for ESP32. This library is the base for future and more advanced Async SSL libraries, such as AsyncSSLWebServer, AsyncHTTPSRequest", + "description":"Asynchronous SSL TCP Library for ESP32. This library is the base for future and more advanced Async SSL libraries, such as AsyncSSLWebServer, AsyncHTTPSRequest, etc", "authors": [ { diff --git a/library.properties b/library.properties index 57d0aec..704444b 100644 --- a/library.properties +++ b/library.properties @@ -1,9 +1,9 @@ name=AsyncTCP_SSL -version=1.2.0 +version=1.3.0 author=Hristo Gochkov, Maarten Fremouw, Thorsten von Eicken, Khoi Hoang maintainer=Khoi Hoang sentence=Asynchronous SSL TCP Library for ESP32. -paragraph=This library is the base for future and more advanced Async SSL libraries, such as AsyncSSLWebServer, AsyncHTTPSRequest +paragraph=This library is the base for future and more advanced Async SSL libraries, such as AsyncSSLWebServer, AsyncHTTPSRequest, etc. category=Communication url=https://github.com/khoih-prog/AsyncTCP_SSL architectures=esp32 diff --git a/platformio/platformio.ini b/platformio/platformio.ini index df82b4a..2039ff5 100644 --- a/platformio/platformio.ini +++ b/platformio/platformio.ini @@ -35,6 +35,8 @@ upload_speed = 921600 ; Checks for the compatibility with frameworks and dev/platforms lib_compat_mode = strict +lib_ldf_mode = chain+ +;lib_ldf_mode = deep+ lib_deps = diff --git a/src/AsyncTCP_SSL.h b/src/AsyncTCP_SSL.h index 8bdf80f..a87e9c0 100644 --- a/src/AsyncTCP_SSL.h +++ b/src/AsyncTCP_SSL.h @@ -15,13 +15,14 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32 1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP 1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error + 1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible *****************************************************************************************************************************/ /* diff --git a/src/AsyncTCP_SSL.hpp b/src/AsyncTCP_SSL.hpp index 9a44fa3..35b6cbd 100644 --- a/src/AsyncTCP_SSL.hpp +++ b/src/AsyncTCP_SSL.hpp @@ -15,13 +15,14 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32 1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP 1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error + 1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible *****************************************************************************************************************************/ /* @@ -54,18 +55,16 @@ ///////////////////////////////////////////////// -#define ASYNC_TCP_SSL_VERSION "AsyncTCP_SSL v1.2.0" +#define ASYNC_TCP_SSL_VERSION "AsyncTCP_SSL v1.3.0" #define ASYNC_TCP_SSL_VERSION_MAJOR 1 -#define ASYNC_TCP_SSL_VERSION_MINOR 2 +#define ASYNC_TCP_SSL_VERSION_MINOR 3 #define ASYNC_TCP_SSL_VERSION_PATCH 0 -#define ASYNC_TCP_SSL_VERSION_INT 1002000 +#define ASYNC_TCP_SSL_VERSION_INT 1003000 ///////////////////////////////////////////////// -#define ASYNC_TCP_SSL_ENABLED true - #include "Arduino.h" #include "IPAddress.h" @@ -86,6 +85,26 @@ extern "C" #include "AsyncTCP_SSL_Debug.h" +/***************************************************** +// Defined in tools/sdk/esp32s3/include/lwip/lwip/src/include/lwip/tcpbase.h +enum tcp_state +{ + CLOSED = 0, + LISTEN = 1, + SYN_SENT = 2, + SYN_RCVD = 3, + ESTABLISHED = 4, + FIN_WAIT_1 = 5, + FIN_WAIT_2 = 6, + CLOSE_WAIT = 7, + CLOSING = 8, + LAST_ACK = 9, + TIME_WAIT = 10 +}; +*****************************************************/ + +#define INVALID_CLOSED_SLOT -1 + ////////////////////////////////////////////////////////////////////////////////////////// //If core is not defined, then we are running in Arduino or PIO @@ -103,21 +122,12 @@ class AsyncSSLClient; ////////////////////////////////////////////////////////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED typedef std::function AcConnectHandlerSSL; typedef std::function AcAckHandlerSSL; typedef std::function AcErrorHandlerSSL; typedef std::function AcDataHandlerSSL; typedef std::function AcPacketHandlerSSL; typedef std::function AcTimeoutHandlerSSL; -#else -typedef std::function AcConnectHandler; -typedef std::function AcAckHandler; -typedef std::function AcErrorHandler; -typedef std::function AcDataHandler; -typedef std::function AcPacketHandler; -typedef std::function AcTimeoutHandler; -#endif ///////////////////////////////////////////////// @@ -142,27 +152,22 @@ class AsyncSSLClient return !(*this == other); } -#if ASYNC_TCP_SSL_ENABLED - bool connect(IPAddress ip, uint16_t port, bool secure = false); - bool connect(const char* host, uint16_t port, bool secure = false); - void setRootCa(const char* rootca, const size_t len); - void setClientCert(const char* cli_cert, const size_t len); - void setClientKey(const char* cli_key, const size_t len); - void setPsk(const char* psk_ident, const char* psk); -#else - bool connect(IPAddress ip, uint16_t port); - bool connect(const char* host, uint16_t port); -#endif // ASYNC_TCP_SSL_ENABLED + bool connect(IPAddress ip, uint16_t port, bool secure = false); + bool connect(const char* host, uint16_t port, bool secure = false); + void setRootCa(const char* rootca, const size_t len); + void setClientCert(const char* cli_cert, const size_t len); + void setClientKey(const char* cli_key, const size_t len); + void setPsk(const char* psk_ident, const char* psk); void close(bool now = false); void stop(); int8_t abort(); bool free(); - bool canSend();//ack is not pending - size_t space();//space available in the TCP window + bool canSend(); //ack is not pending + size_t space(); //space available in the TCP window size_t add(const char* data, size_t size, uint8_t apiflags = ASYNC_WRITE_FLAG_COPY); //add for sending - bool send();//send all data added with the method above + bool send(); //send all data added with the method above //write equals add()+send() size_t write(const char* data); @@ -173,23 +178,23 @@ class AsyncSSLClient bool connected(); bool disconnecting(); bool disconnected(); - bool freeable();//disconnected or disconnecting + bool freeable(); //disconnected or disconnecting uint16_t getMss(); uint32_t getRxTimeout(); - void setRxTimeout(uint32_t timeout);//no RX data timeout for the connection in seconds + void setRxTimeout(uint32_t timeout); //no RX data timeout for the connection in seconds uint32_t getAckTimeout(); - void setAckTimeout(uint32_t timeout);//no ACK timeout for the last sent packet in milliseconds + void setAckTimeout(uint32_t timeout); //no ACK timeout for the last sent packet in milliseconds void setNoDelay(bool nodelay); bool getNoDelay(); - uint32_t getRemoteAddress(); - uint16_t getRemotePort(); - uint32_t getLocalAddress(); - uint16_t getLocalPort(); + uint32_t getRemoteAddress(); + uint16_t getRemotePort(); + uint32_t getLocalAddress(); + uint16_t getLocalPort(); //compatibility IPAddress remoteIP(); @@ -197,25 +202,14 @@ class AsyncSSLClient IPAddress localIP(); uint16_t localPort(); -#if ASYNC_TCP_SSL_ENABLED - void onConnect(AcConnectHandlerSSL cb, void* arg = 0); //on successful connect - void onDisconnect(AcConnectHandlerSSL cb, void* arg = 0); //disconnected - void onAck(AcAckHandlerSSL cb, void* arg = 0); //ack received - void onError(AcErrorHandlerSSL cb, void* arg = 0); //unsuccessful connect or error - void onData(AcDataHandlerSSL cb, void* arg = 0); //data received (called if onPacket is not used) - void onPacket(AcPacketHandlerSSL cb, void* arg = 0); //data received - void onTimeout(AcTimeoutHandlerSSL cb, void* arg = 0); //ack timeout - void onPoll(AcConnectHandlerSSL cb, void* arg = 0); //every 125ms when connected -#else - void onConnect(AcConnectHandler cb, void* arg = 0); //on successful connect - void onDisconnect(AcConnectHandler cb, void* arg = 0); //disconnected - void onAck(AcAckHandler cb, void* arg = 0); //ack received - void onError(AcErrorHandler cb, void* arg = 0); //unsuccessful connect or error - void onData(AcDataHandler cb, void* arg = 0); //data received (called if onPacket is not used) - void onPacket(AcPacketHandler cb, void* arg = 0); //data received - void onTimeout(AcTimeoutHandler cb, void* arg = 0); //ack timeout - void onPoll(AcConnectHandler cb, void* arg = 0); //every 125ms when connected -#endif + void onConnect(AcConnectHandlerSSL cb, void* arg = 0); //on successful connect + void onDisconnect(AcConnectHandlerSSL cb, void* arg = 0); //disconnected + void onAck(AcAckHandlerSSL cb, void* arg = 0); //ack received + void onError(AcErrorHandlerSSL cb, void* arg = 0); //unsuccessful connect or error + void onData(AcDataHandlerSSL cb, void* arg = 0); //data received (called if onPacket is not used) + void onPacket(AcPacketHandlerSSL cb, void* arg = 0); //data received + void onTimeout(AcTimeoutHandlerSSL cb, void* arg = 0); //ack timeout + void onPoll(AcConnectHandlerSSL cb, void* arg = 0); //every 125ms when connected void ackPacket(struct pbuf * pb);//ack pbuf from onPacket size_t ack(size_t len); //ack data that you have not acked using the method below @@ -225,8 +219,8 @@ class AsyncSSLClient _ack_pcb = false; //will not ack the current packet. Call from onData } - const char * errorToString(int8_t error); - const char * stateToString(); + const char * errorToString(int8_t error); + const char * stateToString(); //Do not use any of the functions below! static int8_t _s_poll(void *arg, struct tcp_pcb *tpcb); @@ -238,13 +232,11 @@ class AsyncSSLClient static int8_t _s_connected(void* arg, void* tpcb, int8_t err); static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg); -#if ASYNC_TCP_SSL_ENABLED static void _s_data(void *arg, struct tcp_pcb *tcp, uint8_t * data, size_t len); static void _s_handshake(void *arg, struct tcp_pcb *tcp, struct tcp_ssl_pcb* ssl); static void _s_ssl_error(void *arg, struct tcp_pcb *tcp, int8_t err); -#endif // ASYNC_TCP_SSL_ENABLED - int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err); + int8_t _recv(tcp_pcb* pcb, pbuf* pb, int8_t err); tcp_pcb * pcb() { @@ -259,56 +251,37 @@ class AsyncSSLClient ////// protected: - tcp_pcb* _pcb; - std::string _hostname; - int8_t _closed_slot; - -#if ASYNC_TCP_SSL_ENABLED - AcConnectHandlerSSL _connect_cb; - void* _connect_cb_arg; - AcConnectHandlerSSL _discard_cb; - void* _discard_cb_arg; - AcAckHandlerSSL _sent_cb; - void* _sent_cb_arg; - AcErrorHandlerSSL _error_cb; - void* _error_cb_arg; - AcDataHandlerSSL _recv_cb; - void* _recv_cb_arg; - AcPacketHandlerSSL _pb_cb; - void* _pb_cb_arg; - AcTimeoutHandlerSSL _timeout_cb; - void* _timeout_cb_arg; - AcConnectHandlerSSL _poll_cb; - void* _poll_cb_arg; -#else - AcConnectHandler _connect_cb; - void* _connect_cb_arg; - AcConnectHandler _discard_cb; - void* _discard_cb_arg; - AcAckHandler _sent_cb; - void* _sent_cb_arg; - AcErrorHandler _error_cb; - void* _error_cb_arg; - AcDataHandler _recv_cb; - void* _recv_cb_arg; - AcPacketHandler _pb_cb; - void* _pb_cb_arg; - AcTimeoutHandler _timeout_cb; - void* _timeout_cb_arg; - AcConnectHandler _poll_cb; - void* _poll_cb_arg; -#endif - - bool _pcb_busy; - uint32_t _pcb_sent_at; - bool _ack_pcb; - uint32_t _rx_ack_len; - uint32_t _rx_last_packet; - uint32_t _rx_since_timeout; - uint32_t _ack_timeout; - uint16_t _connect_port; - -#if ASYNC_TCP_SSL_ENABLED + tcp_pcb* _pcb; + std::string _hostname; + int8_t _closed_slot; + + AcConnectHandlerSSL _connect_cb; + void* _connect_cb_arg; + AcConnectHandlerSSL _discard_cb; + void* _discard_cb_arg; + AcAckHandlerSSL _sent_cb; + void* _sent_cb_arg; + AcErrorHandlerSSL _error_cb; + void* _error_cb_arg; + AcDataHandlerSSL _recv_cb; + void* _recv_cb_arg; + AcPacketHandlerSSL _pb_cb; + void* _pb_cb_arg; + AcTimeoutHandlerSSL _timeout_cb; + void* _timeout_cb_arg; + AcConnectHandlerSSL _poll_cb; + void* _poll_cb_arg; + + bool _pcb_busy; + uint32_t _pcb_sent_at; + bool _ack_pcb; + uint32_t _rx_ack_len; + uint32_t _rx_last_packet; + uint32_t _rx_since_timeout; + uint32_t _ack_timeout; + uint16_t _connect_port; + + ////// SSL size_t _root_ca_len; char* _root_ca; size_t _cli_cert_len; @@ -320,7 +293,7 @@ class AsyncSSLClient const char* _psk_ident; const char* _psk; -#endif // ASYNC_TCP_SSL_ENABLED + ////// int8_t _close(); void _free_closed_slot(); @@ -333,18 +306,16 @@ class AsyncSSLClient int8_t _lwip_fin(tcp_pcb* pcb, int8_t err); void _dns_found(struct ip_addr *ipaddr); -#if ASYNC_TCP_SSL_ENABLED - void _ssl_error(int8_t err); -#endif // ASYNC_TCP_SSL_ENABLED + ////// SSL + void _ssl_error(int8_t err); + ////// public: AsyncSSLClient* prev; AsyncSSLClient* next; }; -#if ASYNC_TCP_SSL_ENABLED typedef std::function AcSSlFileHandlerSSL; -#endif ////////////////////////////////////////////////////////////////////////////////////////////// @@ -354,17 +325,12 @@ class AsyncSSLServer AsyncSSLServer(IPAddress addr, uint16_t port); AsyncSSLServer(uint16_t port); ~AsyncSSLServer(); - //void onClient(AcConnectHandler cb, void* arg); -#if ASYNC_TCP_SSL_ENABLED void onClient(AcConnectHandlerSSL cb, void* arg); // Dummy, so it compiles with ESP Async WebServer library enabled. - void onSslFileRequest(AcSSlFileHandlerSSL cb, void* arg) {}; - void beginSecure(const char *cert, const char *private_key_file, const char *password) {}; -#else - void onClient(AcConnectHandler cb, void* arg); -#endif + void onSslFileRequest(AcSSlFileHandlerSSL cb, void* arg) {}; + void beginSecure(const char *cert, const char *private_key_file, const char *password) {}; void begin(); void end(); @@ -381,15 +347,10 @@ class AsyncSSLServer IPAddress _addr; bool _noDelay; - tcp_pcb* _pcb; - -#if ASYNC_TCP_SSL_ENABLED - AcConnectHandlerSSL _connect_cb; -#else - AcConnectHandler _connect_cb; -#endif + tcp_pcb* _pcb; - void* _connect_cb_arg; + AcConnectHandlerSSL _connect_cb; + void* _connect_cb_arg; int8_t _accept(tcp_pcb* newpcb, int8_t err); int8_t _accepted(AsyncSSLClient* client); diff --git a/src/AsyncTCP_SSL_Debug.h b/src/AsyncTCP_SSL_Debug.h index fdebfc2..acd5323 100644 --- a/src/AsyncTCP_SSL_Debug.h +++ b/src/AsyncTCP_SSL_Debug.h @@ -15,13 +15,14 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32 1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP 1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error + 1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible *****************************************************************************************************************************/ #pragma once @@ -64,6 +65,9 @@ #define ATCP_LOGERROR2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); } #define ATCP_HEXLOGERROR2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); } #define ATCP_LOGERROR3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); } +#define ATCP_LOGERROR5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>0) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); } + +///////////////////////////////////////////////////////// #define ATCP_LOGWARN(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); } #define ATCP_LOGWARN0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT(x); } @@ -72,6 +76,9 @@ #define ATCP_LOGWARN2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); } #define ATCP_HEXLOGWARN2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); } #define ATCP_LOGWARN3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); } +#define ATCP_LOGWARN5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>1) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); } + +///////////////////////////////////////////////////////// #define ATCP_LOGINFO(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); } #define ATCP_LOGINFO0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT(x); } @@ -80,6 +87,9 @@ #define ATCP_LOGINFO2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); } #define ATCP_HEXLOGINFO2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); } #define ATCP_LOGINFO3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); } +#define ATCP_LOGINFO5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>2) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); } + +///////////////////////////////////////////////////////// #define ATCP_LOGDEBUG(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINTLN(x); } #define ATCP_LOGDEBUG0(x) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT(x); } @@ -88,5 +98,8 @@ #define ATCP_LOGDEBUG2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINTLN(z); } #define ATCP_HEXLOGDEBUG2(x,y,z) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP0X; ATCP_PRINT(y, HEX); ATCP_PRINT_SP0X; ATCP_PRINTLN(z, HEX); } #define ATCP_LOGDEBUG3(x,y,z,w) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINTLN(w); } +#define ATCP_LOGDEBUG5(x,y,z,w,xx,yy) if(_ASYNC_TCP_SSL_LOGLEVEL_>3) { ATCP_PRINT_MARK; ATCP_PRINT(x); ATCP_PRINT_SP; ATCP_PRINT(y); ATCP_PRINT_SP; ATCP_PRINT(z); ATCP_PRINT_SP; ATCP_PRINT(w); ATCP_PRINT_SP; ATCP_PRINT(xx); ATCP_PRINT_SP; ATCP_PRINTLN(yy); } + +///////////////////////////////////////////////////////// #endif //ASYNC_TCP_SSL_DEBUG_H diff --git a/src/AsyncTCP_SSL_Impl.h b/src/AsyncTCP_SSL_Impl.h index 4cfa49f..35b8502 100644 --- a/src/AsyncTCP_SSL_Impl.h +++ b/src/AsyncTCP_SSL_Impl.h @@ -15,13 +15,14 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32 1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP 1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error + 1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible *****************************************************************************************************************************/ /* @@ -50,8 +51,6 @@ #include "Arduino.h" -#define ASYNC_TCP_SSL_ENABLED true - #include "AsyncTCP_SSL_Debug.h" extern "C" @@ -65,11 +64,7 @@ extern "C" #include "esp_task_wdt.h" -#if 0 - #define ASYNC_TCP_SSL_DEBUG(...) do { ets_printf("T %s- ", pcTaskGetTaskName(xTaskGetCurrentTaskHandle())); ets_printf(__VA_ARGS__); } while(0) -#else - #define ASYNC_TCP_SSL_DEBUG(...) -#endif +#define ASYNC_TCP_SSL_DEBUG(...) ////////////////////////////////////////////////////////////////////////////////////////// @@ -84,7 +79,15 @@ extern "C" typedef enum { - LWIP_TCP_SENT, LWIP_TCP_RECV, LWIP_TCP_FIN, LWIP_TCP_ERROR, LWIP_TCP_POLL, LWIP_TCP_CLEAR, LWIP_TCP_ACCEPT, LWIP_TCP_CONNECTED, LWIP_TCP_DNS + LWIP_TCP_SENT, + LWIP_TCP_RECV, + LWIP_TCP_FIN, + LWIP_TCP_ERROR, + LWIP_TCP_POLL, + LWIP_TCP_CLEAR, + LWIP_TCP_ACCEPT, + LWIP_TCP_CONNECTED, + LWIP_TCP_DNS } lwip_event_t; typedef struct @@ -147,7 +150,6 @@ typedef struct static xQueueHandle _async_queue; static TaskHandle_t _async_service_task_handle = NULL; - static SemaphoreHandle_t _slots_lock; const int _number_of_closed_slots = CONFIG_LWIP_MAX_ACTIVE_TCP; static int _closed_slots[_number_of_closed_slots]; @@ -162,7 +164,6 @@ static int _closed_index = []() for (int i = 0; i < _number_of_closed_slots; ++ i) { _closed_slots[i] = 1; - } return 1; @@ -211,7 +212,7 @@ static inline bool _get_async_event(lwip_event_packet_t ** e) static bool _remove_events_with_arg(void * arg) { lwip_event_packet_t * first_packet = NULL; - lwip_event_packet_t * packet = NULL; + lwip_event_packet_t * packet = NULL; if (!_async_queue) { @@ -527,7 +528,6 @@ static void _tcp_dns_found(const char * name, struct ip_addr * ipaddr, void * ar { lwip_event_packet_t * e = (lwip_event_packet_t *) malloc(sizeof(lwip_event_packet_t)); - //ets_printf("+DNS: name=%s ipaddr=0x%08x arg=%x\n", name, ipaddr, arg); ATCP_LOGDEBUG3("_tcp_dns_found: name =", name, ", IP =", ipaddr_ntoa(ipaddr)); ATCP_HEXLOGDEBUG1("_tcp_dns_found: arg =", (uint32_t) arg); @@ -563,6 +563,15 @@ static int8_t _tcp_accept(void * arg, AsyncSSLClient * client) if (!_prepend_async_event(&e)) { free((void*)(e)); + + // KH Test Memory Leak + if (client) + { + ATCP_LOGDEBUG("AsyncTCP_SSL: _tcp_accept: Delete Client"); + delete(client); + client = nullptr; + } + ////// } return ERR_OK; @@ -623,9 +632,10 @@ typedef struct static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; - if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) + if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { msg->err = tcp_output(msg->pcb); } @@ -643,8 +653,10 @@ static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) } tcp_api_call_t msg; - msg.pcb = pcb; + + msg.pcb = pcb; msg.closed_slot = closed_slot; + tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -655,9 +667,10 @@ static esp_err_t _tcp_output(tcp_pcb * pcb, int8_t closed_slot) static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; - if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) + if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags); } @@ -675,11 +688,13 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char* data, } tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; - msg.write.data = data; - msg.write.size = size; + + msg.pcb = pcb; + msg.closed_slot = closed_slot; + msg.write.data = data; + msg.write.size = size; msg.write.apiflags = apiflags; + tcpip_api_call(_tcp_write_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -690,11 +705,13 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char* data, static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; - if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) + if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { msg->err = 0; + tcp_recved(msg->pcb, msg->received); } @@ -711,9 +728,11 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, int8_t closed_slot, size_t len) } tcp_api_call_t msg; - msg.pcb = pcb; + + msg.pcb = pcb; msg.closed_slot = closed_slot; - msg.received = len; + msg.received = len; + tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -724,9 +743,10 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, int8_t closed_slot, size_t len) static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; - if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) + if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { msg->err = tcp_close(msg->pcb); } @@ -744,8 +764,10 @@ static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) } tcp_api_call_t msg; - msg.pcb = pcb; + + msg.pcb = pcb; msg.closed_slot = closed_slot; + tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -756,9 +778,10 @@ static esp_err_t _tcp_close(tcp_pcb * pcb, int8_t closed_slot) static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = ERR_CONN; - if (msg->closed_slot == -1 || !_closed_slots[msg->closed_slot]) + if (msg->closed_slot == INVALID_CLOSED_SLOT || !_closed_slots[msg->closed_slot]) { tcp_abort(msg->pcb); } @@ -776,8 +799,10 @@ static esp_err_t _tcp_abort(tcp_pcb * pcb, int8_t closed_slot) } tcp_api_call_t msg; - msg.pcb = pcb; + + msg.pcb = pcb; msg.closed_slot = closed_slot; + tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -788,6 +813,7 @@ static esp_err_t _tcp_abort(tcp_pcb * pcb, int8_t closed_slot) static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = tcp_connect(msg->pcb, msg->connect.addr, msg->connect.port, msg->connect.cb); return msg->err; @@ -803,11 +829,13 @@ static esp_err_t _tcp_connect(tcp_pcb * pcb, int8_t closed_slot, ip_addr_t * add } tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = closed_slot; + + msg.pcb = pcb; + msg.closed_slot = closed_slot; msg.connect.addr = addr; msg.connect.port = port; - msg.connect.cb = cb; + msg.connect.cb = cb; + tcpip_api_call(_tcp_connect_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -818,6 +846,7 @@ static esp_err_t _tcp_connect(tcp_pcb * pcb, int8_t closed_slot, ip_addr_t * add static err_t _tcp_bind_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = tcp_bind(msg->pcb, msg->bind.addr, msg->bind.port); return msg->err; @@ -833,10 +862,12 @@ static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) } tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = -1; - msg.bind.addr = addr; - msg.bind.port = port; + + msg.pcb = pcb; + msg.closed_slot = INVALID_CLOSED_SLOT; + msg.bind.addr = addr; + msg.bind.port = port; + tcpip_api_call(_tcp_bind_api, (struct tcpip_api_call_data*)&msg); return msg.err; @@ -847,7 +878,9 @@ static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) static err_t _tcp_listen_api(struct tcpip_api_call_data *api_call_msg) { tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; + msg->err = 0; + msg->pcb = tcp_listen_with_backlog(msg->pcb, msg->backlog); return msg->err; @@ -863,9 +896,11 @@ static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) } tcp_api_call_t msg; - msg.pcb = pcb; - msg.closed_slot = -1; - msg.backlog = backlog ? backlog : 0xFF; + + msg.pcb = pcb; + msg.closed_slot = INVALID_CLOSED_SLOT; + msg.backlog = backlog ? backlog : 0xFF; + tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call_data*)&msg); return msg.pcb; @@ -874,8 +909,6 @@ static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) ///////////////////////////////////////////// // KH -#if ASYNC_TCP_SSL_ENABLED -//#if 1 //ASYNC_TCP_SSL_ENABLED extern "C" { // The following API stubs are for use in tcp_mbedtls.c @@ -884,7 +917,6 @@ extern "C" esp_err_t _tcp_output4ssl(tcp_pcb * pcb, void* client) { // KH - //return _tcp_output(pcb, reinterpret_cast (client) ); return _tcp_output(pcb, (reinterpret_cast (client) )->getClosed_Slot() ); ////// } @@ -892,16 +924,11 @@ extern "C" esp_err_t _tcp_write4ssl(tcp_pcb * pcb, const char* data, size_t size, uint8_t apiflags, void* client) { // KH - //return _tcp_write(pcb, data, size, apiflags, reinterpret_cast (client) ); - // static esp_err_t _tcp_write(tcp_pcb * pcb, int8_t closed_slot, const char* data, size_t size, uint8_t apiflags) - // _tcp_write(_pcb, _closed_slot, data, will_send, apiflags); - //return _tcp_write(pcb, _closed_slots, data, size, apiflags, (int8_t) (reinterpret_cast (client) ) ); return _tcp_write(pcb, (reinterpret_cast (client) )->getClosed_Slot(), data, size, apiflags); ////// } } -#endif ////////////////////////////////////////////////////////////////////////////////////// @@ -931,7 +958,7 @@ AsyncSSLClient::AsyncSSLClient(tcp_pcb* pcb) , _rx_since_timeout(0) , _ack_timeout(ASYNC_MAX_ACK_TIME) , _connect_port(0) -#if ASYNC_TCP_SSL_ENABLED + // SSL , _root_ca_len(0) , _root_ca(NULL) , _cli_cert_len(0) @@ -942,13 +969,15 @@ AsyncSSLClient::AsyncSSLClient(tcp_pcb* pcb) , _handshake_done(true) , _psk_ident(0) , _psk(0) -#endif // ASYNC_TCP_SSL_ENABLED + ////// , prev(NULL) , next(NULL) { _pcb = pcb; - _closed_slot = -1; - if (_pcb) { + _closed_slot = INVALID_CLOSED_SLOT; + + if (_pcb) + { _allocate_closed_slot(); _rx_last_packet = millis(); tcp_arg(_pcb, this); @@ -995,11 +1024,13 @@ AsyncSSLClient& AsyncSSLClient::operator=(const AsyncSSLClient& other) tcp_sent(_pcb, &_tcp_sent); tcp_err(_pcb, &_tcp_error); tcp_poll(_pcb, &_tcp_poll, 1); -#if ASYNC_TCP_SSL_ENABLED + + // SSL if (tcp_ssl_has(_pcb)) { - _pcb_secure = true; + _pcb_secure = true; _handshake_done = false; + tcp_ssl_arg(_pcb, this); tcp_ssl_data(_pcb, &_s_data); tcp_ssl_handshake(_pcb, &_s_handshake); @@ -1010,7 +1041,7 @@ AsyncSSLClient& AsyncSSLClient::operator=(const AsyncSSLClient& other) _pcb_secure = false; _handshake_done = true; } -#endif // ASYNC_TCP_SSL_ENABLED + ////// } return *this; @@ -1020,7 +1051,7 @@ AsyncSSLClient& AsyncSSLClient::operator=(const AsyncSSLClient& other) bool AsyncSSLClient::operator==(const AsyncSSLClient &other) { - return _pcb == other._pcb; + return (_pcb == other._pcb); } ///////////////////////////////////////////// @@ -1054,97 +1085,65 @@ AsyncSSLClient & AsyncSSLClient::operator+=(const AsyncSSLClient &other) Callback Setters * */ -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onConnect(AcConnectHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onConnect(AcConnectHandler cb, void* arg) -#endif { - _connect_cb = cb; + _connect_cb = cb; _connect_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onDisconnect(AcConnectHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onDisconnect(AcConnectHandler cb, void* arg) -#endif { - _discard_cb = cb; + _discard_cb = cb; _discard_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onAck(AcAckHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onAck(AcAckHandler cb, void* arg) -#endif { - _sent_cb = cb; + _sent_cb = cb; _sent_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onError(AcErrorHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onError(AcErrorHandler cb, void* arg) -#endif { - _error_cb = cb; + _error_cb = cb; _error_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onData(AcDataHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onData(AcDataHandler cb, void* arg) -#endif { - _recv_cb = cb; + _recv_cb = cb; _recv_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onPacket(AcPacketHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onPacket(AcPacketHandler cb, void* arg) -#endif { - _pb_cb = cb; + _pb_cb = cb; _pb_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onTimeout(AcTimeoutHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onTimeout(AcTimeoutHandler cb, void* arg) -#endif { - _timeout_cb = cb; + _timeout_cb = cb; _timeout_cb_arg = arg; } ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::onPoll(AcConnectHandlerSSL cb, void* arg) -#else -void AsyncSSLClient::onPoll(AcConnectHandler cb, void* arg) -#endif { - _poll_cb = cb; + _poll_cb = cb; _poll_cb_arg = arg; } @@ -1154,19 +1153,15 @@ void AsyncSSLClient::onPoll(AcConnectHandler cb, void* arg) Main Public Methods * */ -#if ASYNC_TCP_SSL_ENABLED bool AsyncSSLClient::connect(IPAddress ip, uint16_t port, bool secure) { -#else -bool AsyncSSLClient::connect(IPAddress ip, uint16_t port) -{ -#endif // ASYNC_TCP_SSL_ENABLED if (_pcb) { - ATCP_LOGWARN1("connect: already connected, state =", _pcb->state); + ATCP_LOGWARN1("connect: already connected, state =", stateToString()); + return false; } - + if (!_start_async_task()) { ATCP_LOGERROR("connect: failed to start task"); @@ -1187,19 +1182,17 @@ bool AsyncSSLClient::connect(IPAddress ip, uint16_t port) return false; } -///////////////////////////////////////////// - -#if ASYNC_TCP_SSL_ENABLED + // SSL _pcb_secure = secure; _handshake_done = !secure; -#endif // ASYNC_TCP_SSL_ENABLED + ////// tcp_arg(pcb, this); tcp_err(pcb, &_tcp_error); tcp_recv(pcb, &_tcp_recv); tcp_sent(pcb, &_tcp_sent); tcp_poll(pcb, &_tcp_poll, 1); - //_tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected); + _tcp_connect(pcb, _closed_slot, &addr, port, (tcp_connected_fn)&_tcp_connected); return true; @@ -1207,11 +1200,7 @@ bool AsyncSSLClient::connect(IPAddress ip, uint16_t port) ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED bool AsyncSSLClient::connect(const char* host, uint16_t port, bool secure) -#else -bool AsyncSSLClient::connect(const char* host, uint16_t port) -#endif // ASYNC_TCP_SSL_ENABLED { ip_addr_t addr; @@ -1223,23 +1212,21 @@ bool AsyncSSLClient::connect(const char* host, uint16_t port) } err_t err = dns_gethostbyname(host, &addr, (dns_found_callback)&_tcp_dns_found, this); + if (err == ERR_OK) { -#if ASYNC_TCP_SSL_ENABLED _hostname = host; + return connect(IPAddress(addr.u_addr.ip4.addr), port, secure); -#else - return connect(IPAddress(addr.u_addr.ip4.addr), port); -#endif // ASYNC_TCP_SSL_ENABLED } else if (err == ERR_INPROGRESS) { _connect_port = port; -#if ASYNC_TCP_SSL_ENABLED + _hostname = host; _pcb_secure = secure; _handshake_done = !secure; -#endif // ASYNC_TCP_SSL_ENABLED + return true; } @@ -1275,13 +1262,9 @@ int8_t AsyncSSLClient::abort() ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED - -///////////////////////////////////////////// - void AsyncSSLClient::setRootCa(const char* rootca, const size_t len) { - _root_ca = (char*)rootca; + _root_ca = (char*)rootca; _root_ca_len = len; } @@ -1289,7 +1272,7 @@ void AsyncSSLClient::setRootCa(const char* rootca, const size_t len) void AsyncSSLClient::setClientCert(const char* cli_cert, const size_t len) { - _cli_cert = (char*)cli_cert; + _cli_cert = (char*)cli_cert; _cli_cert_len = len; } @@ -1297,7 +1280,7 @@ void AsyncSSLClient::setClientCert(const char* cli_cert, const size_t len) void AsyncSSLClient::setClientKey(const char* cli_key, const size_t len) { - _cli_key = (char*)cli_key; + _cli_key = (char*)cli_key; _cli_key_len = len; } @@ -1306,18 +1289,15 @@ void AsyncSSLClient::setClientKey(const char* cli_key, const size_t len) void AsyncSSLClient::setPsk(const char* psk_ident, const char* psk) { _psk_ident = psk_ident; - _psk = psk; + _psk = psk; } -///////////////////////////////////////////// - -#endif // ASYNC_TCP_SSL_ENABLED ///////////////////////////////////////////// size_t AsyncSSLClient::space() { - if ((_pcb != NULL) && (_pcb->state == 4)) + if ((_pcb != NULL) && (_pcb->state == ESTABLISHED)) { return tcp_sndbuf(_pcb); } @@ -1341,7 +1321,6 @@ size_t AsyncSSLClient::add(const char* data, size_t size, uint8_t apiflags) return 0; } -#if ASYNC_TCP_SSL_ENABLED if (_pcb_secure) { int sent = tcp_ssl_write(_pcb, (uint8_t*)data, size); @@ -1361,8 +1340,9 @@ size_t AsyncSSLClient::add(const char* data, size_t size, uint8_t apiflags) return 0; } -#endif // ASYNC_TCP_SSL_ENABLED + size_t will_send = (room < size) ? room : size; + int8_t err = ERR_OK; err = _tcp_write(_pcb, _closed_slot, data, will_send, apiflags); @@ -1379,20 +1359,18 @@ size_t AsyncSSLClient::add(const char* data, size_t size, uint8_t apiflags) bool AsyncSSLClient::send() { -#if ASYNC_TCP_SSL_ENABLED - - //delay(1); // 5 is OK + // 5 is also OK vTaskDelay(1 / portTICK_PERIOD_MS); - //if(_pcb_secure) return true; -#endif // ASYNC_TCP_SSL_ENABLED int8_t err = ERR_OK; + err = _tcp_output(_pcb, _closed_slot); if (err == ERR_OK) { - _pcb_busy = true; + _pcb_busy = true; _pcb_sent_at = millis(); + return true; } @@ -1437,24 +1415,23 @@ void AsyncSSLClient::ackPacket(struct pbuf * pb) int8_t AsyncSSLClient::_close() { - //ets_printf("X: 0x%08x\n", (uint32_t)this); int8_t err = ERR_OK; if (_pcb) { -#if ASYNC_TCP_SSL_ENABLED if (_pcb_secure) { tcp_ssl_free(_pcb); } -#endif // ASYNC_TCP_SSL_ENABLED tcp_arg(_pcb, NULL); tcp_sent(_pcb, NULL); tcp_recv(_pcb, NULL); tcp_err(_pcb, NULL); tcp_poll(_pcb, NULL, 0); + _tcp_clear_events(this); + err = _tcp_close(_pcb, _closed_slot); if (err != ERR_OK) @@ -1478,18 +1455,19 @@ int8_t AsyncSSLClient::_close() void AsyncSSLClient::_allocate_closed_slot() { xSemaphoreTake(_slots_lock, portMAX_DELAY); + uint32_t closed_slot_min_index = 0; for (int i = 0; i < _number_of_closed_slots; ++ i) { - if ((_closed_slot == -1 || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) + if ((_closed_slot == INVALID_CLOSED_SLOT || _closed_slots[i] <= closed_slot_min_index) && _closed_slots[i] != 0) { closed_slot_min_index = _closed_slots[i]; _closed_slot = i; } } - if (_closed_slot != -1) + if (_closed_slot != INVALID_CLOSED_SLOT) { _closed_slots[_closed_slot] = 0; } @@ -1501,11 +1479,11 @@ void AsyncSSLClient::_allocate_closed_slot() void AsyncSSLClient::_free_closed_slot() { - if (_closed_slot != -1) + if (_closed_slot != INVALID_CLOSED_SLOT) { _closed_slots[_closed_slot] = _closed_index; - _closed_slot = -1; - ++ _closed_index; + _closed_slot = INVALID_CLOSED_SLOT; + _closed_index++; } } @@ -1523,10 +1501,7 @@ int8_t AsyncSSLClient::_connected(void* pcb, int8_t err) { _rx_last_packet = millis(); _pcb_busy = false; - // tcp_recv(_pcb, &_tcp_recv); - // tcp_sent(_pcb, &_tcp_sent); - // tcp_poll(_pcb, &_tcp_poll, 1); -#if ASYNC_TCP_SSL_ENABLED + if (_pcb_secure) { bool err = false; @@ -1552,21 +1527,13 @@ int8_t AsyncSSLClient::_connected(void* pcb, int8_t err) tcp_ssl_handshake(_pcb, &_s_handshake); tcp_ssl_err(_pcb, &_s_ssl_error); } -#endif // ASYNC_TCP_SSL_ENABLED } -#if ASYNC_TCP_SSL_ENABLED // _connect_cb happens after SSL handshake if this is a secure connection if (_connect_cb && !_pcb_secure) { _connect_cb(_connect_cb_arg, this); } -#else - if (_connect_cb) - { - _connect_cb(_connect_cb_arg, this); - } -#endif // ASYNC_TCP_SSL_ENABLED return ERR_OK; } @@ -1577,12 +1544,11 @@ void AsyncSSLClient::_error(int8_t err) { if (_pcb) { -#if ASYNC_TCP_SSL_ENABLED if (_pcb_secure) { tcp_ssl_free(_pcb); } -#endif // ASYNC_TCP_SSL_ENABLED + tcp_arg(_pcb, NULL); if (_pcb->state == LISTEN) @@ -1592,6 +1558,7 @@ void AsyncSSLClient::_error(int8_t err) tcp_err(_pcb, NULL); tcp_poll(_pcb, NULL, 0); } + _pcb = NULL; } @@ -1608,7 +1575,6 @@ void AsyncSSLClient::_error(int8_t err) ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLClient::_ssl_error(int8_t err) { if (_error_cb) @@ -1616,7 +1582,6 @@ void AsyncSSLClient::_ssl_error(int8_t err) _error_cb(_error_cb_arg, this, err + 64); } } -#endif // ASYNC_TCP_SSL_ENABLED ///////////////////////////////////////////// @@ -1691,21 +1656,24 @@ int8_t AsyncSSLClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) while (pb != NULL) { _rx_last_packet = millis(); + pbuf *nxt = pb->next; - pb->next = NULL; + pb->next = NULL; -#if ASYNC_TCP_SSL_ENABLED if (_pcb_secure) { ATCP_LOGINFO1("_recv: tot_len =", pb->tot_len); int err = tcp_ssl_read(pcb, pb); // tcp_ssl_read always processes the full pbuf, so ack all of it + // KH //_tcp_recved(pcb, pb->len); _tcp_recved(pcb, _closed_slot, pb->len); ////// + pbuf_free(pb); + // handle errors if (err < 0) { @@ -1719,8 +1687,8 @@ int8_t AsyncSSLClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) return ERR_BUF; // for lack of a better error value } - } else -#endif // ASYNC_TCP_SSL_ENABLED + } + else { //we should not ack before we assimilate the data _ack_pcb = true; @@ -1744,6 +1712,7 @@ int8_t AsyncSSLClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) { _tcp_recved(_pcb, _closed_slot, pb->len); } + pbuf_free(pb); } } @@ -1779,7 +1748,7 @@ int8_t AsyncSSLClient::_poll(tcp_pcb* pcb) { _pcb_busy = false; - ATCP_LOGWARN1("_poll: ack timeout, state =", pcb->state); + ATCP_LOGWARN1("_poll: ack timeout, state =", stateToString()); if (_timeout_cb) _timeout_cb(_timeout_cb_arg, this, (now - _pcb_sent_at)); @@ -1790,21 +1759,20 @@ int8_t AsyncSSLClient::_poll(tcp_pcb* pcb) // RX Timeout if (_rx_since_timeout && (now - _rx_last_packet) >= (_rx_since_timeout * 1000)) { - ATCP_LOGWARN1("_poll: rx timeout, state =", pcb->state); + ATCP_LOGWARN1("_poll: rx timeout, state =", stateToString()); _close(); return ERR_OK; } -#if ASYNC_TCP_SSL_ENABLED if (_pcb_secure && !_handshake_done && (now - _rx_last_packet) >= SSL_HANDSHAKE_TIMEOUT) { - ATCP_LOGWARN1("_poll: ssl handshake timeout, state =", pcb->state); + ATCP_LOGWARN1("_poll: ssl handshake timeout, state =", stateToString()); _close(); + return ERR_OK; } -#endif // ASYNC_TCP_SSL_ENABLED // Everything is fine if (_poll_cb) @@ -1821,11 +1789,7 @@ void AsyncSSLClient::_dns_found(struct ip_addr *ipaddr) { if (ipaddr && ipaddr->u_addr.ip4.addr) { -#if ASYNC_TCP_SSL_ENABLED connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port, _pcb_secure); -#else - connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port); -#endif // ASYNC_TCP_SSL_ENABLED } else { @@ -1861,7 +1825,7 @@ bool AsyncSSLClient::free() return true; } - if (_pcb->state == 0 || _pcb->state > 4) + if ( (_pcb->state == CLOSED) || (_pcb->state > ESTABLISHED) ) { return true; } @@ -2051,7 +2015,7 @@ uint8_t AsyncSSLClient::state() return 0; } - return _pcb->state; + return (_pcb->state); } ///////////////////////////////////////////// @@ -2063,7 +2027,7 @@ bool AsyncSSLClient::connected() return false; } - return _pcb->state == 4; + return (_pcb->state == ESTABLISHED); } ///////////////////////////////////////////// @@ -2075,7 +2039,7 @@ bool AsyncSSLClient::connecting() return false; } - return _pcb->state > 0 && _pcb->state < 4; + return (_pcb->state > CLOSED && _pcb->state < ESTABLISHED); } ///////////////////////////////////////////// @@ -2087,7 +2051,7 @@ bool AsyncSSLClient::disconnecting() return false; } - return _pcb->state > 4 && _pcb->state < 10; + return (_pcb->state > ESTABLISHED && _pcb->state < TIME_WAIT); } ///////////////////////////////////////////// @@ -2099,7 +2063,7 @@ bool AsyncSSLClient::disconnected() return true; } - return _pcb->state == 0 || _pcb->state == 10; + return (_pcb->state == CLOSED || _pcb->state == TIME_WAIT); } ///////////////////////////////////////////// @@ -2111,7 +2075,7 @@ bool AsyncSSLClient::freeable() return true; } - return _pcb->state == 0 || _pcb->state > 4; + return (_pcb->state == CLOSED || _pcb->state > ESTABLISHED); } ///////////////////////////////////////////// @@ -2127,24 +2091,42 @@ const char * AsyncSSLClient::errorToString(int8_t error) { switch (error) { - case ERR_OK: return "OK"; - case ERR_MEM: return "Out of memory error"; - case ERR_BUF: return "Buffer error"; - case ERR_TIMEOUT: return "Timeout"; - case ERR_RTE: return "Routing problem"; - case ERR_INPROGRESS: return "Operation in progress"; - case ERR_VAL: return "Illegal value"; - case ERR_WOULDBLOCK: return "Operation would block"; - case ERR_USE: return "Address in use"; - case ERR_ALREADY: return "Already connected"; - case ERR_CONN: return "Not connected"; - case ERR_IF: return "Low-level netif error"; - case ERR_ABRT: return "Connection aborted"; - case ERR_RST: return "Connection reset"; - case ERR_CLSD: return "Connection closed"; - case ERR_ARG: return "Illegal argument"; - case -55: return "DNS failed"; - default: return "UNKNOWN"; + case ERR_OK: + return "OK"; + case ERR_MEM: + return "Out of memory error"; + case ERR_BUF: + return "Buffer error"; + case ERR_TIMEOUT: + return "Timeout"; + case ERR_RTE: + return "Routing problem"; + case ERR_INPROGRESS: + return "Operation in progress"; + case ERR_VAL: + return "Illegal value"; + case ERR_WOULDBLOCK: + return "Operation would block"; + case ERR_USE: + return "Address in use"; + case ERR_ALREADY: + return "Already connected"; + case ERR_CONN: + return "Not connected"; + case ERR_IF: + return "Low-level netif error"; + case ERR_ABRT: + return "Connection aborted"; + case ERR_RST: + return "Connection reset"; + case ERR_CLSD: + return "Connection closed"; + case ERR_ARG: + return "Illegal argument"; + case -55: + return "DNS failed"; + default: + return "UNKNOWN"; } } @@ -2154,18 +2136,30 @@ const char * AsyncSSLClient::stateToString() { switch (state()) { - case 0: return "Closed"; - case 1: return "Listen"; - case 2: return "SYN Sent"; - case 3: return "SYN Received"; - case 4: return "Established"; - case 5: return "FIN Wait 1"; - case 6: return "FIN Wait 2"; - case 7: return "Close Wait"; - case 8: return "Closing"; - case 9: return "Last ACK"; - case 10: return "Time Wait"; - default: return "UNKNOWN"; + case CLOSED: + return "Closed"; + case LISTEN: + return "Listen"; + case SYN_SENT: + return "SYN Sent"; + case SYN_RCVD: + return "SYN Received"; + case ESTABLISHED: + return "Established"; + case FIN_WAIT_1: + return "FIN Wait 1"; + case FIN_WAIT_2: + return "FIN Wait 2"; + case CLOSE_WAIT: + return "Close Wait"; + case CLOSING: + return "Closing"; + case LAST_ACK: + return "Last ACK"; + case TIME_WAIT: + return "Time Wait"; + default: + return "UNKNOWN"; } } @@ -2231,10 +2225,6 @@ int8_t AsyncSSLClient::_s_connected(void * arg, void * pcb, int8_t err) ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED - -///////////////////////////////////////////// - void AsyncSSLClient::_s_data(void *arg, struct tcp_pcb *tcp, uint8_t * data, size_t len) { AsyncSSLClient *c = reinterpret_cast(arg); @@ -2247,7 +2237,7 @@ void AsyncSSLClient::_s_data(void *arg, struct tcp_pcb *tcp, uint8_t * data, siz void AsyncSSLClient::_s_handshake(void *arg, struct tcp_pcb *tcp, struct tcp_ssl_pcb* ssl) { - AsyncSSLClient *c = reinterpret_cast(arg); + AsyncSSLClient *c = reinterpret_cast(arg); c->_handshake_done = true; if (c->_connect_cb) @@ -2261,10 +2251,6 @@ void AsyncSSLClient::_s_ssl_error(void *arg, struct tcp_pcb *tcp, int8_t err) reinterpret_cast(arg)->_ssl_error(err); } -///////////////////////////////////////////// - -#endif // ASYNC_TCP_SSL_ENABLED - ////////////////////////////////////////////////////////////////////////////////////////// /* @@ -2300,13 +2286,9 @@ AsyncSSLServer::~AsyncSSLServer() ///////////////////////////////////////////// -#if ASYNC_TCP_SSL_ENABLED void AsyncSSLServer::onClient(AcConnectHandlerSSL cb, void* arg) -#else -void AsyncSSLServer::onClient(AcConnectHandler cb, void* arg) -#endif { - _connect_cb = cb; + _connect_cb = cb; _connect_cb_arg = arg; } @@ -2327,6 +2309,7 @@ void AsyncSSLServer::begin() } int8_t err; + _pcb = tcp_new_ip_type(IPADDR_TYPE_V4); if (!_pcb) @@ -2337,8 +2320,10 @@ void AsyncSSLServer::begin() } ip_addr_t local_addr; - local_addr.type = IPADDR_TYPE_V4; + + local_addr.type = IPADDR_TYPE_V4; local_addr.u_addr.ip4.addr = (uint32_t) _addr; + err = _tcp_bind(_pcb, &local_addr, _port); if (err != ERR_OK) @@ -2351,6 +2336,7 @@ void AsyncSSLServer::begin() } static uint8_t backlog = 5; + _pcb = _tcp_listen_with_backlog(_pcb, backlog); if (!_pcb) @@ -2396,6 +2382,7 @@ int8_t AsyncSSLServer::_accept(tcp_pcb* pcb, int8_t err) if (c) { c->setNoDelay(_noDelay); + return _tcp_accept(this, c); } } diff --git a/src/tcp_mbedtls.c b/src/tcp_mbedtls.c index f2b15fe..102418c 100644 --- a/src/tcp_mbedtls.c +++ b/src/tcp_mbedtls.c @@ -15,21 +15,20 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32 1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP 1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error + 1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible *****************************************************************************************************************************/ #ifndef _ASYNC_TCP_SSL_LOGLEVEL_ #define _ASYNC_TCP_SSL_LOGLEVEL_ 1 #endif -#define ASYNC_TCP_SSL_ENABLED true - #include "tcp_mbedtls.h" #include "lwip/tcp.h" #include "mbedtls/debug.h" @@ -40,11 +39,7 @@ extern esp_err_t _tcp_output4ssl(struct tcp_pcb * pcb, void* client); extern esp_err_t _tcp_write4ssl(struct tcp_pcb * pcb, const char* data, size_t size, uint8_t apiflags, void* client); -#if 0 -#define TCP_SSL_DEBUG(...) do { ets_printf("T %s- ", pcTaskGetTaskName(xTaskGetCurrentTaskHandle())); ets_printf(__VA_ARGS__); } while(0) -#else #define TCP_SSL_DEBUG(...) -#endif static const char pers[] = "esp32-tls"; @@ -58,10 +53,8 @@ static int handle_error(int err) #ifdef MBEDTLS_ERROR_C char error_buf[100]; mbedtls_strerror(err, error_buf, 100); - TCP_SSL_DEBUG("%s\n", error_buf); #endif - TCP_SSL_DEBUG("MbedTLS message code: %d\n", err); return err; } @@ -93,55 +86,51 @@ static uint8_t _tcp_ssl_has_client = 0; struct tcp_ssl_pcb { - struct tcp_pcb *tcp; - int fd; - mbedtls_ssl_context ssl_ctx; - mbedtls_ssl_config ssl_conf; - mbedtls_x509_crt ca_cert; - bool has_ca_cert; - mbedtls_x509_crt client_cert; - bool has_client_cert; - mbedtls_pk_context client_key; - mbedtls_ctr_drbg_context drbg_ctx; - mbedtls_entropy_context entropy_ctx; - uint8_t type; - // int handshake; - void* arg; - tcp_ssl_data_cb_t on_data; - tcp_ssl_handshake_cb_t on_handshake; - tcp_ssl_error_cb_t on_error; - size_t last_wr; - struct pbuf *tcp_pbuf; - int pbuf_offset; - struct tcp_ssl_pcb* next; + struct tcp_pcb *tcp; + int fd; + mbedtls_ssl_context ssl_ctx; + mbedtls_ssl_config ssl_conf; + mbedtls_x509_crt ca_cert; + bool has_ca_cert; + mbedtls_x509_crt client_cert; + bool has_client_cert; + mbedtls_pk_context client_key; + mbedtls_ctr_drbg_context drbg_ctx; + mbedtls_entropy_context entropy_ctx; + uint8_t type; + void *arg; + tcp_ssl_data_cb_t on_data; + tcp_ssl_handshake_cb_t on_handshake; + tcp_ssl_error_cb_t on_error; + size_t last_wr; + struct pbuf *tcp_pbuf; + int pbuf_offset; + struct tcp_ssl_pcb *next; }; typedef struct tcp_ssl_pcb tcp_ssl_t; static tcp_ssl_t * tcp_ssl_array = NULL; -static int tcp_ssl_next_fd = 0; +static int tcp_ssl_next_fd = 0; ///////////////////////////////////////////// // tcp_ssl_recv attempts to read up to len bytes into buf from data already received. // It is called by mbedtls. int tcp_ssl_recv(void *ctx, unsigned char *buf, size_t len) -{ - TCP_SSL_DEBUG("tcp_ssl_recv: ctx: 0x%X, buf: 0x%X, len: %d\n", ctx, buf, len); - +{ tcp_ssl_t *tcp_ssl = (tcp_ssl_t*)ctx; - u16_t recv_len = 0; + u16_t recv_len = 0; if (tcp_ssl->tcp_pbuf == NULL || tcp_ssl->tcp_pbuf->tot_len == 0) { - TCP_SSL_DEBUG("tcp_ssl_recv: not yet ready to read: tcp_pbuf: 0x%X.\n", tcp_ssl->tcp_pbuf); + //TCP_SSL_DEBUG("tcp_ssl_recv: not yet ready to read: tcp_pbuf: 0x%X.\n", tcp_ssl->tcp_pbuf); return MBEDTLS_ERR_SSL_WANT_READ; } recv_len = pbuf_copy_partial(tcp_ssl->tcp_pbuf, buf, len, tcp_ssl->pbuf_offset); - //TCP_SSL_DEBUG("tcp_ssl_recv: len: %d, recv_len: %d, pbuf_offset: %d, tcp_pbuf len: %d.\n", - // len, recv_len, tcp_ssl->pbuf_offset, tcp_ssl->tcp_pbuf->len); + tcp_ssl->pbuf_offset += recv_len; if (recv_len == 0) @@ -158,25 +147,25 @@ int tcp_ssl_recv(void *ctx, unsigned char *buf, size_t len) // It is called by mbedtls. int tcp_ssl_send(void *ctx, const unsigned char *buf, size_t len) { - TCP_SSL_DEBUG("tcp_ssl_send: ctx: 0x%X, buf: 0x%X, len: %d\n", ctx, buf, len); + //TCP_SSL_DEBUG("tcp_ssl_send: ctx: 0x%X, buf: 0x%X, len: %d\n", ctx, buf, len); if (ctx == NULL) { - TCP_SSL_DEBUG("tcp_ssl_send: no context set\n"); + //TCP_SSL_DEBUG("tcp_ssl_send: no context set\n"); return -1; } if (buf == NULL) { - TCP_SSL_DEBUG("tcp_ssl_send: buf not set\n"); + //TCP_SSL_DEBUG("tcp_ssl_send: buf not set\n"); return -1; } tcp_ssl_t *tcp_ssl = (tcp_ssl_t*)ctx; size_t tcp_len = 0; - int err = ERR_OK; + int err = ERR_OK; if (tcp_sndbuf(tcp_ssl->tcp) < len) { @@ -184,7 +173,7 @@ int tcp_ssl_send(void *ctx, const unsigned char *buf, size_t len) if (tcp_len == 0) { - TCP_SSL_DEBUG("tcp_ssl_send: tcp_sndbuf is zero: %d\n", len); + //TCP_SSL_DEBUG("tcp_ssl_send: tcp_sndbuf is zero: %d\n", len); return ERR_MEM; } @@ -199,7 +188,7 @@ int tcp_ssl_send(void *ctx, const unsigned char *buf, size_t len) tcp_len = 2 * tcp_ssl->tcp->mss; } - TCP_SSL_DEBUG("tcp_ssl_send: tcp_write(%x, %x, %d, %x)\n", tcp_ssl->tcp, (char *)buf, tcp_len, tcp_ssl->arg); + //TCP_SSL_DEBUG("tcp_ssl_send: tcp_write(%x, %x, %d, %x)\n", tcp_ssl->tcp, (char *)buf, tcp_len, tcp_ssl->arg); err = _tcp_write4ssl(tcp_ssl->tcp, (char *)buf, tcp_len, TCP_WRITE_FLAG_COPY, tcp_ssl->arg); @@ -207,24 +196,24 @@ int tcp_ssl_send(void *ctx, const unsigned char *buf, size_t len) { if (err == ERR_MEM) { - TCP_SSL_DEBUG("tcp_ssl_send: No memory %d (%d)\n", tcp_len, len); + //TCP_SSL_DEBUG("tcp_ssl_send: No memory %d (%d)\n", tcp_len, len); return err; } - TCP_SSL_DEBUG("tcp_ssl_send: tcp_write error: %d\n", err); + //TCP_SSL_DEBUG("tcp_ssl_send: tcp_write error: %d\n", err); return err; } else if (err == ERR_OK) { - TCP_SSL_DEBUG("tcp_ssl_send: tcp_output: %d / %d\n", tcp_len, len); + //TCP_SSL_DEBUG("tcp_ssl_send: tcp_output: %d / %d\n", tcp_len, len); err = _tcp_output4ssl(tcp_ssl->tcp, tcp_ssl->arg); if (err != ERR_OK) { - TCP_SSL_DEBUG("tcp_ssl_send: tcp_output err: %d\n", err); + //TCP_SSL_DEBUG("tcp_ssl_send: tcp_output err: %d\n", err); return err; } @@ -249,27 +238,27 @@ tcp_ssl_t * tcp_ssl_new(struct tcp_pcb *tcp, void* arg) if (tcp_ssl_next_fd < 0) { - tcp_ssl_next_fd = 0;//overflow + tcp_ssl_next_fd = 0; //overflow } tcp_ssl_t * new_item = (tcp_ssl_t*)malloc(sizeof(tcp_ssl_t)); if (!new_item) { - TCP_SSL_DEBUG("tcp_ssl_new: failed to allocate tcp_ssl\n"); + //TCP_SSL_DEBUG("tcp_ssl_new: failed to allocate tcp_ssl\n"); return NULL; } - new_item->tcp = tcp; - new_item->arg = arg; - new_item->on_data = NULL; - new_item->on_handshake = NULL; - new_item->on_error = NULL; - new_item->tcp_pbuf = NULL; - new_item->pbuf_offset = 0; - new_item->next = NULL; - new_item->has_ca_cert = false; + new_item->tcp = tcp; + new_item->arg = arg; + new_item->on_data = NULL; + new_item->on_handshake = NULL; + new_item->on_error = NULL; + new_item->tcp_pbuf = NULL; + new_item->pbuf_offset = 0; + new_item->next = NULL; + new_item->has_ca_cert = false; new_item->has_client_cert = false; if (tcp_ssl_array == NULL) @@ -313,7 +302,6 @@ tcp_ssl_t* tcp_ssl_get(struct tcp_pcb *tcp) int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, const char* root_ca, const size_t root_ca_len, const char* cli_cert, const size_t cli_cert_len, const char* cli_key, const size_t cli_key_len) { - tcp_ssl_t* tcp_ssl; if (tcp == NULL) @@ -351,49 +339,23 @@ int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, con tcp_ssl->has_client_cert = true; } - //mbedtls_ctr_drbg_seed(&tcp_ssl->drbg_ctx, mbedtls_entropy_func, - // &tcp_ssl->entropy_ctx, (const unsigned char*)pers, strlen(pers)); mbedtls_ctr_drbg_seed(&tcp_ssl->drbg_ctx, mbedtls_entropy_func, &tcp_ssl->entropy_ctx, (const unsigned char*)pers, sizeof(pers)); if (mbedtls_ssl_config_defaults(&tcp_ssl->ssl_conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) { - TCP_SSL_DEBUG("error setting SSL config.\n"); + //TCP_SSL_DEBUG("error setting SSL config.\n"); tcp_ssl_free(tcp); + return -1; } int ret = 0; -#if 0 - if (root_ca != NULL && root_ca_len > 0) - { - TCP_SSL_DEBUG("setting the root ca.\n"); - - mbedtls_x509_crt_init(&tcp_ssl->ca_cert); - - mbedtls_ssl_conf_authmode(&tcp_ssl->ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED); - - ret = mbedtls_x509_crt_parse(&tcp_ssl->ca_cert, (const unsigned char *)root_ca, root_ca_len); - - if ( ret < 0 ) - { - TCP_SSL_DEBUG(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); - return handle_error(ret); - } - - mbedtls_ssl_conf_ca_chain(&tcp_ssl->ssl_conf, &tcp_ssl->ca_cert, NULL); - } - else - { - mbedtls_ssl_conf_authmode(&tcp_ssl->ssl_conf, MBEDTLS_SSL_VERIFY_OPTIONAL); - } -#endif - if (tcp_ssl->has_ca_cert) { - TCP_SSL_DEBUG("setting the root ca.\n"); + //TCP_SSL_DEBUG("setting the root ca.\n"); mbedtls_x509_crt_init(&tcp_ssl->ca_cert); @@ -403,9 +365,10 @@ int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, con if ( ret < 0 ) { - TCP_SSL_DEBUG(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); + //TCP_SSL_DEBUG(" failed\n ! mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); tcp_ssl_free(tcp); + return handle_error(ret); } @@ -418,35 +381,34 @@ int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, con if (tcp_ssl->has_client_cert) { - TCP_SSL_DEBUG("loading client cert"); + //TCP_SSL_DEBUG("loading client cert"); ret = mbedtls_x509_crt_parse(&tcp_ssl->client_cert, (const unsigned char *) cli_cert, cli_cert_len); if (ret < 0) { tcp_ssl_free(tcp); + return handle_error(ret); } - TCP_SSL_DEBUG("loading private key"); + //TCP_SSL_DEBUG("loading private key"); ret = mbedtls_pk_parse_key(&tcp_ssl->client_key, (const unsigned char *) cli_key, cli_key_len, NULL, 0); if (ret != 0) { tcp_ssl_free(tcp); + return handle_error(ret); } mbedtls_ssl_conf_own_cert(&tcp_ssl->ssl_conf, &tcp_ssl->client_cert, &tcp_ssl->client_key); } - ////// - - if (hostname != NULL) { - TCP_SSL_DEBUG("setting the hostname: %s\n", hostname); + //TCP_SSL_DEBUG("setting the hostname: %s\n", hostname); if ((ret = mbedtls_ssl_set_hostname(&tcp_ssl->ssl_ctx, hostname)) != 0) { @@ -472,9 +434,10 @@ int tcp_ssl_new_client(struct tcp_pcb *tcp, void *arg, const char* hostname, con if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - TCP_SSL_DEBUG("handshake error!\n"); + //TCP_SSL_DEBUG("handshake error!\n"); tcp_ssl_free(tcp); + return handle_error(ret); } @@ -488,14 +451,12 @@ int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident { tcp_ssl_t* tcp_ssl; - ////// if (pskey == NULL || psk_ident == NULL) { - TCP_SSL_DEBUG(" failed\n ! pre-shared key or identity is NULL\n\n"); + //TCP_SSL_DEBUG(" failed\n ! pre-shared key or identity is NULL\n\n"); return -1; } - ////// if (tcp == NULL) return -1; @@ -503,35 +464,34 @@ int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident if (tcp_ssl_get(tcp) != NULL) return -1; - ////// int pskey_len = strnlen(pskey, 2 * MBEDTLS_PSK_MAX_LEN + 1); if ((pskey_len > 2 * MBEDTLS_PSK_MAX_LEN) || (pskey_len & 1) != 0) { - TCP_SSL_DEBUG(" failed\n ! pre-shared key not valid hex or too long\n\n"); + //TCP_SSL_DEBUG(" failed\n ! pre-shared key not valid hex or too long\n\n"); return -1; } - ////// tcp_ssl = tcp_ssl_new(tcp, arg); - if (tcp_ssl == NULL) return -1; + + if (tcp_ssl == NULL) + return -1; mbedtls_entropy_init(&tcp_ssl->entropy_ctx); mbedtls_ctr_drbg_init(&tcp_ssl->drbg_ctx); mbedtls_ssl_init(&tcp_ssl->ssl_ctx); mbedtls_ssl_config_init(&tcp_ssl->ssl_conf); - //mbedtls_ctr_drbg_seed(&tcp_ssl->drbg_ctx, mbedtls_entropy_func, - // &tcp_ssl->entropy_ctx, (const uint8_t*)pers, strlen(pers)); mbedtls_ctr_drbg_seed(&tcp_ssl->drbg_ctx, mbedtls_entropy_func, &tcp_ssl->entropy_ctx, (const uint8_t*)pers, sizeof(pers)); if (mbedtls_ssl_config_defaults(&tcp_ssl->ssl_conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) { - TCP_SSL_DEBUG("error setting SSL config.\n"); + //TCP_SSL_DEBUG("error setting SSL config.\n"); tcp_ssl_free(tcp); + return -1; } @@ -539,12 +499,12 @@ int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident int ret = 0; - TCP_SSL_DEBUG("setting the pre-shared key.\n"); + //TCP_SSL_DEBUG("setting the pre-shared key.\n"); // convert PSK from hex string to binary ////// //if ((strlen(pskey) & 1) != 0 || strlen(pskey) > 2*MBEDTLS_PSK_MAX_LEN) { - // TCP_SSL_DEBUG(" failed\n ! pre-shared key not valid hex or too long\n\n"); + // //TCP_SSL_DEBUG(" failed\n ! pre-shared key not valid hex or too long\n\n"); // return -1; //} ////// @@ -581,15 +541,12 @@ int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident } // set mbedtls config - //ret = mbedtls_ssl_conf_psk(&tcp_ssl->ssl_conf, psk, psk_len, - // (const unsigned char *)psk_ident, strlen(psk_ident)); - ret = mbedtls_ssl_conf_psk(&tcp_ssl->ssl_conf, psk, psk_len, - (const unsigned char *)psk_ident, strnlen(psk_ident, 64)); - ////// + ret = mbedtls_ssl_conf_psk(&tcp_ssl->ssl_conf, psk, psk_len, (const unsigned char *)psk_ident, + strnlen(psk_ident, 64)); if (ret != 0) { - TCP_SSL_DEBUG(" failed\n ! mbedtls_ssl_conf_psk returned -0x%x\n\n", -ret); + //TCP_SSL_DEBUG(" failed\n ! mbedtls_ssl_conf_psk returned -0x%x\n\n", -ret); return handle_error(ret); } @@ -610,7 +567,7 @@ int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - TCP_SSL_DEBUG("handshake error!\n"); + //TCP_SSL_DEBUG("handshake error!\n"); return handle_error(ret); } @@ -624,7 +581,7 @@ int tcp_ssl_new_psk_client(struct tcp_pcb *tcp, void *arg, const char* psk_ident // encrypted, and then transmitted on the TCP connection. int tcp_ssl_write(struct tcp_pcb *tcp, uint8_t *data, size_t len) { - TCP_SSL_DEBUG("tcp_ssl_write(%x, %x, len=%d)\n", tcp, data, len); + //TCP_SSL_DEBUG("tcp_ssl_write(%x, %x, len=%d)\n", tcp, data, len); if (tcp == NULL) { @@ -646,14 +603,14 @@ int tcp_ssl_write(struct tcp_pcb *tcp, uint8_t *data, size_t len) { if (rc != MBEDTLS_ERR_SSL_WANT_READ && rc != MBEDTLS_ERR_SSL_WANT_WRITE) { - TCP_SSL_DEBUG("about to call mbedtls_ssl_write\n"); + //TCP_SSL_DEBUG("about to call mbedtls_ssl_write\n"); return handle_error(rc); } if (rc != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { - TCP_SSL_DEBUG("tcp_ssl_write error: %d\r\n", rc); + //TCP_SSL_DEBUG("tcp_ssl_write error: %d\r\n", rc); } return rc; @@ -665,31 +622,29 @@ int tcp_ssl_write(struct tcp_pcb *tcp, uint8_t *data, size_t len) ///////////////////////////////////////////// /* - typedef enum - { - MBEDTLS_SSL_HELLO_REQUEST, - MBEDTLS_SSL_CLIENT_HELLO, - MBEDTLS_SSL_SERVER_HELLO, - MBEDTLS_SSL_SERVER_CERTIFICATE, - MBEDTLS_SSL_SERVER_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_REQUEST, - MBEDTLS_SSL_SERVER_HELLO_DONE, - MBEDTLS_SSL_CLIENT_CERTIFICATE, - MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, - MBEDTLS_SSL_CERTIFICATE_VERIFY, - MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_CLIENT_FINISHED, - MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, - MBEDTLS_SSL_SERVER_FINISHED, - MBEDTLS_SSL_FLUSH_BUFFERS, - MBEDTLS_SSL_HANDSHAKE_WRAPUP, - MBEDTLS_SSL_HANDSHAKE_OVER, - MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, - MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, - } - mbedtls_ssl_states; - - +typedef enum +{ + MBEDTLS_SSL_HELLO_REQUEST, + MBEDTLS_SSL_CLIENT_HELLO, + MBEDTLS_SSL_SERVER_HELLO, + MBEDTLS_SSL_SERVER_CERTIFICATE, + MBEDTLS_SSL_SERVER_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_REQUEST, + MBEDTLS_SSL_SERVER_HELLO_DONE, + MBEDTLS_SSL_CLIENT_CERTIFICATE, + MBEDTLS_SSL_CLIENT_KEY_EXCHANGE, + MBEDTLS_SSL_CERTIFICATE_VERIFY, + MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC, + MBEDTLS_SSL_CLIENT_FINISHED, + MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC, + MBEDTLS_SSL_SERVER_FINISHED, + MBEDTLS_SSL_FLUSH_BUFFERS, + MBEDTLS_SSL_HANDSHAKE_WRAPUP, + MBEDTLS_SSL_HANDSHAKE_OVER, + MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET, + MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT, +} +mbedtls_ssl_states; */ ///////////////////////////////////////////// @@ -699,16 +654,18 @@ int tcp_ssl_write(struct tcp_pcb *tcp, uint8_t *data, size_t len) // onData callback with the decrypted data. int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) { - TCP_SSL_DEBUG("tcp_ssl_read(%x, %x)\n", tcp, p); + //TCP_SSL_DEBUG("tcp_ssl_read(%x, %x)\n", tcp, p); if (tcp == NULL) { return -1; } - int read_bytes = 0; + int read_bytes = 0; int total_bytes = 0; + static const size_t read_buf_size = 1024; + uint8_t read_buf[read_buf_size]; tcp_ssl_t *tcp_ssl = tcp_ssl_get(tcp); @@ -725,7 +682,7 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) // TCP_SSL_DEBUG("READY TO READ SOME DATA\n"); - tcp_ssl->tcp_pbuf = p; + tcp_ssl->tcp_pbuf = p; tcp_ssl->pbuf_offset = 0; bool debugPrinted = false; @@ -734,11 +691,10 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) { if (tcp_ssl->ssl_ctx.state != MBEDTLS_SSL_HANDSHAKE_OVER) { - //KH to print once if (!debugPrinted) { - TCP_SSL_DEBUG("start handshake: %d\n", tcp_ssl->ssl_ctx.state); + //TCP_SSL_DEBUG("start handshake: %d\n", tcp_ssl->ssl_ctx.state); debugPrinted = true; } @@ -748,14 +704,14 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) if (ret == 0) { - TCP_SSL_DEBUG("Protocol is %s, Ciphersuite is %s\n", mbedtls_ssl_get_version(&tcp_ssl->ssl_ctx), mbedtls_ssl_get_ciphersuite(&tcp_ssl->ssl_ctx)); + //TCP_SSL_DEBUG("Protocol is %s, Ciphersuite is %s\n", mbedtls_ssl_get_version(&tcp_ssl->ssl_ctx), mbedtls_ssl_get_ciphersuite(&tcp_ssl->ssl_ctx)); ////// - TCP_SSL_DEBUG("Verifying peer X.509 certificate..."); + //TCP_SSL_DEBUG("Verifying peer X.509 certificate..."); if ((mbedtls_ssl_get_verify_result(&tcp_ssl->ssl_ctx)) != 0) { - TCP_SSL_DEBUG("handshake error: %d\n", ret); + //TCP_SSL_DEBUG("handshake error: %d\n", ret); handle_error(ret); @@ -764,7 +720,7 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) } else { - TCP_SSL_DEBUG("Certificate verified."); + //TCP_SSL_DEBUG("Certificate verified."); } ////// @@ -773,7 +729,7 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) } else if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - TCP_SSL_DEBUG("handshake error: %d\n", ret); + //TCP_SSL_DEBUG("handshake error: %d\n", ret); handle_error(ret); @@ -786,7 +742,8 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) else { read_bytes = mbedtls_ssl_read(&tcp_ssl->ssl_ctx, (unsigned char *)&read_buf, read_buf_size); - TCP_SSL_DEBUG("tcp_ssl_read: read_bytes: %d, total_bytes: %d, tot_len: %d, pbuf_offset: %d\r\n", read_bytes, total_bytes, p->tot_len, tcp_ssl->pbuf_offset); + //TCP_SSL_DEBUG("tcp_ssl_read: read_bytes: %d, total_bytes: %d, tot_len: %d, pbuf_offset: %d\r\n", + // read_bytes, total_bytes, p->tot_len, tcp_ssl->pbuf_offset); if (read_bytes < 0) { @@ -797,10 +754,11 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) } else if (read_bytes != MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { - TCP_SSL_DEBUG("tcp_ssl_read: read error: %d\n", read_bytes); + //TCP_SSL_DEBUG("tcp_ssl_read: read error: %d\n", read_bytes); } total_bytes = read_bytes; + break; } else if (read_bytes > 0) @@ -815,8 +773,6 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) } //KH - //yield(); - //delay(1); vTaskDelay(1 / portTICK_PERIOD_MS); ////// @@ -824,14 +780,14 @@ int tcp_ssl_read(struct tcp_pcb *tcp, struct pbuf *p) tcp_ssl->tcp_pbuf = NULL; - return total_bytes >= 0 ? 0 : total_bytes; // return error code + return (total_bytes >= 0 ? 0 : total_bytes); // return error code } ///////////////////////////////////////////// int tcp_ssl_free(struct tcp_pcb *tcp) { - TCP_SSL_DEBUG("tcp_ssl_free(%x)\n", tcp); + //TCP_SSL_DEBUG("tcp_ssl_free(%x)\n", tcp); if (tcp == NULL) { @@ -854,7 +810,6 @@ int tcp_ssl_free(struct tcp_pcb *tcp) mbedtls_ctr_drbg_free(&item->drbg_ctx); mbedtls_entropy_free(&item->entropy_ctx); - ////// if (item->has_ca_cert) { mbedtls_x509_crt_free(&item->ca_cert); @@ -865,9 +820,9 @@ int tcp_ssl_free(struct tcp_pcb *tcp) mbedtls_x509_crt_free(&item->client_cert); mbedtls_pk_free(&item->client_key); } - ////// free(item); + return 0; } diff --git a/src/tcp_mbedtls.h b/src/tcp_mbedtls.h index f15d9d8..0347bc8 100644 --- a/src/tcp_mbedtls.h +++ b/src/tcp_mbedtls.h @@ -15,19 +15,20 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - Version: 1.2.0 + Version: 1.3.0 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 21/10/2021 Initial coding to support only ESP32 1.1.0 K Hoang 22/10/2021 Fix bug. Enable coexistence with AsyncTCP 1.2.0 K Hoang 23/01/2022 Fix `multiple-definitions` linker error + 1.3.0 K Hoang 04/09/2022 Clean up. Remove hard-code if possible *****************************************************************************************************************************/ #ifndef LWIPR_MBEDTLS_H #define LWIPR_MBEDTLS_H -#define ASYNC_TCP_SSL_ENABLED true +///////////////////////////////////////////// #include "mbedtls/platform.h" #include "mbedtls/net.h" @@ -37,6 +38,7 @@ #include "mbedtls/ctr_drbg.h" #include "mbedtls/error.h" +///////////////////////////////////////////// #ifdef __cplusplus extern "C" { @@ -82,6 +84,5 @@ void tcp_ssl_err(struct tcp_pcb *tcp, tcp_ssl_error_cb_t arg); } #endif - #endif // LWIPR_MBEDTLS_H