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