| /* |
| * |
| * Copyright (c) 2020-2021 Project CHIP Authors |
| * All rights reserved. |
| * |
| * 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. |
| */ |
| |
| /** |
| * @file |
| * This file implements a process to effect a functional test for |
| * the SecureSessionTable class within the transport layer |
| * |
| */ |
| |
| #include <gtest/gtest.h> |
| |
| #include <lib/core/ErrorStr.h> |
| #include <lib/support/CodeUtils.h> |
| #include <transport/SecureSessionTable.h> |
| |
| namespace { |
| |
| using namespace chip; |
| using namespace chip::Transport; |
| using namespace chip::System::Clock::Literals; |
| |
| PeerAddress AddressFromString(const char * str) |
| { |
| Inet::IPAddress addr; |
| |
| VerifyOrDie(Inet::IPAddress::FromString(str, addr)); |
| |
| return PeerAddress::UDP(addr); |
| } |
| |
| const PeerAddress kPeer1Addr = AddressFromString("fe80::1"); |
| const PeerAddress kPeer2Addr = AddressFromString("fe80::2"); |
| const PeerAddress kPasePeerAddr = AddressFromString("fe80::3"); |
| |
| const NodeId kLocalNodeId = 0xC439A991071292DB; |
| const NodeId kCasePeer1NodeId = 123; |
| const NodeId kCasePeer2NodeId = 6; |
| const FabricIndex kFabricIndex = 8; |
| |
| const CATValues kPeer1CATs = { { 0xABCD0001, 0xABCE0100, 0xABCD0020 } }; |
| const CATValues kPeer2CATs = { { 0xABCD0012, kUndefinedCAT, kUndefinedCAT } }; |
| |
| class TestPeerConnections : public ::testing::Test |
| { |
| public: |
| static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } |
| static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } |
| }; |
| |
| TEST_F(TestPeerConnections, TestBasicFunctionality) |
| { |
| SecureSessionTable connections; |
| System::Clock::Internal::MockClock clock; |
| System::Clock::ClockBase * realClock = &System::SystemClock(); |
| System::Clock::Internal::SetSystemClockForTesting(&clock); |
| clock.SetMonotonic(100_ms64); |
| CATValues peerCATs; |
| Optional<SessionHandle> sessions[CHIP_CONFIG_SECURE_SESSION_POOL_SIZE]; |
| |
| // First node, peer session id 1, local session id 2 |
| auto optionalSession = connections.CreateNewSecureSessionForTest(SecureSession::Type::kCASE, 2, kLocalNodeId, kCasePeer1NodeId, |
| kPeer1CATs, 1, kFabricIndex, GetDefaultMRPConfig()); |
| EXPECT_TRUE(optionalSession.HasValue()); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetSecureSessionType(), SecureSession::Type::kCASE); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetPeerNodeId(), kCasePeer1NodeId); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetLocalNodeId(), kLocalNodeId); |
| EXPECT_EQ(optionalSession.Value()->GetPeer(), ScopedNodeId(kCasePeer1NodeId, kFabricIndex)); |
| EXPECT_EQ(optionalSession.Value()->GetLocalScopedNodeId(), ScopedNodeId(kLocalNodeId, kFabricIndex)); |
| peerCATs = optionalSession.Value()->AsSecureSession()->GetPeerCATs(); |
| EXPECT_EQ(memcmp(&peerCATs, &kPeer1CATs, sizeof(CATValues)), 0); |
| |
| // Second node, peer session id 3, local session id 4 |
| optionalSession = connections.CreateNewSecureSessionForTest(SecureSession::Type::kCASE, 4, kLocalNodeId, kCasePeer2NodeId, |
| kPeer2CATs, 3, kFabricIndex, GetDefaultMRPConfig()); |
| EXPECT_TRUE(optionalSession.HasValue()); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetSecureSessionType(), SecureSession::Type::kCASE); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetPeerNodeId(), kCasePeer2NodeId); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetLocalNodeId(), kLocalNodeId); |
| EXPECT_EQ(optionalSession.Value()->GetPeer(), ScopedNodeId(kCasePeer2NodeId, kFabricIndex)); |
| EXPECT_EQ(optionalSession.Value()->GetLocalScopedNodeId(), ScopedNodeId(kLocalNodeId, kFabricIndex)); |
| EXPECT_EQ(optionalSession.Value()->AsSecureSession()->GetLastActivityTime(), 100_ms64); |
| peerCATs = optionalSession.Value()->AsSecureSession()->GetPeerCATs(); |
| EXPECT_EQ(memcmp(&peerCATs, &kPeer2CATs, sizeof(CATValues)), 0); |
| |
| // |
| // Fill up the session table. |
| // |
| for (int i = 2; i < CHIP_CONFIG_SECURE_SESSION_POOL_SIZE; ++i) |
| { |
| sessions[i] = connections.CreateNewSecureSessionForTest( |
| SecureSession::Type::kCASE, static_cast<uint16_t>(static_cast<uint16_t>(i) + 6u), kLocalNodeId, kCasePeer2NodeId, |
| kPeer2CATs, 3, kFabricIndex, GetDefaultMRPConfig()); |
| EXPECT_TRUE(sessions[i].HasValue()); |
| } |
| |
| // #endif |
| System::Clock::Internal::SetSystemClockForTesting(realClock); |
| } |
| |
| TEST_F(TestPeerConnections, TestFindByKeyId) |
| { |
| SecureSessionTable connections; |
| System::Clock::Internal::MockClock clock; |
| System::Clock::ClockBase * realClock = &System::SystemClock(); |
| System::Clock::Internal::SetSystemClockForTesting(&clock); |
| |
| // First node, peer session id 1, local session id 2 |
| auto optionalSession = connections.CreateNewSecureSessionForTest(SecureSession::Type::kCASE, 2, kLocalNodeId, kCasePeer1NodeId, |
| kPeer1CATs, 1, kFabricIndex, GetDefaultMRPConfig()); |
| EXPECT_TRUE(optionalSession.HasValue()); |
| |
| EXPECT_FALSE(connections.FindSecureSessionByLocalKey(1).HasValue()); |
| EXPECT_TRUE(connections.FindSecureSessionByLocalKey(2).HasValue()); |
| |
| // Second node, peer session id 3, local session id 4 |
| optionalSession = connections.CreateNewSecureSessionForTest(SecureSession::Type::kCASE, 4, kLocalNodeId, kCasePeer2NodeId, |
| kPeer2CATs, 3, kFabricIndex, GetDefaultMRPConfig()); |
| EXPECT_TRUE(optionalSession.HasValue()); |
| |
| EXPECT_FALSE(connections.FindSecureSessionByLocalKey(3).HasValue()); |
| EXPECT_TRUE(connections.FindSecureSessionByLocalKey(4).HasValue()); |
| |
| System::Clock::Internal::SetSystemClockForTesting(realClock); |
| } |
| |
| struct ExpiredCallInfo |
| { |
| int callCount = 0; |
| NodeId lastCallNodeId = 0; |
| PeerAddress lastCallPeerAddress = PeerAddress::Uninitialized(); |
| }; |
| |
| } // namespace |