All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.whispersystems.libaxolotl.state.SessionRecord Maven / Gradle / Ivy

The newest version!
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 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 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 previousStructures = new LinkedList<>();

    for (SessionState previousState : previousStates) {
      previousStructures.add(previousState.getStructure());
    }

    RecordStructure record = RecordStructure.newBuilder()
                                            .setCurrentSession(sessionState.getStructure())
                                            .addAllPreviousSessions(previousStructures)
                                            .build();

    return record.toByteArray();
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy