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