Extract ClusterMatcherObserver interface to separate file and move code that handles...
authorJanus Varmarken <varmarken@gmail.com>
Mon, 14 Jan 2019 23:54:36 +0000 (15:54 -0800)
committerJanus Varmarken <varmarken@gmail.com>
Mon, 14 Jan 2019 23:54:36 +0000 (15:54 -0800)
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/AbstractClusterMatcher.java
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/ClusterMatcherObserver.java [new file with mode: 0644]
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/layer3/Layer3ClusterMatcher.java
Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/layer3/SignatureDetector.java

index bda6493..45c6a55 100644 (file)
@@ -2,6 +2,7 @@ package edu.uci.iotproject.detection;
 
 import org.pcap4j.core.PcapPacket;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
@@ -20,6 +21,11 @@ abstract public class AbstractClusterMatcher {
      */
     protected final List<List<PcapPacket>> mCluster;
 
+    /**
+     * Observers registered for callbacks from this {@link AbstractClusterMatcher}.
+     */
+    protected final List<ClusterMatcherObserver> mObservers;
+
     protected AbstractClusterMatcher(List<List<PcapPacket>> cluster) {
         // ===================== PRECONDITION SECTION =====================
         cluster = Objects.requireNonNull(cluster, "cluster cannot be null");
@@ -34,6 +40,23 @@ abstract public class AbstractClusterMatcher {
         // ================================================================
         // Let the subclass prune the provided cluster
         mCluster = pruneCluster(cluster);
+        mObservers = new ArrayList<>();
+    }
+
+    /**
+     * Register for callbacks from this cluster matcher.
+     * @param observer The target of the callbacks.
+     */
+    public final void addObserver(ClusterMatcherObserver observer) {
+        mObservers.add(observer);
+    }
+
+    /**
+     * Deregister for callbacks from this cluster matcher.
+     * @param observer The callback target that is to be deregistered.
+     */
+    public final void removeObserver(ClusterMatcherObserver observer) {
+        mObservers.remove(observer);
     }
 
     /**
diff --git a/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/ClusterMatcherObserver.java b/Code/Projects/SmartPlugDetector/src/main/java/edu/uci/iotproject/detection/ClusterMatcherObserver.java
new file mode 100644 (file)
index 0000000..d67c520
--- /dev/null
@@ -0,0 +1,26 @@
+package edu.uci.iotproject.detection;
+
+import org.pcap4j.core.PcapPacket;
+
+import java.util.List;
+
+/**
+ * Interface used by client code to register for receiving a notification whenever an {@link AbstractClusterMatcher}
+ * detects traffic that matches an element of its associated cluster.
+ *
+ * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
+ * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
+ */
+public interface ClusterMatcherObserver {
+
+    /**
+     * Callback that is invoked by an {@link AbstractClusterMatcher} whenever it detects traffic that matches an element
+     * of its associated cluster.
+     *
+     * @param clusterMatcher The {@link AbstractClusterMatcher} that detected a match (i.e., classified traffic as
+     *                       pertaining to its associated cluster).
+     * @param match The traffic that was deemed to match the cluster associated with {@code clusterMatcher}.
+     */
+    void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match);
+
+}
index b5e3077..81002bd 100644 (file)
@@ -1,6 +1,7 @@
 package edu.uci.iotproject.detection.layer3;
 
 import edu.uci.iotproject.detection.AbstractClusterMatcher;
+import edu.uci.iotproject.detection.ClusterMatcherObserver;
 import edu.uci.iotproject.trafficreassembly.layer3.Conversation;
 import edu.uci.iotproject.trafficreassembly.layer3.TcpReassembler;
 import edu.uci.iotproject.analysis.TcpConversationUtils;
@@ -65,8 +66,6 @@ public class Layer3ClusterMatcher extends AbstractClusterMatcher implements Pack
      */
     private final String mRouterWanIp;
 
-    private final ClusterMatchObserver[] mObservers;
-
     /**
      * Create a {@link Layer3ClusterMatcher}.
      * @param cluster The cluster that traffic is matched against.
@@ -77,12 +76,12 @@ public class Layer3ClusterMatcher extends AbstractClusterMatcher implements Pack
      *                          {@code cluster}, i.e., when the examined traffic is classified as pertaining to
      *                          {@code cluster}.
      */
-    public Layer3ClusterMatcher(List<List<PcapPacket>> cluster, String routerWanIp, ClusterMatchObserver... detectionObservers) {
+    public Layer3ClusterMatcher(List<List<PcapPacket>> cluster, String routerWanIp,
+                                ClusterMatcherObserver... detectionObservers) {
         super(cluster);
-        // ===================== PRECONDITION SECTION =====================
-        mObservers = Objects.requireNonNull(detectionObservers, "detectionObservers cannot be null");
-        if (mObservers.length == 0) {
-            throw new IllegalArgumentException("no detectionObservers provided");
+        Objects.requireNonNull(detectionObservers, "detectionObservers cannot be null");
+        for (ClusterMatcherObserver obs : detectionObservers) {
+            addObserver(obs);
         }
         // Build the cluster members' direction sequence.
         // Note: assumes that the provided cluster was captured within the local network (routerWanIp is set to null).
@@ -100,7 +99,6 @@ public class Layer3ClusterMatcher extends AbstractClusterMatcher implements Pack
                             "pattern"
             );
         }
-        // ================================================================
         mRouterWanIp = routerWanIp;
     }
 
@@ -148,7 +146,7 @@ public class Layer3ClusterMatcher extends AbstractClusterMatcher implements Pack
                         isPresent()) {
                     List<PcapPacket> matchSeq = match.get();
                     // Notify observers about the match.
-                    Arrays.stream(mObservers).forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
+                    mObservers.forEach(o -> o.onMatch(Layer3ClusterMatcher.this, matchSeq));
                     /*
                      * Get the index in cPkts of the last packet in the sequence of packets that matches the searched
                      * signature sequence.
@@ -333,21 +331,4 @@ public class Layer3ClusterMatcher extends AbstractClusterMatcher implements Pack
         return directions;
     }
 
-    /**
-     * Interface used by client code to register for receiving a notification whenever the {@link Layer3ClusterMatcher}
-     * detects traffic that is similar to the traffic that makes up the cluster returned by
-     * {@link Layer3ClusterMatcher#getCluster()}.
-     */
-    interface ClusterMatchObserver {
-        /**
-         * Callback that is invoked whenever a sequence that is similar to a sequence associated with the cluster (i.e.,
-         * a sequence is a member of the cluster) is detected in the traffic that the associated {@link Layer3ClusterMatcher}
-         * observes.
-         * @param clusterMatcher The {@link Layer3ClusterMatcher} that detected a match (classified traffic as pertaining to
-         *                       its associated cluster).
-         * @param match The traffic that was deemed to match the cluster associated with {@code clusterMatcher}.
-         */
-        void onMatch(Layer3ClusterMatcher clusterMatcher, List<PcapPacket> match);
-    }
-
 }
index ad47106..4095074 100644 (file)
@@ -2,6 +2,8 @@ package edu.uci.iotproject.detection.layer3;
 
 import edu.uci.iotproject.analysis.TriggerTrafficExtractor;
 import edu.uci.iotproject.analysis.UserAction;
+import edu.uci.iotproject.detection.AbstractClusterMatcher;
+import edu.uci.iotproject.detection.ClusterMatcherObserver;
 import edu.uci.iotproject.io.PcapHandleReader;
 import edu.uci.iotproject.util.PrintUtils;
 import org.jgrapht.GraphPath;
@@ -23,7 +25,7 @@ import java.util.function.Consumer;
  * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
  * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
  */
-public class SignatureDetector implements PacketListener, Layer3ClusterMatcher.ClusterMatchObserver {
+public class SignatureDetector implements PacketListener, ClusterMatcherObserver {
 
     // Test client
     public static void main(String[] args) throws PcapNativeException, NotOpenException {
@@ -520,7 +522,7 @@ public class SignatureDetector implements PacketListener, Layer3ClusterMatcher.C
     }
 
     @Override
-    public void onMatch(Layer3ClusterMatcher clusterMatcher, List<PcapPacket> match) {
+    public void onMatch(AbstractClusterMatcher clusterMatcher, List<PcapPacket> match) {
         // Add the match at the corresponding index
         pendingMatches[mClusterMatcherIds.get(clusterMatcher)].add(match);
         checkSignatureMatch();