More Java Code
authorBrian Demsky <bdemsky@plrg.eecs.uci.edu>
Sat, 23 Jul 2016 18:18:51 +0000 (11:18 -0700)
committerBrian Demsky <bdemsky@plrg.eecs.uci.edu>
Sat, 23 Jul 2016 18:18:51 +0000 (11:18 -0700)
src/.gitignore [deleted file]
src/java/iotcloud/CloudComm.java
src/java/iotcloud/IoTString.java
src/java/iotcloud/RejectedMessage.java
src/java/iotcloud/Slot.java
src/java/iotcloud/SlotBuffer.java [new file with mode: 0644]
src/java/iotcloud/Table.java

diff --git a/src/.gitignore b/src/.gitignore
deleted file mode 100644 (file)
index 0cf5f64..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-*.o
-*~
-*.class
index 4f64036..eb061a4 100644 (file)
@@ -26,55 +26,62 @@ class CloudComm {
        }
 
        public Slot[] putSlot(Slot slot, int max) throws IOException{
-               long sequencenumber=slot.getSequenceNumber();
-               byte[] bytes=slot.encode(mac);
-               
-               URL url=buildRequest(true, sequencenumber, max);
-               URLConnection con=url.openConnection();
-               HttpURLConnection http = (HttpURLConnection) con;
-               http.setRequestMethod("POST");
-               http.setFixedLengthStreamingMode(bytes.length);
-               http.setDoOutput(true);
-               http.connect();
-               OutputStream os=http.getOutputStream();
-               os.write(bytes);
-               System.out.println(http.getResponseMessage());
-
-               InputStream is=http.getInputStream();
-               DataInputStream dis=new DataInputStream(is);
-               byte[] resptype=new byte[7];
-               dis.readFully(resptype);
-               if (Arrays.equals(resptype, "getslot".getBytes()))
-                       return processSlots(dis);
-               else if (Arrays.equals(resptype, "putslot".getBytes()))
-                       return null;
-               else
-                       throw new Error("Bad response to putslot");
+               try {
+                       long sequencenumber=slot.getSequenceNumber();
+                       byte[] bytes=slot.encode(mac);
+                       
+                       URL url=buildRequest(true, sequencenumber, max);
+                       URLConnection con=url.openConnection();
+                       HttpURLConnection http = (HttpURLConnection) con;
+                       http.setRequestMethod("POST");
+                       http.setFixedLengthStreamingMode(bytes.length);
+                       http.setDoOutput(true);
+                       http.connect();
+                       OutputStream os=http.getOutputStream();
+                       os.write(bytes);
+                       System.out.println(http.getResponseMessage());
+                       
+                       InputStream is=http.getInputStream();
+                       DataInputStream dis=new DataInputStream(is);
+                       byte[] resptype=new byte[7];
+                       dis.readFully(resptype);
+                       if (Arrays.equals(resptype, "getslot".getBytes()))
+                               return processSlots(dis);
+                       else if (Arrays.equals(resptype, "putslot".getBytes()))
+                               return null;
+                       else
+                               throw new Error("Bad response to putslot");
+               } catch (Exception e) {
+                       throw new Error("putSlot failed");
+               }
        }
        
-       public Slot[] getSlots(long sequencenumber) throws IOException {
-               URL url=buildRequest(false, sequencenumber, 0);
-               URLConnection con=url.openConnection();
-               HttpURLConnection http = (HttpURLConnection) con;
-               http.setRequestMethod("POST");
-               http.connect();
-               System.out.println(http.getResponseMessage());
-               InputStream is=http.getInputStream();
-
-               DataInputStream dis=new DataInputStream(is);
-               byte[] resptype=new byte[7];
-               dis.readFully(resptype);
-               if (!Arrays.equals(resptype, "getslot".getBytes()))
-                       throw new Error("Bad Response: "+new String(resptype));
-               else
-                       return processSlots(dis);
+       public Slot[] getSlots(long sequencenumber) {
+               try {
+                       URL url=buildRequest(false, sequencenumber, 0);
+                       URLConnection con=url.openConnection();
+                       HttpURLConnection http = (HttpURLConnection) con;
+                       http.setRequestMethod("POST");
+                       http.connect();
+                       System.out.println(http.getResponseMessage());
+                       InputStream is=http.getInputStream();
+                       
+                       DataInputStream dis=new DataInputStream(is);
+                       byte[] resptype=new byte[7];
+                       dis.readFully(resptype);
+                       if (!Arrays.equals(resptype, "getslot".getBytes()))
+                               throw new Error("Bad Response: "+new String(resptype));
+                       else
+                               return processSlots(dis);
+               } catch (Exception e) {
+                       throw new Error("getSlots failed");
+               }
        }
                
        Slot[] processSlots(DataInputStream dis) throws IOException {
                int numberofslots=dis.readInt();
                int[] sizesofslots=new int[numberofslots];
                Slot[] slots=new Slot[numberofslots];
-               System.out.println(numberofslots);
                for(int i=0;i<numberofslots;i++)
                        sizesofslots[i]=dis.readInt();
 
index 1fe7d0e..37fba1b 100644 (file)
@@ -1,6 +1,6 @@
-package IoTCloud;
+package iotcloud;
 
-import util.Arrays;
+import java.util.Arrays;
 
 public class IoTString {
        byte[] array;
index 6a080b7..c0dfaa6 100644 (file)
@@ -3,30 +3,34 @@ import java.nio.ByteBuffer;
 
 class RejectedMessage extends Entry {
        private long machineid;
-       private long seqnum;
+       private long oldseqnum;
+       private long newseqnum;
        private boolean equalto;
 
-       RejectedMessage(long _machineid, long _seqnum, boolean _equalto) {
+       RejectedMessage(long _machineid, long _oldseqnum, long _newseqnum, boolean _equalto) {
                machineid=_machineid;
-               seqnum=_seqnum;
+               oldseqnum=_oldseqnum;
+               newseqnum=_newseqnum;
                equalto=_equalto;
        }
        
        static Entry decode(ByteBuffer bb) {
                long machineid=bb.getLong();
-               long seqnum=bb.getLong();
+               long oldseqnum=bb.getLong();
+               long newseqnum=bb.getLong();
                byte equalto=bb.get();
-               return new RejectedMessage(machineid, seqnum, equalto==1);
+               return new RejectedMessage(machineid, oldseqnum, newseqnum, equalto==1);
        }
        
        void encode(ByteBuffer bb) {
                bb.put(Entry.TypeRejectedMessage);
                bb.putLong(machineid);
-               bb.putLong(seqnum);
+               bb.putLong(oldseqnum);
+               bb.putLong(newseqnum);
                bb.put(equalto?(byte)1:(byte)0);
        }
        
        int getSize() {
-               return 2*Long.BYTES + 2*Byte.BYTES;
+               return 3*Long.BYTES + 2*Byte.BYTES;
        }
 }
index b0002b0..8b6f619 100644 (file)
@@ -26,6 +26,14 @@ class Slot {
                seqnum=_seqnum;
        }
 
+       byte[] getHMAC() {
+               return hmac;
+       }
+
+       byte[] getPrevHMAC() {
+               return prevhmac;
+       }
+       
        static Slot decode(byte[] array, Mac mac) {
                mac.update(array, HMAC_SIZE, array.length-HMAC_SIZE);
                byte[] realmac=mac.doFinal();
diff --git a/src/java/iotcloud/SlotBuffer.java b/src/java/iotcloud/SlotBuffer.java
new file mode 100644 (file)
index 0000000..a2bac02
--- /dev/null
@@ -0,0 +1,72 @@
+package iotcloud;
+
+class SlotBuffer {
+       static final int DEFAULT_SIZE = 128;
+
+       private Slot[] array;
+       private int head;
+       private int tail;
+       private long oldestseqn;
+       
+       SlotBuffer() {
+               array=new Slot[DEFAULT_SIZE+1];
+       }
+
+       int size() {
+               if (head >= tail)
+                       return head - tail;
+               return (array.length + head) - tail;
+       }
+       
+       void resize(int newsize) {
+               if (newsize == (array.length-1))
+                       return;
+               Slot[] newarray = new Slot[newsize+1];
+               int currsize = size();
+               int index = tail;
+               for(int i=0; i < currsize; i++) {
+                       newarray[i] = array[index];
+                       if ((++index) == array.length)
+                               index = 0;
+               }
+               array = newarray;
+               tail = currsize;
+               head = 0;
+       }
+
+       void putSlot(Slot s) {
+               array[head]=s;
+               head++;
+               if (oldestseqn==0)
+                       oldestseqn = s.getSequenceNumber();
+
+               if (head==tail) {
+                       tail++;
+                       oldestseqn++;
+               }
+       }
+
+       Slot getSlot(long seqnum) {
+               int diff=(int) (seqnum-oldestseqn);
+               int index=diff + tail;
+               if (index > array.length) {
+                       if (head >= tail)
+                               return null;
+                       index-= array.length;
+               }
+               
+               if (index >= array.length ||
+                               index >= head)
+                       return null;
+               
+               return array[index];
+       }
+
+       long getOldestSeqNum() {
+               return oldestseqn;
+       }
+
+       long getNewestSeqNum() {
+               return oldestseqn + size();
+       }
+}
index 5efe9b2..5c6ec6b 100644 (file)
@@ -1,16 +1,21 @@
 package iotcloud;
 import java.util.HashMap;
+import java.util.Arrays;
 import javax.crypto.spec.*;
 import javax.crypto.*;
 
 public class Table {
        int numslots;
-       HashMap table=new HashMap();
+       HashMap<IoTString, IoTString> table=new HashMap<IoTString, IoTString>();
+       SlotBuffer buffer;
        CloudComm cloud;
        private Mac hmac;
+       long sequencenumber;
        
        public Table(String baseurl, String password) {
                initCloud(baseurl, password);
+               buffer = new SlotBuffer();
+               sequencenumber = 1;
        }
 
        private void initCloud(String baseurl, String password) {
@@ -39,6 +44,47 @@ public class Table {
                }
        }
 
+       public void update() {
+               Slot[] newslots=cloud.getSlots(sequencenumber);
+               validateandupdate(newslots);
+       }
+
+       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!");
+
+               checkHMACChain(newslots);
+               
+               if (firstseqnum == (buffer.getNewestSeqNum()+1)) {
+                       //contiguous update
+               } else {
+                       //non-contiguous update
+               }
 
+               
+       }
+
+       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");
+               }
 
+               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");
+               }
+       }
+       
 }