Merge "Add support for app data accounting for in-kernel dataplanes"
This commit is contained in:
@@ -24,6 +24,7 @@ import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Process;
|
||||
import android.os.SystemClock;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
@@ -1487,8 +1488,31 @@ public final class NetworkStats implements Parcelable {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (recycle.uid == tunUid) {
|
||||
// Add up traffic through tunUid's underlying interfaces.
|
||||
if (tunUid == Process.SYSTEM_UID) {
|
||||
// Kernel-based VPN or VCN, traffic sent by apps on the VPN/VCN network
|
||||
//
|
||||
// Since the data is not UID-accounted on underlying networks, just use VPN/VCN
|
||||
// network usage as ground truth. Encrypted traffic on the underlying networks will
|
||||
// never be processed here because encrypted traffic on the underlying interfaces
|
||||
// is not present in UID stats, and this method is only called on UID stats.
|
||||
if (tunIface.equals(recycle.iface)) {
|
||||
tunIfaceTotal.add(recycle);
|
||||
underlyingIfacesTotal.add(recycle);
|
||||
|
||||
// In steady state, there should always be one network, but edge cases may
|
||||
// result in the network being null (network lost), and thus no underlying
|
||||
// ifaces is possible.
|
||||
if (perInterfaceTotal.length > 0) {
|
||||
// While platform VPNs and VCNs have exactly one underlying network, that
|
||||
// network may have multiple interfaces (eg for 464xlat). This layer does
|
||||
// not have the required information to identify which of the interfaces
|
||||
// were used. Select "any" of the interfaces. Since overhead is already
|
||||
// lost, this number is an approximation anyways.
|
||||
perInterfaceTotal[0].add(recycle);
|
||||
}
|
||||
}
|
||||
} else if (recycle.uid == tunUid) {
|
||||
// VpnService VPN, traffic sent by the VPN app over underlying networks
|
||||
for (int j = 0; j < underlyingIfaces.size(); j++) {
|
||||
if (Objects.equals(underlyingIfaces.get(j), recycle.iface)) {
|
||||
perInterfaceTotal[j].add(recycle);
|
||||
@@ -1497,7 +1521,7 @@ public final class NetworkStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
} else if (tunIface.equals(recycle.iface)) {
|
||||
// Add up all tunIface traffic excluding traffic from the vpn app itself.
|
||||
// VpnService VPN; traffic sent by apps on the VPN network
|
||||
tunIfaceTotal.add(recycle);
|
||||
}
|
||||
}
|
||||
@@ -1532,9 +1556,13 @@ public final class NetworkStats implements Parcelable {
|
||||
// Consider only entries that go onto the VPN interface.
|
||||
continue;
|
||||
}
|
||||
if (uid[i] == tunUid) {
|
||||
|
||||
if (uid[i] == tunUid && tunUid != Process.SYSTEM_UID) {
|
||||
// Exclude VPN app from the redistribution, as it can choose to create packet
|
||||
// streams by writing to itself.
|
||||
//
|
||||
// However, for platform VPNs, do not exclude the system's usage of the VPN network,
|
||||
// since it is never local-only, and never double counted
|
||||
continue;
|
||||
}
|
||||
tmpEntry.uid = uid[i];
|
||||
@@ -1641,6 +1669,12 @@ public final class NetworkStats implements Parcelable {
|
||||
int tunUid,
|
||||
@NonNull List<String> underlyingIfaces,
|
||||
@NonNull Entry[] moved) {
|
||||
if (tunUid == Process.SYSTEM_UID) {
|
||||
// No traffic recorded on a per-UID basis for in-kernel VPN/VCNs over underlying
|
||||
// networks; thus no traffic to deduct.
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < underlyingIfaces.size(); i++) {
|
||||
moved[i].uid = tunUid;
|
||||
// Add debug info
|
||||
|
||||
Reference in New Issue
Block a user