From 8dcdc2cf3159dbceaba268d4e2f4dbd586281573 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Fri, 1 Feb 2019 00:48:27 +0800 Subject: [PATCH] [meshcop] border agent of native commissioner (#3535) This commit enables a node serve as the border agent of native commissioner by adding the border agent UDP port to unsecure port when the security policy allows. To fully test verify this commit, we need a native commissioner, which I will submit a separate commit to enable that. --- include/openthread/dataset.h | 1 + src/core/meshcop/border_agent.hpp | 5 ++-- src/core/meshcop/meshcop.hpp | 1 + src/core/meshcop/meshcop_tlvs.hpp | 48 +++++++++++++++++++++++++++++++ src/core/net/ip6_filter.cpp | 7 +++++ src/core/net/ip6_filter.hpp | 9 ++++++ src/core/thread/mle.cpp | 6 ++++ src/core/thread/mle_router.cpp | 6 ++++ 8 files changed, 80 insertions(+), 3 deletions(-) diff --git a/include/openthread/dataset.h b/include/openthread/dataset.h index 082576894..d9a2838a3 100644 --- a/include/openthread/dataset.h +++ b/include/openthread/dataset.h @@ -238,6 +238,7 @@ typedef enum otMeshcopTlvType OT_MESHCOP_TLV_SECURITYPOLICY = 12, ///< meshcop Security Policy TLV OT_MESHCOP_TLV_GET = 13, ///< meshcop Get TLV OT_MESHCOP_TLV_ACTIVETIMESTAMP = 14, ///< meshcop Active Timestamp TLV + OT_MESHCOP_TLV_COMMISSIONER_UDP_PORT = 15, ///< meshcop Commissioner UDP Port TLV OT_MESHCOP_TLV_STATE = 16, ///< meshcop State TLV OT_MESHCOP_TLV_JOINER_DTLS = 17, ///< meshcop Joiner DTLS Encapsulation TLV OT_MESHCOP_TLV_JOINER_UDP_PORT = 18, ///< meshcop Joiner UDP Port TLV diff --git a/src/core/meshcop/border_agent.hpp b/src/core/meshcop/border_agent.hpp index 3af0855a7..46b900fc8 100644 --- a/src/core/meshcop/border_agent.hpp +++ b/src/core/meshcop/border_agent.hpp @@ -127,9 +127,8 @@ private: enum { - kBorderAgentUdpPort = 49191, ///< UDP port of border agent service. - kKeepAliveTimeout = 50 * 1000, ///< Timeout to reject a commissioner. - kRestartDelay = 1 * 1000, ///< Delay to restart border agent service. + kKeepAliveTimeout = 50 * 1000, ///< Timeout to reject a commissioner. + kRestartDelay = 1 * 1000, ///< Delay to restart border agent service. }; Ip6::MessageInfo mMessageInfo; diff --git a/src/core/meshcop/meshcop.hpp b/src/core/meshcop/meshcop.hpp index 08e53ff53..c70178b6c 100644 --- a/src/core/meshcop/meshcop.hpp +++ b/src/core/meshcop/meshcop.hpp @@ -49,6 +49,7 @@ namespace MeshCoP { enum { kMeshCoPMessagePriority = Message::kPriorityNet, ///< The priority for MeshCoP message + kBorderAgentUdpPort = 49191, ///< UDP port of border agent service. }; /** diff --git a/src/core/meshcop/meshcop_tlvs.hpp b/src/core/meshcop/meshcop_tlvs.hpp index b10866c12..52f0c42e7 100644 --- a/src/core/meshcop/meshcop_tlvs.hpp +++ b/src/core/meshcop/meshcop_tlvs.hpp @@ -85,6 +85,7 @@ public: kSecurityPolicy = OT_MESHCOP_TLV_SECURITYPOLICY, ///< Security Policy TLV kGet = OT_MESHCOP_TLV_GET, ///< Get TLV kActiveTimestamp = OT_MESHCOP_TLV_ACTIVETIMESTAMP, ///< Active Timestamp TLV + kCommissionerUdpPort = OT_MESHCOP_TLV_COMMISSIONER_UDP_PORT, ///< Commissioner UDP Port TLV kState = OT_MESHCOP_TLV_STATE, ///< State TLV kJoinerDtlsEncapsulation = OT_MESHCOP_TLV_JOINER_DTLS, ///< Joiner DTLS Encapsulation TLV kJoinerUdpPort = OT_MESHCOP_TLV_JOINER_UDP_PORT, ///< Joiner UDP Port TLV @@ -977,6 +978,53 @@ public: bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); } } OT_TOOL_PACKED_END; +/** + * This class implements Commissioner UDP Port TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class CommissionerUdpPortTlv : public Tlv +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) + { + SetType(kCommissionerUdpPort); + SetLength(sizeof(*this) - sizeof(Tlv)); + } + + /** + * This method indicates whether or not the TLV appears to be well-formed. + * + * @retval TRUE If the TLV appears to be well-formed. + * @retval FALSE If the TLV does not appear to be well-formed. + * + */ + bool IsValid(void) const { return GetLength() == sizeof(*this) - sizeof(Tlv); } + + /** + * This method returns the UDP Port value. + * + * @returns The UDP Port value. + * + */ + uint16_t GetUdpPort(void) const { return HostSwap16(mUdpPort); } + + /** + * This method sets the UDP Port value. + * + * @param[in] aUdpPort The UDP Port value. + * + */ + void SetUdpPort(uint16_t aUdpPort) { mUdpPort = HostSwap16(aUdpPort); } + +private: + uint16_t mUdpPort; +} OT_TOOL_PACKED_END; + /** * This class implements State TLV generation and parsing. * diff --git a/src/core/net/ip6_filter.cpp b/src/core/net/ip6_filter.cpp index d68f2ff16..60e4776ee 100644 --- a/src/core/net/ip6_filter.cpp +++ b/src/core/net/ip6_filter.cpp @@ -37,6 +37,7 @@ #include "common/code_utils.hpp" #include "common/instance.hpp" +#include "meshcop/meshcop.hpp" #include "net/ip6.hpp" #include "net/tcp.hpp" #include "net/udp6.hpp" @@ -46,6 +47,7 @@ namespace ot { namespace Ip6 { Filter::Filter(void) + : mAllowNativeCommissioner(true) { memset(mUnsecurePorts, 0, sizeof(mUnsecurePorts)); } @@ -84,6 +86,11 @@ bool Filter::Accept(Message &aMessage) const ExitNow(rval = true); } + // Allow native commissioner traffic + if (mAllowNativeCommissioner && dstport == MeshCoP::kBorderAgentUdpPort) + { + ExitNow(rval = true); + } break; case kProtoTcp: diff --git a/src/core/net/ip6_filter.hpp b/src/core/net/ip6_filter.hpp index 165648e1f..0e4ec145b 100644 --- a/src/core/net/ip6_filter.hpp +++ b/src/core/net/ip6_filter.hpp @@ -115,12 +115,21 @@ public: */ const uint16_t *GetUnsecurePorts(uint8_t &aNumEntries) const; + /** + * This method sets whether to allow native commissioner traffic. + * + * @param[in] aAllow Whether to allow native commissioner traffic. + * + */ + void AllowNativeCommissioner(bool aAllow) { mAllowNativeCommissioner = aAllow; } + private: enum { kMaxUnsecurePorts = 2, }; uint16_t mUnsecurePorts[kMaxUnsecurePorts]; + bool mAllowNativeCommissioner; }; } // namespace Ip6 diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 65ccfd70f..570dbdf11 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1530,6 +1530,12 @@ void Mle::HandleStateChanged(otChangedFlags aFlags) Store(); } + if (aFlags & OT_CHANGED_SECURITY_POLICY) + { + GetNetif().GetIp6Filter().AllowNativeCommissioner( + (GetNetif().GetKeyManager().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) != 0); + } + exit: return; } diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 0c8bfdba7..52bc2b168 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2742,6 +2742,12 @@ otError MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, uint1 if (netif.GetKeyManager().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) { + MeshCoP::CommissionerUdpPortTlv commissionerUdpPort; + + commissionerUdpPort.Init(); + commissionerUdpPort.SetUdpPort(MeshCoP::kBorderAgentUdpPort); + SuccessOrExit(error = message->Append(&commissionerUdpPort, sizeof(commissionerUdpPort))); + discoveryResponse.SetNativeCommissioner(true); } else