• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 includes definitions for TCP/IPv6 sockets.
32  */
33 
34 #ifndef TCP6_HPP_
35 #define TCP6_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/tcp.h>
40 
41 #include "common/as_core_type.hpp"
42 #include "common/clearable.hpp"
43 #include "common/linked_list.hpp"
44 #include "common/locator.hpp"
45 #include "common/non_copyable.hpp"
46 #include "common/timer.hpp"
47 #include "net/ip6_headers.hpp"
48 #include "net/socket.hpp"
49 
50 /*
51  * These structures and functions are forward-declared here to avoid
52  * #includ'ing third_party/tcplp/tcplp.h in this header file.
53  */
54 extern "C" {
55 struct tcpcb;
56 struct tcpcb_listen;
57 struct tcplp_signals;
58 
59 /*
60  * The next two declarations intentionally change argument names from the
61  * original declarations in TCPlp, in order to comply with OpenThread's format.
62  */
63 
64 // NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name)
65 void tcplp_sys_set_timer(struct tcpcb *aTcb, uint8_t aTimerFlag, uint32_t aDelay);
66 
67 // NOLINTNEXTLINE(readability-inconsistent-declaration-parameter-name)
68 void tcplp_sys_stop_timer(struct tcpcb *aTcb, uint8_t aTimerFlag);
69 }
70 
71 namespace ot {
72 namespace Ip6 {
73 
74 /**
75  * @addtogroup core-tcp
76  *
77  * @brief
78  *   This module includes definitions for TCP/IPv6 sockets.
79  *
80  * @{
81  */
82 
83 /**
84  * Implements TCP message handling.
85  */
86 class Tcp : public InstanceLocator, private NonCopyable
87 {
88 public:
89     /**
90      * Represents an endpoint of a TCP/IPv6 connection.
91      */
92     class Endpoint : public otTcpEndpoint, public LinkedListEntry<Endpoint>, public GetProvider<Endpoint>
93     {
94         friend class Tcp;
95         friend class LinkedList<Endpoint>;
96 
97     public:
98         /**
99          * Initializes a TCP endpoint.
100          *
101          * Calling this function causes OpenThread to keep track of this Endpoint
102          * and store and retrieve TCP data inside of it. The application
103          * should refrain from directly accessing or modifying the fields in
104          * this Endpoint. If the application needs to reclaim the memory backing
105          * this Endpoint, it should call otTcpEndpointDeinitialize().
106          *
107          * @sa otTcpEndpointInitialize in include/openthread/tcp.h.
108          *
109          * @param[in]  aInstance  A pointer to an OpenThread instance.
110          * @param[in]  aArgs      A pointer to a structure of arguments.
111          *
112          * @retval kErrorNone    Successfully opened the TCP endpoint.
113          * @retval kErrorFailed  Failed to open the TCP endpoint.
114          */
115         Error Initialize(Instance &aInstance, const otTcpEndpointInitializeArgs &aArgs);
116 
117         /**
118          * Obtains the Instance that was associated with this Endpoint upon
119          * initialization.
120          *
121          * @sa otTcpEndpointGetInstance
122          *
123          * @returns  The Instance pointer associated with this Endpoint.
124          */
125         Instance &GetInstance(void) const;
126 
127         /**
128          * Obtains the context pointer that was associated this Endpoint upon
129          * initialization.
130          *
131          * @sa otTcpEndpointGetContext
132          *
133          * @returns  The context pointer associated with this Endpoint.
134          */
GetContext(void)135         void *GetContext(void) { return mContext; }
136 
137         /**
138          * Obtains a pointer to a TCP endpoint's local host and port.
139          *
140          * The contents of the host and port may be stale if this socket is not in a
141          * connected state and has not been bound after it was last disconnected.
142          *
143          * @sa otTcpGetLocalAddress
144          *
145          * @returns  The local host and port of this Endpoint.
146          */
147         const SockAddr &GetLocalAddress(void) const;
148 
149         /**
150          * Obtains a pointer to a TCP endpoint's peer's host and port.
151          *
152          * The contents of the host and port may be stale if this socket is not in a
153          * connected state.
154          *
155          * @sa otTcpGetPeerAddress
156          *
157          * @returns  The host and port of the connection peer of this Endpoint.
158          */
159         const SockAddr &GetPeerAddress(void) const;
160 
161         /**
162          * Binds the TCP endpoint to an IP address and port.
163          *
164          * @sa otTcpBind
165          *
166          * @param[in]  aSockName   The address and port to which to bind this TCP endpoint.
167          *
168          * @retval kErrorNone    Successfully bound the TCP endpoint.
169          * @retval kErrorFailed  Failed to bind the TCP endpoint.
170          */
171         Error Bind(const SockAddr &aSockName);
172 
173         /**
174          * Records the remote host and port for this connection.
175          *
176          * By default TCP Fast Open is used. This means that this function merely
177          * records the remote host and port, and that the TCP connection establishment
178          * handshake only happens on the first call to otTcpSendByReference(). TCP Fast
179          * Open can be explicitly disabled using @p aFlags, in which case the TCP
180          * connection establishment handshake is initiated immediately.
181          *
182          * @sa otTcpConnect
183          *
184          * @param[in]  aSockName  The IP address and port of the host to which to connect.
185          * @param[in]  aFlags     Flags specifying options for this operation (see enumeration above).
186          *
187          * @retval kErrorNone    Successfully completed the operation.
188          * @retval kErrorFailed  Failed to complete the operation.
189          */
190         Error Connect(const SockAddr &aSockName, uint32_t aFlags);
191 
192         /**
193          * Adds data referenced by the linked buffer pointed to by @p aBuffer to the
194          * send buffer.
195          *
196          * Upon a successful call to this function, the linked buffer and data it
197          * references are owned by the TCP stack; they should not be modified by the
198          * application until a "send done" callback returns ownership of those objects
199          * to the application. It is acceptable to call this function to add another
200          * linked buffer to the send queue, even if the "send done" callback for a
201          * previous invocation of this function has not yet fired.
202          *
203          * Note that @p aBuffer should not be chained; its mNext field should be
204          * NULL. If additional data will be added right after this call, then the
205          * OT_TCP_SEND_MORE_TO_COME flag should be used as a hint to the TCP
206          * implementation.
207          *
208          * @sa otTcpSendByReference
209          *
210          * @param[in]  aBuffer    A pointer to the linked buffer chain referencing data to add to the send buffer.
211          * @param[in]  aFlags     Flags specifying options for this operation (see enumeration above).
212          *
213          * @retval kErrorNone    Successfully added data to the send buffer.
214          * @retval kErrorFailed  Failed to add data to the send buffer.
215          */
216         Error SendByReference(otLinkedBuffer &aBuffer, uint32_t aFlags);
217 
218         /**
219          * Adds data to the send buffer by extending the length of the final
220          * otLinkedBuffer in the send buffer by the specified amount.
221          *
222          * If the send buffer is empty, then the operation fails.
223          *
224          * @sa otTcpSendByExtension
225          *
226          * @param[in]  aNumBytes  The number of bytes by which to extend the length of the final linked buffer.
227          * @param[in]  aFlags     Flags specifying options for this operation (see enumeration above).
228          *
229          * @retval kErrorNone    Successfully added data to the send buffer.
230          * @retval kErrorFailed  Failed to add data to the send buffer.
231          */
232         Error SendByExtension(size_t aNumBytes, uint32_t aFlags);
233 
234         /**
235          * Provides the application with a linked buffer chain referencing data
236          * currently in the TCP receive buffer.
237          *
238          * The linked buffer chain is valid until the "receive ready" callback is next
239          * invoked, or until the next call to otTcpReceiveContiguify() or
240          * otTcpCommitReceive().
241          *
242          * @sa otTcpReceiveByReference
243          *
244          * @param[out]  aBuffer    A pointer to the linked buffer chain referencing data currently in the receive
245          * buffer.
246          *
247          * @retval kErrorNone    Successfully completed the operation.
248          * @retval kErrorFailed  Failed to complete the operation.
249          */
250         Error ReceiveByReference(const otLinkedBuffer *&aBuffer);
251 
252         /**
253          * Reorganizes the receive buffer to be entirely contiguous in memory.
254          *
255          * This is optional; an application can simply traverse the linked buffer
256          * chain obtained by calling @p otTcpReceiveByReference. Some
257          * applications may wish to call this function to make the receive buffer
258          * contiguous to simplify their data processing, but this comes at the expense
259          * of CPU time to reorganize the data in the receive buffer.
260          *
261          * @sa otTcpReceiveContiguify
262          *
263          * @retval kErrorNone    Successfully completed the operation.
264          * @retval kErrorFailed  Failed to complete the operation.
265          */
266         Error ReceiveContiguify(void);
267 
268         /**
269          * Informs the TCP stack that the application has finished processing
270          * @p aNumBytes bytes of data at the start of the receive buffer and that the
271          * TCP stack need not continue maintaining those bytes in the receive buffer.
272          *
273          * @sa otTcpCommitReceive
274          *
275          * @param[in]  aNumBytes  The number of bytes consumed.
276          * @param[in]  aFlags     Flags specifying options for this operation (none yet).
277          *
278          * @retval kErrorNone    Successfully completed the receive operation.
279          * @retval kErrorFailed  Failed to complete the receive operation.
280          */
281         Error CommitReceive(size_t aNumBytes, uint32_t aFlags);
282 
283         /**
284          * Informs the connection peer that this TCP endpoint will not send more data.
285          *
286          * This should be used when the application has no more data to send to the
287          * connection peer. For this connection, future reads on the connection peer
288          * will result in the "end of stream" condition, and future writes on this
289          * connection endpoint will fail.
290          *
291          * The "end of stream" condition only applies after any data previously
292          * provided to the TCP stack to send out has been received by the connection
293          * peer.
294          *
295          * @sa otTcpSendEndOfStream
296          *
297          * @retval kErrorNone    Successfully queued the "end of stream" condition for transmission.
298          * @retval kErrorFailed  Failed to queue the "end of stream" condition for transmission.
299          */
300         Error SendEndOfStream(void);
301 
302         /**
303          * Forcibly ends the TCP connection associated with this TCP endpoint.
304          *
305          * This immediately makes the TCP endpoint free for use for another connection
306          * and empties the send and receive buffers, transferring ownership of any data
307          * provided by the application in otTcpSendByReference() calls back to
308          * the application. The TCP endpoint's callbacks and memory for the receive
309          * buffer remain associated with the TCP endpoint.
310          *
311          * @sa otTcpAbort
312          *
313          * @retval kErrorNone    Successfully aborted the TCP endpoint's connection.
314          * @retval kErrorFailed  Failed to abort the TCP endpoint's connection.
315          */
316         Error Abort(void);
317 
318         /**
319          * Deinitializes this TCP endpoint.
320          *
321          * This means that OpenThread no longer keeps track of this TCP endpoint and
322          * deallocates all resources it has internally allocated for this TCP endpoint.
323          * The application can reuse the memory backing the TCP endpoint as it sees fit.
324          *
325          * If it corresponds to a live TCP connection, the connection is terminated
326          * unceremoniously (as in otTcpAbort()). All resources the application has
327          * provided for this TCP endpoint (linked buffers for the send buffer, memory
328          * for the receive buffer, this Endpoint structure itself, etc.) are
329          * immediately returned to the application.
330          *
331          * @sa otTcpEndpointDeinitialize
332          *
333          * @retval kErrorNone    Successfully deinitialized the TCP endpoint.
334          * @retval kErrorFailed  Failed to deinitialize the TCP endpoint.
335          */
336         Error Deinitialize(void);
337 
338         /**
339          * Converts a reference to a struct tcpcb to a reference to its
340          * enclosing Endpoint.
341          */
FromTcb(struct tcpcb & aTcb)342         static Endpoint &FromTcb(struct tcpcb &aTcb) { return *reinterpret_cast<Endpoint *>(&aTcb); }
343 
344         /**
345          * Obtains a reference to this Endpoint's struct tcpcb.
346          */
GetTcb(void)347         struct tcpcb &GetTcb(void) { return *reinterpret_cast<struct tcpcb *>(&mTcb); }
348 
349         /**
350          * Obtains a const reference to this Endpoint's struct tcpcb.
351          */
GetTcb(void) const352         const struct tcpcb &GetTcb(void) const { return *reinterpret_cast<const struct tcpcb *>(&mTcb); }
353 
354         /**
355          * Checks if this Endpoint is in the closed state.
356          */
357         bool IsClosed(void) const;
358 
359     private:
360         friend void ::tcplp_sys_set_timer(struct tcpcb *aTcb, uint8_t aTimerFlag, uint32_t aDelay);
361         friend void ::tcplp_sys_stop_timer(struct tcpcb *aTcb, uint8_t aTimerFlag);
362 
363         static constexpr uint8_t kTimerDelack       = 0;
364         static constexpr uint8_t kTimerRexmtPersist = 1;
365         static constexpr uint8_t kTimerKeep         = 2;
366         static constexpr uint8_t kTimer2Msl         = 3;
367         static constexpr uint8_t kNumTimers         = 4;
368 
369         static uint8_t TimerFlagToIndex(uint8_t aTimerFlag);
370 
371         bool IsTimerActive(uint8_t aTimerIndex);
372         void SetTimer(uint8_t aTimerFlag, uint32_t aDelay);
373         void CancelTimer(uint8_t aTimerFlag);
374         bool FirePendingTimers(TimeMilli aNow, bool &aHasFutureTimer, TimeMilli &aEarliestFutureExpiry);
375 
376         void PostCallbacksAfterSend(size_t aSent, size_t aBacklogBefore);
377         bool FirePendingCallbacks(void);
378 
379         size_t GetSendBufferBytes(void) const;
380         size_t GetInFlightBytes(void) const;
381         size_t GetBacklogBytes(void) const;
382 
383         Address       &GetLocalIp6Address(void);
384         const Address &GetLocalIp6Address(void) const;
385         Address       &GetForeignIp6Address(void);
386         const Address &GetForeignIp6Address(void) const;
387         bool           Matches(const MessageInfo &aMessageInfo) const;
388     };
389 
390     /**
391      * Represents a TCP/IPv6 listener.
392      */
393     class Listener : public otTcpListener, public LinkedListEntry<Listener>, public GetProvider<Listener>
394     {
395         friend class LinkedList<Listener>;
396 
397     public:
398         /**
399          * Initializes a TCP listener.
400          *
401          * Calling this function causes OpenThread to keep track of the TCP listener
402          * and store and retrieve TCP data inside this Listener. The application should
403          * refrain from directly accessing or modifying the fields in this Listener. If
404          * the application needs to reclaim the memory backing this Listener, it should
405          * call otTcpListenerDeinitialize().
406          *
407          * @sa otTcpListenerInitialize
408          *
409          * @param[in]  aInstance  A pointer to an OpenThread instance.
410          * @param[in]  aArgs      A pointer to a structure of arguments.
411          *
412          * @retval kErrorNone    Successfully opened the TCP listener.
413          * @retval kErrorFailed  Failed to open the TCP listener.
414          */
415         Error Initialize(Instance &aInstance, const otTcpListenerInitializeArgs &aArgs);
416 
417         /**
418          * Obtains the otInstance that was associated with this Listener upon
419          * initialization.
420          *
421          * @sa otTcpListenerGetInstance
422          *
423          * @returns  The otInstance pointer associated with this Listener.
424          */
425         Instance &GetInstance(void) const;
426 
427         /**
428          * Obtains the context pointer that was associated with this Listener upon
429          * initialization.
430          *
431          * @sa otTcpListenerGetContext
432          *
433          * @returns  The context pointer associated with this Listener.
434          */
GetContext(void)435         void *GetContext(void) { return mContext; }
436 
437         /**
438          * Causes incoming TCP connections that match the specified IP address and port
439          * to trigger this TCP listener's callbacks.
440          *
441          * @sa otTcpListen
442          *
443          * @param[in]  aSockName  The address and port on which to listen for incoming connections.
444          *
445          * @retval kErrorNone    Successfully initiated listening on the TCP listener.
446          * @retval kErrorFailed  Failed to initiate listening on the TCP listener.
447          */
448         Error Listen(const SockAddr &aSockName);
449 
450         /**
451          * Causes this TCP listener to stop listening for incoming connections.
452          *
453          * @sa otTcpStopListening
454          *
455          * @retval kErrorNone    Successfully stopped listening on the TCP listener.
456          * @retval kErrorFailed  Failed to stop listening on the TCP listener.
457          */
458         Error StopListening(void);
459 
460         /**
461          * Deinitializes this TCP listener.
462          *
463          * This means that OpenThread no longer keeps track of this TCP listener and
464          * deallocates all resources it has internally allocated for this TCP endpoint.
465          * The application can reuse the memory backing the TCP listener as it sees
466          * fit.
467          *
468          * If the TCP listener is currently listening, it stops listening.
469          *
470          * @sa otTcpListenerDeinitialize
471          *
472          * @retval kErrorNone    Successfully deinitialized the TCP listener.
473          * @retval kErrorFailed  Failed to deinitialize the TCP listener.
474          */
475         Error Deinitialize(void);
476 
477         /**
478          * Converts a reference to a struct tcpcb_listen to a reference to its
479          * enclosing Listener.
480          */
FromTcbListen(struct tcpcb_listen & aTcbListen)481         static Listener &FromTcbListen(struct tcpcb_listen &aTcbListen)
482         {
483             return *reinterpret_cast<Listener *>(&aTcbListen);
484         }
485 
486         /**
487          * Obtains a reference to this Listener's struct tcpcb_listen.
488          */
GetTcbListen(void)489         struct tcpcb_listen &GetTcbListen(void) { return *reinterpret_cast<struct tcpcb_listen *>(&mTcbListen); }
490 
491         /**
492          * Obtains a const reference to this Listener's struct tcpcb_listen.
493          */
GetTcbListen(void) const494         const struct tcpcb_listen &GetTcbListen(void) const
495         {
496             return *reinterpret_cast<const struct tcpcb_listen *>(&mTcbListen);
497         }
498 
499         /**
500          * Checks if this Listener is in the closed state.
501          */
502         bool IsClosed(void) const;
503 
504     private:
505         Address       &GetLocalIp6Address(void);
506         const Address &GetLocalIp6Address(void) const;
507         bool           Matches(const MessageInfo &aMessageInfo) const;
508     };
509 
510     /**
511      * Implements TCP header parsing.
512      */
513     OT_TOOL_PACKED_BEGIN
514     class Header : public Clearable<Header>
515     {
516     public:
517         static constexpr uint8_t kChecksumFieldOffset = 16; ///< Byte offset of the Checksum field in the TCP header.
518 
519         /**
520          * Returns the TCP Source Port.
521          *
522          * @returns The TCP Source Port.
523          */
GetSourcePort(void) const524         uint16_t GetSourcePort(void) const { return BigEndian::HostSwap16(mSource); }
525 
526         /**
527          * Returns the TCP Destination Port.
528          *
529          * @returns The TCP Destination Port.
530          */
GetDestinationPort(void) const531         uint16_t GetDestinationPort(void) const { return BigEndian::HostSwap16(mDestination); }
532 
533         /**
534          * Sets the TCP Source Port.
535          *
536          * @param[in]  aPort  The TCP Source Port.
537          */
SetSourcePort(uint16_t aPort)538         void SetSourcePort(uint16_t aPort) { mSource = BigEndian::HostSwap16(aPort); }
539 
540         /**
541          * Sets the TCP Destination Port.
542          *
543          * @param[in]  aPort  The TCP Destination Port.
544          */
SetDestinationPort(uint16_t aPort)545         void SetDestinationPort(uint16_t aPort) { mDestination = BigEndian::HostSwap16(aPort); }
546 
547         /**
548          * Returns the TCP Sequence Number.
549          *
550          * @returns The TCP Sequence Number.
551          */
GetSequenceNumber(void) const552         uint32_t GetSequenceNumber(void) const { return BigEndian::HostSwap32(mSequenceNumber); }
553 
554         /**
555          * Returns the TCP Acknowledgment Sequence Number.
556          *
557          * @returns The TCP Acknowledgment Sequence Number.
558          */
GetAcknowledgmentNumber(void) const559         uint32_t GetAcknowledgmentNumber(void) const { return BigEndian::HostSwap32(mAckNumber); }
560 
561         /**
562          * Returns the TCP Flags.
563          *
564          * @returns The TCP Flags.
565          */
GetFlags(void) const566         uint16_t GetFlags(void) const { return BigEndian::HostSwap16(mFlags); }
567 
568         /**
569          * Returns the TCP Window.
570          *
571          * @returns The TCP Window.
572          */
GetWindow(void) const573         uint16_t GetWindow(void) const { return BigEndian::HostSwap16(mWindow); }
574 
575         /**
576          * Returns the TCP Checksum.
577          *
578          * @returns The TCP Checksum.
579          */
GetChecksum(void) const580         uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mChecksum); }
581 
582         /**
583          * Returns the TCP Urgent Pointer.
584          *
585          * @returns The TCP Urgent Pointer.
586          */
GetUrgentPointer(void) const587         uint16_t GetUrgentPointer(void) const { return BigEndian::HostSwap16(mUrgentPointer); }
588 
589     private:
590         uint16_t mSource;
591         uint16_t mDestination;
592         uint32_t mSequenceNumber;
593         uint32_t mAckNumber;
594         uint16_t mFlags;
595         uint16_t mWindow;
596         uint16_t mChecksum;
597         uint16_t mUrgentPointer;
598     } OT_TOOL_PACKED_END;
599 
600     /**
601      * Initializes the object.
602      *
603      * @param[in] aInstance  A reference to the OpenThread instance.
604      */
605     explicit Tcp(Instance &aInstance);
606 
607     /**
608      * Processes a received TCP segment.
609      *
610      * @param[in]  aIp6Header    A reference to a structure containing the segment's IPv6 header.
611      * @param[in]  aMessage      A reference to the message containing the TCP segment.
612      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
613      *
614      * @retval kErrorNone  Successfully processed the TCP segment.
615      * @retval kErrorDrop  Dropped the TCP segment due to an invalid checksum.
616      */
617     Error HandleMessage(ot::Ip6::Header &aIp6Header, Message &aMessage, MessageInfo &aMessageInfo);
618 
619     /**
620      * Automatically selects a local address and/or port for communication with the specified peer.
621      *
622      * @param[in] aPeer         The peer's address and port.
623      * @param[in,out] aToBind   The SockAddr into which to store the selected address and/or port.
624      * @param[in] aBindAddress  If true, the local address is selected; if not, the current address
625      *                          in @p aToBind is treated as a given.
626      * @param[in] aBindPort     If true, the local port is selected; if not, the current port in
627      *                          @p aToBind is treated as a given.
628      *
629      * @returns  True if successful, false otherwise.
630      */
631     bool AutoBind(const SockAddr &aPeer, SockAddr &aToBind, bool aBindAddress, bool aBindPort);
632 
633     /**
634      * Checks if an Endpoint is in the list of initialized endpoints.
635      */
IsInitialized(const Endpoint & aEndpoint) const636     bool IsInitialized(const Endpoint &aEndpoint) const { return mEndpoints.Contains(aEndpoint); }
637 
638     /**
639      * Checks if a Listener is in the list of initialized Listeners.
640      */
IsInitialized(const Listener & aListener) const641     bool IsInitialized(const Listener &aListener) const { return mListeners.Contains(aListener); }
642 
643 private:
644     enum
645     {
646         kDynamicPortMin = 49152, ///< Service Name and Transport Protocol Port Number Registry
647         kDynamicPortMax = 65535, ///< Service Name and Transport Protocol Port Number Registry
648     };
649 
650     static constexpr uint8_t kEstablishedCallbackFlag      = (1 << 0);
651     static constexpr uint8_t kSendDoneCallbackFlag         = (1 << 1);
652     static constexpr uint8_t kForwardProgressCallbackFlag  = (1 << 2);
653     static constexpr uint8_t kReceiveAvailableCallbackFlag = (1 << 3);
654     static constexpr uint8_t kDisconnectedCallbackFlag     = (1 << 4);
655 
656     void ProcessSignals(Endpoint             &aEndpoint,
657                         otLinkedBuffer       *aPriorHead,
658                         size_t                aPriorBacklog,
659                         struct tcplp_signals &aSignals) const;
660 
661     static Error BsdErrorToOtError(int aBsdError);
662     bool         CanBind(const SockAddr &aSockName);
663 
664     void HandleTimer(void);
665 
666     void ProcessCallbacks(void);
667 
668     using TcpTasklet = TaskletIn<Tcp, &Tcp::ProcessCallbacks>;
669     using TcpTimer   = TimerMilliIn<Tcp, &Tcp::HandleTimer>;
670 
671     TcpTimer   mTimer;
672     TcpTasklet mTasklet;
673 
674     LinkedList<Endpoint> mEndpoints;
675     LinkedList<Listener> mListeners;
676     uint16_t             mEphemeralPort;
677 };
678 
679 } // namespace Ip6
680 
681 DefineCoreType(otTcpEndpoint, Ip6::Tcp::Endpoint);
682 DefineCoreType(otTcpListener, Ip6::Tcp::Listener);
683 
684 } // namespace ot
685 
686 #endif // TCP6_HPP_
687