TcpSocketMonitor: Add stats tables per sockets and per networks
This patch defines SocketEntry and TcpStats for tracking inside
TcpSocketMonitor per-socket and per-network tcp statistics.
For the time being, the following data is tracked:
- total packet sent and lost
- average rtt
- time diff between last packet sent and last ack received
Bug: 64147860
Test: tested manually, watching the result of
$ adb shell dumpsys netd tcp_socket_info
Change-Id: If032a4884ac5dcd693ccfc4bc738167d848a9833
diff --git a/server/TcpSocketMonitor.h b/server/TcpSocketMonitor.h
index ec39a13..f408ff0 100644
--- a/server/TcpSocketMonitor.h
+++ b/server/TcpSocketMonitor.h
@@ -20,25 +20,62 @@
#include <chrono>
#include <condition_variable>
#include <mutex>
+#include <unordered_map>
#include <android-base/thread_annotations.h>
#include "utils/String16.h"
+#include "Fwmark.h"
+
namespace android {
namespace net {
+using std::chrono::milliseconds;
+
class DumpWriter;
class TcpSocketMonitor {
public:
+ using time_point = std::chrono::time_point<std::chrono::steady_clock>;
+
static const String16 DUMP_KEYWORD;
- static const std::chrono::milliseconds kDefaultPollingInterval;
+ static const milliseconds kDefaultPollingInterval;
+
+ // A subset of fields found in struct inet_diag_msg and struct tcp_info.
+ struct TcpStats {
+ // Number of packets sent. Tracks struct tcp_sock data_segs_out.
+ // Not available on 3.18 kernels.
+ uint32_t sent;
+ // Number of packets lost. Tracks struct tcp_sock lost_out.
+ uint32_t lost;
+ // Smoothed round trip time. Tracks struct tcp_sock srtt_us.
+ uint32_t rttUs;
+ // Milliseconds difference between the last packet sent and last ack received.
+ int32_t sentAckDiffMs;
+ // Number of socket stats aggregated in this TcpStats entry.
+ int32_t nSockets;
+ };
+
+ // Socket metadata used for computing TcpStats diff across sock_diag dumps.
+ struct SocketEntry {
+ // Number of packets sent. Tracks struct tcp_sock data_segs_out.
+ // Not available on 3.18 kernels.
+ uint32_t sent;
+ // Number of packets lost. Tracks struct tcp_sock lost_out.
+ uint32_t lost;
+ // Last update timestamp for that socket.
+ time_point lastUpdate;
+ // Socket mark.
+ Fwmark mark;
+ // The uid owning the socket.
+ uint32_t uid;
+ };
TcpSocketMonitor();
~TcpSocketMonitor();
void dump(DumpWriter& dw);
- void setPollingInterval(std::chrono::milliseconds duration);
+ void setPollingInterval(milliseconds duration);
void resumePolling();
void suspendPolling();
@@ -46,21 +83,32 @@
void poll();
void waitForNextPoll();
bool isRunning();
+ void updateSocketStats(time_point now, Fwmark mark, const struct inet_diag_msg *sockinfo,
+ const struct tcp_info *tcpinfo, uint32_t tcpinfoLen) REQUIRES(mLock);
// Lock guarding all reads and writes to member variables.
std::mutex mLock;
// Used by the polling thread for sleeping between poll operations.
std::condition_variable mCv;
+ // The thread that polls sock_diag continously.
+ std::thread mPollingThread;
// The duration of a sleep between polls. Can be updated by the instance owner for dynamically
// adjusting the polling rate.
- std::chrono::milliseconds mNextSleepDurationMs GUARDED_BY(mLock);
+ milliseconds mNextSleepDurationMs GUARDED_BY(mLock);
// The time of the last successful poll operation.
- std::chrono::time_point<std::chrono::steady_clock> mLastPoll GUARDED_BY(mLock);
+ time_point mLastPoll GUARDED_BY(mLock);
// True if the polling thread should sleep until notified.
bool mIsSuspended GUARDED_BY(mLock);
// True while the polling thread should poll.
bool mIsRunning GUARDED_BY(mLock);
- std::thread mPollingThread;
+ // Map of SocketEntry structs keyed by socket cookie. This map tracks per-socket data needed for
+ // computing diffs between sock_diag dumps. Entries for closed sockets are continously cleaned
+ // after every dump operation based on timestamps of last updates.
+ std::unordered_map<uint64_t, SocketEntry> mSocketEntries GUARDED_BY(mLock);
+ // Map of TcpStats entries aggregated per network and keyed per network id.
+ // This map tracks per-network data for a single sock_diag dump and is cleared before every dump
+ // operation.
+ std::unordered_map<uint32_t, TcpStats> mNetworkStats GUARDED_BY(mLock);
};
} // namespace net