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