aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/main/java/org/whispersystems/libaxolotl/state/SessionRecord.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/main/java/org/whispersystems/libaxolotl/state/SessionRecord.java')
-rw-r--r--java/src/main/java/org/whispersystems/libaxolotl/state/SessionRecord.java117
1 files changed, 117 insertions, 0 deletions
diff --git a/java/src/main/java/org/whispersystems/libaxolotl/state/SessionRecord.java b/java/src/main/java/org/whispersystems/libaxolotl/state/SessionRecord.java
new file mode 100644
index 00000000..76c64922
--- /dev/null
+++ b/java/src/main/java/org/whispersystems/libaxolotl/state/SessionRecord.java
@@ -0,0 +1,117 @@
+package org.whispersystems.libaxolotl.state;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.whispersystems.libaxolotl.state.StorageProtos.RecordStructure;
+import static org.whispersystems.libaxolotl.state.StorageProtos.SessionStructure;
+
+/**
+ * A SessionRecord encapsulates the state of an ongoing session.
+ *
+ * @author Moxie Marlinspike
+ */
+public class SessionRecord {
+
+ private static final int ARCHIVED_STATES_MAX_LENGTH = 40;
+
+ private SessionState sessionState = new SessionState();
+ private LinkedList<SessionState> previousStates = new LinkedList<>();
+ private boolean fresh = false;
+
+ public SessionRecord() {
+ this.fresh = true;
+ }
+
+ public SessionRecord(SessionState sessionState) {
+ this.sessionState = sessionState;
+ this.fresh = false;
+ }
+
+ public SessionRecord(byte[] serialized) throws IOException {
+ RecordStructure record = RecordStructure.parseFrom(serialized);
+ this.sessionState = new SessionState(record.getCurrentSession());
+ this.fresh = false;
+
+ for (SessionStructure previousStructure : record.getPreviousSessionsList()) {
+ previousStates.add(new SessionState(previousStructure));
+ }
+ }
+
+ public boolean hasSessionState(int version, byte[] aliceBaseKey) {
+ if (sessionState.getSessionVersion() == version &&
+ Arrays.equals(aliceBaseKey, sessionState.getAliceBaseKey()))
+ {
+ return true;
+ }
+
+ for (SessionState state : previousStates) {
+ if (state.getSessionVersion() == version &&
+ Arrays.equals(aliceBaseKey, state.getAliceBaseKey()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public SessionState getSessionState() {
+ return sessionState;
+ }
+
+ /**
+ * @return the list of all currently maintained "previous" session states.
+ */
+ public List<SessionState> getPreviousSessionStates() {
+ return previousStates;
+ }
+
+
+ public boolean isFresh() {
+ return fresh;
+ }
+
+ /**
+ * Move the current {@link SessionState} into the list of "previous" session states,
+ * and replace the current {@link org.whispersystems.libaxolotl.state.SessionState}
+ * with a fresh reset instance.
+ */
+ public void archiveCurrentState() {
+ promoteState(new SessionState());
+ }
+
+ public void promoteState(SessionState promotedState) {
+ this.previousStates.addFirst(sessionState);
+ this.sessionState = promotedState;
+
+ if (previousStates.size() > ARCHIVED_STATES_MAX_LENGTH) {
+ previousStates.removeLast();
+ }
+ }
+
+ public void setState(SessionState sessionState) {
+ this.sessionState = sessionState;
+ }
+
+ /**
+ * @return a serialized version of the current SessionRecord.
+ */
+ public byte[] serialize() {
+ List<SessionStructure> previousStructures = new LinkedList<>();
+
+ for (SessionState previousState : previousStates) {
+ previousStructures.add(previousState.getStructure());
+ }
+
+ RecordStructure record = RecordStructure.newBuilder()
+ .setCurrentSession(sessionState.getStructure())
+ .addAllPreviousSessions(previousStructures)
+ .build();
+
+ return record.toByteArray();
+ }
+
+}