2 #include "ByteBuffer.h"
7 #include "LastMessage.h"
10 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array<char> *_prevhmac, Array<char> *_hmac, int64_t _localSequenceNumber) :
14 machineid(_machineid),
15 entries(new Vector<Entry *>()),
18 freespace(SLOT_SIZE - getBaseSize()),
20 localSequenceNumber(_localSequenceNumber) {
23 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array<char> *_prevhmac, int64_t _localSequenceNumber) :
27 machineid(_machineid),
28 entries(new Vector<Entry *>()),
31 freespace(SLOT_SIZE - getBaseSize()),
33 localSequenceNumber(_localSequenceNumber) {
36 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, int64_t _localSequenceNumber) :
38 prevhmac(new Array<char>(HMAC_SIZE)),
40 machineid(_machineid),
41 entries(new Vector<Entry *>()),
44 freespace(SLOT_SIZE - getBaseSize()),
46 localSequenceNumber(_localSequenceNumber) {
53 for(uint i=0; i< entries->size(); i++)
54 delete entries->get(i);
58 Entry *Slot::addEntry(Entry *e) {
62 freespace -= e->getSize();
66 void Slot::addShallowEntry(Entry *e) {
69 freespace -= e->getSize();
73 * Returns true if the slot has free space to hold the entry without
74 * using its reserved space. */
76 bool Slot::hasSpace(Entry *e) {
77 int newfreespace = freespace - e->getSize();
78 return newfreespace >= 0;
81 Vector<Entry *> *Slot::getEntries() {
85 Slot *Slot_decode(Table *table, Array<char> *array, Mac *mac) {
86 mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE);
87 Array<char> *realmac = mac->doFinal();
89 ByteBuffer *bb = ByteBuffer_wrap(array);
90 Array<char> *hmac = new Array<char>(HMAC_SIZE);
91 Array<char> *prevhmac = new Array<char>(HMAC_SIZE);
94 if (!realmac->equals(hmac))
95 throw new Error("Server Error: Invalid HMAC! Potential Attack!");
98 int64_t seqnum = bb->getLong();
99 int64_t machineid = bb->getLong();
100 int numentries = bb->getInt();
101 Slot *slot = new Slot(table, seqnum, machineid, prevhmac, hmac, -1);
103 for (int i = 0; i < numentries; i++) {
104 slot->addShallowEntry(Entry_decode(slot, bb));
111 char Slot::getType() {
115 Array<char> *Slot::encode(Mac *mac) {
116 Array<char> *array = new Array<char>(SLOT_SIZE);
117 ByteBuffer *bb = ByteBuffer_wrap(array);
118 /* Leave space for the slot HMAC. */
119 bb->position(HMAC_SIZE);
122 bb->putLong(machineid);
123 bb->putInt(entries->size());
124 for (uint ei = 0; ei < entries->size(); ei++) {
125 Entry *entry = entries->get(ei);
128 /* Compute our HMAC */
129 mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE);
130 Array<char> *realmac = mac->doFinal();
141 * Returns the live set of entries for this Slot. Generates a fake
142 * LastMessage entry to represent the information stored by the slot
146 Vector<Entry *> *Slot::getLiveEntries(bool resize) {
147 Vector<Entry *> *liveEntries = new Vector<Entry *>();
148 for (uint ei = 0; ei < entries->size(); ei++) {
149 Entry *entry = entries->get(ei);
150 if (entry->isLive()) {
151 if (!resize || entry->getType() != TypeTableStatus)
152 liveEntries->add(entry);
156 if (seqnumlive && !resize)
157 liveEntries->add(new LastMessage(this, machineid, seqnum));
164 * Records that a newer slot records the fact that this slot was
165 * sent by the relevant machine.
168 void Slot::setDead() {
170 decrementLiveCount();
174 * Update the count of live entries.
177 void Slot::decrementLiveCount() {
179 if (livecount == 0) {
180 table->decrementLiveCount();
184 Array<char> *Slot::getSlotCryptIV() {
185 ByteBuffer *buffer = ByteBuffer_allocate(CloudComm_IV_SIZE);
186 buffer->putLong(machineid);
187 int64_t localSequenceNumberShift = localSequenceNumber << 16;
188 buffer->putLong(localSequenceNumberShift);
189 return buffer->array();