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 fakeLastMessage(NULL),
21 localSequenceNumber(_localSequenceNumber) {
24 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array<char> *_prevhmac, int64_t _localSequenceNumber) :
28 machineid(_machineid),
29 entries(new Vector<Entry *>()),
32 freespace(SLOT_SIZE - getBaseSize()),
34 fakeLastMessage(NULL),
35 localSequenceNumber(_localSequenceNumber) {
38 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, int64_t _localSequenceNumber) :
40 prevhmac(new Array<char>(HMAC_SIZE)),
42 machineid(_machineid),
43 entries(new Vector<Entry *>()),
46 freespace(SLOT_SIZE - getBaseSize()),
48 fakeLastMessage(NULL),
49 localSequenceNumber(_localSequenceNumber) {
56 for(uint i=0; i< entries->size(); i++)
57 entries->get(i)->releaseRef();
60 delete fakeLastMessage;
63 Entry *Slot::addEntry(Entry *e) {
67 freespace -= e->getSize();
71 void Slot::addShallowEntry(Entry *e) {
74 freespace -= e->getSize();
78 * Returns true if the slot has free space to hold the entry without
79 * using its reserved space. */
81 bool Slot::hasSpace(Entry *e) {
82 int newfreespace = freespace - e->getSize();
83 return newfreespace >= 0;
86 Vector<Entry *> *Slot::getEntries() {
90 Slot *Slot_decode(Table *table, Array<char> *array, Mac *mac) {
91 mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE);
92 Array<char> *realmac = mac->doFinal();
94 ByteBuffer *bb = ByteBuffer_wrap(array);
95 Array<char> *hmac = new Array<char>(HMAC_SIZE);
96 Array<char> *prevhmac = new Array<char>(HMAC_SIZE);
99 if (!realmac->equals(hmac))
100 throw new Error("Server Error: Invalid HMAC! Potential Attack!");
103 int64_t seqnum = bb->getLong();
104 int64_t machineid = bb->getLong();
105 int numentries = bb->getInt();
106 Slot *slot = new Slot(table, seqnum, machineid, prevhmac, hmac, -1);
108 for (int i = 0; i < numentries; i++) {
109 slot->addShallowEntry(Entry_decode(slot, bb));
116 char Slot::getType() {
120 Array<char> *Slot::encode(Mac *mac) {
121 Array<char> *array = new Array<char>(SLOT_SIZE);
122 ByteBuffer *bb = ByteBuffer_wrap(array);
123 /* Leave space for the slot HMAC. */
124 bb->position(HMAC_SIZE);
127 bb->putLong(machineid);
128 bb->putInt(entries->size());
129 for (uint ei = 0; ei < entries->size(); ei++) {
130 Entry *entry = entries->get(ei);
133 /* Compute our HMAC */
134 mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE);
135 Array<char> *realmac = mac->doFinal();
146 * Returns the live set of entries for this Slot. Generates a fake
147 * LastMessage entry to represent the information stored by the slot
151 Vector<Entry *> *Slot::getLiveEntries(bool resize) {
152 Vector<Entry *> *liveEntries = new Vector<Entry *>();
153 for (uint ei = 0; ei < entries->size(); ei++) {
154 Entry *entry = entries->get(ei);
155 if (entry->isLive()) {
156 if (!resize || entry->getType() != TypeTableStatus)
157 liveEntries->add(entry);
161 if (seqnumlive && !resize) {
162 if (! fakeLastMessage)
163 fakeLastMessage = new LastMessage(this, machineid, seqnum);
164 liveEntries->add(fakeLastMessage);
171 * Records that a newer slot records the fact that this slot was
172 * sent by the relevant machine.
175 void Slot::setDead() {
177 decrementLiveCount();
181 * Update the count of live entries.
184 void Slot::decrementLiveCount() {
186 if (livecount == 0) {
187 table->decrementLiveCount();
191 Array<char> *Slot::getSlotCryptIV() {
192 ByteBuffer *buffer = ByteBuffer_allocate(CloudComm_IV_SIZE);
193 buffer->putLong(machineid);
194 int64_t localSequenceNumberShift = localSequenceNumber << 16;
195 buffer->putLong(localSequenceNumberShift);
196 Array<char> * array = buffer->array();
197 buffer->releaseArray();