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         enum : uint8_t
364         {
365             kTimerDelack       = 0,
366             kTimerRexmtPersist = 1,
367             kTimerKeep         = 2,
368             kTimer2Msl         = 3,
369             kNumTimers         = 4,
370         };
371 
372         static uint8_t TimerFlagToIndex(uint8_t aTimerFlag);
373 
374         bool IsTimerActive(uint8_t aTimerIndex);
375         void SetTimer(uint8_t aTimerFlag, uint32_t aDelay);
376         void CancelTimer(uint8_t aTimerFlag);
377         bool FirePendingTimers(TimeMilli aNow, bool &aHasFutureTimer, TimeMilli &aEarliestFutureExpiry);
378 
379         void PostCallbacksAfterSend(size_t aSent, size_t aBacklogBefore);
380         bool FirePendingCallbacks(void);
381 
382         size_t GetSendBufferBytes(void) const;
383         size_t GetInFlightBytes(void) const;
384         size_t GetBacklogBytes(void) const;
385 
386         Address       &GetLocalIp6Address(void);
387         const Address &GetLocalIp6Address(void) const;
388         Address       &GetForeignIp6Address(void);
389         const Address &GetForeignIp6Address(void) const;
390         bool           Matches(const MessageInfo &aMessageInfo) const;
391     };
392 
393     /**
394      * Represents a TCP/IPv6 listener.
395      */
396     class Listener : public otTcpListener, public LinkedListEntry<Listener>, public GetProvider<Listener>
397     {
398         friend class LinkedList<Listener>;
399 
400     public:
401         /**
402          * Initializes a TCP listener.
403          *
404          * Calling this function causes OpenThread to keep track of the TCP listener
405          * and store and retrieve TCP data inside this Listener. The application should
406          * refrain from directly accessing or modifying the fields in this Listener. If
407          * the application needs to reclaim the memory backing this Listener, it should
408          * call otTcpListenerDeinitialize().
409          *
410          * @sa otTcpListenerInitialize
411          *
412          * @param[in]  aInstance  A pointer to an OpenThread instance.
413          * @param[in]  aArgs      A pointer to a structure of arguments.
414          *
415          * @retval kErrorNone    Successfully opened the TCP listener.
416          * @retval kErrorFailed  Failed to open the TCP listener.
417          */
418         Error Initialize(Instance &aInstance, const otTcpListenerInitializeArgs &aArgs);
419 
420         /**
421          * Obtains the otInstance that was associated with this Listener upon
422          * initialization.
423          *
424          * @sa otTcpListenerGetInstance
425          *
426          * @returns  The otInstance pointer associated with this Listener.
427          */
428         Instance &GetInstance(void) const;
429 
430         /**
431          * Obtains the context pointer that was associated with this Listener upon
432          * initialization.
433          *
434          * @sa otTcpListenerGetContext
435          *
436          * @returns  The context pointer associated with this Listener.
437          */
GetContext(void)438         void *GetContext(void) { return mContext; }
439 
440         /**
441          * Causes incoming TCP connections that match the specified IP address and port
442          * to trigger this TCP listener's callbacks.
443          *
444          * @sa otTcpListen
445          *
446          * @param[in]  aSockName  The address and port on which to listen for incoming connections.
447          *
448          * @retval kErrorNone    Successfully initiated listening on the TCP listener.
449          * @retval kErrorFailed  Failed to initiate listening on the TCP listener.
450          */
451         Error Listen(const SockAddr &aSockName);
452 
453         /**
454          * Causes this TCP listener to stop listening for incoming connections.
455          *
456          * @sa otTcpStopListening
457          *
458          * @retval kErrorNone    Successfully stopped listening on the TCP listener.
459          * @retval kErrorFailed  Failed to stop listening on the TCP listener.
460          */
461         Error StopListening(void);
462 
463         /**
464          * Deinitializes this TCP listener.
465          *
466          * This means that OpenThread no longer keeps track of this TCP listener and
467          * deallocates all resources it has internally allocated for this TCP endpoint.
468          * The application can reuse the memory backing the TCP listener as it sees
469          * fit.
470          *
471          * If the TCP listener is currently listening, it stops listening.
472          *
473          * @sa otTcpListenerDeinitialize
474          *
475          * @retval kErrorNone    Successfully deinitialized the TCP listener.
476          * @retval kErrorFailed  Failed to deinitialize the TCP listener.
477          */
478         Error Deinitialize(void);
479 
480         /**
481          * Converts a reference to a struct tcpcb_listen to a reference to its
482          * enclosing Listener.
483          */
FromTcbListen(struct tcpcb_listen & aTcbListen)484         static Listener &FromTcbListen(struct tcpcb_listen &aTcbListen)
485         {
486             return *reinterpret_cast<Listener *>(&aTcbListen);
487         }
488 
489         /**
490          * Obtains a reference to this Listener's struct tcpcb_listen.
491          */
GetTcbListen(void)492         struct tcpcb_listen &GetTcbListen(void) { return *reinterpret_cast<struct tcpcb_listen *>(&mTcbListen); }
493 
494         /**
495          * Obtains a const reference to this Listener's struct tcpcb_listen.
496          */
GetTcbListen(void) const497         const struct tcpcb_listen &GetTcbListen(void) const
498         {
499             return *reinterpret_cast<const struct tcpcb_listen *>(&mTcbListen);
500         }
501 
502         /**
503          * Checks if this Listener is in the closed state.
504          */
505         bool IsClosed(void) const;
506 
507     private:
508         Address       &GetLocalIp6Address(void);
509         const Address &GetLocalIp6Address(void) const;
510         bool           Matches(const MessageInfo &aMessageInfo) const;
511     };
512 
513     /**
514      * Implements TCP header parsing.
515      */
516     OT_TOOL_PACKED_BEGIN
517     class Header : public Clearable<Header>
518     {
519     public:
520         static constexpr uint8_t kChecksumFieldOffset = 16; ///< Byte offset of the Checksum field in the TCP header.
521 
522         /**
523          * Returns the TCP Source Port.
524          *
525          * @returns The TCP Source Port.
526          */
GetSourcePort(void) const527         uint16_t GetSourcePort(void) const { return BigEndian::HostSwap16(mSource); }
528 
529         /**
530          * Returns the TCP Destination Port.
531          *
532          * @returns The TCP Destination Port.
533          */
GetDestinationPort(void) const534         uint16_t GetDestinationPort(void) const { return BigEndian::HostSwap16(mDestination); }
535 
536         /**
537          * Returns the TCP Sequence Number.
538          *
539          * @returns The TCP Sequence Number.
540          */
GetSequenceNumber(void) const541         uint32_t GetSequenceNumber(void) const { return BigEndian::HostSwap32(mSequenceNumber); }
542 
543         /**
544          * Returns the TCP Acknowledgment Sequence Number.
545          *
546          * @returns The TCP Acknowledgment Sequence Number.
547          */
GetAcknowledgmentNumber(void) const548         uint32_t GetAcknowledgmentNumber(void) const { return BigEndian::HostSwap32(mAckNumber); }
549 
550         /**
551          * Returns the TCP Flags.
552          *
553          * @returns The TCP Flags.
554          */
GetFlags(void) const555         uint16_t GetFlags(void) const { return BigEndian::HostSwap16(mFlags); }
556 
557         /**
558          * Returns the TCP Window.
559          *
560          * @returns The TCP Window.
561          */
GetWindow(void) const562         uint16_t GetWindow(void) const { return BigEndian::HostSwap16(mWindow); }
563 
564         /**
565          * Returns the TCP Checksum.
566          *
567          * @returns The TCP Checksum.
568          */
GetChecksum(void) const569         uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mChecksum); }
570 
571         /**
572          * Returns the TCP Urgent Pointer.
573          *
574          * @returns The TCP Urgent Pointer.
575          */
GetUrgentPointer(void) const576         uint16_t GetUrgentPointer(void) const { return BigEndian::HostSwap16(mUrgentPointer); }
577 
578     private:
579         uint16_t mSource;
580         uint16_t mDestination;
581         uint32_t mSequenceNumber;
582         uint32_t mAckNumber;
583         uint16_t mFlags;
584         uint16_t mWindow;
585         uint16_t mChecksum;
586         uint16_t mUrgentPointer;
587     } OT_TOOL_PACKED_END;
588 
589     /**
590      * Initializes the object.
591      *
592      * @param[in] aInstance  A reference to the OpenThread instance.
593      */
594     explicit Tcp(Instance &aInstance);
595 
596     /**
597      * Processes a received TCP segment.
598      *
599      * @param[in]  aIp6Header    A reference to a structure containing the segment's IPv6 header.
600      * @param[in]  aMessage      A reference to the message containing the TCP segment.
601      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
602      *
603      * @retval kErrorNone  Successfully processed the TCP segment.
604      * @retval kErrorDrop  Dropped the TCP segment due to an invalid checksum.
605      */
606     Error HandleMessage(ot::Ip6::Header &aIp6Header, Message &aMessage, MessageInfo &aMessageInfo);
607 
608     /**
609      * Automatically selects a local address and/or port for communication with the specified peer.
610      *
611      * @param[in] aPeer         The peer's address and port.
612      * @param[in,out] aToBind   The SockAddr into which to store the selected address and/or port.
613      * @param[in] aBindAddress  If true, the local address is selected; if not, the current address
614      *                          in @p aToBind is treated as a given.
615      * @param[in] aBindPort     If true, the local port is selected; if not, the current port in
616      *                          @p aToBind is treated as a given.
617      *
618      * @returns  True if successful, false otherwise.
619      */
620     bool AutoBind(const SockAddr &aPeer, SockAddr &aToBind, bool aBindAddress, bool aBindPort);
621 
622     /**
623      * Checks if an Endpoint is in the list of initialized endpoints.
624      */
IsInitialized(const Endpoint & aEndpoint) const625     bool IsInitialized(const Endpoint &aEndpoint) const { return mEndpoints.Contains(aEndpoint); }
626 
627     /**
628      * Checks if a Listener is in the list of initialized Listeners.
629      */
IsInitialized(const Listener & aListener) const630     bool IsInitialized(const Listener &aListener) const { return mListeners.Contains(aListener); }
631 
632 private:
633     enum
634     {
635         kDynamicPortMin = 49152, ///< Service Name and Transport Protocol Port Number Registry
636         kDynamicPortMax = 65535, ///< Service Name and Transport Protocol Port Number Registry
637     };
638 
639     static constexpr uint8_t kEstablishedCallbackFlag      = (1 << 0);
640     static constexpr uint8_t kSendDoneCallbackFlag         = (1 << 1);
641     static constexpr uint8_t kForwardProgressCallbackFlag  = (1 << 2);
642     static constexpr uint8_t kReceiveAvailableCallbackFlag = (1 << 3);
643     static constexpr uint8_t kDisconnectedCallbackFlag     = (1 << 4);
644 
645     void ProcessSignals(Endpoint             &aEndpoint,
646                         otLinkedBuffer       *aPriorHead,
647                         size_t                aPriorBacklog,
648                         struct tcplp_signals &aSignals) const;
649 
650     static Error BsdErrorToOtError(int aBsdError);
651     bool         CanBind(const SockAddr &aSockName);
652 
653     void HandleTimer(void);
654 
655     void ProcessCallbacks(void);
656 
657     using TcpTasklet = TaskletIn<Tcp, &Tcp::ProcessCallbacks>;
658     using TcpTimer   = TimerMilliIn<Tcp, &Tcp::HandleTimer>;
659 
660     TcpTimer   mTimer;
661     TcpTasklet mTasklet;
662 
663     LinkedList<Endpoint> mEndpoints;
664     LinkedList<Listener> mListeners;
665     uint16_t             mEphemeralPort;
666 };
667 
668 } // namespace Ip6
669 
670 DefineCoreType(otTcpEndpoint, Ip6::Tcp::Endpoint);
671 DefineCoreType(otTcpListener, Ip6::Tcp::Listener);
672 
673 } // namespace ot
674 
675 #endif // TCP6_HPP_
676