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