From fa09e8a75d21bd86b4797e32fdb0c58b25ba05c5 Mon Sep 17 00:00:00 2001 From: kangping Date: Tue, 6 Apr 2021 13:31:43 +0800 Subject: [PATCH] [meshcop] fix UDP proxy (#6396) The MeshCoP UDP Proxy packets should not be sent/received with platform UDP. --- src/core/meshcop/border_agent.cpp | 21 ++++++++++++++++----- src/core/meshcop/border_agent.hpp | 10 ++++++++++ src/core/meshcop/dataset_manager.cpp | 3 ++- src/core/net/ip6_address.hpp | 2 +- src/core/net/udp6.cpp | 3 +++ 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/core/meshcop/border_agent.cpp b/src/core/meshcop/border_agent.cpp index 821bd5d71..897de42c2 100644 --- a/src/core/meshcop/border_agent.cpp +++ b/src/core/meshcop/border_agent.cpp @@ -185,6 +185,9 @@ void BorderAgent::HandleCoapResponse(ForwardContext &aForwardContext, const Coap IgnoreError(Get().GetCommissionerAloc(mCommissionerAloc.GetAddress(), sessionId)); Get().AddUnicastAddress(mCommissionerAloc); IgnoreError(Get().AddReceiver(mUdpReceiver)); + + otLogInfoMeshCoP("commissioner accepted: session ID=%d, ALOC=%s", sessionId, + mCommissionerAloc.GetAddress().ToString().AsCString()); } } @@ -285,6 +288,7 @@ BorderAgent::BorderAgent(Instance &aInstance) , mUdpReceiver(BorderAgent::HandleUdpReceive, this) , mTimer(aInstance, HandleTimeout) , mState(kStateStopped) + , mUdpProxyPort(0) { mCommissionerAloc.InitAsThreadOriginRealmLocalScope(); } @@ -325,14 +329,18 @@ void BorderAgent::HandleProxyTransmit(const Coap::Message &aMessage) SuccessOrExit(error = message->SetLength(tlv.GetUdpLength())); aMessage.CopyTo(offset + sizeof(tlv), 0, tlv.GetUdpLength(), *message); - messageInfo.SetSockPort(tlv.GetSourcePort() != 0 ? tlv.GetSourcePort() : Get().GetEphemeralPort()); + VerifyOrExit(tlv.GetSourcePort() > 0 && tlv.GetDestinationPort() > 0, error = kErrorDrop); + + messageInfo.SetSockPort(tlv.GetSourcePort()); messageInfo.SetSockAddr(mCommissionerAloc.GetAddress()); messageInfo.SetPeerPort(tlv.GetDestinationPort()); SuccessOrExit(error = Tlv::Find(aMessage, messageInfo.GetPeerAddr())); SuccessOrExit(error = Get().SendDatagram(*message, messageInfo, Ip6::kProtoUdp)); - otLogInfoMeshCoP("Proxy transmit sent"); + mUdpProxyPort = tlv.GetSourcePort(); + + otLogInfoMeshCoP("Proxy transmit sent to %s", messageInfo.GetPeerAddr().ToString().AsCString()); exit: FreeMessageOnError(message, error); @@ -557,7 +565,8 @@ void BorderAgent::HandleConnected(bool aConnected) otLogInfoMeshCoP("Commissioner disconnected"); IgnoreError(Get().RemoveReceiver(mUdpReceiver)); Get().RemoveUnicastAddress(mCommissionerAloc); - mState = kStateStarted; + mState = kStateStarted; + mUdpProxyPort = 0; } } @@ -585,7 +594,8 @@ Error BorderAgent::Start(void) Get().AddResource(mRelayReceive); - mState = kStateStarted; + mState = kStateStarted; + mUdpProxyPort = 0; exit: return error; @@ -629,7 +639,8 @@ Error BorderAgent::Stop(void) coaps.Stop(); - mState = kStateStopped; + mState = kStateStopped; + mUdpProxyPort = 0; exit: return error; diff --git a/src/core/meshcop/border_agent.hpp b/src/core/meshcop/border_agent.hpp index 4a0d8d451..2409e4754 100644 --- a/src/core/meshcop/border_agent.hpp +++ b/src/core/meshcop/border_agent.hpp @@ -106,6 +106,15 @@ public: */ void ApplyMeshLocalPrefix(void); + /** + * This method returns the UDP Proxy port to which the commissioner is currently + * bound. + * + * @returns The current UDP Proxy port or 0 if no Proxy Transmit has been received yet. + * + */ + uint16_t GetUdpProxyPort(void) const { return mUdpProxyPort; } + private: class ForwardContext : public InstanceLocatorInit { @@ -187,6 +196,7 @@ private: TimerMilli mTimer; State mState; + uint16_t mUdpProxyPort; }; } // namespace MeshCoP diff --git a/src/core/meshcop/dataset_manager.cpp b/src/core/meshcop/dataset_manager.cpp index ae94d2e54..18d982022 100644 --- a/src/core/meshcop/dataset_manager.cpp +++ b/src/core/meshcop/dataset_manager.cpp @@ -448,7 +448,8 @@ void DatasetManager::SendGetResponse(const Coap::Message & aRequest, SuccessOrExit(error = Get().SendMessage(*message, aMessageInfo)); - otLogInfoMeshCoP("sent dataset get response"); + otLogInfoMeshCoP("sent %s dataset get response to %s", (GetType() == Dataset::kActive ? "active" : "pending"), + aMessageInfo.GetPeerAddr().ToString().AsCString()); exit: FreeMessageOnError(message, error); diff --git a/src/core/net/ip6_address.hpp b/src/core/net/ip6_address.hpp index c775b17f4..e0efdba2d 100644 --- a/src/core/net/ip6_address.hpp +++ b/src/core/net/ip6_address.hpp @@ -421,7 +421,7 @@ public: bool IsAnycastLocator(void) const; /** - * This method indicates whether or not the Interface Identifier (IID) matches a Service Anycast Locator (ALOC). + * This method indicates whether or not the Interface Identifier (IID) matches a Service Anycast Locator (ALOC). * * In addition to checking that the IID matches the locator pattern (`0000:00ff:fe00:xxxx`), this method also * checks that the locator value is a valid Service ALOC16 (0xfc10 – 0xfc2f). diff --git a/src/core/net/udp6.cpp b/src/core/net/udp6.cpp index a01504151..8594f2331 100644 --- a/src/core/net/udp6.cpp +++ b/src/core/net/udp6.cpp @@ -527,6 +527,9 @@ exit: bool Udp::ShouldUsePlatformUdp(uint16_t aPort) const { return (aPort != Mle::kUdpPort && aPort != Tmf::kUdpPort +#if OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE + && aPort != Get().GetUdpProxyPort() +#endif #if OPENTHREAD_FTD && aPort != Get().GetJoinerUdpPort() #endif