1 /*
2  *  Copyright (c) 2016, 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 UDP/IPv6 sockets.
32  */
33 
34 #ifndef UDP6_HPP_
35 #define UDP6_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <openthread/udp.h>
40 #include <openthread/platform/udp.h>
41 
42 #include "common/as_core_type.hpp"
43 #include "common/callback.hpp"
44 #include "common/clearable.hpp"
45 #include "common/linked_list.hpp"
46 #include "common/locator.hpp"
47 #include "common/non_copyable.hpp"
48 #include "net/ip6_headers.hpp"
49 
50 namespace ot {
51 namespace Ip6 {
52 
53 class Udp;
54 
55 /**
56  * @addtogroup core-udp
57  *
58  * @brief
59  *   This module includes definitions for UDP/IPv6 sockets.
60  *
61  * @{
62  *
63  */
64 
65 #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE && OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
66 #error "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE and OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE must not both be set."
67 #endif
68 
69 /**
70  * Defines the network interface identifiers.
71  *
72  */
73 enum NetifIdentifier : uint8_t
74 {
75     kNetifUnspecified = OT_NETIF_UNSPECIFIED, ///< Unspecified network interface.
76     kNetifThread      = OT_NETIF_THREAD,      ///< The Thread interface.
77     kNetifBackbone    = OT_NETIF_BACKBONE,    ///< The Backbone interface.
78 };
79 
80 /**
81  * Implements core UDP message handling.
82  *
83  */
84 class Udp : public InstanceLocator, private NonCopyable
85 {
86 public:
87     /**
88      * Implements a UDP/IPv6 socket.
89      *
90      */
91     class SocketHandle : public otUdpSocket, public LinkedListEntry<SocketHandle>, public Clearable<SocketHandle>
92     {
93         friend class Udp;
94         friend class LinkedList<SocketHandle>;
95 
96     public:
97         /**
98          * Indicates whether or not the socket is bound.
99          *
100          * @retval TRUE if the socket is bound (i.e. source port is non-zero).
101          * @retval FALSE if the socket is not bound (source port is zero).
102          *
103          */
IsBound(void) const104         bool IsBound(void) const { return mSockName.mPort != 0; }
105 
106         /**
107          * Returns the local socket address.
108          *
109          * @returns A reference to the local socket address.
110          *
111          */
GetSockName(void)112         SockAddr &GetSockName(void) { return AsCoreType(&mSockName); }
113 
114         /**
115          * Returns the local socket address.
116          *
117          * @returns A reference to the local socket address.
118          *
119          */
GetSockName(void) const120         const SockAddr &GetSockName(void) const { return AsCoreType(&mSockName); }
121 
122         /**
123          * Returns the peer's socket address.
124          *
125          * @returns A reference to the peer's socket address.
126          *
127          */
GetPeerName(void)128         SockAddr &GetPeerName(void) { return AsCoreType(&mPeerName); }
129 
130         /**
131          * Returns the peer's socket address.
132          *
133          * @returns A reference to the peer's socket address.
134          *
135          */
GetPeerName(void) const136         const SockAddr &GetPeerName(void) const { return AsCoreType(&mPeerName); }
137 
138     private:
139         bool Matches(const MessageInfo &aMessageInfo) const;
140 
HandleUdpReceive(Message & aMessage,const MessageInfo & aMessageInfo)141         void HandleUdpReceive(Message &aMessage, const MessageInfo &aMessageInfo)
142         {
143             mHandler(mContext, &aMessage, &aMessageInfo);
144         }
145     };
146 
147     /**
148      * Implements a UDP/IPv6 socket.
149      *
150      */
151     class Socket : public InstanceLocator, public SocketHandle
152     {
153         friend class Udp;
154 
155     public:
156         /**
157          * Initializes the object.
158          *
159          * @param[in]  aInstance  A reference to OpenThread instance.
160          *
161          */
162         explicit Socket(Instance &aInstance);
163 
164         /**
165          * Returns a new UDP message with default settings (link security enabled and `kPriorityNormal`)
166          *
167          * @returns A pointer to the message or `nullptr` if no buffers are available.
168          *
169          */
170         Message *NewMessage(void);
171 
172         /**
173          * Returns a new UDP message with default settings (link security enabled and `kPriorityNormal`)
174          *
175          * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
176          *
177          * @returns A pointer to the message or `nullptr` if no buffers are available.
178          *
179          */
180         Message *NewMessage(uint16_t aReserved);
181 
182         /**
183          * Returns a new UDP message with sufficient header space reserved.
184          *
185          * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
186          * @param[in]  aSettings  The message settings (default is used if not provided).
187          *
188          * @returns A pointer to the message or `nullptr` if no buffers are available.
189          *
190          */
191         Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings);
192 
193         /**
194          * Opens the UDP socket.
195          *
196          * @param[in]  aHandler  A pointer to a function that is called when receiving UDP messages.
197          * @param[in]  aContext  A pointer to arbitrary context information.
198          *
199          * @retval kErrorNone     Successfully opened the socket.
200          * @retval kErrorFailed   Failed to open the socket.
201          *
202          */
203         Error Open(otUdpReceive aHandler, void *aContext);
204 
205         /**
206          * Returns if the UDP socket is open.
207          *
208          * @returns If the UDP socket is open.
209          *
210          */
211         bool IsOpen(void) const;
212 
213         /**
214          * Binds the UDP socket.
215          *
216          * @param[in]  aSockAddr            A reference to the socket address.
217          * @param[in]  aNetifIdentifier     The network interface identifier.
218          *
219          * @retval kErrorNone            Successfully bound the socket.
220          * @retval kErrorInvalidArgs     Unable to bind to Thread network interface with the given address.
221          * @retval kErrorFailed          Failed to bind UDP Socket.
222          *
223          */
224         Error Bind(const SockAddr &aSockAddr, NetifIdentifier aNetifIdentifier = kNetifThread);
225 
226         /**
227          * Binds the UDP socket.
228          *
229          * @param[in]  aPort                A port number.
230          * @param[in]  aNetifIdentifier     The network interface identifier.
231          *
232          * @retval kErrorNone            Successfully bound the socket.
233          * @retval kErrorFailed          Failed to bind UDP Socket.
234          *
235          */
236         Error Bind(uint16_t aPort, NetifIdentifier aNetifIdentifier = kNetifThread);
237 
238         /**
239          * Binds the UDP socket.
240          *
241          * @retval kErrorNone    Successfully bound the socket.
242          * @retval kErrorFailed  Failed to bind UDP Socket.
243          *
244          */
Bind(void)245         Error Bind(void) { return Bind(0); }
246 
247         /**
248          * Connects the UDP socket.
249          *
250          * @param[in]  aSockAddr  A reference to the socket address.
251          *
252          * @retval kErrorNone    Successfully connected the socket.
253          * @retval kErrorFailed  Failed to connect UDP Socket.
254          *
255          */
256         Error Connect(const SockAddr &aSockAddr);
257 
258         /**
259          * Connects the UDP socket.
260          *
261          * @param[in]  aPort        A port number.
262          *
263          * @retval kErrorNone    Successfully connected the socket.
264          * @retval kErrorFailed  Failed to connect UDP Socket.
265          *
266          */
267         Error Connect(uint16_t aPort);
268 
269         /**
270          * Connects the UDP socket.
271          *
272          * @retval kErrorNone    Successfully connected the socket.
273          * @retval kErrorFailed  Failed to connect UDP Socket.
274          *
275          */
Connect(void)276         Error Connect(void) { return Connect(0); }
277 
278         /**
279          * Closes the UDP socket.
280          *
281          * @retval kErrorNone    Successfully closed the UDP socket.
282          * @retval kErrorFailed  Failed to close UDP Socket.
283          *
284          */
285         Error Close(void);
286 
287         /**
288          * Sends a UDP message.
289          *
290          * @param[in]  aMessage      The message to send.
291          * @param[in]  aMessageInfo  The message info associated with @p aMessage.
292          *
293          * @retval kErrorNone         Successfully sent the UDP message.
294          * @retval kErrorInvalidArgs  If no peer is specified in @p aMessageInfo or by Connect().
295          * @retval kErrorNoBufs       Insufficient available buffer to add the UDP and IPv6 headers.
296          *
297          */
298         Error SendTo(Message &aMessage, const MessageInfo &aMessageInfo);
299 
300 #if OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
301         /**
302          * Configures the UDP socket to join a multicast group on a Host network interface.
303          *
304          * @param[in]  aNetifIdentifier     The network interface identifier.
305          * @param[in]  aAddress             The multicast group address.
306          *
307          * @retval  kErrorNone    Successfully joined the multicast group.
308          * @retval  kErrorFailed  Failed to join the multicast group.
309          *
310          */
311         Error JoinNetifMulticastGroup(NetifIdentifier aNetifIdentifier, const Address &aAddress);
312 
313         /**
314          * Configures the UDP socket to leave a multicast group on a Host network interface.
315          *
316          * @param[in]  aNetifIdentifier     The network interface identifier.
317          * @param[in]  aAddress             The multicast group address.
318          *
319          * @retval  kErrorNone   Successfully left the multicast group.
320          * @retval  kErrorFailed Failed to leave the multicast group.
321          *
322          */
323         Error LeaveNetifMulticastGroup(NetifIdentifier aNetifIdentifier, const Address &aAddress);
324 #endif
325     };
326 
327     /**
328      * Implements a UDP receiver.
329      *
330      */
331     class Receiver : public otUdpReceiver, public LinkedListEntry<Receiver>
332     {
333         friend class Udp;
334 
335     public:
336         /**
337          * Initializes the UDP receiver.
338          *
339          * @param[in]   aHandler     A pointer to the function to handle UDP message.
340          * @param[in]   aContext     A pointer to arbitrary context information.
341          *
342          */
Receiver(otUdpHandler aHandler,void * aContext)343         Receiver(otUdpHandler aHandler, void *aContext)
344         {
345             mNext    = nullptr;
346             mHandler = aHandler;
347             mContext = aContext;
348         }
349 
350     private:
HandleMessage(Message & aMessage,const MessageInfo & aMessageInfo)351         bool HandleMessage(Message &aMessage, const MessageInfo &aMessageInfo)
352         {
353             return mHandler(mContext, &aMessage, &aMessageInfo);
354         }
355     };
356 
357     /**
358      * Implements UDP header generation and parsing.
359      *
360      */
361     OT_TOOL_PACKED_BEGIN
362     class Header : public Clearable<Header>
363     {
364     public:
365         static constexpr uint16_t kSourcePortFieldOffset = 0; ///< Byte offset of Source Port field in UDP header.
366         static constexpr uint16_t kDestPortFieldOffset   = 2; ///< Byte offset of Destination Port field in UDP header.
367         static constexpr uint16_t kLengthFieldOffset     = 4; ///< Byte offset of Length field in UDP header.
368         static constexpr uint16_t kChecksumFieldOffset   = 6; ///< Byte offset of Checksum field in UDP header.
369 
370         /**
371          * Returns the UDP Source Port.
372          *
373          * @returns The UDP Source Port.
374          *
375          */
GetSourcePort(void) const376         uint16_t GetSourcePort(void) const { return BigEndian::HostSwap16(mSourcePort); }
377 
378         /**
379          * Sets the UDP Source Port.
380          *
381          * @param[in]  aPort  The UDP Source Port.
382          *
383          */
SetSourcePort(uint16_t aPort)384         void SetSourcePort(uint16_t aPort) { mSourcePort = BigEndian::HostSwap16(aPort); }
385 
386         /**
387          * Returns the UDP Destination Port.
388          *
389          * @returns The UDP Destination Port.
390          *
391          */
GetDestinationPort(void) const392         uint16_t GetDestinationPort(void) const { return BigEndian::HostSwap16(mDestinationPort); }
393 
394         /**
395          * Sets the UDP Destination Port.
396          *
397          * @param[in]  aPort  The UDP Destination Port.
398          *
399          */
SetDestinationPort(uint16_t aPort)400         void SetDestinationPort(uint16_t aPort) { mDestinationPort = BigEndian::HostSwap16(aPort); }
401 
402         /**
403          * Returns the UDP Length.
404          *
405          * @returns The UDP Length.
406          *
407          */
GetLength(void) const408         uint16_t GetLength(void) const { return BigEndian::HostSwap16(mLength); }
409 
410         /**
411          * Sets the UDP Length.
412          *
413          * @param[in]  aLength  The UDP Length.
414          *
415          */
SetLength(uint16_t aLength)416         void SetLength(uint16_t aLength) { mLength = BigEndian::HostSwap16(aLength); }
417 
418         /**
419          * Returns the UDP Checksum.
420          *
421          * @returns The UDP Checksum.
422          *
423          */
GetChecksum(void) const424         uint16_t GetChecksum(void) const { return BigEndian::HostSwap16(mChecksum); }
425 
426         /**
427          * Sets the UDP Checksum.
428          *
429          * @param[in]  aChecksum  The UDP Checksum.
430          *
431          */
SetChecksum(uint16_t aChecksum)432         void SetChecksum(uint16_t aChecksum) { mChecksum = BigEndian::HostSwap16(aChecksum); }
433 
434     private:
435         uint16_t mSourcePort;
436         uint16_t mDestinationPort;
437         uint16_t mLength;
438         uint16_t mChecksum;
439 
440     } OT_TOOL_PACKED_END;
441 
442     /**
443      * Initializes the object.
444      *
445      * @param[in]  aInstance  A reference to OpenThread instance.
446      *
447      */
448     explicit Udp(Instance &aInstance);
449 
450     /**
451      * Adds a UDP receiver.
452      *
453      * @param[in]  aReceiver  A reference to the UDP receiver.
454      *
455      * @retval kErrorNone    Successfully added the UDP receiver.
456      * @retval kErrorAlready The UDP receiver was already added.
457      *
458      */
459     Error AddReceiver(Receiver &aReceiver);
460 
461     /**
462      * Removes a UDP receiver.
463      *
464      * @param[in]  aReceiver  A reference to the UDP receiver.
465      *
466      * @retval kErrorNone       Successfully removed the UDP receiver.
467      * @retval kErrorNotFound   The UDP receiver was not added.
468      *
469      */
470     Error RemoveReceiver(Receiver &aReceiver);
471 
472     /**
473      * Opens a UDP socket.
474      *
475      * @param[in]  aSocket   A reference to the socket.
476      * @param[in]  aHandler  A pointer to a function that is called when receiving UDP messages.
477      * @param[in]  aContext  A pointer to arbitrary context information.
478      *
479      * @retval kErrorNone     Successfully opened the socket.
480      * @retval kErrorFailed   Failed to open the socket.
481      *
482      */
483     Error Open(SocketHandle &aSocket, otUdpReceive aHandler, void *aContext);
484 
485     /**
486      * Returns if a UDP socket is open.
487      *
488      * @param[in]  aSocket   A reference to the socket.
489      *
490      * @returns If the UDP socket is open.
491      *
492      */
IsOpen(const SocketHandle & aSocket) const493     bool IsOpen(const SocketHandle &aSocket) const { return mSockets.Contains(aSocket); }
494 
495     /**
496      * Binds a UDP socket.
497      *
498      * @param[in]  aSocket          A reference to the socket.
499      * @param[in]  aSockAddr        A reference to the socket address.
500      * @param[in]  aNetifIdentifier The network interface identifier.
501      *
502      * @retval kErrorNone            Successfully bound the socket.
503      * @retval kErrorInvalidArgs     Unable to bind to Thread network interface with the given address.
504      * @retval kErrorFailed          Failed to bind UDP Socket.
505      *
506      */
507     Error Bind(SocketHandle &aSocket, const SockAddr &aSockAddr, NetifIdentifier aNetifIdentifier);
508 
509     /**
510      * Connects a UDP socket.
511      *
512      * @param[in]  aSocket    A reference to the socket.
513      * @param[in]  aSockAddr  A reference to the socket address.
514      *
515      * @retval kErrorNone    Successfully connected the socket.
516      * @retval kErrorFailed  Failed to connect UDP Socket.
517      *
518      */
519     Error Connect(SocketHandle &aSocket, const SockAddr &aSockAddr);
520 
521     /**
522      * Closes the UDP socket.
523      *
524      * @param[in]  aSocket    A reference to the socket.
525      *
526      * @retval kErrorNone    Successfully closed the UDP socket.
527      * @retval kErrorFailed  Failed to close UDP Socket.
528      *
529      */
530     Error Close(SocketHandle &aSocket);
531 
532     /**
533      * Sends a UDP message using a socket.
534      *
535      * @param[in]  aSocket       A reference to the socket.
536      * @param[in]  aMessage      The message to send.
537      * @param[in]  aMessageInfo  The message info associated with @p aMessage.
538      *
539      * @retval kErrorNone         Successfully sent the UDP message.
540      * @retval kErrorInvalidArgs  If no peer is specified in @p aMessageInfo or by Connect().
541      * @retval kErrorNoBufs       Insufficient available buffer to add the UDP and IPv6 headers.
542      *
543      */
544     Error SendTo(SocketHandle &aSocket, Message &aMessage, const MessageInfo &aMessageInfo);
545 
546     /**
547      * Returns a new ephemeral port.
548      *
549      * @returns A new ephemeral port.
550      *
551      */
552     uint16_t GetEphemeralPort(void);
553 
554     /**
555      * Returns a new UDP message with default settings (link security enabled and `kPriorityNormal`)
556      *
557      * @returns A pointer to the message or `nullptr` if no buffers are available.
558      *
559      */
560     Message *NewMessage(void);
561 
562     /**
563      * Returns a new UDP message with default settings (link security enabled and `kPriorityNormal`)
564      *
565      * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
566      *
567      * @returns A pointer to the message or `nullptr` if no buffers are available.
568      *
569      */
570     Message *NewMessage(uint16_t aReserved);
571 
572     /**
573      * Returns a new UDP message with sufficient header space reserved.
574      *
575      * @param[in]  aReserved  The number of header bytes to reserve after the UDP header.
576      * @param[in]  aSettings  The message settings.
577      *
578      * @returns A pointer to the message or `nullptr` if no buffers are available.
579      *
580      */
581     Message *NewMessage(uint16_t aReserved, const Message::Settings &aSettings);
582 
583     /**
584      * Sends an IPv6 datagram.
585      *
586      * @param[in]  aMessage      A reference to the message.
587      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
588      *
589      * @retval kErrorNone    Successfully enqueued the message into an output interface.
590      * @retval kErrorNoBufs  Insufficient available buffer to add the IPv6 headers.
591      *
592      */
593     Error SendDatagram(Message &aMessage, MessageInfo &aMessageInfo);
594 
595     /**
596      * Handles a received UDP message.
597      *
598      * @param[in]  aMessage      A reference to the UDP message to process.
599      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
600      *
601      * @retval kErrorNone  Successfully processed the UDP message.
602      * @retval kErrorDrop  Could not fully process the UDP message.
603      *
604      */
605     Error HandleMessage(Message &aMessage, MessageInfo &aMessageInfo);
606 
607     /**
608      * Handles a received UDP message with offset set to the payload.
609      *
610      * @param[in]  aMessage      A reference to the UDP message to process.
611      * @param[in]  aMessageInfo  A reference to the message info associated with @p aMessage.
612      *
613      */
614     void HandlePayload(Message &aMessage, MessageInfo &aMessageInfo);
615 
616     /**
617      * Returns the head of UDP Sockets list.
618      *
619      * @returns A pointer to the head of UDP Socket linked list.
620      *
621      */
GetUdpSockets(void)622     SocketHandle *GetUdpSockets(void) { return mSockets.GetHead(); }
623 
624 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
625     /**
626      * Sets the forward sender.
627      *
628      * @param[in]   aForwarder  A function pointer to forward UDP packets.
629      * @param[in]   aContext    A pointer to arbitrary context information.
630      *
631      */
SetUdpForwarder(otUdpForwarder aForwarder,void * aContext)632     void SetUdpForwarder(otUdpForwarder aForwarder, void *aContext) { mUdpForwarder.Set(aForwarder, aContext); }
633 #endif
634 
635     /**
636      * Returns whether a udp port is being used by OpenThread or any of it's optional
637      * features, e.g. CoAP API.
638      *
639      * @param[in]   aPort       The udp port
640      *
641      * @retval True when port is used by the OpenThread.
642      * @retval False when the port is not used by OpenThread.
643      *
644      */
645     bool IsPortInUse(uint16_t aPort) const;
646 
647     /**
648      * Returns whether a udp port belongs to the platform or the stack.
649      *
650      * @param[in]   aPort       The udp port
651      *
652      * @retval True when the port belongs to the platform.
653      * @retval False when the port belongs to the stack.
654      *
655      */
656     bool ShouldUsePlatformUdp(uint16_t aPort) const;
657 
658 private:
659     static constexpr uint16_t kDynamicPortMin = 49152; // Service Name and Transport Protocol Port Number Registry
660     static constexpr uint16_t kDynamicPortMax = 65535; // Service Name and Transport Protocol Port Number Registry
661 
662     // Reserved range for use by SRP server
663     static constexpr uint16_t kSrpServerPortMin = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MIN;
664     static constexpr uint16_t kSrpServerPortMax = OPENTHREAD_CONFIG_SRP_SERVER_UDP_PORT_MAX;
665 
666     static bool IsPortReserved(uint16_t aPort);
667 
668     void AddSocket(SocketHandle &aSocket);
669     void RemoveSocket(SocketHandle &aSocket);
670 #if OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE
671     bool ShouldUsePlatformUdp(const SocketHandle &aSocket) const;
672 #endif
673 
674 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
675     void                SetBackboneSocket(SocketHandle &aSocket);
676     const SocketHandle *GetBackboneSockets(void) const;
677     bool                IsBackboneSocket(const SocketHandle &aSocket) const;
678 #endif
679 
680     uint16_t                 mEphemeralPort;
681     LinkedList<Receiver>     mReceivers;
682     LinkedList<SocketHandle> mSockets;
683 #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
684     SocketHandle *mPrevBackboneSockets;
685 #endif
686 #if OPENTHREAD_CONFIG_UDP_FORWARD_ENABLE
687     Callback<otUdpForwarder> mUdpForwarder;
688 #endif
689 };
690 
691 /**
692  * @}
693  *
694  */
695 
696 } // namespace Ip6
697 
698 DefineCoreType(otUdpSocket, Ip6::Udp::SocketHandle);
699 DefineCoreType(otUdpReceiver, Ip6::Udp::Receiver);
700 DefineMapEnum(otNetifIdentifier, Ip6::NetifIdentifier);
701 
702 } // namespace ot
703 
704 #endif // UDP6_HPP_
705