Cleaned up git
[iotcloud.git] / version1 / src / java / iotcloud / RejectedMessage.java
diff --git a/version1/src/java/iotcloud/RejectedMessage.java b/version1/src/java/iotcloud/RejectedMessage.java
new file mode 100644 (file)
index 0000000..9c84f18
--- /dev/null
@@ -0,0 +1,88 @@
+package iotcloud;
+import java.nio.ByteBuffer;
+import java.util.HashSet;
+
+/**
+ * Entry for tracking messages that the server rejected.  We have to
+ * make sure that all clients know that this message was rejected to
+ * prevent the server from reusing these messages in an attack.
+ * @author Brian Demsky
+ * @version 1.0
+ */
+
+
+class RejectedMessage extends Entry {
+       /* Machine identifier */
+       private long machineid;
+       /* Oldest sequence number in range */
+       private long oldseqnum;
+       /* Newest sequence number in range */
+       private long newseqnum;
+       /* Is the machine identifier of the relevant slots equal to (or not
+        * equal to) the specified machine identifier. */
+       private boolean equalto;
+       /* Set of machines that have not received notification. */
+       private HashSet<Long> watchset;
+
+       RejectedMessage(Slot slot, long _machineid, long _oldseqnum, long _newseqnum, boolean _equalto) {
+               super(slot);
+               machineid=_machineid;
+               oldseqnum=_oldseqnum;
+               newseqnum=_newseqnum;
+               equalto=_equalto;
+       }
+
+       long getOldSeqNum() {
+               return oldseqnum;
+       }
+
+       long getNewSeqNum() {
+               return newseqnum;
+       }
+
+       boolean getEqual() {
+               return equalto;
+       }
+
+       long getMachineID() {
+               return machineid;
+       }
+
+       static Entry decode(Slot slot, ByteBuffer bb) {
+               long machineid=bb.getLong();
+               long oldseqnum=bb.getLong();
+               long newseqnum=bb.getLong();
+               byte equalto=bb.get();
+               return new RejectedMessage(slot, machineid, oldseqnum, newseqnum, equalto==1);
+       }
+
+       void setWatchSet(HashSet<Long> _watchset) {
+               watchset=_watchset;
+       }
+
+       void removeWatcher(long machineid) {
+               if (watchset.remove(machineid))
+                       if (watchset.isEmpty())
+                               setDead();
+       }
+
+       void encode(ByteBuffer bb) {
+               bb.put(Entry.TypeRejectedMessage);
+               bb.putLong(machineid);
+               bb.putLong(oldseqnum);
+               bb.putLong(newseqnum);
+               bb.put(equalto?(byte)1:(byte)0);
+       }
+
+       int getSize() {
+               return 3*Long.BYTES + 2*Byte.BYTES;
+       }
+
+       byte getType() {
+               return Entry.TypeRejectedMessage;
+       }
+       
+       Entry getCopy(Slot s) {
+               return new RejectedMessage(s, machineid, oldseqnum, newseqnum, equalto);
+       }
+}