2 import java.util.Vector;
3 import java.nio.ByteBuffer;
4 import javax.crypto.Mac;
5 import java.util.Arrays;
8 * Data structuring for holding Slot information.
13 class Slot implements Liveness {
14 /** Sets the slot size. */
15 static final int SLOT_SIZE=2048;
16 /** Sets the size for the HMAC. */
17 static final int HMAC_SIZE=32;
19 /** Sequence number of the slot. */
20 private long seqnum;//
21 /** HMAC of previous slot. */
22 private byte[] prevhmac;//
23 /** HMAC of this slot. */
24 private byte[] hmac;//
25 /** Machine that sent this slot. */
26 private long machineid;//
27 /** Vector of entries in this slot. */
28 private Vector<Entry> entries;
29 /** Pieces of information that are live. */
30 private int livecount;//
31 /** Flag that indicates whether this slot is still live for
32 * recording the machine that sent it. */
33 private boolean seqnumlive;//
34 /** Number of bytes of free space. */
35 private int freespace;
36 /** Reference to Table */
39 Slot(Table _table, long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac) {
44 entries=new Vector<Entry>();
47 freespace = SLOT_SIZE - getBaseSize();
51 Slot(Table _table, long _seqnum, long _machineid, byte[] _prevhmac) {
52 this(_table, _seqnum, _machineid, _prevhmac, null);
56 Slot(long _seqnum, long _machineid) {
57 this(_seqnum, _machineid, new byte[ HMAC_SIZE], null);
59 Slot(Table _table, long _seqnum, long _machineid) {
60 this(_table, _seqnum, _machineid, new byte[HMAC_SIZE], null);
61 >>>>>>> f80cc30f294899f47cef3507334f8ca357862e5e
68 byte[] getPrevHMAC() {
72 void addEntry(Entry e) {
76 freespace -= e.getSize();
79 private void addShallowEntry(Entry e) {
82 freespace -= e.getSize();
86 * Returns true if the slot has free space to hold the entry without
87 * using its reserved space. */
89 boolean hasSpace(Entry e) {
90 int newfreespace = freespace - e.getSize();
91 return newfreespace >= 0;
94 Vector<Entry> getEntries() {
98 static Slot decode(Table table, byte[] array, Mac mac) {
99 mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
100 byte[] realmac=mac.doFinal();
102 ByteBuffer bb=ByteBuffer.wrap(array);
103 byte[] hmac=new byte[HMAC_SIZE];
104 byte[] prevhmac=new byte[HMAC_SIZE];
107 if (!Arrays.equals(realmac, hmac))
108 throw new Error("Server Error: Invalid HMAC! Potential Attack!");
110 long seqnum=bb.getLong();
111 long machineid=bb.getLong();
112 int numentries=bb.getInt();
113 Slot slot=new Slot(table, seqnum, machineid, prevhmac, hmac);
115 for(int i=0; i<numentries; i++) {
116 slot.addShallowEntry(Entry.decode(slot, bb));
122 byte[] encode(Mac mac) {
123 byte[] array=new byte[SLOT_SIZE];
124 ByteBuffer bb=ByteBuffer.wrap(array);
125 /* Leave space for the slot HMAC. */
126 bb.position(HMAC_SIZE);
129 bb.putLong(machineid);
130 bb.putInt(entries.size());
131 for(Entry entry:entries) {
134 /* Compute our HMAC */
135 mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
136 byte[] realmac=mac.doFinal();
144 * Returns the empty size of a Slot. Includes 2 HMACs, the machine
145 * identifier, the sequence number, and the number of entries.
148 return 2*HMAC_SIZE+2*Long.BYTES+Integer.BYTES;
152 * Returns the live set of entries for this Slot. Generates a fake
153 * LastMessage entry to represent the information stored by the slot
157 Vector<Entry> getLiveEntries(boolean resize) {
158 Vector<Entry> liveEntries=new Vector<Entry>();
159 for(Entry entry: entries) {
160 if (entry.isLive()) {
161 if (!resize || entry.getType() != Entry.TypeTableStatus)
162 liveEntries.add(entry);
166 if (seqnumlive && !resize)
167 liveEntries.add(new LastMessage(this, machineid, seqnum));
173 * Returns the sequence number of the slot.
176 long getSequenceNumber() {
181 * Returns the machine that sent this slot.
184 long getMachineID() {
189 * Records that a newer slot records the fact that this slot was
190 * sent by the relevant machine.
195 decrementLiveCount();
199 * Update the count of live entries.
202 void decrementLiveCount() {
205 table.decrementLiveCount();
209 * Returns whether the slot stores any live information.
213 return livecount > 0;
216 public String toString() {
217 return "<"+getSequenceNumber()+">";