Commit | Line | Data |
---|---|---|
e73a4ba5 | 1 | /******************************************************************************* |
eccbf48c | 2 | * Copyright (c) 2013, 2016 École Polytechnique de Montréal |
e73a4ba5 GB |
3 | * |
4 | * All rights reserved. This program and the accompanying materials are made | |
5 | * available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | * | |
9 | * Contributors: | |
10 | * Geneviève Bastien - Initial implementation and API | |
97de0bca | 11 | * Patrick Tasse - Remove getSubField |
e73a4ba5 GB |
12 | *******************************************************************************/ |
13 | ||
dc327459 | 14 | package org.eclipse.tracecompass.internal.lttng2.kernel.core.event.matching; |
e73a4ba5 | 15 | |
eccbf48c GB |
16 | import java.util.HashMap; |
17 | import java.util.HashSet; | |
18 | import java.util.Map; | |
409bea20 | 19 | import java.util.Set; |
eccbf48c | 20 | import java.util.WeakHashMap; |
e73a4ba5 | 21 | |
eccbf48c GB |
22 | import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout; |
23 | import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace; | |
2bdf0193 | 24 | import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; |
2bdf0193 | 25 | import org.eclipse.tracecompass.tmf.core.event.TmfEventField; |
f44be666 | 26 | import org.eclipse.tracecompass.tmf.core.event.matching.IEventMatchingKey; |
92bf3802 | 27 | import org.eclipse.tracecompass.tmf.core.event.matching.ITmfMatchEventDefinition; |
f44be666 | 28 | import org.eclipse.tracecompass.tmf.core.event.matching.TcpEventKey; |
92bf3802 | 29 | import org.eclipse.tracecompass.tmf.core.event.matching.TmfEventMatching.Direction; |
2bdf0193 | 30 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; |
dc327459 | 31 | import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents; |
2bdf0193 | 32 | import org.eclipse.tracecompass.tmf.core.trace.TmfEventTypeCollectionHelper; |
e73a4ba5 GB |
33 | |
34 | /** | |
eccbf48c GB |
35 | * Class to match tcp events. They use the main kernel's tracepoints |
36 | * netif_receive_skb and net_dev_queue to check if they have a TCP header and | |
37 | * use the sequence, acknowledge and flags fields to match packets | |
e73a4ba5 GB |
38 | * |
39 | * @author Geneviève Bastien | |
e73a4ba5 | 40 | */ |
92bf3802 | 41 | public class TcpLttngEventMatching implements ITmfMatchEventDefinition { |
e73a4ba5 | 42 | |
eccbf48c | 43 | private static final Map<IKernelAnalysisEventLayout, Set<String>> REQUIRED_EVENTS = new HashMap<>(); |
e73a4ba5 | 44 | |
eccbf48c GB |
45 | /** Use a weak hash map so that traces can be garbage collected */ |
46 | private static final Map<ITmfTrace, IKernelAnalysisEventLayout> TRACE_LAYOUTS = new WeakHashMap<>(); | |
e73a4ba5 | 47 | |
e73a4ba5 GB |
48 | @Override |
49 | public boolean canMatchTrace(ITmfTrace trace) { | |
eccbf48c GB |
50 | // Get the events that this trace needs to have |
51 | if (!(trace instanceof IKernelTrace)) { | |
52 | // Not a kernel trace, we cannot know what events to use, return | |
53 | // false | |
54 | return false; | |
55 | } | |
56 | IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout(); | |
57 | TRACE_LAYOUTS.put(trace, layout); | |
58 | ||
59 | Set<String> events = REQUIRED_EVENTS.get(layout); | |
60 | if (events == null) { | |
61 | events = new HashSet<>(); | |
62 | events.addAll(layout.eventsNetworkSend()); | |
63 | events.addAll(layout.eventsNetworkReceive()); | |
64 | REQUIRED_EVENTS.put(layout, events); | |
65 | } | |
66 | ||
dc327459 | 67 | if (!(trace instanceof ITmfTraceWithPreDefinedEvents)) { |
eccbf48c | 68 | // No predefined events, suppose events are present |
dc327459 | 69 | return true; |
e73a4ba5 | 70 | } |
dc327459 | 71 | ITmfTraceWithPreDefinedEvents ktrace = (ITmfTraceWithPreDefinedEvents) trace; |
409bea20 GB |
72 | |
73 | Set<String> traceEvents = TmfEventTypeCollectionHelper.getEventNames(ktrace.getContainedEventTypes()); | |
eccbf48c | 74 | traceEvents.retainAll(events); |
409bea20 | 75 | return !traceEvents.isEmpty(); |
e73a4ba5 GB |
76 | } |
77 | ||
dbc7991d AM |
78 | /** |
79 | * @since 1.0 | |
80 | */ | |
e73a4ba5 GB |
81 | @Override |
82 | public Direction getDirection(ITmfEvent event) { | |
eccbf48c GB |
83 | IKernelAnalysisEventLayout layout = TRACE_LAYOUTS.get(event.getTrace()); |
84 | if (layout == null) { | |
85 | return null; | |
86 | } | |
578716e6 | 87 | String evname = event.getName(); |
e73a4ba5 | 88 | /* Is the event a tcp socket in or out event */ |
eccbf48c | 89 | if (layout.eventsNetworkReceive().contains(evname)) { |
92bf3802 | 90 | return Direction.EFFECT; |
eccbf48c | 91 | } else if (layout.eventsNetworkSend().contains(evname)) { |
8a8d14a2 | 92 | return Direction.CAUSE; |
e73a4ba5 GB |
93 | } |
94 | return null; | |
95 | } | |
96 | ||
f44be666 GB |
97 | @Override |
98 | public IEventMatchingKey getEventKey(ITmfEvent event) { | |
eccbf48c GB |
99 | IKernelAnalysisEventLayout layout = TRACE_LAYOUTS.get(event.getTrace()); |
100 | if (layout == null) { | |
f44be666 GB |
101 | return null; |
102 | } | |
eccbf48c GB |
103 | |
104 | TmfEventField content = (TmfEventField) event.getContent(); | |
105 | ||
106 | Long sequence = content.getFieldValue(Long.class, layout.fieldPathTcpSeq()); | |
107 | Long ack = content.getFieldValue(Long.class, layout.fieldPathTcpAckSeq()); | |
108 | Long flags = content.getFieldValue(Long.class, layout.fieldPathTcpFlags()); | |
109 | ||
110 | if (sequence == null || ack == null || flags == null) { | |
f44be666 GB |
111 | return null; |
112 | } | |
113 | ||
eccbf48c | 114 | IEventMatchingKey key = new TcpEventKey(sequence, ack, flags); |
f44be666 | 115 | return key; |
eccbf48c | 116 | |
f44be666 GB |
117 | } |
118 | ||
e73a4ba5 | 119 | } |