xref: /aosp_15_r20/system/netd/server/TcpSocketMonitor.h (revision 8542734a0dd1db395a4d42aae09c37f3c3c3e7a1)
1*8542734aSAndroid Build Coastguard Worker /*
2*8542734aSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*8542734aSAndroid Build Coastguard Worker  *
4*8542734aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8542734aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8542734aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8542734aSAndroid Build Coastguard Worker  *
8*8542734aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8542734aSAndroid Build Coastguard Worker  *
10*8542734aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8542734aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8542734aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8542734aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8542734aSAndroid Build Coastguard Worker  * limitations under the License.
15*8542734aSAndroid Build Coastguard Worker  */
16*8542734aSAndroid Build Coastguard Worker 
17*8542734aSAndroid Build Coastguard Worker #ifndef TCP_SOCKET_MONITOR_H
18*8542734aSAndroid Build Coastguard Worker #define TCP_SOCKET_MONITOR_H
19*8542734aSAndroid Build Coastguard Worker 
20*8542734aSAndroid Build Coastguard Worker #include <chrono>
21*8542734aSAndroid Build Coastguard Worker #include <condition_variable>
22*8542734aSAndroid Build Coastguard Worker #include <mutex>
23*8542734aSAndroid Build Coastguard Worker #include <thread>
24*8542734aSAndroid Build Coastguard Worker #include <unordered_map>
25*8542734aSAndroid Build Coastguard Worker 
26*8542734aSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h>
27*8542734aSAndroid Build Coastguard Worker #include "netdutils/DumpWriter.h"
28*8542734aSAndroid Build Coastguard Worker #include "utils/String16.h"
29*8542734aSAndroid Build Coastguard Worker 
30*8542734aSAndroid Build Coastguard Worker #include "Fwmark.h"
31*8542734aSAndroid Build Coastguard Worker 
32*8542734aSAndroid Build Coastguard Worker struct inet_diag_msg;
33*8542734aSAndroid Build Coastguard Worker struct tcp_info;
34*8542734aSAndroid Build Coastguard Worker 
35*8542734aSAndroid Build Coastguard Worker namespace android {
36*8542734aSAndroid Build Coastguard Worker namespace net {
37*8542734aSAndroid Build Coastguard Worker 
38*8542734aSAndroid Build Coastguard Worker using std::chrono::milliseconds;
39*8542734aSAndroid Build Coastguard Worker 
40*8542734aSAndroid Build Coastguard Worker class TcpSocketMonitor {
41*8542734aSAndroid Build Coastguard Worker   public:
42*8542734aSAndroid Build Coastguard Worker     using time_point = std::chrono::time_point<std::chrono::steady_clock>;
43*8542734aSAndroid Build Coastguard Worker 
44*8542734aSAndroid Build Coastguard Worker     static const String16 DUMP_KEYWORD;
45*8542734aSAndroid Build Coastguard Worker     static const milliseconds kDefaultPollingInterval;
46*8542734aSAndroid Build Coastguard Worker 
47*8542734aSAndroid Build Coastguard Worker     // A subset of fields found in struct inet_diag_msg and struct tcp_info.
48*8542734aSAndroid Build Coastguard Worker     struct TcpStats {
49*8542734aSAndroid Build Coastguard Worker         // Number of packets sent. Tracks struct tcp_sock data_segs_out.
50*8542734aSAndroid Build Coastguard Worker         // Not available on 3.18 kernels.
51*8542734aSAndroid Build Coastguard Worker         uint32_t sent;
52*8542734aSAndroid Build Coastguard Worker         // Number of packets lost. Tracks struct tcp_sock lost_out.
53*8542734aSAndroid Build Coastguard Worker         uint32_t lost;
54*8542734aSAndroid Build Coastguard Worker         // Smoothed round trip time. Tracks struct tcp_sock srtt_us.
55*8542734aSAndroid Build Coastguard Worker         uint32_t rttUs;
56*8542734aSAndroid Build Coastguard Worker         // Milliseconds difference between the last packet sent and last ack received.
57*8542734aSAndroid Build Coastguard Worker         int32_t sentAckDiffMs;
58*8542734aSAndroid Build Coastguard Worker         // Number of socket stats aggregated in this TcpStats entry.
59*8542734aSAndroid Build Coastguard Worker         int32_t nSockets;
60*8542734aSAndroid Build Coastguard Worker     };
61*8542734aSAndroid Build Coastguard Worker 
62*8542734aSAndroid Build Coastguard Worker     // Socket metadata used for computing TcpStats diff across sock_diag dumps.
63*8542734aSAndroid Build Coastguard Worker     struct SocketEntry {
64*8542734aSAndroid Build Coastguard Worker         // Number of packets sent. Tracks struct tcp_sock data_segs_out.
65*8542734aSAndroid Build Coastguard Worker         // Not available on 3.18 kernels.
66*8542734aSAndroid Build Coastguard Worker         uint32_t sent;
67*8542734aSAndroid Build Coastguard Worker         // Number of packets lost. Tracks struct tcp_sock lost_out.
68*8542734aSAndroid Build Coastguard Worker         uint32_t lost;
69*8542734aSAndroid Build Coastguard Worker         // Last update timestamp for that socket.
70*8542734aSAndroid Build Coastguard Worker         time_point lastUpdate;
71*8542734aSAndroid Build Coastguard Worker         // Socket mark.
72*8542734aSAndroid Build Coastguard Worker         Fwmark mark;
73*8542734aSAndroid Build Coastguard Worker         // The uid owning the socket.
74*8542734aSAndroid Build Coastguard Worker         uint32_t uid;
75*8542734aSAndroid Build Coastguard Worker     };
76*8542734aSAndroid Build Coastguard Worker 
77*8542734aSAndroid Build Coastguard Worker     TcpSocketMonitor();
78*8542734aSAndroid Build Coastguard Worker     ~TcpSocketMonitor();
79*8542734aSAndroid Build Coastguard Worker 
80*8542734aSAndroid Build Coastguard Worker     void dump(netdutils::DumpWriter& dw);
81*8542734aSAndroid Build Coastguard Worker     void setPollingInterval(milliseconds duration);
82*8542734aSAndroid Build Coastguard Worker     void resumePolling();
83*8542734aSAndroid Build Coastguard Worker     void suspendPolling();
84*8542734aSAndroid Build Coastguard Worker 
85*8542734aSAndroid Build Coastguard Worker   private:
86*8542734aSAndroid Build Coastguard Worker     void poll();
87*8542734aSAndroid Build Coastguard Worker     void waitForNextPoll();
88*8542734aSAndroid Build Coastguard Worker     bool isRunning();
89*8542734aSAndroid Build Coastguard Worker     void updateSocketStats(time_point now, Fwmark mark, const struct inet_diag_msg *sockinfo,
90*8542734aSAndroid Build Coastguard Worker                            const struct tcp_info *tcpinfo, uint32_t tcpinfoLen) REQUIRES(mLock);
91*8542734aSAndroid Build Coastguard Worker 
92*8542734aSAndroid Build Coastguard Worker     // Lock guarding all reads and writes to member variables.
93*8542734aSAndroid Build Coastguard Worker     std::mutex mLock;
94*8542734aSAndroid Build Coastguard Worker     // Used by the polling thread for sleeping between poll operations.
95*8542734aSAndroid Build Coastguard Worker     std::condition_variable mCv;
96*8542734aSAndroid Build Coastguard Worker     // The thread that polls sock_diag continuously.
97*8542734aSAndroid Build Coastguard Worker     std::thread mPollingThread;
98*8542734aSAndroid Build Coastguard Worker     // The duration of a sleep between polls. Can be updated by the instance owner for dynamically
99*8542734aSAndroid Build Coastguard Worker     // adjusting the polling rate.
100*8542734aSAndroid Build Coastguard Worker     milliseconds mNextSleepDurationMs GUARDED_BY(mLock);
101*8542734aSAndroid Build Coastguard Worker     // The time of the last successful poll operation.
102*8542734aSAndroid Build Coastguard Worker     time_point mLastPoll GUARDED_BY(mLock);
103*8542734aSAndroid Build Coastguard Worker     // True if the polling thread should sleep until notified.
104*8542734aSAndroid Build Coastguard Worker     bool mIsSuspended GUARDED_BY(mLock);
105*8542734aSAndroid Build Coastguard Worker     // True while the polling thread should poll.
106*8542734aSAndroid Build Coastguard Worker     bool mIsRunning GUARDED_BY(mLock);
107*8542734aSAndroid Build Coastguard Worker     // Map of SocketEntry structs keyed by socket cookie. This map tracks per-socket data needed for
108*8542734aSAndroid Build Coastguard Worker     // computing diffs between sock_diag dumps. Entries for closed sockets are continuously cleaned
109*8542734aSAndroid Build Coastguard Worker     // after every dump operation based on timestamps of last updates.
110*8542734aSAndroid Build Coastguard Worker     std::unordered_map<uint64_t, SocketEntry> mSocketEntries GUARDED_BY(mLock);
111*8542734aSAndroid Build Coastguard Worker     // Map of TcpStats entries aggregated per network and keyed per network id.
112*8542734aSAndroid Build Coastguard Worker     // This map tracks per-network data for a single sock_diag dump and is cleared before every dump
113*8542734aSAndroid Build Coastguard Worker     // operation.
114*8542734aSAndroid Build Coastguard Worker     std::unordered_map<uint32_t, TcpStats> mNetworkStats GUARDED_BY(mLock);
115*8542734aSAndroid Build Coastguard Worker };
116*8542734aSAndroid Build Coastguard Worker 
117*8542734aSAndroid Build Coastguard Worker }  // namespace net
118*8542734aSAndroid Build Coastguard Worker }  // namespace android
119*8542734aSAndroid Build Coastguard Worker 
120*8542734aSAndroid Build Coastguard Worker #endif /* TCP_SOCKET_MONITOR_H */
121