1 package edu.uci.iotproject.analysis;
3 import org.pcap4j.core.PacketListener;
4 import org.pcap4j.core.PcapPacket;
6 import java.time.Instant;
10 * A {@link PacketListener} that marks network traffic as (potentially) related to a user's actions by comparing the
11 * timestamp of each packet to the timestamps of the provided list of user actions.
13 * @author Janus Varmarken {@literal <jvarmark@uci.edu>}
14 * @author Rahmadi Trimananda {@literal <rtrimana@uci.edu>}
16 public class TrafficLabeler implements PacketListener {
18 private final Map<UserAction, List<PcapPacket>> mActionToTrafficMap;
19 private final List<UserAction> mActionsSorted;
21 public TrafficLabeler(List<UserAction> userActions) {
22 // Init map with empty lists (no packets have been mapped to UserActions at the onset).
23 mActionToTrafficMap = new HashMap<>();
24 userActions.forEach(ua -> mActionToTrafficMap.put(ua, new ArrayList<>()));
25 // Sort list of UserActions by timestamp in order to facilitate fast Packet-to-UserAction mapping.
26 // For safety reasons, we create an internal copy of the list to prevent external code from changing the list's
27 // contents as that would render our assumptions about order of elements invalid.
28 // In addition, this also ensures that we do not break assumptions made by external code as we avoid reordering
29 // the elements of the list passed from the external code.
30 // If performance is to be favored over safety, assign userActions to mActionsSorted directly.
31 mActionsSorted = new ArrayList<>();
32 mActionsSorted.addAll(userActions);
33 Collections.sort(mActionsSorted, (ua1, ua2) -> ua1.getTimestamp().compareTo(ua2.getTimestamp()));
38 public void gotPacket(PcapPacket packet) {
39 // Locate UserAction corresponding to packet, if any.
40 int index = Collections.binarySearch(mActionsSorted, new UserAction(null, packet.getTimestamp()), (listItem, key) -> {
41 // Start of inclusion interval is the time of the user action
42 Instant intervalStart = listItem.getTimestamp();
43 // End of inclusion interval is some arbitrary number of milliseconds after the user action.
44 Instant intervalEnd = intervalStart.plusMillis(TriggerTrafficExtractor.INCLUSION_WINDOW_MILLIS);
45 if (key.getTimestamp().isAfter(intervalStart) && key.getTimestamp().isBefore(intervalEnd)) {
46 // Packet lies within specified interval after the current UserAction, so we're done.
47 // Communicate termination to binarySearch by returning 0 which indicates equality.
50 // If packet lies outside inclusion interval of current list item, continue search in lower or upper half of
51 // list depending on whether the timestamp of the current list item is smaller or greater than that of the
53 return listItem.getTimestamp().compareTo(key.getTimestamp());
56 // Associate the packet to the its corresponding user action (located during the binary search above).
57 mActionToTrafficMap.get(mActionsSorted.get(index)).add(packet);
59 // Ignore packet if it is not found to be in temporal proximity of a user action.