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_utils.hpp" 53 #include "common/time.hpp" 54 55 namespace ot { 56 namespace Cli { 57 58 /** 59 * Implements a CLI-based TCP example. 60 */ 61 class TcpExample : private Utils 62 { 63 public: 64 /** 65 * Constructor 66 * 67 * @param[in] aInstance The OpenThread Instance. 68 * @param[in] aOutputImplementer An `OutputImplementer`. 69 */ 70 TcpExample(otInstance *aInstance, OutputImplementer &aOutputImplementer); 71 72 /** 73 * Processes a CLI sub-command. 74 * 75 * @param[in] aArgs An array of command line arguments. 76 * 77 * @retval OT_ERROR_NONE Successfully executed the CLI command. 78 * @retval OT_ERROR_PENDING The CLI command was successfully started but final result is pending. 79 * @retval OT_ERROR_INVALID_COMMAND Invalid or unknown CLI command. 80 * @retval OT_ERROR_INVALID_ARGS Invalid arguments. 81 * @retval ... Error during execution of the CLI command. 82 */ 83 otError Process(Arg aArgs[]); 84 85 private: 86 using Command = CommandEntry<TcpExample>; 87 88 template <CommandId kCommandId> otError Process(Arg aArgs[]); 89 90 otError ContinueBenchmarkCircularSend(void); 91 void CompleteBenchmark(void); 92 93 #if OPENTHREAD_CONFIG_TLS_ENABLE 94 void PrepareTlsHandshake(void); 95 bool ContinueTlsHandshake(void); 96 #endif 97 98 static void HandleTcpEstablishedCallback(otTcpEndpoint *aEndpoint); 99 static void HandleTcpSendDoneCallback(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData); 100 static void HandleTcpForwardProgressCallback(otTcpEndpoint *aEndpoint, size_t aInSendBuffer, size_t aBacklog); 101 static void HandleTcpReceiveAvailableCallback(otTcpEndpoint *aEndpoint, 102 size_t aBytesAvailable, 103 bool aEndOfStream, 104 size_t aBytesRemaining); 105 static void HandleTcpDisconnectedCallback(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason); 106 static otTcpIncomingConnectionAction HandleTcpAcceptReadyCallback(otTcpListener *aListener, 107 const otSockAddr *aPeer, 108 otTcpEndpoint **aAcceptInto); 109 static void HandleTcpAcceptDoneCallback(otTcpListener *aListener, 110 otTcpEndpoint *aEndpoint, 111 const otSockAddr *aPeer); 112 113 void HandleTcpEstablished(otTcpEndpoint *aEndpoint); 114 void HandleTcpSendDone(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData); 115 void HandleTcpForwardProgress(otTcpEndpoint *aEndpoint, size_t aInSendBuffer, size_t aBacklog); 116 void HandleTcpReceiveAvailable(otTcpEndpoint *aEndpoint, 117 size_t aBytesAvailable, 118 bool aEndOfStream, 119 size_t aBytesRemaining); 120 void HandleTcpDisconnected(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason); 121 otTcpIncomingConnectionAction HandleTcpAcceptReady(otTcpListener *aListener, 122 const otSockAddr *aPeer, 123 otTcpEndpoint **aAcceptInto); 124 void HandleTcpAcceptDone(otTcpListener *aListener, otTcpEndpoint *aEndpoint, const otSockAddr *aPeer); 125 126 #if OPENTHREAD_CONFIG_TLS_ENABLE 127 static void MbedTlsDebugOutput(void *ctx, int level, const char *file, int line, const char *str); 128 #endif 129 130 void OutputBenchmarkResult(void); 131 132 otTcpEndpoint mEndpoint; 133 otTcpListener mListener; 134 135 bool mInitialized; 136 bool mEndpointConnected; 137 bool mEndpointConnectedFastOpen; 138 bool mSendBusy; 139 bool mUseCircularSendBuffer; 140 bool mUseTls; 141 bool mTlsHandshakeComplete; 142 143 otTcpCircularSendBuffer mSendBuffer; 144 otLinkedBuffer mSendLink; 145 uint8_t mSendBufferBytes[OPENTHREAD_CONFIG_CLI_TCP_RECEIVE_BUFFER_SIZE]; 146 uint8_t mReceiveBufferBytes[OPENTHREAD_CONFIG_CLI_TCP_RECEIVE_BUFFER_SIZE]; 147 148 otLinkedBuffer 149 mBenchmarkLinks[(sizeof(mReceiveBufferBytes) + sizeof(mSendBufferBytes) - 1) / sizeof(mSendBufferBytes)]; 150 uint32_t mBenchmarkBytesTotal; 151 uint32_t mBenchmarkBytesUnsent; 152 TimeMilli mBenchmarkStart; 153 uint32_t mBenchmarkTimeUsed; 154 uint32_t mBenchmarkLastBytesTotal; 155 otTcpEndpointAndCircularSendBuffer mEndpointAndCircularSendBuffer; 156 157 #if OPENTHREAD_CONFIG_TLS_ENABLE 158 mbedtls_ssl_context mSslContext; 159 mbedtls_ssl_config mSslConfig; 160 mbedtls_x509_crt mSrvCert; 161 mbedtls_pk_context mPKey; 162 mbedtls_entropy_context mEntropy; 163 #endif // OPENTHREAD_CONFIG_TLS_ENABLE 164 165 static constexpr const char *sBenchmarkData = 166 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 167 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 168 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 169 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 170 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 171 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 172 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 173 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 174 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 175 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 176 static constexpr const size_t sBenchmarkDataLength = 1040; 177 178 #if OPENTHREAD_CONFIG_TLS_ENABLE 179 static constexpr const char *sCasPem = "-----BEGIN CERTIFICATE-----\r\n" 180 "MIIBtDCCATqgAwIBAgIBTTAKBggqhkjOPQQDAjBLMQswCQYDVQQGEwJOTDERMA8G\r\n" 181 "A1UEChMIUG9sYXJTU0wxKTAnBgNVBAMTIFBvbGFyU1NMIFRlc3QgSW50ZXJtZWRp\r\n" 182 "YXRlIEVDIENBMB4XDTE1MDkwMTE0MDg0M1oXDTI1MDgyOTE0MDg0M1owSjELMAkG\r\n" 183 "A1UEBhMCVUsxETAPBgNVBAoTCG1iZWQgVExTMSgwJgYDVQQDEx9tYmVkIFRMUyBU\r\n" 184 "ZXN0IGludGVybWVkaWF0ZSBDQSAzMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\r\n" 185 "732fWHLNPMPsP1U1ibXvb55erlEVMlpXBGsj+KYwVqU1XCmW9Z9hhP7X/5js/DX9\r\n" 186 "2J/utoHyjUtVpQOzdTrbsaMQMA4wDAYDVR0TBAUwAwEB/zAKBggqhkjOPQQDAgNo\r\n" 187 "ADBlAjAJRxbGRas3NBmk9MnGWXg7PT1xnRELHRWWIvfLdVQt06l1/xFg3ZuPdQdt\r\n" 188 "Qh7CK80CMQD7wa1o1a8qyDKBfLN636uKmKGga0E+vYXBeFCy9oARBangGCB0B2vt\r\n" 189 "pz590JvGWfM=\r\n" 190 "-----END CERTIFICATE-----\r\n"; 191 static constexpr const size_t sCasPemLength = 665; // includes NUL byte 192 193 static constexpr const char *sSrvPem = "-----BEGIN CERTIFICATE-----\r\n" 194 "MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" 195 "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" 196 "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" 197 "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" 198 "CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" 199 "2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" 200 "BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" 201 "PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" 202 "clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" 203 "CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" 204 "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" 205 "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" 206 "-----END CERTIFICATE-----\r\n"; 207 static constexpr const size_t sSrvPemLength = 813; // includes NUL byte 208 209 static constexpr const char *sSrvKey = "-----BEGIN EC PRIVATE KEY-----\r\n" 210 "MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" 211 "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" 212 "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" 213 "-----END EC PRIVATE KEY-----\r\n"; 214 static constexpr const size_t sSrvKeyLength = 233; // includes NUL byte 215 216 static constexpr const char *sEcjpakePassword = "TLS-over-TCPlp"; 217 static constexpr const size_t sEcjpakePasswordLength = 14; 218 static const int sCipherSuites[]; 219 #endif // OPENTHREAD_CONFIG_TLS_ENABLE 220 }; 221 222 } // namespace Cli 223 } // namespace ot 224 225 #endif // CLI_TCP_EXAMPLE_HPP_ 226