3 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, char *_prevhmac, char *_hmac, int64_t _localSequenceNumber) {
5 machineid = _machineid;
8 entries = new Vector<Entry *>();
11 freespace = SLOT_SIZE - getBaseSize();
13 localSequenceNumber = _localSequenceNumber;
16 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, char *_prevhmac, int64_t _localSequenceNumber) {
17 this(_table, _seqnum, _machineid, _prevhmac, NULL, _localSequenceNumber);
20 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, int64_t _localSequenceNumber) {
21 this(_table, _seqnum, _machineid, new char[HMAC_SIZE], NULL, _localSequenceNumber);
24 Entry *Slot::addEntry(Entry *e) {
28 freespace -= e->getSize();
32 void Slot::removeEntry(Entry *e) {
35 freespace += e->getSize();
38 void Slot::addShallowEntry(Entry *e) {
41 freespace -= e->getSize();
45 * Returns true if the slot has free space to hold the entry without
46 * using its reserved space. */
48 bool Slot::hasSpace(Entry *e) {
49 int newfreespace = freespace - e->getSize();
50 return newfreespace >= 0;
53 Vector<Entry *> *Slot::getEntries() {
57 Slot *Slotdecode(Table *table, char *array, Mac *mac) {
58 mac->update(array, HMAC_SIZE, array.length - HMAC_SIZE);
59 char *realmac = mac->doFinal();
61 ByteBuffer *bb = ByteBuffer_wrap(array);
62 char *hmac = new char[HMAC_SIZE];
63 char *prevhmac = new char[HMAC_SIZE];
66 if (!Arrays.equals(realmac, hmac))
67 throw new Error("Server Error: Invalid HMAC! Potential Attack!");
69 int64_t seqnum = bb->getLong();
70 int64_t machineid = bb->getLong();
71 int numentries = bb->getInt();
72 Slot slot = new Slot(table, seqnum, machineid, prevhmac, hmac, -1);
74 for (int i = 0; i < numentries; i++) {
75 slot->addShallowEntry(Entry->decode(slot, bb));
81 char *Slot::encode(Mac mac) {
82 char *array = new char[SLOT_SIZE];
83 ByteBuffer *bb = ByteBuffer_wrap(array);
84 /* Leave space for the slot HMAC. */
85 bb->position(HMAC_SIZE);
88 bb->putLong(machineid);
89 bb->putInt(entries->size());
90 for (Entry entry : entries) {
93 /* Compute our HMAC */
94 mac->update(array, HMAC_SIZE, array.length - HMAC_SIZE);
95 char *realmac = mac->doFinal();
104 * Returns the live set of entries for this Slot. Generates a fake
105 * LastMessage entry to represent the information stored by the slot
109 Vector<Entry *> *Slot::getLiveEntries(bool resize) {
110 Vector<Entry *> *liveEntries = new Vector<Entry *>();
111 for (Entry *entry : entries) {
112 if (entry->isLive()) {
113 if (!resize || entry->getType() != Entry->TypeTableStatus)
114 liveEntries->add(entry);
118 if (seqnumlive && !resize)
119 liveEntries->add(new LastMessage(this, machineid, seqnum));
126 * Records that a newer slot records the fact that this slot was
127 * sent by the relevant machine.
130 void Slot::setDead() {
132 decrementLiveCount();
136 * Update the count of live entries.
139 void Slot::decrementLiveCount() {
141 if (livecount == 0) {
142 table->decrementLiveCount();
146 char *Slot::getSlotCryptIV() {
147 ByteBuffer *buffer = ByteBuffer_allocate(CloudComm.IV_SIZE);
148 buffer->putLong(machineid);
149 int64_t localSequenceNumberShift = localSequenceNumber << 16;
150 buffer->putLong(localSequenceNumberShift);
151 return buffer->array();