From 710707c2a9d89be3c3139f01a863db2c2ddd0132 Mon Sep 17 00:00:00 2001 From: Xiao Ma Date: Sat, 19 Nov 2016 14:10:55 +0800 Subject: [PATCH] Accept MGMT_COMM_SET.req as long as at least one valid tlv is included. (#989) --- src/core/thread/network_data_leader_ftd.cpp | 26 ++++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/core/thread/network_data_leader_ftd.cpp b/src/core/thread/network_data_leader_ftd.cpp index 589e8f6f2..113e4338f 100644 --- a/src/core/thread/network_data_leader_ftd.cpp +++ b/src/core/thread/network_data_leader_ftd.cpp @@ -188,32 +188,46 @@ void Leader::HandleCommissioningSet(Coap::Header &aHeader, Message &aMessage, co uint8_t tlvs[NetworkData::kMaxSize]; MeshCoP::StateTlv::State state = MeshCoP::StateTlv::kAccept; bool hasSessionId = false; + bool hasValidTlv = false; uint16_t sessionId = 0; VerifyOrExit(mMle.GetDeviceState() == Mle::kDeviceStateLeader, state = MeshCoP::StateTlv::kReject); aMessage.Read(offset, length, tlvs); - // Session Id and Border Router Locator MUST NOT be set, and only includes commissioning data tlvs + // Session Id and Border Router Locator MUST NOT be set, but accept including unexpected or + // unknown TLV as long as there is at least one valid TLV. for (MeshCoP::Tlv *cur = reinterpret_cast(tlvs); cur < reinterpret_cast(tlvs + length); cur = cur->GetNext()) { MeshCoP::Tlv::Type type = cur->GetType(); - VerifyOrExit(type == MeshCoP::Tlv::kCommissionerSessionId || - type == MeshCoP::Tlv::kJoinerUdpPort || type == MeshCoP::Tlv::kSteeringData, - state = MeshCoP::StateTlv::kReject); - - if (type == MeshCoP::Tlv::kCommissionerSessionId) + if (type == MeshCoP::Tlv::kJoinerUdpPort || type == MeshCoP::Tlv::kSteeringData) + { + hasValidTlv = true; + } + else if (type == MeshCoP::Tlv::kBorderAgentLocator) + { + ExitNow(state = MeshCoP::StateTlv::kReject); + } + else if (type == MeshCoP::Tlv::kCommissionerSessionId) { hasSessionId = true; sessionId = static_cast(cur)->GetCommissionerSessionId(); } + else + { + // do nothing for unexpected or unknown TLV + } } + // verify whether or not commissioner session id TLV is included VerifyOrExit(hasSessionId, state = MeshCoP::StateTlv::kReject); + // verify whether or not MGMT_COMM_SET.req includes at least one valid TLV + VerifyOrExit(hasValidTlv, state = MeshCoP::StateTlv::kReject); + for (MeshCoP::Tlv *cur = reinterpret_cast(mTlvs + sizeof(CommissioningDataTlv)); cur < reinterpret_cast(mTlvs + mLength); cur = cur->GetNext())