+++ /dev/null
-package iotcloud;
-import java.util.Vector;
-import java.nio.ByteBuffer;
-import javax.crypto.Mac;
-import java.util.Arrays;
-
-/**
- * Data structuring for holding Slot information.
- * @author Brian Demsky
- * @version 1.0
- */
-
-class Slot implements Liveness {
- /** Sets the slot size. */
- static final int SLOT_SIZE=2048;
- /** Sets the size for the HMAC. */
- static final int HMAC_SIZE=32;
-
- /** Sequence number of the slot. */
- private long seqnum;
- /** HMAC of previous slot. */
- private byte[] prevhmac;
- /** HMAC of this slot. */
- private byte[] hmac;
- /** Machine that sent this slot. */
- private long machineid;
- /** Vector of entries in this slot. */
- private Vector<Entry> entries;
- /** Pieces of information that are live. */
- private int livecount;
- /** Flag that indicates whether this slot is still live for
- * recording the machine that sent it. */
- private boolean seqnumlive;
- /** Number of bytes of free space. */
- private int freespace;
- /** Reference to Table */
- private Table table;
-
- Slot(Table _table, long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac) {
- seqnum=_seqnum;
- machineid=_machineid;
- prevhmac=_prevhmac;
- hmac=_hmac;
- entries=new Vector<Entry>();
- livecount=1;
- seqnumlive=true;
- freespace = SLOT_SIZE - getBaseSize();
- table=_table;
- }
-
- Slot(Table _table, long _seqnum, long _machineid, byte[] _prevhmac) {
- this(_table, _seqnum, _machineid, _prevhmac, null);
- }
-
- Slot(Table _table, long _seqnum, long _machineid) {
- this(_table, _seqnum, _machineid, new byte[HMAC_SIZE], null);
- }
-
- byte[] getHMAC() {
- return hmac;
- }
-
- byte[] getPrevHMAC() {
- return prevhmac;
- }
-
- void addEntry(Entry e) {
- e=e.getCopy(this);
- entries.add(e);
- livecount++;
- freespace -= e.getSize();
- }
-
- private void addShallowEntry(Entry e) {
- entries.add(e);
- livecount++;
- freespace -= e.getSize();
- }
-
- /**
- * Returns true if the slot has free space to hold the entry without
- * using its reserved space. */
-
- boolean hasSpace(Entry e) {
- int newfreespace = freespace - e.getSize();
- return newfreespace >= 0;
- }
-
- Vector<Entry> getEntries() {
- return entries;
- }
-
- static Slot decode(Table table, byte[] array, Mac mac) {
- mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
- byte[] realmac=mac.doFinal();
-
- ByteBuffer bb=ByteBuffer.wrap(array);
- byte[] hmac=new byte[HMAC_SIZE];
- byte[] prevhmac=new byte[HMAC_SIZE];
- bb.get(hmac);
- bb.get(prevhmac);
- if (!Arrays.equals(realmac, hmac))
- throw new Error("Server Error: Invalid HMAC! Potential Attack!");
-
- long seqnum=bb.getLong();
- long machineid=bb.getLong();
- int numentries=bb.getInt();
- Slot slot=new Slot(table, seqnum, machineid, prevhmac, hmac);
-
- for(int i=0; i<numentries; i++) {
- slot.addShallowEntry(Entry.decode(slot, bb));
- }
-
- return slot;
- }
-
- byte[] encode(Mac mac) {
- byte[] array=new byte[SLOT_SIZE];
- ByteBuffer bb=ByteBuffer.wrap(array);
- /* Leave space for the slot HMAC. */
- bb.position(HMAC_SIZE);
- bb.put(prevhmac);
- bb.putLong(seqnum);
- bb.putLong(machineid);
- bb.putInt(entries.size());
- for(Entry entry:entries) {
- entry.encode(bb);
- }
- /* Compute our HMAC */
- mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
- byte[] realmac=mac.doFinal();
- hmac = realmac;
- bb.position(0);
- bb.put(realmac);
- return array;
- }
-
- /**
- * Returns the empty size of a Slot. Includes 2 HMACs, the machine
- * identifier, the sequence number, and the number of entries.
- */
- int getBaseSize() {
- return 2*HMAC_SIZE+2*Long.BYTES+Integer.BYTES;
- }
-
- /**
- * Returns the live set of entries for this Slot. Generates a fake
- * LastMessage entry to represent the information stored by the slot
- * itself.
- */
-
- Vector<Entry> getLiveEntries(boolean resize) {
- Vector<Entry> liveEntries=new Vector<Entry>();
- for(Entry entry: entries) {
- if (entry.isLive()) {
- if (!resize || entry.getType() != Entry.TypeTableStatus)
- liveEntries.add(entry);
- }
- }
-
- if (seqnumlive && !resize)
- liveEntries.add(new LastMessage(this, machineid, seqnum));
-
- return liveEntries;
- }
-
- /**
- * Returns the sequence number of the slot.
- */
-
- long getSequenceNumber() {
- return seqnum;
- }
-
- /**
- * Returns the machine that sent this slot.
- */
-
- long getMachineID() {
- return machineid;
- }
-
- /**
- * Records that a newer slot records the fact that this slot was
- * sent by the relevant machine.
- */
-
- void setDead() {
- seqnumlive=false;
- decrementLiveCount();
- }
-
- /**
- * Update the count of live entries.
- */
-
- void decrementLiveCount() {
- livecount--;
- if (livecount==0)
- table.decrementLiveCount();
- }
-
- /**
- * Returns whether the slot stores any live information.
- */
-
- boolean isLive() {
- return livecount > 0;
- }
-
- public String toString() {
- return "<"+getSequenceNumber()+">";
- }
-}