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