Skip to content

Commit

Permalink
Add support for CASE session caching for session resume use cases
Browse files Browse the repository at this point in the history
- Add tests for the CASE session cache
  • Loading branch information
nivi-apple committed Nov 17, 2021
1 parent e568d70 commit 61d02d8
Show file tree
Hide file tree
Showing 7 changed files with 442 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/lib/core/CHIPConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -2691,6 +2691,13 @@ extern const char CHIP_NON_PRODUCTION_MARKER[];
#define CHIP_CONFIG_MAX_SESSION_RELEASE_DELEGATES 2
#endif

/**
*@def CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE ** @brief * Maximum number of CASE sessions that a device caches that can be
resumed * /
#ifndef CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE
#define CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE 4
#endif
/**
* @}
*/
2 changes: 2 additions & 0 deletions src/protocols/secure_channel/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ static_library("secure_channel") {
"CASEServer.h",
"CASESession.cpp",
"CASESession.h",
"CASESessionCache.cpp",
"CASESessionCache.h",
"PASESession.cpp",
"PASESession.h",
"RendezvousParameters.h",
Expand Down
2 changes: 2 additions & 0 deletions src/protocols/secure_channel/CASESession.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ class DLL_EXPORT CASESession : public Messaging::ExchangeDelegate, public Pairin
*/
CHIP_ERROR ParseSigma1();

bool MatchResumptionId(const ByteSpan & resumptionID) { return resumptionID.data_equal(ByteSpan(mResumptionId)); }

private:
enum State : uint8_t
{
Expand Down
108 changes: 108 additions & 0 deletions src/protocols/secure_channel/CASESessionCache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <protocols/secure_channel/CASESessionCache.h>

namespace chip {

CASESessionCache::CASESessionCache() {}

CASESessionCache::~CASESessionCache()
{
mCachePool.ForEachActiveObject([&](auto * ec) {
mCachePool.ReleaseObject(ec);
return true;
});
}

CASESessionSerializable * CASESessionCache::GetLRUSession()
{
uint64_t minTimeStamp = UINT64_MAX;
CASESessionSerializable * lruSession = nullptr;
mCachePool.ForEachActiveObject([&](auto * ec) {
if (minTimeStamp > ec->mSessionSetupTimeStamp)
{
minTimeStamp = ec->mSessionSetupTimeStamp;
lruSession = ec;
}
return true;
});
return lruSession;
}

CHIP_ERROR CASESessionCache::Add(CASESession & session)
{
// It's not an error if a device doesn't have cache for storing the sessions.
VerifyOrReturnError(mCachePool.Size() > 0, CHIP_NO_ERROR);

// If the cache is full, get the least recently used session index and release that.
if (mCachePool.Exhausted())
{
mCachePool.ReleaseObject(GetLRUSession());
}

CASESessionSerializable serializable;
ReturnLogErrorOnFailure(session.ToSerializable(serializable));
mCachePool.CreateObject(serializable);
return CHIP_NO_ERROR;
}

CHIP_ERROR CASESessionCache::Remove(const ByteSpan & resumptionID)
{
CHIP_ERROR err = CHIP_NO_ERROR;
CASESession session;
mCachePool.ForEachActiveObject([&](auto * ec) {
err = session.FromSerializable(*ec);
if (session.MatchResumptionId(resumptionID))
{
mCachePool.ReleaseObject(ec);
}
return true;
});

return err;
}

CHIP_ERROR CASESessionCache::Get(const ByteSpan & resumptionID, CASESession & out_session)
{
CHIP_ERROR err = CHIP_NO_ERROR;
bool found = false;
mCachePool.ForEachActiveObject([&](auto * ec) {
err = out_session.FromSerializable(*ec);
if (out_session.MatchResumptionId(resumptionID))
{
found = true;
return false;
}
return true;
});

if (!found)
{
err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND;
}

return err;
}

CHIP_ERROR CASESessionCache::Get(const PeerId & peer, CASESession & out_session)
{
// TODO: Implement this based on peer id
return CHIP_NO_ERROR;
}

} // namespace chip
42 changes: 42 additions & 0 deletions src/protocols/secure_channel/CASESessionCache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <lib/core/CHIPError.h>
#include <lib/core/PeerId.h>
#include <protocols/secure_channel/CASESession.h>

namespace chip {

class CASESessionCache
{
public:
CASESessionCache();
virtual ~CASESessionCache();

CHIP_ERROR Add(CASESession & session);
CHIP_ERROR Remove(const ByteSpan & resumptionID);
CHIP_ERROR Get(const ByteSpan & resumptionID, CASESession & out_session);
CHIP_ERROR Get(const PeerId & peer, CASESession & out_session);

private:
BitMapObjectPool<CASESessionSerializable, CHIP_CONFIG_CASE_SESSION_RESUME_CACHE_SIZE> mCachePool;
CASESessionSerializable * GetLRUSession();
};

} // namespace chip
1 change: 1 addition & 0 deletions src/protocols/secure_channel/tests/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ chip_test_suite("tests") {

test_sources = [
"TestCASESession.cpp",
"TestCASESessionCache.cpp",

# TODO - Fix Message Counter Sync to use group key
# "TestMessageCounterManager.cpp",
Expand Down
Loading

0 comments on commit 61d02d8

Please sign in to comment.