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 MyVector<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 MyVector<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 MyVector<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 MyVector<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!");
101 myerror("Server Error: Invalid HMAC! Potential Attack!\n");
104 int64_t seqnum = bb->getLong();
105 int64_t machineid = bb->getLong();
106 int numentries = bb->getInt();
107 Slot *slot = new Slot(table, seqnum, machineid, prevhmac, hmac, -1);
109 for (int i = 0; i < numentries; i++) {
110 slot->addShallowEntry(Entry_decode(slot, bb));
117 char Slot::getType() {
121 Array<char> *Slot::encode(Mac *mac) {
122 Array<char> *array = new Array<char>(SLOT_SIZE);
123 ByteBuffer *bb = ByteBuffer_wrap(array);
124 /* Leave space for the slot HMAC. */
125 bb->position(HMAC_SIZE);
128 bb->putLong(machineid);
129 bb->putInt(entries->size());
130 for (uint ei = 0; ei < entries->size(); ei++) {
131 Entry *entry = entries->get(ei);
134 /* Compute our HMAC */
135 mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE);
136 Array<char> *realmac = mac->doFinal();
147 * Returns the live set of entries for this Slot. Generates a fake
148 * LastMessage entry to represent the information stored by the slot
152 MyVector<Entry *> *Slot::getLiveEntries(bool resize) {
153 MyVector<Entry *> *liveEntries = new MyVector<Entry *>();
154 for (uint ei = 0; ei < entries->size(); ei++) {
155 Entry *entry = entries->get(ei);
156 if (entry->isLive()) {
157 if (!resize || entry->getType() != TypeTableStatus)
158 liveEntries->add(entry);
162 if (seqnumlive && !resize) {
163 if (! fakeLastMessage)
164 fakeLastMessage = new LastMessage(this, machineid, seqnum);
165 liveEntries->add(fakeLastMessage);
172 * Records that a newer slot records the fact that this slot was
173 * sent by the relevant machine.
176 void Slot::setDead() {
178 decrementLiveCount();
182 * Update the count of live entries.
185 void Slot::decrementLiveCount() {
187 if (livecount == 0) {
188 table->decrementLiveCount();
192 Array<char> *Slot::getSlotCryptIV() {
193 ByteBuffer *buffer = ByteBuffer_allocate(CloudComm_IV_SIZE);
194 buffer->putLong(machineid);
195 int64_t localSequenceNumberShift = localSequenceNumber << 16;
196 buffer->putLong(localSequenceNumberShift);
197 Array<char> * array = buffer->array();
198 buffer->releaseArray();