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 * @brief 32 * This file defines the OpenThread TCP API. 33 */ 34 35 #ifndef OPENTHREAD_TCP_H_ 36 #define OPENTHREAD_TCP_H_ 37 38 #include <openthread/ip6.h> 39 40 #ifdef __cplusplus 41 extern "C" { 42 #endif 43 44 /** 45 * @addtogroup api-tcp 46 * 47 * @brief 48 * This module includes functions that control TCP communication. 49 * 50 * @{ 51 */ 52 53 /** 54 * A linked buffer structure for use with TCP. 55 * 56 * A single otLinkedBuffer structure references an array of bytes in memory, 57 * via mData and mLength. The mNext field is used to form a chain of 58 * otLinkedBuffer structures. 59 */ 60 typedef struct otLinkedBuffer 61 { 62 struct otLinkedBuffer *mNext; ///< Pointer to the next linked buffer in the chain, or NULL if it is the end. 63 const uint8_t *mData; ///< Pointer to data referenced by this linked buffer. 64 size_t mLength; ///< Length of this linked buffer (number of bytes). 65 } otLinkedBuffer; 66 67 struct otTcpEndpoint; 68 typedef struct otTcpEndpoint otTcpEndpoint; 69 70 /** 71 * This callback informs the application that the TCP 3-way handshake is 72 * complete and that the connection is now established. 73 * 74 * @param[in] aEndpoint The TCP endpoint whose connection is now established. 75 */ 76 typedef void (*otTcpEstablished)(otTcpEndpoint *aEndpoint); 77 78 /** 79 * This callback informs the application that data in the provided 80 * @p aData have been acknowledged by the connection peer and that @p aData and 81 * the data it contains can be reclaimed by the application. 82 * 83 * The @p aData are guaranteed to be identical to those passed in to TCP via 84 * otTcpSendByReference(), including any extensions effected via 85 * otTcpSendByExtension(). 86 * 87 * @param[in] aEndpoint The TCP endpoint for the connection. 88 * @param[in] aData A pointer to the otLinkedBuffer that can be reclaimed. 89 */ 90 typedef void (*otTcpSendDone)(otTcpEndpoint *aEndpoint, otLinkedBuffer *aData); 91 92 /** 93 * This callback informs the application if forward progress has been made in 94 * transferring data from the send buffer to the recipient. This callback is 95 * not necessary for correct TCP operation. Most applications can just rely on 96 * the otTcpSendDone() callback to reclaim linked buffers once the TCP stack is 97 * done using them. The purpose of this callback is to support advanced 98 * applications that benefit from finer-grained information about how the 99 * the connection is making forward progress in transferring data to the 100 * connection peer. 101 * 102 * This callback's operation is closely tied to TCP's send buffer. The send 103 * buffer can be understood as having two regions. First, there is the 104 * "in-flight" region at the head (front) of the send buffer. It corresponds 105 * to data which has been sent to the recipient, but is not yet acknowledged. 106 * Second, there is the "backlog" region, which consists of all data in the 107 * send buffer that is not in the "in-flight" region. The "backlog" region 108 * corresponds to data that is queued for sending, but has not yet been sent. 109 * 110 * The callback is invoked in response to two types of events. First, the 111 * "in-flight" region of the send buffer may shrink (e.g., when the recipient 112 * acknowledges data that we sent earlier). Second, the "backlog" region of the 113 * send buffer may shrink (e.g., new data was sent out). These two conditions 114 * often occur at the same time, in response to an ACK segment from the 115 * connection peer, which is why they are combined in a single callback. 116 * 117 * The TCP stack only uses the @p aInSendBuffer bytes at the tail of the send 118 * buffer; when @p aInSendBuffer decreases by an amount x, it means that x 119 * additional bytes that were formerly at the head of the send buffer are no 120 * longer part of the send buffer and can now be reclaimed (i.e., overwritten) 121 * by the application. Note that the otLinkedBuffer structure itself can only 122 * be reclaimed once all bytes that it references are no longer part of the 123 * send buffer. 124 * 125 * This callback subsumes otTcpSendDone(), in the following sense: applications 126 * can determine when linked buffers can be reclaimed by comparing 127 * @p aInSendBuffer with how many bytes are in each linked buffer. However, we 128 * expect otTcpSendDone(), which directly conveys which otLinkedBuffers can be 129 * reclaimed, to be much simpler to use. If both callbacks are registered and 130 * are triggered by the same event (e.g., the same ACK segment received), then 131 * the otTcpSendDone() callback will be triggered first, followed by this 132 * callback. 133 * 134 * Additionally, this callback provides @p aBacklog, which indicates how many 135 * bytes of data in the send buffer are not yet in flight. For applications 136 * that only want to add data to the send buffer when there is an assurance 137 * that it will be sent out soon, it may be desirable to only send out data 138 * when @p aBacklog is suitably small (0 or close to 0). For example, an 139 * application may use @p aBacklog so that it can react to queue buildup by 140 * dropping or aggregating data to avoid creating a backlog of data. 141 * 142 * After a call to otTcpSendByReference() or otTcpSendByExtension() with a 143 * positive number of bytes, the otTcpForwardProgress() callback is guaranteed 144 * to be called, to indicate when the bytes that were added to the send buffer 145 * are sent out. The call to otTcpForwardProgress() may be made immediately 146 * after the bytes are added to the send buffer (if some of those bytes are 147 * immediately sent out, reducing the backlog), or sometime in the future (once 148 * the connection sends out some or all of the data, reducing the backlog). By 149 * "immediately," we mean that the callback is immediately scheduled for 150 * execution in a tasklet; to avoid reentrancy-related complexity, the 151 * otTcpForwardProgress() callback is never directly called from the 152 * otTcpSendByReference() or otTcpSendByExtension() functions. 153 * 154 * @param[in] aEndpoint The TCP endpoint for the connection. 155 * @param[in] aInSendBuffer The number of bytes in the send buffer (sum of "in-flight" and "backlog" regions). 156 * @param[in] aBacklog The number of bytes that are queued for sending but have not yet been sent (the "backlog" 157 * region). 158 */ 159 typedef void (*otTcpForwardProgress)(otTcpEndpoint *aEndpoint, size_t aInSendBuffer, size_t aBacklog); 160 161 /** 162 * This callback indicates the number of bytes available for consumption from 163 * the receive buffer. 164 * 165 * It is called whenever bytes are added to the receive buffer and when the 166 * end of stream is reached. If the end of the stream has been reached (i.e., 167 * if no more data will become available to read because the connection peer 168 * has closed their end of the connection for writing), then @p aEndOfStream is 169 * true. Finally, @p aBytesRemaining indicates how much capacity is left in the 170 * receive buffer to hold additional data that arrives. 171 * 172 * @param[in] aEndpoint The TCP endpoint for the connection. 173 * @param[in] aBytesAvailable The number of bytes in the connection's receive buffer. 174 * @param[in] aEndOfStream Indicates if additional data, beyond what is already in the connection's receive buffer, 175 * can be received. 176 * @param[in] aBytesRemaining The number of additional bytes that can be received before the receive buffer becomes 177 * full. 178 */ 179 typedef void (*otTcpReceiveAvailable)(otTcpEndpoint *aEndpoint, 180 size_t aBytesAvailable, 181 bool aEndOfStream, 182 size_t aBytesRemaining); 183 184 typedef enum otTcpDisconnectedReason 185 { 186 OT_TCP_DISCONNECTED_REASON_NORMAL, 187 OT_TCP_DISCONNECTED_REASON_REFUSED, 188 OT_TCP_DISCONNECTED_REASON_RESET, 189 OT_TCP_DISCONNECTED_REASON_TIME_WAIT, 190 OT_TCP_DISCONNECTED_REASON_TIMED_OUT, 191 } otTcpDisconnectedReason; 192 193 /** 194 * This callback indicates that the connection was broken and should no longer 195 * be used, or that a connection has entered the TIME-WAIT state. 196 * 197 * It can occur if a connection establishment attempt (initiated by calling 198 * otTcpConnect()) fails, or any point thereafter (e.g., if the connection 199 * times out or an RST segment is received from the connection peer). Once this 200 * callback fires, all resources that the application provided for this 201 * connection (i.e., any `otLinkedBuffers` and memory they reference, but not 202 * the TCP endpoint itself or space for the receive buffers) can be reclaimed. 203 * In the case of a connection entering the TIME-WAIT state, this callback is 204 * called twice, once upon entry into the TIME-WAIT state (with 205 * OT_TCP_DISCONNECTED_REASON_TIME_WAIT, and again when the TIME-WAIT state 206 * expires (with OT_TCP_DISCONNECTED_REASON_NORMAL). 207 * 208 * @param[in] aEndpoint The TCP endpoint whose connection has been lost. 209 * @param[in] aReason The reason why the connection was lost. 210 */ 211 typedef void (*otTcpDisconnected)(otTcpEndpoint *aEndpoint, otTcpDisconnectedReason aReason); 212 213 /** 214 * OT_TCP_ENDPOINT_TCB_SIZE_BASE and OT_TCP_ENDPOINT_TCB_NUM_POINTERS are 215 * chosen such that the mTcb field of otTcpEndpoint has the same size as 216 * struct tcpcb in TCPlp. This is necessary because the mTcb field, although 217 * opaque in its declaration, is treated as struct tcpcb in the TCP 218 * implementation. 219 */ 220 #define OT_TCP_ENDPOINT_TCB_SIZE_BASE 392 221 #define OT_TCP_ENDPOINT_TCB_NUM_PTR 36 222 223 /** 224 * Represents a TCP endpoint. 225 * 226 * A TCP endpoint acts an endpoint of TCP connection. It can be used to 227 * initiate TCP connections, and, once a TCP connection is established, send 228 * data to and receive data from the connection peer. 229 * 230 * The application should not inspect the fields of this structure directly; it 231 * should only interact with it via the TCP API functions whose signatures are 232 * provided in this file. 233 */ 234 struct otTcpEndpoint 235 { 236 union 237 { 238 uint8_t mSize[OT_TCP_ENDPOINT_TCB_SIZE_BASE + OT_TCP_ENDPOINT_TCB_NUM_PTR * sizeof(void *)]; 239 uint64_t mAlign; 240 } mTcb; 241 242 struct otTcpEndpoint *mNext; ///< A pointer to the next TCP endpoint (internal use only) 243 void *mContext; ///< A pointer to application-specific context 244 245 otTcpEstablished mEstablishedCallback; ///< "Established" callback function 246 otTcpSendDone mSendDoneCallback; ///< "Send done" callback function 247 otTcpForwardProgress mForwardProgressCallback; ///< "Forward progress" callback function 248 otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function 249 otTcpDisconnected mDisconnectedCallback; ///< "Disconnected" callback function 250 251 uint32_t mTimers[4]; 252 253 otLinkedBuffer mReceiveLinks[2]; 254 otSockAddr mSockAddr; 255 256 uint8_t mPendingCallbacks; 257 }; 258 259 /** 260 * Contains arguments to the otTcpEndpointInitialize() function. 261 */ 262 typedef struct otTcpEndpointInitializeArgs 263 { 264 void *mContext; ///< Pointer to application-specific context 265 266 otTcpEstablished mEstablishedCallback; ///< "Established" callback function 267 otTcpSendDone mSendDoneCallback; ///< "Send done" callback function 268 otTcpForwardProgress mForwardProgressCallback; ///< "Forward progress" callback function 269 otTcpReceiveAvailable mReceiveAvailableCallback; ///< "Receive available" callback function 270 otTcpDisconnected mDisconnectedCallback; ///< "Disconnected" callback function 271 272 void *mReceiveBuffer; ///< Pointer to memory provided to the system for the TCP receive buffer 273 size_t mReceiveBufferSize; ///< Size of memory provided to the system for the TCP receive buffer 274 } otTcpEndpointInitializeArgs; 275 276 /** 277 * @def OT_TCP_RECEIVE_BUFFER_SIZE_FEW_HOPS 278 * 279 * Recommended buffer size for TCP connections that traverse about 3 wireless 280 * hops or fewer. 281 * 282 * On platforms where memory is particularly constrained and in situations 283 * where high bandwidth is not necessary, it may be desirable to manually 284 * select a smaller buffer size. 285 */ 286 #define OT_TCP_RECEIVE_BUFFER_SIZE_FEW_HOPS 2598 287 288 /** 289 * @def OT_TCP_RECEIVE_BUFFER_SIZE_MANY_HOPS 290 * 291 * Recommended buffer size for TCP connections that traverse many wireless 292 * hops. 293 * 294 * If the TCP connection traverses a very large number of hops (more than 6 or 295 * so), then it may be advisable to select a large buffer size manually. 296 */ 297 #define OT_TCP_RECEIVE_BUFFER_SIZE_MANY_HOPS 4157 298 299 /** 300 * Initializes a TCP endpoint. 301 * 302 * Calling this function causes OpenThread to keep track of the TCP endpoint 303 * and store and retrieve TCP data inside the @p aEndpoint. The application 304 * should refrain from directly accessing or modifying the fields in 305 * @p aEndpoint. If the application needs to reclaim the memory backing 306 * @p aEndpoint, it should call otTcpEndpointDeinitialize(). 307 * 308 * @param[in] aInstance A pointer to an OpenThread instance. 309 * @param[in] aEndpoint A pointer to a TCP endpoint structure. 310 * @param[in] aArgs A pointer to a structure of arguments. 311 * 312 * @retval OT_ERROR_NONE Successfully opened the TCP endpoint. 313 * @retval OT_ERROR_FAILED Failed to open the TCP endpoint. 314 */ 315 otError otTcpEndpointInitialize(otInstance *aInstance, 316 otTcpEndpoint *aEndpoint, 317 const otTcpEndpointInitializeArgs *aArgs); 318 319 /** 320 * Obtains the otInstance that was associated with @p aEndpoint upon 321 * initialization. 322 * 323 * @param[in] aEndpoint The TCP endpoint whose instance to obtain. 324 * 325 * @returns The otInstance pointer associated with @p aEndpoint. 326 */ 327 otInstance *otTcpEndpointGetInstance(otTcpEndpoint *aEndpoint); 328 329 /** 330 * Obtains the context pointer that was associated with @p aEndpoint upon 331 * initialization. 332 * 333 * @param[in] aEndpoint The TCP endpoint whose context to obtain. 334 * 335 * @returns The context pointer associated with @p aEndpoint. 336 */ 337 void *otTcpEndpointGetContext(otTcpEndpoint *aEndpoint); 338 339 /** 340 * Obtains a pointer to a TCP endpoint's local host and port. 341 * 342 * The contents of the host and port may be stale if this socket is not in a 343 * connected state and has not been bound after it was last disconnected. 344 * 345 * @param[in] aEndpoint The TCP endpoint whose local host and port to obtain. 346 * 347 * @returns The local host and port of @p aEndpoint. 348 */ 349 const otSockAddr *otTcpGetLocalAddress(const otTcpEndpoint *aEndpoint); 350 351 /** 352 * Obtains a pointer to a TCP endpoint's peer's host and port. 353 * 354 * The contents of the host and port may be stale if this socket is not in a 355 * connected state. 356 * 357 * @param[in] aEndpoint The TCP endpoint whose peer's host and port to obtain. 358 * 359 * @returns The host and port of the connection peer of @p aEndpoint. 360 */ 361 const otSockAddr *otTcpGetPeerAddress(const otTcpEndpoint *aEndpoint); 362 363 /** 364 * Binds the TCP endpoint to an IP address and port. 365 * 366 * @param[in] aEndpoint A pointer to the TCP endpoint structure to bind. 367 * @param[in] aSockName The address and port to which to bind this TCP endpoint. 368 * 369 * @retval OT_ERROR_NONE Successfully bound the TCP endpoint. 370 * @retval OT_ERROR_FAILED Failed to bind the TCP endpoint. 371 */ 372 otError otTcpBind(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName); 373 374 /** 375 * Defines flags passed to otTcpConnect(). 376 */ 377 enum 378 { 379 OT_TCP_CONNECT_NO_FAST_OPEN = 1 << 0, 380 }; 381 382 /** 383 * Records the remote host and port for this connection. 384 * 385 * TCP Fast Open must be enabled or disabled using @p aFlags. If it is 386 * disabled, then the TCP connection establishment handshake is initiated 387 * immediately. If it is enabled, then this function merely records the 388 * the remote host and port, and the TCP connection establishment handshake 389 * only happens on the first call to `otTcpSendByReference()`. 390 * 391 * If TCP Fast Open is disabled, then the caller must wait for the 392 * `otTcpEstablished` callback indicating that TCP connection establishment 393 * handshake is done before it can start sending data e.g., by calling 394 * `otTcpSendByReference()`. 395 * 396 * @param[in] aEndpoint A pointer to the TCP endpoint structure to connect. 397 * @param[in] aSockName The IP address and port of the host to which to connect. 398 * @param[in] aFlags Flags specifying options for this operation (see enumeration above). 399 * 400 * @retval OT_ERROR_NONE Successfully completed the operation. 401 * @retval OT_ERROR_FAILED Failed to complete the operation. 402 */ 403 otError otTcpConnect(otTcpEndpoint *aEndpoint, const otSockAddr *aSockName, uint32_t aFlags); 404 405 /** 406 * Defines flags passed to @p otTcpSendByReference. 407 */ 408 enum 409 { 410 OT_TCP_SEND_MORE_TO_COME = 1 << 0, 411 }; 412 413 /** 414 * Adds data referenced by the linked buffer pointed to by @p aBuffer to the 415 * send buffer. 416 * 417 * Upon a successful call to this function, the linked buffer and data it 418 * references are owned by the TCP stack; they should not be modified by the 419 * application until a "send done" callback returns ownership of those objects 420 * to the application. It is acceptable to call this function to add another 421 * linked buffer to the send queue, even if the "send done" callback for a 422 * previous invocation of this function has not yet fired. 423 * 424 * Note that @p aBuffer should not be chained; its mNext field should be 425 * NULL. If additional data will be added right after this call, then the 426 * OT_TCP_SEND_MORE_TO_COME flag should be used as a hint to the TCP 427 * implementation. 428 * 429 * @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to send data. 430 * @param[in] aBuffer A pointer to the linked buffer chain referencing data to add to the send buffer. 431 * @param[in] aFlags Flags specifying options for this operation (see enumeration above). 432 * 433 * @retval OT_ERROR_NONE Successfully added data to the send buffer. 434 * @retval OT_ERROR_FAILED Failed to add data to the send buffer. 435 */ 436 otError otTcpSendByReference(otTcpEndpoint *aEndpoint, otLinkedBuffer *aBuffer, uint32_t aFlags); 437 438 /** 439 * Adds data to the send buffer by extending the length of the final 440 * otLinkedBuffer in the send buffer by the specified amount. 441 * 442 * If the send buffer is empty, then the operation fails. 443 * 444 * @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to send data. 445 * @param[in] aNumBytes The number of bytes by which to extend the length of the final linked buffer. 446 * @param[in] aFlags Flags specifying options for this operation (see enumeration above). 447 * 448 * @retval OT_ERROR_NONE Successfully added data to the send buffer. 449 * @retval OT_ERROR_FAILED Failed to add data to the send buffer. 450 */ 451 otError otTcpSendByExtension(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags); 452 453 /** 454 * Provides the application with a linked buffer chain referencing data 455 * currently in the TCP receive buffer. 456 * 457 * The linked buffer chain is valid until the "receive ready" callback is next 458 * invoked, or until the next call to otTcpReceiveContiguify() or 459 * otTcpCommitReceive(). 460 * 461 * @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to receive 462 * data. 463 * @param[out] aBuffer A pointer to the linked buffer chain referencing data currently in the receive buffer. 464 * 465 * @retval OT_ERROR_NONE Successfully completed the operation. 466 * @retval OT_ERROR_FAILED Failed to complete the operation. 467 */ 468 otError otTcpReceiveByReference(otTcpEndpoint *aEndpoint, const otLinkedBuffer **aBuffer); 469 470 /** 471 * Reorganizes the receive buffer to be entirely contiguous in memory. 472 * 473 * This is optional; an application can simply traverse the linked buffer 474 * chain obtained by calling @p otTcpReceiveByReference. Some 475 * applications may wish to call this function to make the receive buffer 476 * contiguous to simplify their data processing, but this comes at the expense 477 * of CPU time to reorganize the data in the receive buffer. 478 * 479 * @param[in] aEndpoint A pointer to the TCP endpoint whose receive buffer to reorganize. 480 * 481 * @retval OT_ERROR_NONE Successfully completed the operation. 482 * @retval OT_ERROR_FAILED Failed to complete the operation. 483 */ 484 otError otTcpReceiveContiguify(otTcpEndpoint *aEndpoint); 485 486 /** 487 * Informs the TCP stack that the application has finished processing 488 * @p aNumBytes bytes of data at the start of the receive buffer and that the 489 * TCP stack need not continue maintaining those bytes in the receive buffer. 490 * 491 * @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint on which to receive 492 * data. 493 * @param[in] aNumBytes The number of bytes consumed. 494 * @param[in] aFlags Flags specifying options for this operation (none yet). 495 * 496 * @retval OT_ERROR_NONE Successfully completed the receive operation. 497 * @retval OT_ERROR_FAILED Failed to complete the receive operation. 498 */ 499 otError otTcpCommitReceive(otTcpEndpoint *aEndpoint, size_t aNumBytes, uint32_t aFlags); 500 501 /** 502 * Informs the connection peer that this TCP endpoint will not send more data. 503 * 504 * This should be used when the application has no more data to send to the 505 * connection peer. For this connection, future reads on the connection peer 506 * will result in the "end of stream" condition, and future writes on this 507 * connection endpoint will fail. 508 * 509 * The "end of stream" condition only applies after any data previously 510 * provided to the TCP stack to send out has been received by the connection 511 * peer. 512 * 513 * @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint to shut down. 514 * 515 * @retval OT_ERROR_NONE Successfully queued the "end of stream" condition for transmission. 516 * @retval OT_ERROR_FAILED Failed to queue the "end of stream" condition for transmission. 517 */ 518 otError otTcpSendEndOfStream(otTcpEndpoint *aEndpoint); 519 520 /** 521 * Forcibly ends the TCP connection associated with this TCP endpoint. 522 * 523 * This immediately makes the TCP endpoint free for use for another connection 524 * and empties the send and receive buffers, transferring ownership of any data 525 * provided by the application in otTcpSendByReference() and 526 * otTcpSendByExtension() calls back to the application. The TCP endpoint's 527 * callbacks and memory for the receive buffer remain associated with the 528 * TCP endpoint. 529 * 530 * @param[in] aEndpoint A pointer to the TCP endpoint structure representing the TCP endpoint to abort. 531 * 532 * @retval OT_ERROR_NONE Successfully aborted the TCP endpoint's connection. 533 * @retval OT_ERROR_FAILED Failed to abort the TCP endpoint's connection. 534 */ 535 otError otTcpAbort(otTcpEndpoint *aEndpoint); 536 537 /** 538 * Deinitializes this TCP endpoint. 539 * 540 * This means that OpenThread no longer keeps track of this TCP endpoint and 541 * deallocates all resources it has internally allocated for this TCP endpoint. 542 * The application can reuse the memory backing the TCP endpoint as it sees fit. 543 * 544 * If it corresponds to a live TCP connection, the connection is terminated 545 * unceremoniously (as in otTcpAbort()). All resources the application has 546 * provided for this TCP endpoint (linked buffers for the send buffer, memory 547 * for the receive buffer, the @p aEndpoint structure itself, etc.) are 548 * immediately returned to the application. 549 * 550 * @param[in] aEndpoint A pointer to the TCP endpoint structure to deinitialize. 551 * 552 * @retval OT_ERROR_NONE Successfully deinitialized the TCP endpoint. 553 * @retval OT_ERROR_FAILED Failed to deinitialize the TCP endpoint. 554 */ 555 otError otTcpEndpointDeinitialize(otTcpEndpoint *aEndpoint); 556 557 struct otTcpListener; 558 typedef struct otTcpListener otTcpListener; 559 560 /** 561 * Defines incoming connection actions. 562 * 563 * This is used in otTcpAcceptReady() callback. 564 */ 565 typedef enum otTcpIncomingConnectionAction 566 { 567 OT_TCP_INCOMING_CONNECTION_ACTION_ACCEPT, ///< Accept the incoming connection. 568 OT_TCP_INCOMING_CONNECTION_ACTION_DEFER, ///< Defer (silently ignore) the incoming connection. 569 OT_TCP_INCOMING_CONNECTION_ACTION_REFUSE, ///< Refuse the incoming connection. 570 } otTcpIncomingConnectionAction; 571 572 /** 573 * This callback indicates that an incoming connection that matches this TCP 574 * listener has arrived. 575 * 576 * The typical response is for the application to accept the incoming 577 * connection. It does so by populating @p aAcceptInto with a pointer to the 578 * otTcpEndpoint into which to accept the incoming connection. This 579 * otTcpEndpoint must already be initialized using otTcpEndpointInitialize(). 580 * Then, the application returns OT_TCP_INCOMING_CONNECTION_ACTION_ACCEPT. 581 * 582 * Alternatively, the application can decline to accept the incoming 583 * connection. There are two ways for the application to do this. First, if the 584 * application returns OT_TCP_INCOMING_CONNECTION_ACTION_DEFER, then OpenThread 585 * silently ignores the connection establishment request; the connection peer 586 * will likely retransmit the request, at which point the callback will be 587 * called again. This is valuable if resources are not presently available to 588 * accept the connection, but they may be available when the connection peer 589 * retransmits its connection establishment attempt. Second, if the application 590 * returns OT_TCP_INCOMING_CONNECTION_ACTION_REFUSE, then OpenThread sends a 591 * "connection refused" message to the host that attempted to establish a 592 * connection. If the application declines the incoming connection, it is not 593 * required to populate @p aAcceptInto. 594 * 595 * @param[in] aListener The TCP listener that matches the incoming connection. 596 * @param[in] aPeer The host and port from which the incoming connection originates. 597 * @param[out] aAcceptInto The TCP endpoint into which to accept the incoming connection. 598 * 599 * @returns Description of how to handle the incoming connection. 600 */ 601 typedef otTcpIncomingConnectionAction (*otTcpAcceptReady)(otTcpListener *aListener, 602 const otSockAddr *aPeer, 603 otTcpEndpoint **aAcceptInto); 604 605 /** 606 * This callback indicates that the TCP connection is now ready for two-way 607 * communication. 608 * 609 * In the case of TCP Fast Open, this may be before the TCP 610 * connection handshake has actually completed. The application is provided 611 * with the context pointers both for the TCP listener that accepted the 612 * connection and the TCP endpoint into which it was accepted. The provided 613 * context is the one associated with the TCP listener. 614 * 615 * @param[in] aListener The TCP listener that matches the incoming connection. 616 * @param[in] aEndpoint The TCP endpoint into which the incoming connection was accepted. 617 * @param[in] aPeer the host and port from which the incoming connection originated. 618 */ 619 typedef void (*otTcpAcceptDone)(otTcpListener *aListener, otTcpEndpoint *aEndpoint, const otSockAddr *aPeer); 620 621 /** 622 * OT_TCP_LISTENER_TCB_SIZE_BASE and OT_TCP_LISTENER_TCB_NUM_POINTERS are 623 * chosen such that the mTcbListener field of otTcpListener has the same size 624 * as struct tcpcb_listen in TCPlp. This is necessary because the mTcbListen 625 * field, though opaque in its declaration, is treated as struct tcpcb in the 626 * TCP implementation. 627 */ 628 #define OT_TCP_LISTENER_TCB_SIZE_BASE 16 629 #define OT_TCP_LISTENER_TCB_NUM_PTR 3 630 631 /** 632 * Represents a TCP listener. 633 * 634 * A TCP listener is used to listen for and accept incoming TCP connections. 635 * 636 * The application should not inspect the fields of this structure directly; it 637 * should only interact with it via the TCP API functions whose signatures are 638 * provided in this file. 639 */ 640 struct otTcpListener 641 { 642 union 643 { 644 uint8_t mSize[OT_TCP_LISTENER_TCB_SIZE_BASE + OT_TCP_LISTENER_TCB_NUM_PTR * sizeof(void *)]; 645 void *mAlign; 646 } mTcbListen; 647 648 struct otTcpListener *mNext; ///< A pointer to the next TCP listener (internal use only) 649 void *mContext; ///< A pointer to application-specific context 650 651 otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function 652 otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function 653 }; 654 655 /** 656 * Contains arguments to the otTcpListenerInitialize() function. 657 */ 658 typedef struct otTcpListenerInitializeArgs 659 { 660 void *mContext; ///< Pointer to application-specific context 661 662 otTcpAcceptReady mAcceptReadyCallback; ///< "Accept ready" callback function 663 otTcpAcceptDone mAcceptDoneCallback; ///< "Accept done" callback function 664 } otTcpListenerInitializeArgs; 665 666 /** 667 * Initializes a TCP listener. 668 * 669 * Calling this function causes OpenThread to keep track of the TCP listener 670 * and store and retrieve TCP data inside @p aListener. The application should 671 * refrain from directly accessing or modifying the fields in @p aListener. If 672 * the application needs to reclaim the memory backing @p aListener, it should 673 * call otTcpListenerDeinitialize(). 674 * 675 * @param[in] aInstance A pointer to an OpenThread instance. 676 * @param[in] aListener A pointer to a TCP listener structure. 677 * @param[in] aArgs A pointer to a structure of arguments. 678 * 679 * @retval OT_ERROR_NONE Successfully opened the TCP listener. 680 * @retval OT_ERROR_FAILED Failed to open the TCP listener. 681 */ 682 otError otTcpListenerInitialize(otInstance *aInstance, 683 otTcpListener *aListener, 684 const otTcpListenerInitializeArgs *aArgs); 685 686 /** 687 * Obtains the otInstance that was associated with @p aListener upon 688 * initialization. 689 * 690 * @param[in] aListener The TCP listener whose instance to obtain. 691 * 692 * @returns The otInstance pointer associated with @p aListener. 693 */ 694 otInstance *otTcpListenerGetInstance(otTcpListener *aListener); 695 696 /** 697 * Obtains the context pointer that was associated with @p aListener upon 698 * initialization. 699 * 700 * @param[in] aListener The TCP listener whose context to obtain. 701 * 702 * @returns The context pointer associated with @p aListener. 703 */ 704 void *otTcpListenerGetContext(otTcpListener *aListener); 705 706 /** 707 * Causes incoming TCP connections that match the specified IP address and port 708 * to trigger this TCP listener's callbacks. 709 * 710 * @param[in] aListener A pointer to the TCP listener structure that should begin listening. 711 * @param[in] aSockName The address and port on which to listen for incoming connections. 712 * 713 * @retval OT_ERROR_NONE Successfully initiated listening on the TCP listener. 714 * @retval OT_ERROR_FAILED Failed to initiate listening on the TCP listener. 715 */ 716 otError otTcpListen(otTcpListener *aListener, const otSockAddr *aSockName); 717 718 /** 719 * Causes this TCP listener to stop listening for incoming connections. 720 * 721 * @param[in] aListener A pointer to the TCP listener structure that should stop listening. 722 * 723 * @retval OT_ERROR_NONE Successfully stopped listening on the TCP listener. 724 * @retval OT_ERROR_FAILED Failed to stop listening on the TCP listener. 725 */ 726 otError otTcpStopListening(otTcpListener *aListener); 727 728 /** 729 * Deinitializes this TCP listener. 730 * 731 * This means that OpenThread no longer keeps track of this TCP listener and 732 * deallocates all resources it has internally allocated for this TCP listener. 733 * The application can reuse the memory backing the TCP listener as it sees 734 * fit. 735 * 736 * If the TCP listener is currently listening, it stops listening. 737 * 738 * @param[in] aListener A pointer to the TCP listener structure to deinitialize. 739 * 740 * @retval OT_ERROR_NONE Successfully deinitialized the TCP listener. 741 * @retval OT_ERROR_FAILED Failed to deinitialize the TCP listener. 742 */ 743 otError otTcpListenerDeinitialize(otTcpListener *aListener); 744 745 /** 746 * @} 747 */ 748 749 #ifdef __cplusplus 750 } // extern "C" 751 #endif 752 753 #endif // OPENTHREAD_TCP_H_ 754