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