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