Cleanup DatasetManager::Set(). (#1058)

This commit is contained in:
Jonathan Hui
2016-12-09 09:56:34 -08:00
committed by GitHub
parent d095cf884e
commit a3b464044e
2 changed files with 97 additions and 119 deletions
+96 -103
View File
@@ -325,135 +325,128 @@ void DatasetManager::Get(Coap::Header &aHeader, Message &aMessage, const Ip6::Me
ThreadError DatasetManager::Set(Coap::Header &aHeader, Message &aMessage, const Ip6::MessageInfo &aMessageInfo)
{
Tlv tlv;
Timestamp timestamp;
Timestamp *timestamp;
uint16_t offset = aMessage.GetOffset();
Tlv::Type type;
bool isUpdateFromCommissioner = false;
bool isUpdateAffectConnectivity = false;
bool isUpdateIdenticalValue = true;
bool doesAffectConnectivity = false;
StateTlv::State state = StateTlv::kAccept;
ActiveTimestampTlv activeTimestamp;
NetworkMasterKeyTlv masterKey;
PendingTimestampTlv pendingTimestamp;
ChannelTlv channel;
CommissionerSessionIdTlv sessionId;
MeshLocalPrefixTlv meshLocalPrefix;
NetworkMasterKeyTlv masterKey;
PanIdTlv panId;
activeTimestamp.SetLength(0);
masterKey.SetLength(0);
pendingTimestamp.SetLength(0);
channel.SetLength(0);
masterKey.SetLength(0);
meshLocalPrefix.SetLength(0);
panId.SetLength(0);
pendingTimestamp.SetLength(0);
sessionId.SetLength(0);
VerifyOrExit(mMle.GetDeviceState() == Mle::kDeviceStateLeader, state = StateTlv::kReject);
type = (strcmp(mUriSet, OPENTHREAD_URI_ACTIVE_SET) == 0 ? Tlv::kActiveTimestamp : Tlv::kPendingTimestamp);
// verify that TLV data size is less than maximum TLV value size
while (offset < aMessage.GetLength())
{
Tlv::Type tlvType;
aMessage.Read(offset, sizeof(tlv), &tlv);
tlvType = tlv.GetType();
if (tlvType == type)
{
aMessage.Read(offset + sizeof(tlv), sizeof(timestamp), &timestamp);
}
switch (tlvType)
{
case Tlv::kActiveTimestamp:
aMessage.Read(offset, sizeof(activeTimestamp), &activeTimestamp);
break;
case Tlv::kNetworkMasterKey:
aMessage.Read(offset, sizeof(masterKey), &masterKey);
break;
case Tlv::kChannel:
aMessage.Read(offset, sizeof(channel), &channel);
VerifyOrExit(channel.GetChannel() >= kPhyMinChannel && channel.GetChannel() <= kPhyMaxChannel,
state = StateTlv::kReject);
break;
case Tlv::kMeshLocalPrefix:
aMessage.Read(offset, sizeof(meshLocalPrefix), &meshLocalPrefix);
break;
case Tlv::kPanId:
aMessage.Read(offset, sizeof(panId), &panId);
break;
default:
break;
}
// verify the request does not include fields that affect connectivity
if ((type == Tlv::kActiveTimestamp) &&
(tlvType == Tlv::kChannel || tlvType == Tlv::kMeshLocalPrefix ||
tlvType == Tlv::kPanId || tlvType == Tlv::kNetworkMasterKey))
{
isUpdateAffectConnectivity = true;
}
// verify session id is the same
if (tlvType == Tlv::kCommissionerSessionId)
{
CommissionerSessionIdTlv *sessionId;
uint16_t rxSessionId;
isUpdateFromCommissioner = true;
sessionId = static_cast<CommissionerSessionIdTlv *>(mNetworkDataLeader.GetCommissioningDataSubTlv(
Tlv::kCommissionerSessionId));
aMessage.Read(offset + sizeof(tlv), sizeof(rxSessionId), &rxSessionId);
VerifyOrExit(sessionId != NULL && sessionId->GetCommissionerSessionId() == rxSessionId,
state = StateTlv::kReject);
}
// verify that TLV data size is less than maximum TLV value size
VerifyOrExit(tlv.GetLength() <= Dataset::kMaxValueSize, state = StateTlv::kReject);
offset += sizeof(tlv) + tlv.GetLength();
}
// verify whether or not tlv value is identical with current one
if (isUpdateAffectConnectivity &&
(channel.GetChannel() != mNetif.GetMac().GetChannel() ||
panId.GetPanId() != mNetif.GetMac().GetPanId() ||
memcmp(meshLocalPrefix.GetMeshLocalPrefix(), mNetif.GetMle().GetMeshLocalPrefix(),
meshLocalPrefix.GetLength()) != 0 ||
memcmp(masterKey.GetNetworkMasterKey(), mNetif.GetKeyManager().GetMasterKey(NULL),
masterKey.GetLength()) != 0))
{
isUpdateIdenticalValue = false;
otLogInfoMeshCoP("Request includes tlv that affects connectivity.");
}
// verify the update from commissioner should not contain tlv would affect connectivity
VerifyOrExit(!isUpdateFromCommissioner || !(isUpdateAffectConnectivity && !isUpdateIdenticalValue),
state = StateTlv::kReject);
// verify the request includes a timestamp that is ahead of the locally stored value
VerifyOrExit(offset == aMessage.GetLength() && (mLocal.GetTimestamp() == NULL ||
mLocal.GetTimestamp()->Compare(timestamp) > 0), state = StateTlv::kReject);
// verify network master key if active timestamp is behind
if (type == Tlv::kPendingTimestamp)
{
const Timestamp *localActiveTimestamp = mNetif.GetActiveDataset().GetNetwork().GetTimestamp();
if (localActiveTimestamp != NULL && localActiveTimestamp->Compare(activeTimestamp) <= 0)
{
VerifyOrExit(masterKey.GetLength() != 0, state = StateTlv::kReject);
}
}
// verify that does not overflow dataset buffer
VerifyOrExit((offset - aMessage.GetOffset()) <= Dataset::kMaxSize, state = StateTlv::kReject);
type = (strcmp(mUriSet, OPENTHREAD_URI_ACTIVE_SET) == 0 ? Tlv::kActiveTimestamp : Tlv::kPendingTimestamp);
if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) != kThreadError_None)
{
ExitNow(state = StateTlv::kReject);
}
Tlv::GetTlv(aMessage, Tlv::kPendingTimestamp, sizeof(pendingTimestamp), pendingTimestamp);
// verify the request includes a timestamp that is ahead of the locally stored value
timestamp = (type == Tlv::kActiveTimestamp) ?
static_cast<Timestamp *>(&activeTimestamp) :
static_cast<Timestamp *>(&pendingTimestamp);
VerifyOrExit(mLocal.GetTimestamp() == NULL || mLocal.GetTimestamp()->Compare(*timestamp) > 0,
state = StateTlv::kReject);
// check channel
if (Tlv::GetTlv(aMessage, Tlv::kChannel, sizeof(channel), channel) == kThreadError_None)
{
VerifyOrExit(channel.GetChannel() >= kPhyMinChannel && channel.GetChannel() <= kPhyMaxChannel,
state = StateTlv::kReject);
if (type == Tlv::kActiveTimestamp && channel.GetChannel() != mNetif.GetMac().GetChannel())
{
doesAffectConnectivity = true;
}
}
// check PAN ID
if (Tlv::GetTlv(aMessage, Tlv::kPanId, sizeof(panId), panId) == kThreadError_None &&
type == Tlv::kActiveTimestamp &&
panId.GetPanId() != mNetif.GetMac().GetPanId())
{
doesAffectConnectivity = true;
}
// check mesh local prefix
if (Tlv::GetTlv(aMessage, Tlv::kMeshLocalPrefix, sizeof(meshLocalPrefix), meshLocalPrefix) == kThreadError_None &&
type == Tlv::kActiveTimestamp &&
memcmp(meshLocalPrefix.GetMeshLocalPrefix(), mNetif.GetMle().GetMeshLocalPrefix(),
meshLocalPrefix.GetLength()))
{
doesAffectConnectivity = true;
}
// check network master key
if (Tlv::GetTlv(aMessage, Tlv::kNetworkMasterKey, sizeof(masterKey), masterKey) == kThreadError_None &&
type == Tlv::kActiveTimestamp &&
memcmp(masterKey.GetNetworkMasterKey(), mNetif.GetKeyManager().GetMasterKey(NULL),
masterKey.GetLength()))
{
doesAffectConnectivity = true;
}
// check active timestamp rollback
if (type == Tlv::kPendingTimestamp &&
(masterKey.GetLength() == 0 ||
memcmp(masterKey.GetNetworkMasterKey(), mNetif.GetKeyManager().GetMasterKey(NULL),
masterKey.GetLength()) == 0))
{
// no change to master key, active timestamp must be ahead
const Timestamp *localActiveTimestamp = mNetif.GetActiveDataset().GetNetwork().GetTimestamp();
VerifyOrExit(localActiveTimestamp == NULL || localActiveTimestamp->Compare(activeTimestamp) > 0,
state = StateTlv::kReject);
}
// check commissioner session id
if (Tlv::GetTlv(aMessage, Tlv::kCommissionerSessionId, sizeof(sessionId), sessionId) == kThreadError_None)
{
CommissionerSessionIdTlv *localId;
isUpdateFromCommissioner = true;
localId = static_cast<CommissionerSessionIdTlv *>(mNetworkDataLeader.GetCommissioningDataSubTlv(
Tlv::kCommissionerSessionId));
VerifyOrExit(localId != NULL && localId->GetCommissionerSessionId() == sessionId.GetCommissionerSessionId(),
state = StateTlv::kReject);
}
// verify the update from commissioner should not contain tlv would affect connectivity
VerifyOrExit(!isUpdateFromCommissioner || !doesAffectConnectivity, state = StateTlv::kReject);
// update dataset
if (type == Tlv::kPendingTimestamp && isUpdateFromCommissioner)
{
@@ -461,7 +454,7 @@ ThreadError DatasetManager::Set(Coap::Header &aHeader, Message &aMessage, const
mLocal.Set(mNetif.GetActiveDataset().GetNetwork());
}
if (!isUpdateAffectConnectivity || isUpdateIdenticalValue)
if (!doesAffectConnectivity)
{
offset = aMessage.GetOffset();
+1 -16
View File
@@ -67,22 +67,7 @@ ActiveDataset::ActiveDataset(ThreadNetif &aThreadNetif):
bool ActiveDataset::IsTlvInitialized(Tlv::Type aType)
{
bool rval = false;
const Tlv *cur = reinterpret_cast<const Tlv *>(mLocal.GetBytes());
const Tlv *end = reinterpret_cast<const Tlv *>(mLocal.GetBytes() + mLocal.GetSize());
while (cur < end)
{
if (aType == cur->GetType())
{
ExitNow(rval = true);
}
cur = cur->GetNext();
}
exit:
return rval;
return mLocal.Get(aType) != NULL;
}
ThreadError ActiveDataset::GenerateLocal(void)