-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Session Refactoring to bring logic more near to specs (#590)
* Implement MessageCounters a defined and test This commit moves the MessageCounter class into an own file and implements the required variants as defined by specification. It also adds tests * Move MessageCounter into Session As by specification the message counter should be handled by the respective session, so also move it there. * Add Message Reception State implementation and tests To detect duplicate messages the spec defined message Reception state which tracks messages and tests. * Add message reception states into session The message Reception state for the incoming messages is tracked by the sessions. So we add it there. The method "updateMessageCounter" throws an DuplicateMessageError in case of a duplicate. * Remove some messagecounter leftovers in exchangemanager * Adjust SecureSession creation to object style * Refactor duplicate identifier for unspecificed node id * Adjust testing for recent changes * Refactor calculation of next session id The logic to find the next available session id should wrap and search free spots - in worst case it should close the oldest unused session. Additionally this commit moves the session id finding to the respective place where it is needed to prevent taking session ids that are then not ued because of errors. * Allow multiple UnsecureSessions as defined by specs Unsecure Sessions are created by their initiator Node Id ... od 0 if not specified. With this change UnsecureSessions also get a close callback for cleanup reasons only. * Close unsecure sessions after usage * remove unneeded typecase after changes * Update session determination * Add Message duplication handling * Update Exchange handling to the specs * Update CASE handling to handle more error cases correctly * Close exchange after retransmissions ... if close is not already in progress * remove debug logging * [execute-chiptests-long] prepare changelog * enhance tests * Changelog * Address review feedback
- Loading branch information
Showing
23 changed files
with
1,665 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
110 changes: 110 additions & 0 deletions
110
packages/matter-node.js/test/session/SessionManagerTest.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* @license | ||
* Copyright 2022-2023 Project CHIP Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
import { NodeId } from "@project-chip/matter.js/datatype"; | ||
import { SessionManager } from "@project-chip/matter.js/session"; | ||
import { StorageBackendMemory, StorageContext } from "@project-chip/matter.js/storage"; | ||
import { ByteArray } from "@project-chip/matter.js/util"; | ||
import * as assert from "assert"; | ||
|
||
const DUMMY_BYTEARRAY = new ByteArray(); | ||
|
||
describe("SessionManager", () => { | ||
describe("getNextAvailableSessionId", () => { | ||
let storage: StorageBackendMemory; | ||
let storageContext: StorageContext; | ||
let sessionManager: SessionManager<any>; | ||
|
||
beforeEach(() => { | ||
storage = new StorageBackendMemory(); | ||
storageContext = new StorageContext(storage, ["context"]); | ||
|
||
sessionManager = new SessionManager({}, storageContext); | ||
}); | ||
|
||
it("next number is increasing", async () => { | ||
let first = await sessionManager.getNextAvailableSessionId(); | ||
if (first === 0xffff) { | ||
// Keep test simple and just ignore the special case and let it overflow | ||
first = await sessionManager.getNextAvailableSessionId(); | ||
} | ||
const second = await sessionManager.getNextAvailableSessionId(); | ||
assert.strictEqual(first + 1, second); | ||
}); | ||
|
||
it("verify that id is 1 after being 0xffff", async () => { | ||
const first = await sessionManager.getNextAvailableSessionId(); | ||
if (first === 0xffff) { | ||
assert.strictEqual(await sessionManager.getNextAvailableSessionId(), 1); | ||
} else { | ||
for (let i = first; i < 0xfffe; i++) { | ||
// read over until one before overrun | ||
await sessionManager.getNextAvailableSessionId(); | ||
} | ||
assert.strictEqual(await sessionManager.getNextAvailableSessionId(), 0xffff); | ||
assert.strictEqual(await sessionManager.getNextAvailableSessionId(), 1); | ||
} | ||
}); | ||
|
||
it("verify that existing session ids are skipped", async () => { | ||
let first = await sessionManager.getNextAvailableSessionId(); | ||
if (first === 0xfffe) { | ||
// Keep test simple and just ignore the special case and let it overflow | ||
first = await sessionManager.getNextAvailableSessionId(); | ||
} | ||
if (first === 0xffff) { | ||
// Keep test simple and just ignore the special case and let it overflow | ||
first = await sessionManager.getNextAvailableSessionId(); | ||
} | ||
// Create a session with "next expected number" | ||
await sessionManager.createSecureSession({ | ||
sessionId: first + 1, | ||
fabric: undefined, | ||
peerNodeId: NodeId.UNSPECIFIED_NODE_ID, | ||
peerSessionId: 0x8d4b, | ||
sharedSecret: DUMMY_BYTEARRAY, | ||
salt: DUMMY_BYTEARRAY, | ||
isInitiator: false, | ||
isResumption: false, | ||
}); | ||
assert.strictEqual(await sessionManager.getNextAvailableSessionId(), first + 2); | ||
}); | ||
|
||
it("verify that oldest session gets closed when no more ids are available", async () => { | ||
const first = await sessionManager.getNextAvailableSessionId(); | ||
let firstClosed = false; | ||
await sessionManager.createSecureSession({ | ||
sessionId: first, | ||
fabric: undefined, | ||
peerNodeId: NodeId.UNSPECIFIED_NODE_ID, | ||
peerSessionId: 0x8d4b, | ||
sharedSecret: DUMMY_BYTEARRAY, | ||
salt: DUMMY_BYTEARRAY, | ||
isInitiator: false, | ||
isResumption: false, | ||
closeCallback: async () => { | ||
firstClosed = true; | ||
}, | ||
}); | ||
await MockTime.advance(1000); | ||
for (let i = 0; i < 0xfffe; i++) { | ||
const sessionId = await sessionManager.getNextAvailableSessionId(); | ||
await sessionManager.createSecureSession({ | ||
sessionId, | ||
fabric: undefined, | ||
peerNodeId: NodeId.UNSPECIFIED_NODE_ID, | ||
peerSessionId: 0x8d4b, | ||
sharedSecret: DUMMY_BYTEARRAY, | ||
salt: DUMMY_BYTEARRAY, | ||
isInitiator: false, | ||
isResumption: false, | ||
}); | ||
} | ||
assert.strictEqual(await sessionManager.getNextAvailableSessionId(), first); | ||
assert.strictEqual(firstClosed, true); | ||
}).timeout(10000); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.