• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2023, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <perfetto/base/task_runner.h>
20 #include <perfetto/tracing.h>
21 
22 #include <string>
23 #include <unordered_map>
24 
25 #include "netdbpf/NetworkTracePoller.h"
26 
27 // For PacketTrace struct definition
28 #include "netd.h"
29 
30 namespace android {
31 namespace bpf {
32 
33 // BundleKeys are PacketTraces where timestamp and length are ignored.
34 using BundleKey = PacketTrace;
35 
36 // BundleKeys are hashed using all fields except timestamp/length.
37 struct BundleHash {
38   std::size_t operator()(const BundleKey& a) const;
39 };
40 
41 // BundleKeys are equal if all fields except timestamp/length are equal.
42 struct BundleEq {
43   bool operator()(const BundleKey& a, const BundleKey& b) const;
44 };
45 
46 // Track the bundles we've interned and their corresponding intern id (iid). We
47 // use IncrementalState (rather than state in the Handler) so that we stay in
48 // sync with Perfetto's periodic state clearing (which helps recover from packet
49 // loss). When state is cleared, the state object is replaced with a new default
50 // constructed instance.
51 struct NetworkTraceState {
52   bool cleared = true;
53   std::unordered_map<BundleKey, uint64_t, BundleHash, BundleEq> iids;
54 };
55 
56 // Inject our custom incremental state type using type traits.
57 struct NetworkTraceTraits : public perfetto::DefaultDataSourceTraits {
58   using IncrementalStateType = NetworkTraceState;
59 };
60 
61 // NetworkTraceHandler implements the android.network_packets data source. This
62 // class is registered with Perfetto and is instantiated when tracing starts and
63 // destroyed when tracing ends. There is one instance per trace session.
64 class NetworkTraceHandler
65     : public perfetto::DataSource<NetworkTraceHandler, NetworkTraceTraits> {
66  public:
67   // Registers this DataSource.
68   static void RegisterDataSource();
69 
70   // Connects to the system Perfetto daemon and registers the trace handler.
71   static void InitPerfettoTracing();
72 
73   // When isTest is true, skip non-hermetic code.
mIsTest(isTest)74   NetworkTraceHandler(bool isTest = false) : mIsTest(isTest) {}
75 
76   // perfetto::DataSource overrides:
77   void OnSetup(const SetupArgs& args) override;
78   void OnStart(const StartArgs&) override;
79   void OnStop(const StopArgs&) override;
80 
81   // Writes the packets as Perfetto TracePackets, creating packets as needed
82   // using the provided callback (which allows easy testing).
83   void Write(const std::vector<PacketTrace>& packets,
84              NetworkTraceHandler::TraceContext& ctx);
85 
86  private:
87   // Convert a PacketTrace into a Perfetto trace packet.
88   void Fill(const PacketTrace& src,
89             ::perfetto::protos::pbzero::NetworkPacketEvent* event);
90 
91   // Fills in contextual information either inline or via interning.
92   ::perfetto::protos::pbzero::NetworkPacketBundle* FillWithInterning(
93       NetworkTraceState* state, const BundleKey& key,
94       ::perfetto::protos::pbzero::TracePacket* dst);
95 
96   static internal::NetworkTracePoller sPoller;
97   bool mStarted;
98   bool mIsTest;
99 
100   // Values from config, see proto for details.
101   uint32_t mPollMs;
102   uint32_t mInternLimit;
103   uint32_t mAggregationThreshold;
104   bool mDropLocalPort;
105   bool mDropRemotePort;
106   bool mDropTcpFlags;
107 };
108 
109 }  // namespace bpf
110 }  // namespace android
111