more code
authorBrian Demsky <bdemsky@plrg.eecs.uci.edu>
Sat, 23 Jul 2016 20:31:33 +0000 (13:31 -0700)
committerBrian Demsky <bdemsky@plrg.eecs.uci.edu>
Sat, 23 Jul 2016 20:31:33 +0000 (13:31 -0700)
src/java/iotcloud/Entry.java
src/java/iotcloud/KeyValue.java
src/java/iotcloud/LastMessage.java
src/java/iotcloud/RejectedMessage.java
src/java/iotcloud/Slot.java
src/java/iotcloud/SlotIndexer.java [new file with mode: 0644]
src/java/iotcloud/Table.java
src/java/iotcloud/TableStatus.java

index 9f85bacec872ef10af0a4a1978d774b533285613..076b4fc197e1020e7511963728794376bee76401 100644 (file)
@@ -6,7 +6,8 @@ abstract class Entry {
        static final byte TypeLastMessage = 2;
        static final byte TypeRejectedMessage = 3;
        static final byte TypeTableStatus = 4;
-
+       boolean islive = true;
+       
        static Entry decode(ByteBuffer bb) {
                byte type=bb.get();
                switch(type) {
@@ -23,7 +24,17 @@ abstract class Entry {
                }
        }
 
+       boolean isLive() {
+               return islive;
+       }
+
+       void setDead() {
+               islive = false;
+       }
+       
        abstract void encode(ByteBuffer bb);
 
        abstract int getSize();
+
+       abstract byte getType();
 }
index 39125e27d41b1fc2a07a3dc9f52bb7e493f91381..36a56dce99ef45bcbd9fd29eba167c6537bd821f 100644 (file)
@@ -30,4 +30,8 @@ class KeyValue extends Entry {
        int getSize() {
                return 2*Integer.BYTES+key.length+value.length+Byte.BYTES;
        }
+
+       byte getType() {
+               return Entry.TypeKeyValue;
+       }
 }
index 023608bda13136777c190f59b2948f98454ce6cc..23e6bcdedb8d0607a11c543134ad7b1a37863c35 100644 (file)
@@ -26,4 +26,10 @@ class LastMessage extends Entry {
        int getSize() {
                return 2*Long.BYTES+Byte.BYTES;
        }
+
+       byte getType() {
+               return Entry.TypeLastMessage;
+       }
 }
+
+
index c0dfaa621fa49dabd4492e0ed32bd934a98959f6..f8af5ec1624ae6b688072da61eae8baf8d3e823f 100644 (file)
@@ -33,4 +33,8 @@ class RejectedMessage extends Entry {
        int getSize() {
                return 3*Long.BYTES + 2*Byte.BYTES;
        }
+
+       byte getType() {
+               return Entry.TypeRejectedMessage;
+       }
 }
index 8b6f61954de6f259d56b08fa2431a8a9df843a2e..8815a5bcbf42784fe1075bf575a86a19858d2779 100644 (file)
@@ -8,11 +8,11 @@ class Slot {
        public static final int SLOT_SIZE=2048;
        public static final int HMAC_SIZE=32;
 
-       long seqnum;
-       byte[] prevhmac;
-       byte[] hmac;
-       long machineid;
-       Vector<Entry> entries;
+       private long seqnum;
+       private byte[] prevhmac;
+       private byte[] hmac;
+       private long machineid;
+       private Vector<Entry> entries;
 
        Slot(long _seqnum, long _machineid, byte[] _prevhmac, byte[] _hmac, Vector<Entry> _entries) {
                seqnum=_seqnum;
@@ -33,6 +33,10 @@ class Slot {
        byte[] getPrevHMAC() {
                return prevhmac;
        }
+
+       Vector<Entry> getEntries() {
+               return entries;
+       }
        
        static Slot decode(byte[] array, Mac mac) {
                mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
@@ -44,7 +48,7 @@ class Slot {
                bb.get(hmac);
                bb.get(prevhmac);
                if (!Arrays.equals(realmac, hmac))
-                       throw new Error("Invalid HMAC!  Potential Attack!");
+                       throw new Error("Server Error: Invalid HMAC!  Potential Attack!");
 
                long seqnum=bb.getLong();
                long machineid=bb.getLong();
diff --git a/src/java/iotcloud/SlotIndexer.java b/src/java/iotcloud/SlotIndexer.java
new file mode 100644 (file)
index 0000000..4e344b7
--- /dev/null
@@ -0,0 +1,24 @@
+package iotcloud;
+
+class SlotIndexer {
+       private Slot[] updates;
+       private SlotBuffer buffer;
+       private long firstslotseqnum;
+       
+       SlotIndexer(Slot[] _updates, SlotBuffer _buffer) {
+               buffer = _buffer;
+               updates = _updates;
+               firstslotseqnum = updates[0].getSequenceNumber();
+       }
+
+       Slot getSlot(long seqnum) {
+               if (seqnum >= firstslotseqnum) {
+                       int offset = (int) (seqnum - firstslotseqnum);
+                       if (offset >= updates.length)
+                               throw new Error("Invalid Slot Sequence Number Reference");
+                       else
+                               return updates[offset];
+               } else
+                       return buffer.getSlot(seqnum);
+       }
+}
index 5c6ec6b5bfd3fd6d823460e12d5ebe3f556bfb96..679421ec518cb0c739a5de139c4653fc05881fa9 100644 (file)
@@ -7,15 +7,18 @@ import javax.crypto.*;
 public class Table {
        int numslots;
        HashMap<IoTString, IoTString> table=new HashMap<IoTString, IoTString>();
+       HashMap<Long, Long> lastmessage=new HashMap<Long, Long>();
        SlotBuffer buffer;
        CloudComm cloud;
        private Mac hmac;
        long sequencenumber;
+       long machineid;
        
-       public Table(String baseurl, String password) {
-               initCloud(baseurl, password);
+       public Table(String baseurl, String password, long _machineid) {
+               machineid=_machineid;
                buffer = new SlotBuffer();
                sequencenumber = 1;
+               initCloud(baseurl, password);
        }
 
        private void initCloud(String baseurl, String password) {
@@ -52,39 +55,65 @@ public class Table {
        void validateandupdate(Slot[] newslots) {
                //The cloud communication layer has checked slot HMACs already
                //before decoding
-
                if (newslots.length==0)
                        return;
 
                long firstseqnum=newslots[0].getSequenceNumber();
                if (firstseqnum < sequencenumber)
-                       throw new Error("Server sent older slots!");
+                       throw new Error("Server Error: Sent older slots!");
 
-               checkHMACChain(newslots);
-               
-               if (firstseqnum == (buffer.getNewestSeqNum()+1)) {
-                       //contiguous update
-               } else {
-                       //non-contiguous update
+               SlotIndexer indexer = new SlotIndexer(newslots, buffer);
+               checkHMACChain(indexer, newslots);
+               for(Slot slot: newslots) {
+                       processSlot(indexer, slot);
                }
-
                
        }
 
-       void checkHMACChain(Slot[] newslots) {
-               if (newslots[0].getSequenceNumber() == (buffer.getNewestSeqNum()+1)) {
-                       Slot prevslot=buffer.getSlot(buffer.getNewestSeqNum());
-                       Slot currslot=newslots[0];
-                       if (!Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
-                               throw new Error("Error in HMAC Chain");
-               }
+       void processEntry(KeyValue entry, SlotIndexer indexer, Slot slot) {
 
-               for(int i=1; i < newslots.length; i++) {
-                       Slot prevslot=newslots[i-1];
-                       Slot currslot=newslots[i];
-                       if (!Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
-                               throw new Error("Error in HMAC Chain");
+       }
+
+       void processEntry(LastMessage entry, SlotIndexer indexer, Slot slot) {
+
+       }
+
+       void processEntry(RejectedMessage entry, SlotIndexer indexer, Slot slot) {
+
+       }
+
+       void processEntry(TableStatus entry, SlotIndexer indexer, Slot slot) {
+
+       }
+       
+       void processSlot(SlotIndexer indexer, Slot slot) {
+               for(Entry entry : slot.getEntries()) {
+                       switch(entry.getType()) {
+                       case Entry.TypeKeyValue:
+                               processEntry((KeyValue)entry, indexer, slot);
+                               break;
+                       case Entry.TypeLastMessage:
+                               processEntry((LastMessage)entry, indexer, slot);
+                               break;
+                       case Entry.TypeRejectedMessage:
+                               processEntry((RejectedMessage)entry, indexer, slot);
+                               break;
+                       case Entry.TypeTableStatus:
+                               processEntry((TableStatus)entry, indexer, slot);
+                               break;
+                       default:
+                               throw new Error("Unrecognized type: "+entry.getType());
+                       }
                }
        }
        
+       void checkHMACChain(SlotIndexer indexer, Slot[] newslots) {
+               for(int i=0; i < newslots.length; i++) {
+                       Slot currslot=newslots[i];
+                       Slot prevslot=indexer.getSlot(currslot.getSequenceNumber()-1);
+                       if (prevslot != null &&
+                                       !Arrays.equals(prevslot.getHMAC(), currslot.getPrevHMAC()))
+                               throw new Error("Server Error: Invalid HMAC Chain");
+               }
+       }
 }
index 27f9017d006b660bb5072d176fe587fcaa41240e..970ce18de25cb9ef5dc37b4861527be18062a27b 100644 (file)
@@ -21,4 +21,8 @@ class TableStatus extends Entry {
        int getSize() {
                return Integer.BYTES+Byte.BYTES;
        }
+       
+       byte getType() {
+               return Entry.TypeTableStatus;
+       }
 }