X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=version2%2Fsrc%2FC%2FSlot.cpp;fp=version2%2Fsrc%2FC%2FSlot.cpp;h=31cce578dd3e7bac90befcb6cca073a32818c8bf;hb=786e40250f31eff04eec25bbcaae3cd916fedb14;hp=0000000000000000000000000000000000000000;hpb=3f24bffc82ebfe2730308b63100af08645316577;p=iotcloud.git diff --git a/version2/src/C/Slot.cpp b/version2/src/C/Slot.cpp new file mode 100644 index 0000000..31cce57 --- /dev/null +++ b/version2/src/C/Slot.cpp @@ -0,0 +1,200 @@ +#include "Slot.h" +#include "ByteBuffer.h" +#include "Entry.h" +#include "Error.h" +#include "CloudComm.h" +#include "Table.h" +#include "LastMessage.h" +#include "Mac.h" + +Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array *_prevhmac, Array *_hmac, int64_t _localSequenceNumber) : + seqnum(_seqnum), + prevhmac(_prevhmac), + hmac(_hmac), + machineid(_machineid), + entries(new Vector()), + livecount(1), + seqnumlive(true), + freespace(SLOT_SIZE - getBaseSize()), + table(_table), + fakeLastMessage(NULL), + localSequenceNumber(_localSequenceNumber) { +} + +Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, Array *_prevhmac, int64_t _localSequenceNumber) : + seqnum(_seqnum), + prevhmac(_prevhmac), + hmac(NULL), + machineid(_machineid), + entries(new Vector()), + livecount(1), + seqnumlive(true), + freespace(SLOT_SIZE - getBaseSize()), + table(_table), + fakeLastMessage(NULL), + localSequenceNumber(_localSequenceNumber) { +} + +Slot::Slot(Table *_table, int64_t _seqnum, int64_t _machineid, int64_t _localSequenceNumber) : + seqnum(_seqnum), + prevhmac(new Array(HMAC_SIZE)), + hmac(NULL), + machineid(_machineid), + entries(new Vector()), + livecount(1), + seqnumlive(true), + freespace(SLOT_SIZE - getBaseSize()), + table(_table), + fakeLastMessage(NULL), + localSequenceNumber(_localSequenceNumber) { +} + +Slot::~Slot() { + if (hmac != NULL) + delete hmac; + delete prevhmac; + for(uint i=0; i< entries->size(); i++) + entries->get(i)->releaseRef(); + delete entries; + if (fakeLastMessage) + delete fakeLastMessage; +} + +Entry *Slot::addEntry(Entry *e) { + e = e->getCopy(this); + entries->add(e); + livecount++; + freespace -= e->getSize(); + return e; +} + +void Slot::addShallowEntry(Entry *e) { + entries->add(e); + livecount++; + freespace -= e->getSize(); +} + +/** + * Returns true if the slot has free space to hold the entry without + * using its reserved space. */ + +bool Slot::hasSpace(Entry *e) { + int newfreespace = freespace - e->getSize(); + return newfreespace >= 0; +} + +Vector *Slot::getEntries() { + return entries; +} + +Slot *Slot_decode(Table *table, Array *array, Mac *mac) { + mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE); + Array *realmac = mac->doFinal(); + + ByteBuffer *bb = ByteBuffer_wrap(array); + Array *hmac = new Array(HMAC_SIZE); + Array *prevhmac = new Array(HMAC_SIZE); + bb->get(hmac); + bb->get(prevhmac); + if (!realmac->equals(hmac)) + throw new Error("Server Error: Invalid HMAC! Potential Attack!"); + delete realmac; + + int64_t seqnum = bb->getLong(); + int64_t machineid = bb->getLong(); + int numentries = bb->getInt(); + Slot *slot = new Slot(table, seqnum, machineid, prevhmac, hmac, -1); + + for (int i = 0; i < numentries; i++) { + slot->addShallowEntry(Entry_decode(slot, bb)); + } + bb->releaseArray(); + delete bb; + return slot; +} + +char Slot::getType() { + return TypeSlot; +} + +Array *Slot::encode(Mac *mac) { + Array *array = new Array(SLOT_SIZE); + ByteBuffer *bb = ByteBuffer_wrap(array); + /* Leave space for the slot HMAC. */ + bb->position(HMAC_SIZE); + bb->put(prevhmac); + bb->putLong(seqnum); + bb->putLong(machineid); + bb->putInt(entries->size()); + for (uint ei = 0; ei < entries->size(); ei++) { + Entry *entry = entries->get(ei); + entry->encode(bb); + } + /* Compute our HMAC */ + mac->update(array, HMAC_SIZE, array->length() - HMAC_SIZE); + Array *realmac = mac->doFinal(); + hmac = realmac; + bb->position(0); + bb->put(realmac); + bb->releaseArray(); + delete bb; + return array; +} + + +/** + * Returns the live set of entries for this Slot. Generates a fake + * LastMessage entry to represent the information stored by the slot + * itself. + */ + +Vector *Slot::getLiveEntries(bool resize) { + Vector *liveEntries = new Vector(); + for (uint ei = 0; ei < entries->size(); ei++) { + Entry *entry = entries->get(ei); + if (entry->isLive()) { + if (!resize || entry->getType() != TypeTableStatus) + liveEntries->add(entry); + } + } + + if (seqnumlive && !resize) { + if (! fakeLastMessage) + fakeLastMessage = new LastMessage(this, machineid, seqnum); + liveEntries->add(fakeLastMessage); + } + return liveEntries; +} + + +/** + * Records that a newer slot records the fact that this slot was + * sent by the relevant machine. + */ + +void Slot::setDead() { + seqnumlive = false; + decrementLiveCount(); +} + +/** + * Update the count of live entries. + */ + +void Slot::decrementLiveCount() { + livecount--; + if (livecount == 0) { + table->decrementLiveCount(); + } +} + +Array *Slot::getSlotCryptIV() { + ByteBuffer *buffer = ByteBuffer_allocate(CloudComm_IV_SIZE); + buffer->putLong(machineid); + int64_t localSequenceNumberShift = localSequenceNumber << 16; + buffer->putLong(localSequenceNumberShift); + Array * array = buffer->array(); + buffer->releaseArray(); + delete buffer; + return array; +}