1 /* 2 * Copyright (c) 2021, The OpenThread Authors. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of the copyright holder nor the 13 * names of its contributors may be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /** 30 * @file 31 * This file contains definitions for a TCP CLI tool. 32 */ 33 34 #ifndef CLI_TCP_EXAMPLE_HPP_ 35 #define CLI_TCP_EXAMPLE_HPP_ 36 37 #include "openthread-core-config.h" 38 39 #include <openthread/tcp.h> 40 #include <openthread/tcp_ext.h> 41 42 #if OPENTHREAD_CONFIG_TLS_ENABLE 43 44 #include <mbedtls/ctr_drbg.h> 45 #include <mbedtls/entropy.h> 46 #include <mbedtls/ssl.h> 47 #include <mbedtls/x509_crt.h> 48 49 #endif 50 51 #include "cli/cli_config.h" 52 #include "cli/cli_output.hpp" 53 #include "common/time.hpp" 54 55 namespace ot { 56 namespace Cli { 57 58 /** 59 * Implements a CLI-based TCP example. 60 * 61 */ 62 class TcpExample : private Output 63 { 64 public: 65 using Arg = Utils::CmdLineParser::Arg; 66 67 /** 68 * Constructor 69 * 70 * @param[in] aInstance The OpenThread Instance. 71 * @param[in] aOutputImplementer An `OutputImplementer`. 72 * 73 */ 74 TcpExample(otInstance *aInstance, OutputImplementer &aOutputImplementer); 75 76 /** 77 * Processes a CLI sub-command. 78 * 79 * @param[in] aArgs An array of command line arguments. 80 * 81 * @retval OT_ERROR_NONE Successfully executed the CLI command. 82 * @retval OT_ERROR_PENDING The CLI command was successfully started but final result is pending. 83 * @retval OT_ERROR_INVALID_COMMAND Invalid or unknown CLI command. 84 * @retval OT_ERROR_INVALID_ARGS Invalid arguments. 85 * @retval ... Error during execution of the CLI command. 86 * 87 */ 88 otError Process(Arg aArgs[]); 89 90 private: 91 using Command = CommandEntry<TcpExample>; 92 93 template <CommandId kCommandId> otError Process(Arg aArgs[]); 94 95 otError ContinueBenchmarkCircularSend(void); 96 void CompleteBenchmark(void); 97 98 #if OPENTHREAD_CONFIG_TLS_ENABLE 99 void PrepareTlsHandshake(void); 100 bool ContinueTlsHandshake(void); 101 #endif 102 103 static void HandleTcpEstablishedCallback(otTcpEndpoint *aEndpoint); 104 static void HandleTcpSendDoneCallback(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData); 105 static void HandleTcpForwardProgressCallback(otTcpEndpoint *aEndpoint, size_t aInSendBuffer, size_t aBacklog); 106 static void HandleTcpReceiveAvailableCallback(otTcpEndpoint *aEndpoint, 107 size_t aBytesAvailable, 108 bool aEndOfStream, 109 size_t aBytesRemaining); 110 static void HandleTcpDisconnectedCallback(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason); 111 static otTcpIncomingConnectionAction HandleTcpAcceptReadyCallback(otTcpListener *aListener, 112 const otSockAddr *aPeer, 113 otTcpEndpoint **aAcceptInto); 114 static void HandleTcpAcceptDoneCallback(otTcpListener *aListener, 115 otTcpEndpoint *aEndpoint, 116 const otSockAddr *aPeer); 117 118 void HandleTcpEstablished(otTcpEndpoint *aEndpoint); 119 void HandleTcpSendDone(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData); 120 void HandleTcpForwardProgress(otTcpEndpoint *aEndpoint, size_t aInSendBuffer, size_t aBacklog); 121 void HandleTcpReceiveAvailable(otTcpEndpoint *aEndpoint, 122 size_t aBytesAvailable, 123 bool aEndOfStream, 124 size_t aBytesRemaining); 125 void HandleTcpDisconnected(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason); 126 otTcpIncomingConnectionAction HandleTcpAcceptReady(otTcpListener *aListener, 127 const otSockAddr *aPeer, 128 otTcpEndpoint **aAcceptInto); 129 void HandleTcpAcceptDone(otTcpListener *aListener, otTcpEndpoint *aEndpoint, const otSockAddr *aPeer); 130 131 #if OPENTHREAD_CONFIG_TLS_ENABLE 132 static void MbedTlsDebugOutput(void *ctx, int level, const char *file, int line, const char *str); 133 #endif 134 135 void OutputBenchmarkResult(void); 136 137 otTcpEndpoint mEndpoint; 138 otTcpListener mListener; 139 140 bool mInitialized; 141 bool mEndpointConnected; 142 bool mEndpointConnectedFastOpen; 143 bool mSendBusy; 144 bool mUseCircularSendBuffer; 145 bool mUseTls; 146 bool mTlsHandshakeComplete; 147 148 otTcpCircularSendBuffer mSendBuffer; 149 otLinkedBuffer mSendLink; 150 uint8_t mSendBufferBytes[OPENTHREAD_CONFIG_CLI_TCP_RECEIVE_BUFFER_SIZE]; 151 uint8_t mReceiveBufferBytes[OPENTHREAD_CONFIG_CLI_TCP_RECEIVE_BUFFER_SIZE]; 152 153 otLinkedBuffer 154 mBenchmarkLinks[(sizeof(mReceiveBufferBytes) + sizeof(mSendBufferBytes) - 1) / sizeof(mSendBufferBytes)]; 155 uint32_t mBenchmarkBytesTotal; 156 uint32_t mBenchmarkBytesUnsent; 157 TimeMilli mBenchmarkStart; 158 uint32_t mBenchmarkTimeUsed; 159 uint32_t mBenchmarkLastBytesTotal; 160 otTcpEndpointAndCircularSendBuffer mEndpointAndCircularSendBuffer; 161 162 #if OPENTHREAD_CONFIG_TLS_ENABLE 163 mbedtls_ssl_context mSslContext; 164 mbedtls_ssl_config mSslConfig; 165 mbedtls_x509_crt mSrvCert; 166 mbedtls_pk_context mPKey; 167 mbedtls_entropy_context mEntropy; 168 #endif // OPENTHREAD_CONFIG_TLS_ENABLE 169 170 static constexpr const char *sBenchmarkData = 171 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 172 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 173 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 174 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 175 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 176 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 177 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 178 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 179 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 180 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 181 static constexpr const size_t sBenchmarkDataLength = 1040; 182 183 #if OPENTHREAD_CONFIG_TLS_ENABLE 184 static constexpr const char *sCasPem = "-----BEGIN CERTIFICATE-----\r\n" 185 "MIIBtDCCATqgAwIBAgIBTTAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJOTDERMA8G\r\n" 186 "A1UEChMIUG9sYXJTU0wxKTAnBgNVBAMTIFBvbGFyU1NMIFRlc3QgSW50ZXJtZWRp\r\n" 187 "YXRlIEVDIENBMB4XDTE1MDkwMTE0MDg0M1oXDTI1MDgyOTE0MDg0M1owSjELMAkG\r\n" 188 "A1UEBhMCVUsxETAPBgNVBAoTCG1iZWQgVExTMSgwJgYDVQQDEx9tYmVkIFRMUyBU\r\n" 189 "ZXN0IGludGVybWVkaWF0ZSBDQSAzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\r\n" 190 "732fWHLNPMPsP1U1ibXvb55erlEVMlpXBGsj+KYwVqU1XCmW9Z9hhP7X/5js/DX9\r\n" 191 "2J/utoHyjUtVpQOzdTrbsaMQMA4wDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgNo\r\n" 192 "ADBlAjAJRxbGRas3NBmk9MnGWXg7PT1xnRELHRWWIvfLdVQt06l1/xFg3ZuPdQdt\r\n" 193 "Qh7CK80CMQD7wa1o1a8qyDKBfLN636uKmKGga0E+vYXBeFCy9oARBangGCB0B2vt\r\n" 194 "pz590JvGWfM=\r\n" 195 "-----END CERTIFICATE-----\r\n"; 196 static constexpr const size_t sCasPemLength = 665; // includes NUL byte 197 198 static constexpr const char *sSrvPem = "-----BEGIN CERTIFICATE-----\r\n" 199 "MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" 200 "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" 201 "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" 202 "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" 203 "CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" 204 "2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" 205 "BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" 206 "PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" 207 "clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" 208 "CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" 209 "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" 210 "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" 211 "-----END CERTIFICATE-----\r\n"; 212 static constexpr const size_t sSrvPemLength = 813; // includes NUL byte 213 214 static constexpr const char *sSrvKey = "-----BEGIN EC PRIVATE KEY-----\r\n" 215 "MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" 216 "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" 217 "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" 218 "-----END EC PRIVATE KEY-----\r\n"; 219 static constexpr const size_t sSrvKeyLength = 233; // includes NUL byte 220 221 static constexpr const char *sEcjpakePassword = "TLS-over-TCPlp"; 222 static constexpr const size_t sEcjpakePasswordLength = 14; 223 static const int sCipherSuites[]; 224 #endif // OPENTHREAD_CONFIG_TLS_ENABLE 225 }; 226 227 } // namespace Cli 228 } // namespace ot 229 230 #endif // CLI_TCP_EXAMPLE_HPP_ 231