--- /dev/null
+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 {
+ /* Sequence number */
+ private long sequencenum;
+
+
+ /* 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 _sequencenum, long _machineid, long _oldseqnum, long _newseqnum, boolean _equalto) {
+ super(slot);
+ sequencenum = _sequencenum;
+ machineid=_machineid;
+ oldseqnum=_oldseqnum;
+ newseqnum=_newseqnum;
+ equalto=_equalto;
+ }
+
+ long getOldSeqNum() {
+ return oldseqnum;
+ }
+
+ long getNewSeqNum() {
+ return newseqnum;
+ }
+
+ boolean getEqual() {
+ return equalto;
+ }
+
+ long getMachineID() {
+ return machineid;
+ }
+
+
+ long getSequenceNumber() {
+ return sequencenum;
+ }
+
+ static Entry decode(Slot slot, ByteBuffer bb) {
+ long sequencenum=bb.getLong();
+ long machineid=bb.getLong();
+ long oldseqnum=bb.getLong();
+ long newseqnum=bb.getLong();
+ byte equalto=bb.get();
+ return new RejectedMessage(slot,sequencenum, 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(sequencenum);
+ bb.putLong(machineid);
+ bb.putLong(oldseqnum);
+ bb.putLong(newseqnum);
+ bb.put(equalto?(byte)1:(byte)0);
+ }
+
+ int getSize() {
+ return 4*Long.BYTES + 2*Byte.BYTES;
+ }
+
+ byte getType() {
+ return Entry.TypeRejectedMessage;
+ }
+
+ Entry getCopy(Slot s) {
+ return new RejectedMessage(s,sequencenum, machineid, oldseqnum, newseqnum, equalto);
+ }
+}