2 #include "ByteBuffer.h"
7 #include "LastMessage.h"
9 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array<char> *_prevhmac, Array<char> *_hmac, int64_t _localSequenceNumber) :
13 machineid(_machineid),
14 entries(new Vector<Entry *>()),
17 freespace(SLOT_SIZE - getBaseSize()),
19 localSequenceNumber(_localSequenceNumber) {
22 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array<char> *_prevhmac, int64_t _localSequenceNumber) :
26 machineid(_machineid),
27 entries(new Vector<Entry *>()),
30 freespace(SLOT_SIZE - getBaseSize()),
32 localSequenceNumber(_localSequenceNumber) {
35 Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, int64_t _localSequenceNumber) :
37 prevhmac(new Array<char>(HMAC_SIZE)),
39 machineid(_machineid),
40 entries(new Vector<Entry *>()),
43 freespace(SLOT_SIZE - getBaseSize()),
45 localSequenceNumber(_localSequenceNumber) {
48 Entry *Slot::addEntry(Entry *e) {
52 freespace -= e->getSize();
56 void Slot::removeEntry(Entry *e) {
59 freespace += e->getSize();
62 void Slot::addShallowEntry(Entry *e) {
65 freespace -= e->getSize();
69 * Returns true if the slot has free space to hold the entry without
70 * using its reserved space. */
72 bool Slot::hasSpace(Entry *e) {
73 int newfreespace = freespace - e->getSize();
74 return newfreespace >= 0;
77 Vector<Entry *> *Slot::getEntries() {
81 Slot *Slotdecode(Table *table, Array<char> *array, Mac *mac) {
82 mac->update(array, HMAC_SIZE, array.length - HMAC_SIZE);
83 Array<char> *realmac = mac->doFinal();
85 ByteBuffer *bb = ByteBuffer_wrap(array);
86 Array<char> *hmac = new Array<char>(HMAC_SIZE);
87 Array<char> *prevhmac = new Array<char>(HMAC_SIZE);
90 if (!realmac->equals(hmac))
91 throw new Error("Server Error: Invalid HMAC! Potential Attack!");
93 int64_t seqnum = bb->getLong();
94 int64_t machineid = bb->getLong();
95 int numentries = bb->getInt();
96 Slot *slot = new Slot(table, seqnum, machineid, prevhmac, hmac, -1);
98 for (int i = 0; i < numentries; i++) {
99 slot->addShallowEntry(Entry_decode(slot, bb));
105 Array<char> *Slot::encode(Mac *mac) {
106 Array<char> *array = new Array<char>(SLOT_SIZE);
107 ByteBuffer *bb = ByteBuffer_wrap(array);
108 /* Leave space for the slot HMAC. */
109 bb->position(HMAC_SIZE);
112 bb->putLong(machineid);
113 bb->putInt(entries->size());
114 for (Entry *entry : entries) {
117 /* Compute our HMAC */
118 mac->update(array, HMAC_SIZE, array.length - HMAC_SIZE);
119 Array<char> *realmac = mac->doFinal();
128 * Returns the live set of entries for this Slot. Generates a fake
129 * LastMessage entry to represent the information stored by the slot
133 Vector<Entry *> *Slot::getLiveEntries(bool resize) {
134 Vector<Entry *> *liveEntries = new Vector<Entry *>();
135 for (Entry *entry : entries) {
136 if (entry->isLive()) {
137 if (!resize || entry->getType() != TypeTableStatus)
138 liveEntries->add(entry);
142 if (seqnumlive && !resize)
143 liveEntries->add(new LastMessage(this, machineid, seqnum));
150 * Records that a newer slot records the fact that this slot was
151 * sent by the relevant machine.
154 void Slot::setDead() {
156 decrementLiveCount();
160 * Update the count of live entries.
163 void Slot::decrementLiveCount() {
165 if (livecount == 0) {
166 table->decrementLiveCount();
170 Array<char> *Slot::getSlotCryptIV() {
171 ByteBuffer *buffer = ByteBuffer_allocate(CloudComm_IV_SIZE);
172 buffer->putLong(machineid);
173 int64_t localSequenceNumberShift = localSequenceNumber << 16;
174 buffer->putLong(localSequenceNumberShift);
175 return buffer->array();