From d8aae52899b87f193c0711468f484a11e9e38e30 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Mon, 21 Nov 2016 19:04:37 +0000 Subject: [PATCH] Only FTDs handle Discovery Requests and send Discovery Responses. (#998) --- src/core/thread/mle.cpp | 166 +---------------------------- src/core/thread/mle.hpp | 2 - src/core/thread/mle_router.cpp | 164 ++++++++++++++++++++++++++++ src/core/thread/mle_router_ftd.hpp | 2 + src/core/thread/mle_router_mtd.hpp | 1 + 5 files changed, 168 insertions(+), 167 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 212356298..10a1e2eda 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1659,7 +1659,7 @@ void Mle::HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageIn switch (header.GetCommand()) { case Header::kCommandDiscoveryRequest: - HandleDiscoveryRequest(aMessage, aMessageInfo); + mMleRouter.HandleDiscoveryRequest(aMessage, aMessageInfo); break; case Header::kCommandDiscoveryResponse: @@ -2551,170 +2551,6 @@ exit: return error; } -ThreadError Mle::HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) -{ - ThreadError error = kThreadError_None; - Tlv tlv; - MeshCoP::Tlv meshcopTlv; - MeshCoP::DiscoveryRequestTlv discoveryRequest; - MeshCoP::ExtendedPanIdTlv extPanId; - uint16_t offset; - uint16_t end; - - otLogInfoMle("Received discovery request"); - - // only Routers and REEDs respond - VerifyOrExit((mDeviceMode & ModeTlv::kModeFFD) != 0, ;); - - offset = aMessage.GetOffset(); - end = aMessage.GetLength(); - - // find MLE Discovery TLV - while (offset < end) - { - aMessage.Read(offset, sizeof(tlv), &tlv); - - if (tlv.GetType() == Tlv::kDiscovery) - { - break; - } - - offset += sizeof(tlv) + tlv.GetLength(); - } - - VerifyOrExit(offset < end, error = kThreadError_Parse); - - offset += sizeof(tlv); - end = offset + sizeof(tlv) + tlv.GetLength(); - - while (offset < end) - { - aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv); - - switch (meshcopTlv.GetType()) - { - case MeshCoP::Tlv::kDiscoveryRequest: - aMessage.Read(offset, sizeof(discoveryRequest), &discoveryRequest); - VerifyOrExit(discoveryRequest.IsValid(), error = kThreadError_Parse); - break; - - case MeshCoP::Tlv::kExtendedPanId: - aMessage.Read(offset, sizeof(extPanId), &extPanId); - VerifyOrExit(extPanId.IsValid(), error = kThreadError_Parse); - VerifyOrExit(memcmp(mMac.GetExtendedPanId(), extPanId.GetExtendedPanId(), OT_EXT_PAN_ID_SIZE), - error = kThreadError_Drop); - break; - - default: - break; - } - - offset += sizeof(meshcopTlv) + meshcopTlv.GetLength(); - } - - error = SendDiscoveryResponse(aMessageInfo.GetPeerAddr(), aMessage.GetPanId()); - -exit: - - if (error != kThreadError_None) - { - otLogWarnMleErr(error, "Failed to process Discovery Request"); - } - - return error; -} - -ThreadError Mle::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId) -{ - ThreadError error = kThreadError_None; - Message *message; - uint16_t startOffset; - Tlv tlv; - MeshCoP::DiscoveryResponseTlv discoveryResponse; - MeshCoP::ExtendedPanIdTlv extPanId; - MeshCoP::NetworkNameTlv networkName; - MeshCoP::JoinerUdpPortTlv joinerUdpPort; - uint8_t *cur; - uint8_t length; - - VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, ;); - message->SetLinkSecurityEnabled(false); - message->SetSubType(Message::kSubTypeMleDiscoverResponse); - message->SetPanId(aPanId); - SuccessOrExit(error = AppendHeader(*message, Header::kCommandDiscoveryResponse)); - - // Discovery TLV - tlv.SetType(Tlv::kDiscovery); - SuccessOrExit(error = message->Append(&tlv, sizeof(tlv))); - - startOffset = message->GetLength(); - - // Discovery Response TLV - discoveryResponse.Init(); - discoveryResponse.SetVersion(kVersion); - - if (mNetif.GetKeyManager().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) - { - discoveryResponse.SetNativeCommissioner(true); - } - else - { - discoveryResponse.SetNativeCommissioner(false); - } - - SuccessOrExit(error = message->Append(&discoveryResponse, sizeof(discoveryResponse))); - - // Extended PAN ID TLV - extPanId.Init(); - extPanId.SetExtendedPanId(mMac.GetExtendedPanId()); - SuccessOrExit(error = message->Append(&extPanId, sizeof(extPanId))); - - // Network Name TLV - networkName.Init(); - networkName.SetNetworkName(mMac.GetNetworkName()); - SuccessOrExit(error = message->Append(&networkName, sizeof(tlv) + networkName.GetLength())); - - // Steering Data TLV - if ((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL) - { - uint8_t *end = cur + length; - - while (cur < end) - { - MeshCoP::Tlv *meshcop = reinterpret_cast(cur); - - if (meshcop->GetType() == MeshCoP::Tlv::kSteeringData) - { - SuccessOrExit(message->Append(meshcop, sizeof(*meshcop) + meshcop->GetLength())); - break; - } - - cur += sizeof(*meshcop) + meshcop->GetLength(); - } - } - - // Joiner UDP Port TLV - joinerUdpPort.Init(); - joinerUdpPort.SetUdpPort(mJoinerRouter.GetJoinerUdpPort()); - SuccessOrExit(error = message->Append(&joinerUdpPort, sizeof(tlv) + joinerUdpPort.GetLength())); - - tlv.SetLength(static_cast(message->GetLength() - startOffset)); - message->Write(startOffset - sizeof(tlv), sizeof(tlv), &tlv); - - SuccessOrExit(error = SendMessage(*message, aDestination)); - - otLogInfoMle("Sent discovery response"); - -exit: - - if (error != kThreadError_None && message != NULL) - { - message->Free(); - } - - return error; -} - ThreadError Mle::HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) { ThreadError error = kThreadError_None; diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 8b1a7077c..c5b36477a 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1210,12 +1210,10 @@ private: ThreadError HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo, uint32_t aKeySequence); ThreadError HandleAnnounce(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); - ThreadError HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleDiscoveryResponse(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError SendParentRequest(void); ThreadError SendChildIdRequest(void); - ThreadError SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId); void SendOrphanAnnounce(void); bool IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, ConnectivityTlv &aConnectivityTlv) const; diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index a1a68860d..c2d87a2d0 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2303,6 +2303,170 @@ exit: return kThreadError_None; } +ThreadError MleRouter::HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo) +{ + ThreadError error = kThreadError_None; + Tlv tlv; + MeshCoP::Tlv meshcopTlv; + MeshCoP::DiscoveryRequestTlv discoveryRequest; + MeshCoP::ExtendedPanIdTlv extPanId; + uint16_t offset; + uint16_t end; + + otLogInfoMle("Received discovery request"); + + // only Routers and REEDs respond + VerifyOrExit((mDeviceMode & ModeTlv::kModeFFD) != 0, ;); + + offset = aMessage.GetOffset(); + end = aMessage.GetLength(); + + // find MLE Discovery TLV + while (offset < end) + { + aMessage.Read(offset, sizeof(tlv), &tlv); + + if (tlv.GetType() == Tlv::kDiscovery) + { + break; + } + + offset += sizeof(tlv) + tlv.GetLength(); + } + + VerifyOrExit(offset < end, error = kThreadError_Parse); + + offset += sizeof(tlv); + end = offset + sizeof(tlv) + tlv.GetLength(); + + while (offset < end) + { + aMessage.Read(offset, sizeof(meshcopTlv), &meshcopTlv); + + switch (meshcopTlv.GetType()) + { + case MeshCoP::Tlv::kDiscoveryRequest: + aMessage.Read(offset, sizeof(discoveryRequest), &discoveryRequest); + VerifyOrExit(discoveryRequest.IsValid(), error = kThreadError_Parse); + break; + + case MeshCoP::Tlv::kExtendedPanId: + aMessage.Read(offset, sizeof(extPanId), &extPanId); + VerifyOrExit(extPanId.IsValid(), error = kThreadError_Parse); + VerifyOrExit(memcmp(mMac.GetExtendedPanId(), extPanId.GetExtendedPanId(), OT_EXT_PAN_ID_SIZE), + error = kThreadError_Drop); + break; + + default: + break; + } + + offset += sizeof(meshcopTlv) + meshcopTlv.GetLength(); + } + + error = SendDiscoveryResponse(aMessageInfo.GetPeerAddr(), aMessage.GetPanId()); + +exit: + + if (error != kThreadError_None) + { + otLogWarnMleErr(error, "Failed to process Discovery Request"); + } + + return error; +} + +ThreadError MleRouter::SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId) +{ + ThreadError error = kThreadError_None; + Message *message; + uint16_t startOffset; + Tlv tlv; + MeshCoP::DiscoveryResponseTlv discoveryResponse; + MeshCoP::ExtendedPanIdTlv extPanId; + MeshCoP::NetworkNameTlv networkName; + MeshCoP::JoinerUdpPortTlv joinerUdpPort; + uint8_t *cur; + uint8_t length; + + VerifyOrExit((message = NewMessage()) != NULL, ;); + message->SetLinkSecurityEnabled(false); + message->SetSubType(Message::kSubTypeMleDiscoverResponse); + message->SetPanId(aPanId); + SuccessOrExit(error = AppendHeader(*message, Header::kCommandDiscoveryResponse)); + + // Discovery TLV + tlv.SetType(Tlv::kDiscovery); + SuccessOrExit(error = message->Append(&tlv, sizeof(tlv))); + + startOffset = message->GetLength(); + + // Discovery Response TLV + discoveryResponse.Init(); + discoveryResponse.SetVersion(kVersion); + + if (mNetif.GetKeyManager().GetSecurityPolicyFlags() & OT_SECURITY_POLICY_NATIVE_COMMISSIONING) + { + discoveryResponse.SetNativeCommissioner(true); + } + else + { + discoveryResponse.SetNativeCommissioner(false); + } + + SuccessOrExit(error = message->Append(&discoveryResponse, sizeof(discoveryResponse))); + + // Extended PAN ID TLV + extPanId.Init(); + extPanId.SetExtendedPanId(mMac.GetExtendedPanId()); + SuccessOrExit(error = message->Append(&extPanId, sizeof(extPanId))); + + // Network Name TLV + networkName.Init(); + networkName.SetNetworkName(mMac.GetNetworkName()); + SuccessOrExit(error = message->Append(&networkName, sizeof(tlv) + networkName.GetLength())); + + // Steering Data TLV + if ((cur = mNetif.GetNetworkDataLeader().GetCommissioningData(length)) != NULL) + { + uint8_t *end = cur + length; + + while (cur < end) + { + MeshCoP::Tlv *meshcop = reinterpret_cast(cur); + + if (meshcop->GetType() == MeshCoP::Tlv::kSteeringData) + { + SuccessOrExit(message->Append(meshcop, sizeof(*meshcop) + meshcop->GetLength())); + break; + } + + cur += sizeof(*meshcop) + meshcop->GetLength(); + } + } + + // Joiner UDP Port TLV + joinerUdpPort.Init(); + joinerUdpPort.SetUdpPort(mJoinerRouter.GetJoinerUdpPort()); + SuccessOrExit(error = message->Append(&joinerUdpPort, sizeof(tlv) + joinerUdpPort.GetLength())); + + tlv.SetLength(static_cast(message->GetLength() - startOffset)); + message->Write(startOffset - sizeof(tlv), sizeof(tlv), &tlv); + + SuccessOrExit(error = SendMessage(*message, aDestination)); + + otLogInfoMle("Sent discovery response"); + +exit: + + if (error != kThreadError_None && message != NULL) + { + message->Free(); + } + + return error; +} + ThreadError MleRouter::SendChildIdResponse(Child *aChild) { ThreadError error = kThreadError_None; diff --git a/src/core/thread/mle_router_ftd.hpp b/src/core/thread/mle_router_ftd.hpp index ff081906e..d73228912 100644 --- a/src/core/thread/mle_router_ftd.hpp +++ b/src/core/thread/mle_router_ftd.hpp @@ -680,6 +680,7 @@ private: ThreadError HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleDataRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError HandleNetworkDataUpdateRouter(void); + ThreadError HandleDiscoveryRequest(const Message &aMessage, const Ip6::MessageInfo &aMessageInfo); ThreadError ProcessRouteTlv(const RouteTlv &aRoute); void ResetAdvertiseInterval(void); @@ -697,6 +698,7 @@ private: ThreadError SendChildUpdateResponse(Child *aChild, const Ip6::MessageInfo &aMessageInfo, const uint8_t *aTlvs, uint8_t aTlvsLength, const ChallengeTlv *challenge); ThreadError SendDataResponse(const Ip6::Address &aDestination, const uint8_t *aTlvs, uint8_t aTlvsLength); + ThreadError SendDiscoveryResponse(const Ip6::Address &aDestination, uint16_t aPanId); ThreadError SetStateRouter(uint16_t aRloc16); ThreadError SetStateLeader(uint16_t aRloc16); diff --git a/src/core/thread/mle_router_mtd.hpp b/src/core/thread/mle_router_mtd.hpp index 7d18ce56b..eded45c25 100644 --- a/src/core/thread/mle_router_mtd.hpp +++ b/src/core/thread/mle_router_mtd.hpp @@ -152,6 +152,7 @@ private: ThreadError HandleChildUpdateRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; } ThreadError HandleDataRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; } ThreadError HandleNetworkDataUpdateRouter(void) { return kThreadError_None; } + ThreadError HandleDiscoveryRequest(const Message &, const Ip6::MessageInfo &) { return kThreadError_Drop; } ThreadError ProcessRouteTlv(const RouteTlv &aRoute) { (void)aRoute; return kThreadError_None; }