Loading core/java/android/net/metrics/ApfProgramEvent.java +12 −15 Original line number Original line Diff line number Diff line Loading @@ -47,23 +47,19 @@ public final class ApfProgramEvent implements Parcelable { @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) public @interface Flags {} public @interface Flags {} public final long lifetime; // Lifetime of the program in seconds public long lifetime; // Maximum computed lifetime of the program in seconds public final int filteredRas; // Number of RAs filtered by the APF program public long actualLifetime; // Effective program lifetime in seconds public final int currentRas; // Total number of current RAs at generation time public int filteredRas; // Number of RAs filtered by the APF program public final int programLength; // Length of the APF program in bytes public int currentRas; // Total number of current RAs at generation time public final int flags; // Bitfield compound of FLAG_* constants public int programLength; // Length of the APF program in bytes public int flags; // Bitfield compound of FLAG_* constants public ApfProgramEvent( long lifetime, int filteredRas, int currentRas, int programLength, @Flags int flags) { public ApfProgramEvent() { this.lifetime = lifetime; this.filteredRas = filteredRas; this.currentRas = currentRas; this.programLength = programLength; this.flags = flags; } } private ApfProgramEvent(Parcel in) { private ApfProgramEvent(Parcel in) { this.lifetime = in.readLong(); this.lifetime = in.readLong(); this.actualLifetime = in.readLong(); this.filteredRas = in.readInt(); this.filteredRas = in.readInt(); this.currentRas = in.readInt(); this.currentRas = in.readInt(); this.programLength = in.readInt(); this.programLength = in.readInt(); Loading @@ -73,6 +69,7 @@ public final class ApfProgramEvent implements Parcelable { @Override @Override public void writeToParcel(Parcel out, int flags) { public void writeToParcel(Parcel out, int flags) { out.writeLong(lifetime); out.writeLong(lifetime); out.writeLong(actualLifetime); out.writeInt(filteredRas); out.writeInt(filteredRas); out.writeInt(currentRas); out.writeInt(currentRas); out.writeInt(programLength); out.writeInt(programLength); Loading @@ -87,8 +84,8 @@ public final class ApfProgramEvent implements Parcelable { @Override @Override public String toString() { public String toString() { String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever"; String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever"; return String.format("ApfProgramEvent(%d/%d RAs %dB %s %s)", return String.format("ApfProgramEvent(%d/%d RAs %dB %ds/%s %s)", filteredRas, currentRas, filteredRas, currentRas, programLength, lifetimeString, namesOf(flags)); programLength, actualLifetime, lifetimeString, namesOf(flags)); } } public static final Parcelable.Creator<ApfProgramEvent> CREATOR public static final Parcelable.Creator<ApfProgramEvent> CREATOR Loading core/java/android/net/metrics/ApfStats.java +28 −20 Original line number Original line Diff line number Diff line Loading @@ -25,25 +25,28 @@ import android.os.Parcelable; */ */ public final class ApfStats implements Parcelable { public final class ApfStats implements Parcelable { public final long durationMs; // time interval in milliseconds these stastistics covers /** time interval in milliseconds these stastistics covers. */ public final int receivedRas; // number of received RAs public long durationMs; public final int matchingRas; // number of received RAs matching a known RA /** number of received RAs. */ public final int droppedRas; // number of received RAs ignored due to the MAX_RAS limit public int receivedRas; public final int zeroLifetimeRas; // number of received RAs with a minimum lifetime of 0 /** number of received RAs matching a known RA. */ public final int parseErrors; // number of received RAs that could not be parsed public int matchingRas; public final int programUpdates; // number of APF program updates /** number of received RAs ignored due to the MAX_RAS limit. */ public final int maxProgramSize; // maximum APF program size advertised by hardware public int droppedRas; /** number of received RAs with a minimum lifetime of 0. */ public int zeroLifetimeRas; /** number of received RAs that could not be parsed. */ public int parseErrors; /** number of APF program updates from receiving RAs.. */ public int programUpdates; /** total number of APF program updates. */ public int programUpdatesAll; /** number of APF program updates from allowing multicast traffic. */ public int programUpdatesAllowingMulticast; /** maximum APF program size advertised by hardware. */ public int maxProgramSize; public ApfStats(long durationMs, int receivedRas, int matchingRas, int droppedRas, public ApfStats() { int zeroLifetimeRas, int parseErrors, int programUpdates, int maxProgramSize) { this.durationMs = durationMs; this.receivedRas = receivedRas; this.matchingRas = matchingRas; this.droppedRas = droppedRas; this.zeroLifetimeRas = zeroLifetimeRas; this.parseErrors = parseErrors; this.programUpdates = programUpdates; this.maxProgramSize = maxProgramSize; } } private ApfStats(Parcel in) { private ApfStats(Parcel in) { Loading @@ -54,6 +57,8 @@ public final class ApfStats implements Parcelable { this.zeroLifetimeRas = in.readInt(); this.zeroLifetimeRas = in.readInt(); this.parseErrors = in.readInt(); this.parseErrors = in.readInt(); this.programUpdates = in.readInt(); this.programUpdates = in.readInt(); this.programUpdatesAll = in.readInt(); this.programUpdatesAllowingMulticast = in.readInt(); this.maxProgramSize = in.readInt(); this.maxProgramSize = in.readInt(); } } Loading @@ -66,6 +71,8 @@ public final class ApfStats implements Parcelable { out.writeInt(zeroLifetimeRas); out.writeInt(zeroLifetimeRas); out.writeInt(parseErrors); out.writeInt(parseErrors); out.writeInt(programUpdates); out.writeInt(programUpdates); out.writeInt(programUpdatesAll); out.writeInt(programUpdatesAllowingMulticast); out.writeInt(maxProgramSize); out.writeInt(maxProgramSize); } } Loading @@ -83,8 +90,9 @@ public final class ApfStats implements Parcelable { .append(String.format("%d matching, ", matchingRas)) .append(String.format("%d matching, ", matchingRas)) .append(String.format("%d dropped, ", droppedRas)) .append(String.format("%d dropped, ", droppedRas)) .append(String.format("%d zero lifetime, ", zeroLifetimeRas)) .append(String.format("%d zero lifetime, ", zeroLifetimeRas)) .append(String.format("%d parse errors, ", parseErrors)) .append(String.format("%d parse errors}, ", parseErrors)) .append(String.format("%d program updates})", programUpdates)) .append(String.format("updates: {all: %d, RAs: %d, allow multicast: %d})", programUpdatesAll, programUpdates, programUpdatesAllowingMulticast)) .toString(); .toString(); } } Loading services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +19 −8 Original line number Original line Diff line number Diff line Loading @@ -151,7 +151,8 @@ final public class IpConnectivityEventBuilder { } } private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) { private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) { IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch(); IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch(); dnsLookupBatch.networkId = netIdOf(in.netId); dnsLookupBatch.networkId = netIdOf(in.netId); dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes); dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes); dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes); dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes); Loading @@ -160,7 +161,8 @@ final public class IpConnectivityEventBuilder { } } private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) { private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) { IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent(); IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent(); ipProvisioningEvent.ifName = in.ifName; ipProvisioningEvent.ifName = in.ifName; ipProvisioningEvent.eventType = in.eventType; ipProvisioningEvent.eventType = in.eventType; ipProvisioningEvent.latencyMs = (int) in.durationMs; ipProvisioningEvent.latencyMs = (int) in.durationMs; Loading @@ -168,14 +170,16 @@ final public class IpConnectivityEventBuilder { } } private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) { private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) { IpConnectivityLogClass.IpReachabilityEvent ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent(); IpConnectivityLogClass.IpReachabilityEvent ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent(); ipReachabilityEvent.ifName = in.ifName; ipReachabilityEvent.ifName = in.ifName; ipReachabilityEvent.eventType = in.eventType; ipReachabilityEvent.eventType = in.eventType; out.setIpReachabilityEvent(ipReachabilityEvent); out.setIpReachabilityEvent(ipReachabilityEvent); } } private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) { private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) { IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent(); IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent(); defaultNetworkEvent.networkId = netIdOf(in.netId); defaultNetworkEvent.networkId = netIdOf(in.netId); defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId); defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId); defaultNetworkEvent.transportTypes = in.transportTypes; defaultNetworkEvent.transportTypes = in.transportTypes; Loading @@ -184,7 +188,8 @@ final public class IpConnectivityEventBuilder { } } private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) { private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) { IpConnectivityLogClass.NetworkEvent networkEvent = new IpConnectivityLogClass.NetworkEvent(); IpConnectivityLogClass.NetworkEvent networkEvent = new IpConnectivityLogClass.NetworkEvent(); networkEvent.networkId = netIdOf(in.netId); networkEvent.networkId = netIdOf(in.netId); networkEvent.eventType = in.eventType; networkEvent.eventType = in.eventType; networkEvent.latencyMs = (int) in.durationMs; networkEvent.latencyMs = (int) in.durationMs; Loading @@ -192,7 +197,8 @@ final public class IpConnectivityEventBuilder { } } private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) { private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) { IpConnectivityLogClass.ValidationProbeEvent validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent(); IpConnectivityLogClass.ValidationProbeEvent validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent(); validationProbeEvent.networkId = netIdOf(in.netId); validationProbeEvent.networkId = netIdOf(in.netId); validationProbeEvent.latencyMs = (int) in.durationMs; validationProbeEvent.latencyMs = (int) in.durationMs; validationProbeEvent.probeType = in.probeType; validationProbeEvent.probeType = in.probeType; Loading @@ -201,8 +207,10 @@ final public class IpConnectivityEventBuilder { } } private static void setApfProgramEvent(IpConnectivityEvent out, ApfProgramEvent in) { private static void setApfProgramEvent(IpConnectivityEvent out, ApfProgramEvent in) { IpConnectivityLogClass.ApfProgramEvent apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent(); IpConnectivityLogClass.ApfProgramEvent apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent(); apfProgramEvent.lifetime = in.lifetime; apfProgramEvent.lifetime = in.lifetime; apfProgramEvent.effectiveLifetime = in.actualLifetime; apfProgramEvent.filteredRas = in.filteredRas; apfProgramEvent.filteredRas = in.filteredRas; apfProgramEvent.currentRas = in.currentRas; apfProgramEvent.currentRas = in.currentRas; apfProgramEvent.programLength = in.programLength; apfProgramEvent.programLength = in.programLength; Loading @@ -216,7 +224,8 @@ final public class IpConnectivityEventBuilder { } } private static void setApfStats(IpConnectivityEvent out, ApfStats in) { private static void setApfStats(IpConnectivityEvent out, ApfStats in) { IpConnectivityLogClass.ApfStatistics apfStatistics = new IpConnectivityLogClass.ApfStatistics(); IpConnectivityLogClass.ApfStatistics apfStatistics = new IpConnectivityLogClass.ApfStatistics(); apfStatistics.durationMs = in.durationMs; apfStatistics.durationMs = in.durationMs; apfStatistics.receivedRas = in.receivedRas; apfStatistics.receivedRas = in.receivedRas; apfStatistics.matchingRas = in.matchingRas; apfStatistics.matchingRas = in.matchingRas; Loading @@ -224,6 +233,8 @@ final public class IpConnectivityEventBuilder { apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas; apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas; apfStatistics.parseErrors = in.parseErrors; apfStatistics.parseErrors = in.parseErrors; apfStatistics.programUpdates = in.programUpdates; apfStatistics.programUpdates = in.programUpdates; apfStatistics.programUpdatesAll = in.programUpdatesAll; apfStatistics.programUpdatesAllowingMulticast = in.programUpdatesAllowingMulticast; apfStatistics.maxProgramSize = in.maxProgramSize; apfStatistics.maxProgramSize = in.maxProgramSize; out.setApfStatistics(apfStatistics); out.setApfStatistics(apfStatistics); } } Loading services/net/java/android/net/apf/ApfFilter.java +59 −31 Original line number Original line Diff line number Diff line Loading @@ -93,17 +93,10 @@ public class ApfFilter { class ReceiveThread extends Thread { class ReceiveThread extends Thread { private final byte[] mPacket = new byte[1514]; private final byte[] mPacket = new byte[1514]; private final FileDescriptor mSocket; private final FileDescriptor mSocket; private volatile boolean mStopped; // Starting time of the RA receiver thread. private final long mStart = SystemClock.elapsedRealtime(); private final long mStart = SystemClock.elapsedRealtime(); private final ApfStats mStats = new ApfStats(); private int mReceivedRas; // Number of received RAs private volatile boolean mStopped; private int mMatchingRas; // Number of received RAs matching a known RA private int mDroppedRas; // Number of received RAs ignored due to the MAX_RAS limit private int mParseErrors; // Number of received RAs that could not be parsed private int mZeroLifetimeRas; // Number of received RAs with a 0 lifetime private int mProgramUpdates; // Number of APF program updates triggered by receiving a RA public ReceiveThread(FileDescriptor socket) { public ReceiveThread(FileDescriptor socket) { mSocket = socket; mSocket = socket; Loading Loading @@ -134,35 +127,40 @@ public class ApfFilter { } } private void updateStats(ProcessRaResult result) { private void updateStats(ProcessRaResult result) { mReceivedRas++; mStats.receivedRas++; switch(result) { switch(result) { case MATCH: case MATCH: mMatchingRas++; mStats.matchingRas++; return; return; case DROPPED: case DROPPED: mDroppedRas++; mStats.droppedRas++; return; return; case PARSE_ERROR: case PARSE_ERROR: mParseErrors++; mStats.parseErrors++; return; return; case ZERO_LIFETIME: case ZERO_LIFETIME: mZeroLifetimeRas++; mStats.zeroLifetimeRas++; return; return; case UPDATE_EXPIRY: case UPDATE_EXPIRY: mMatchingRas++; mStats.matchingRas++; mProgramUpdates++; mStats.programUpdates++; return; return; case UPDATE_NEW_RA: case UPDATE_NEW_RA: mProgramUpdates++; mStats.programUpdates++; return; return; } } } } private void logStats() { private void logStats() { long durationMs = SystemClock.elapsedRealtime() - mStart; final long nowMs = SystemClock.elapsedRealtime(); int maxSize = mApfCapabilities.maximumApfProgramSize; synchronized (this) { mMetricsLog.log(new ApfStats(durationMs, mReceivedRas, mMatchingRas, mDroppedRas, mStats.durationMs = nowMs - mStart; mZeroLifetimeRas, mParseErrors, mProgramUpdates, maxSize)); mStats.maxProgramSize = mApfCapabilities.maximumApfProgramSize; mStats.programUpdatesAll = mNumProgramUpdates; mStats.programUpdatesAllowingMulticast = mNumProgramUpdatesAllowingMulticast; mMetricsLog.log(mStats); logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS); } } } } } Loading Loading @@ -218,6 +216,8 @@ public class ApfFilter { 4, // Protocol size: 4 4, // Protocol size: 4 }; }; private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; // Do not log ApfProgramEvents whose actual lifetimes was less than this. private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2; private final ApfCapabilities mApfCapabilities; private final ApfCapabilities mApfCapabilities; private final IpManager.Callback mIpManagerCallback; private final IpManager.Callback mIpManagerCallback; Loading Loading @@ -247,6 +247,7 @@ public class ApfFilter { mMulticastFilter = multicastFilter; mMulticastFilter = multicastFilter; mMetricsLog = log; mMetricsLog = log; // TODO: ApfFilter should not generate programs until IpManager sends provisioning success. maybeStartFilter(); maybeStartFilter(); } } Loading Loading @@ -661,14 +662,19 @@ public class ApfFilter { // How long should the last installed filter program live for? In seconds. // How long should the last installed filter program live for? In seconds. @GuardedBy("this") @GuardedBy("this") private long mLastInstalledProgramMinLifetime; private long mLastInstalledProgramMinLifetime; @GuardedBy("this") private ApfProgramEvent mLastInstallEvent; // For debugging only. The last program installed. // For debugging only. The last program installed. @GuardedBy("this") @GuardedBy("this") private byte[] mLastInstalledProgram; private byte[] mLastInstalledProgram; // For debugging only. How many times the program was updated since we started. // How many times the program was updated since we started. @GuardedBy("this") private int mNumProgramUpdates = 0; // How many times the program was updated since we started for allowing multicast traffic. @GuardedBy("this") @GuardedBy("this") private int mNumProgramUpdates; private int mNumProgramUpdatesAllowingMulticast = 0; /** /** * Generate filter code to process ARP packets. Execution of this code ends in either the * Generate filter code to process ARP packets. Execution of this code ends in either the Loading Loading @@ -947,7 +953,8 @@ public class ApfFilter { Log.e(TAG, "Failed to generate APF program.", e); Log.e(TAG, "Failed to generate APF program.", e); return; return; } } mLastTimeInstalledProgram = currentTimeSeconds(); final long now = currentTimeSeconds(); mLastTimeInstalledProgram = now; mLastInstalledProgramMinLifetime = programMinLifetime; mLastInstalledProgramMinLifetime = programMinLifetime; mLastInstalledProgram = program; mLastInstalledProgram = program; mNumProgramUpdates++; mNumProgramUpdates++; Loading @@ -956,9 +963,26 @@ public class ApfFilter { hexDump("Installing filter: ", program, program.length); hexDump("Installing filter: ", program, program.length); } } mIpManagerCallback.installPacketFilter(program); mIpManagerCallback.installPacketFilter(program); int flags = ApfProgramEvent.flagsFor(mIPv4Address != null, mMulticastFilter); logApfProgramEventLocked(now); mMetricsLog.log(new ApfProgramEvent( mLastInstallEvent = new ApfProgramEvent(); programMinLifetime, rasToFilter.size(), mRas.size(), program.length, flags)); mLastInstallEvent.lifetime = programMinLifetime; mLastInstallEvent.filteredRas = rasToFilter.size(); mLastInstallEvent.currentRas = mRas.size(); mLastInstallEvent.programLength = program.length; mLastInstallEvent.flags = ApfProgramEvent.flagsFor(mIPv4Address != null, mMulticastFilter); } private void logApfProgramEventLocked(long now) { if (mLastInstallEvent == null) { return; } ApfProgramEvent ev = mLastInstallEvent; mLastInstallEvent = null; ev.actualLifetime = now - mLastTimeInstalledProgram; if (ev.actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) { return; } mMetricsLog.log(ev); } } /** /** Loading Loading @@ -1078,11 +1102,15 @@ public class ApfFilter { mRas.clear(); mRas.clear(); } } public synchronized void setMulticastFilter(boolean enabled) { public synchronized void setMulticastFilter(boolean isEnabled) { if (mMulticastFilter != enabled) { if (mMulticastFilter == isEnabled) { mMulticastFilter = enabled; return; installNewProgramLocked(); } } mMulticastFilter = isEnabled; if (!isEnabled) { mNumProgramUpdatesAllowingMulticast++; } installNewProgramLocked(); } } /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */ /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */ Loading tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +6 −3 Original line number Original line Diff line number Diff line Loading @@ -304,6 +304,7 @@ public class IpConnectivityEventBuilderTest extends TestCase { ConnectivityMetricsEvent ev = describeIpEvent( ConnectivityMetricsEvent ev = describeIpEvent( aType(ApfProgramEvent.class), aType(ApfProgramEvent.class), aLong(200), aLong(200), aLong(18), anInt(7), anInt(7), anInt(9), anInt(9), anInt(2048), anInt(2048), Loading @@ -320,7 +321,7 @@ public class IpConnectivityEventBuilderTest extends TestCase { " apf_program_event <", " apf_program_event <", " current_ras: 9", " current_ras: 9", " drop_multicast: true", " drop_multicast: true", " effective_lifetime: 0", " effective_lifetime: 18", " filtered_ras: 7", " filtered_ras: 7", " has_ipv4_addr: true", " has_ipv4_addr: true", " lifetime: 200", " lifetime: 200", Loading @@ -343,6 +344,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { anInt(1), anInt(1), anInt(2), anInt(2), anInt(4), anInt(4), anInt(7), anInt(3), anInt(2048)); anInt(2048)); String want = joinLines( String want = joinLines( Loading @@ -360,8 +363,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { " max_program_size: 2048", " max_program_size: 2048", " parse_errors: 2", " parse_errors: 2", " program_updates: 4", " program_updates: 4", " program_updates_all: 0", " program_updates_all: 7", " program_updates_allowing_multicast: 0", " program_updates_allowing_multicast: 3", " received_ras: 10", " received_ras: 10", " zero_lifetime_ras: 1", " zero_lifetime_ras: 1", " >", " >", Loading Loading
core/java/android/net/metrics/ApfProgramEvent.java +12 −15 Original line number Original line Diff line number Diff line Loading @@ -47,23 +47,19 @@ public final class ApfProgramEvent implements Parcelable { @Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE) public @interface Flags {} public @interface Flags {} public final long lifetime; // Lifetime of the program in seconds public long lifetime; // Maximum computed lifetime of the program in seconds public final int filteredRas; // Number of RAs filtered by the APF program public long actualLifetime; // Effective program lifetime in seconds public final int currentRas; // Total number of current RAs at generation time public int filteredRas; // Number of RAs filtered by the APF program public final int programLength; // Length of the APF program in bytes public int currentRas; // Total number of current RAs at generation time public final int flags; // Bitfield compound of FLAG_* constants public int programLength; // Length of the APF program in bytes public int flags; // Bitfield compound of FLAG_* constants public ApfProgramEvent( long lifetime, int filteredRas, int currentRas, int programLength, @Flags int flags) { public ApfProgramEvent() { this.lifetime = lifetime; this.filteredRas = filteredRas; this.currentRas = currentRas; this.programLength = programLength; this.flags = flags; } } private ApfProgramEvent(Parcel in) { private ApfProgramEvent(Parcel in) { this.lifetime = in.readLong(); this.lifetime = in.readLong(); this.actualLifetime = in.readLong(); this.filteredRas = in.readInt(); this.filteredRas = in.readInt(); this.currentRas = in.readInt(); this.currentRas = in.readInt(); this.programLength = in.readInt(); this.programLength = in.readInt(); Loading @@ -73,6 +69,7 @@ public final class ApfProgramEvent implements Parcelable { @Override @Override public void writeToParcel(Parcel out, int flags) { public void writeToParcel(Parcel out, int flags) { out.writeLong(lifetime); out.writeLong(lifetime); out.writeLong(actualLifetime); out.writeInt(filteredRas); out.writeInt(filteredRas); out.writeInt(currentRas); out.writeInt(currentRas); out.writeInt(programLength); out.writeInt(programLength); Loading @@ -87,8 +84,8 @@ public final class ApfProgramEvent implements Parcelable { @Override @Override public String toString() { public String toString() { String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever"; String lifetimeString = (lifetime < Long.MAX_VALUE) ? lifetime + "s" : "forever"; return String.format("ApfProgramEvent(%d/%d RAs %dB %s %s)", return String.format("ApfProgramEvent(%d/%d RAs %dB %ds/%s %s)", filteredRas, currentRas, filteredRas, currentRas, programLength, lifetimeString, namesOf(flags)); programLength, actualLifetime, lifetimeString, namesOf(flags)); } } public static final Parcelable.Creator<ApfProgramEvent> CREATOR public static final Parcelable.Creator<ApfProgramEvent> CREATOR Loading
core/java/android/net/metrics/ApfStats.java +28 −20 Original line number Original line Diff line number Diff line Loading @@ -25,25 +25,28 @@ import android.os.Parcelable; */ */ public final class ApfStats implements Parcelable { public final class ApfStats implements Parcelable { public final long durationMs; // time interval in milliseconds these stastistics covers /** time interval in milliseconds these stastistics covers. */ public final int receivedRas; // number of received RAs public long durationMs; public final int matchingRas; // number of received RAs matching a known RA /** number of received RAs. */ public final int droppedRas; // number of received RAs ignored due to the MAX_RAS limit public int receivedRas; public final int zeroLifetimeRas; // number of received RAs with a minimum lifetime of 0 /** number of received RAs matching a known RA. */ public final int parseErrors; // number of received RAs that could not be parsed public int matchingRas; public final int programUpdates; // number of APF program updates /** number of received RAs ignored due to the MAX_RAS limit. */ public final int maxProgramSize; // maximum APF program size advertised by hardware public int droppedRas; /** number of received RAs with a minimum lifetime of 0. */ public int zeroLifetimeRas; /** number of received RAs that could not be parsed. */ public int parseErrors; /** number of APF program updates from receiving RAs.. */ public int programUpdates; /** total number of APF program updates. */ public int programUpdatesAll; /** number of APF program updates from allowing multicast traffic. */ public int programUpdatesAllowingMulticast; /** maximum APF program size advertised by hardware. */ public int maxProgramSize; public ApfStats(long durationMs, int receivedRas, int matchingRas, int droppedRas, public ApfStats() { int zeroLifetimeRas, int parseErrors, int programUpdates, int maxProgramSize) { this.durationMs = durationMs; this.receivedRas = receivedRas; this.matchingRas = matchingRas; this.droppedRas = droppedRas; this.zeroLifetimeRas = zeroLifetimeRas; this.parseErrors = parseErrors; this.programUpdates = programUpdates; this.maxProgramSize = maxProgramSize; } } private ApfStats(Parcel in) { private ApfStats(Parcel in) { Loading @@ -54,6 +57,8 @@ public final class ApfStats implements Parcelable { this.zeroLifetimeRas = in.readInt(); this.zeroLifetimeRas = in.readInt(); this.parseErrors = in.readInt(); this.parseErrors = in.readInt(); this.programUpdates = in.readInt(); this.programUpdates = in.readInt(); this.programUpdatesAll = in.readInt(); this.programUpdatesAllowingMulticast = in.readInt(); this.maxProgramSize = in.readInt(); this.maxProgramSize = in.readInt(); } } Loading @@ -66,6 +71,8 @@ public final class ApfStats implements Parcelable { out.writeInt(zeroLifetimeRas); out.writeInt(zeroLifetimeRas); out.writeInt(parseErrors); out.writeInt(parseErrors); out.writeInt(programUpdates); out.writeInt(programUpdates); out.writeInt(programUpdatesAll); out.writeInt(programUpdatesAllowingMulticast); out.writeInt(maxProgramSize); out.writeInt(maxProgramSize); } } Loading @@ -83,8 +90,9 @@ public final class ApfStats implements Parcelable { .append(String.format("%d matching, ", matchingRas)) .append(String.format("%d matching, ", matchingRas)) .append(String.format("%d dropped, ", droppedRas)) .append(String.format("%d dropped, ", droppedRas)) .append(String.format("%d zero lifetime, ", zeroLifetimeRas)) .append(String.format("%d zero lifetime, ", zeroLifetimeRas)) .append(String.format("%d parse errors, ", parseErrors)) .append(String.format("%d parse errors}, ", parseErrors)) .append(String.format("%d program updates})", programUpdates)) .append(String.format("updates: {all: %d, RAs: %d, allow multicast: %d})", programUpdatesAll, programUpdates, programUpdatesAllowingMulticast)) .toString(); .toString(); } } Loading
services/core/java/com/android/server/connectivity/IpConnectivityEventBuilder.java +19 −8 Original line number Original line Diff line number Diff line Loading @@ -151,7 +151,8 @@ final public class IpConnectivityEventBuilder { } } private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) { private static void setDnsEvent(IpConnectivityEvent out, DnsEvent in) { IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch(); IpConnectivityLogClass.DNSLookupBatch dnsLookupBatch = new IpConnectivityLogClass.DNSLookupBatch(); dnsLookupBatch.networkId = netIdOf(in.netId); dnsLookupBatch.networkId = netIdOf(in.netId); dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes); dnsLookupBatch.eventTypes = bytesToInts(in.eventTypes); dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes); dnsLookupBatch.returnCodes = bytesToInts(in.returnCodes); Loading @@ -160,7 +161,8 @@ final public class IpConnectivityEventBuilder { } } private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) { private static void setIpManagerEvent(IpConnectivityEvent out, IpManagerEvent in) { IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent(); IpConnectivityLogClass.IpProvisioningEvent ipProvisioningEvent = new IpConnectivityLogClass.IpProvisioningEvent(); ipProvisioningEvent.ifName = in.ifName; ipProvisioningEvent.ifName = in.ifName; ipProvisioningEvent.eventType = in.eventType; ipProvisioningEvent.eventType = in.eventType; ipProvisioningEvent.latencyMs = (int) in.durationMs; ipProvisioningEvent.latencyMs = (int) in.durationMs; Loading @@ -168,14 +170,16 @@ final public class IpConnectivityEventBuilder { } } private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) { private static void setIpReachabilityEvent(IpConnectivityEvent out, IpReachabilityEvent in) { IpConnectivityLogClass.IpReachabilityEvent ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent(); IpConnectivityLogClass.IpReachabilityEvent ipReachabilityEvent = new IpConnectivityLogClass.IpReachabilityEvent(); ipReachabilityEvent.ifName = in.ifName; ipReachabilityEvent.ifName = in.ifName; ipReachabilityEvent.eventType = in.eventType; ipReachabilityEvent.eventType = in.eventType; out.setIpReachabilityEvent(ipReachabilityEvent); out.setIpReachabilityEvent(ipReachabilityEvent); } } private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) { private static void setDefaultNetworkEvent(IpConnectivityEvent out, DefaultNetworkEvent in) { IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent(); IpConnectivityLogClass.DefaultNetworkEvent defaultNetworkEvent = new IpConnectivityLogClass.DefaultNetworkEvent(); defaultNetworkEvent.networkId = netIdOf(in.netId); defaultNetworkEvent.networkId = netIdOf(in.netId); defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId); defaultNetworkEvent.previousNetworkId = netIdOf(in.prevNetId); defaultNetworkEvent.transportTypes = in.transportTypes; defaultNetworkEvent.transportTypes = in.transportTypes; Loading @@ -184,7 +188,8 @@ final public class IpConnectivityEventBuilder { } } private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) { private static void setNetworkEvent(IpConnectivityEvent out, NetworkEvent in) { IpConnectivityLogClass.NetworkEvent networkEvent = new IpConnectivityLogClass.NetworkEvent(); IpConnectivityLogClass.NetworkEvent networkEvent = new IpConnectivityLogClass.NetworkEvent(); networkEvent.networkId = netIdOf(in.netId); networkEvent.networkId = netIdOf(in.netId); networkEvent.eventType = in.eventType; networkEvent.eventType = in.eventType; networkEvent.latencyMs = (int) in.durationMs; networkEvent.latencyMs = (int) in.durationMs; Loading @@ -192,7 +197,8 @@ final public class IpConnectivityEventBuilder { } } private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) { private static void setValidationProbeEvent(IpConnectivityEvent out, ValidationProbeEvent in) { IpConnectivityLogClass.ValidationProbeEvent validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent(); IpConnectivityLogClass.ValidationProbeEvent validationProbeEvent = new IpConnectivityLogClass.ValidationProbeEvent(); validationProbeEvent.networkId = netIdOf(in.netId); validationProbeEvent.networkId = netIdOf(in.netId); validationProbeEvent.latencyMs = (int) in.durationMs; validationProbeEvent.latencyMs = (int) in.durationMs; validationProbeEvent.probeType = in.probeType; validationProbeEvent.probeType = in.probeType; Loading @@ -201,8 +207,10 @@ final public class IpConnectivityEventBuilder { } } private static void setApfProgramEvent(IpConnectivityEvent out, ApfProgramEvent in) { private static void setApfProgramEvent(IpConnectivityEvent out, ApfProgramEvent in) { IpConnectivityLogClass.ApfProgramEvent apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent(); IpConnectivityLogClass.ApfProgramEvent apfProgramEvent = new IpConnectivityLogClass.ApfProgramEvent(); apfProgramEvent.lifetime = in.lifetime; apfProgramEvent.lifetime = in.lifetime; apfProgramEvent.effectiveLifetime = in.actualLifetime; apfProgramEvent.filteredRas = in.filteredRas; apfProgramEvent.filteredRas = in.filteredRas; apfProgramEvent.currentRas = in.currentRas; apfProgramEvent.currentRas = in.currentRas; apfProgramEvent.programLength = in.programLength; apfProgramEvent.programLength = in.programLength; Loading @@ -216,7 +224,8 @@ final public class IpConnectivityEventBuilder { } } private static void setApfStats(IpConnectivityEvent out, ApfStats in) { private static void setApfStats(IpConnectivityEvent out, ApfStats in) { IpConnectivityLogClass.ApfStatistics apfStatistics = new IpConnectivityLogClass.ApfStatistics(); IpConnectivityLogClass.ApfStatistics apfStatistics = new IpConnectivityLogClass.ApfStatistics(); apfStatistics.durationMs = in.durationMs; apfStatistics.durationMs = in.durationMs; apfStatistics.receivedRas = in.receivedRas; apfStatistics.receivedRas = in.receivedRas; apfStatistics.matchingRas = in.matchingRas; apfStatistics.matchingRas = in.matchingRas; Loading @@ -224,6 +233,8 @@ final public class IpConnectivityEventBuilder { apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas; apfStatistics.zeroLifetimeRas = in.zeroLifetimeRas; apfStatistics.parseErrors = in.parseErrors; apfStatistics.parseErrors = in.parseErrors; apfStatistics.programUpdates = in.programUpdates; apfStatistics.programUpdates = in.programUpdates; apfStatistics.programUpdatesAll = in.programUpdatesAll; apfStatistics.programUpdatesAllowingMulticast = in.programUpdatesAllowingMulticast; apfStatistics.maxProgramSize = in.maxProgramSize; apfStatistics.maxProgramSize = in.maxProgramSize; out.setApfStatistics(apfStatistics); out.setApfStatistics(apfStatistics); } } Loading
services/net/java/android/net/apf/ApfFilter.java +59 −31 Original line number Original line Diff line number Diff line Loading @@ -93,17 +93,10 @@ public class ApfFilter { class ReceiveThread extends Thread { class ReceiveThread extends Thread { private final byte[] mPacket = new byte[1514]; private final byte[] mPacket = new byte[1514]; private final FileDescriptor mSocket; private final FileDescriptor mSocket; private volatile boolean mStopped; // Starting time of the RA receiver thread. private final long mStart = SystemClock.elapsedRealtime(); private final long mStart = SystemClock.elapsedRealtime(); private final ApfStats mStats = new ApfStats(); private int mReceivedRas; // Number of received RAs private volatile boolean mStopped; private int mMatchingRas; // Number of received RAs matching a known RA private int mDroppedRas; // Number of received RAs ignored due to the MAX_RAS limit private int mParseErrors; // Number of received RAs that could not be parsed private int mZeroLifetimeRas; // Number of received RAs with a 0 lifetime private int mProgramUpdates; // Number of APF program updates triggered by receiving a RA public ReceiveThread(FileDescriptor socket) { public ReceiveThread(FileDescriptor socket) { mSocket = socket; mSocket = socket; Loading Loading @@ -134,35 +127,40 @@ public class ApfFilter { } } private void updateStats(ProcessRaResult result) { private void updateStats(ProcessRaResult result) { mReceivedRas++; mStats.receivedRas++; switch(result) { switch(result) { case MATCH: case MATCH: mMatchingRas++; mStats.matchingRas++; return; return; case DROPPED: case DROPPED: mDroppedRas++; mStats.droppedRas++; return; return; case PARSE_ERROR: case PARSE_ERROR: mParseErrors++; mStats.parseErrors++; return; return; case ZERO_LIFETIME: case ZERO_LIFETIME: mZeroLifetimeRas++; mStats.zeroLifetimeRas++; return; return; case UPDATE_EXPIRY: case UPDATE_EXPIRY: mMatchingRas++; mStats.matchingRas++; mProgramUpdates++; mStats.programUpdates++; return; return; case UPDATE_NEW_RA: case UPDATE_NEW_RA: mProgramUpdates++; mStats.programUpdates++; return; return; } } } } private void logStats() { private void logStats() { long durationMs = SystemClock.elapsedRealtime() - mStart; final long nowMs = SystemClock.elapsedRealtime(); int maxSize = mApfCapabilities.maximumApfProgramSize; synchronized (this) { mMetricsLog.log(new ApfStats(durationMs, mReceivedRas, mMatchingRas, mDroppedRas, mStats.durationMs = nowMs - mStart; mZeroLifetimeRas, mParseErrors, mProgramUpdates, maxSize)); mStats.maxProgramSize = mApfCapabilities.maximumApfProgramSize; mStats.programUpdatesAll = mNumProgramUpdates; mStats.programUpdatesAllowingMulticast = mNumProgramUpdatesAllowingMulticast; mMetricsLog.log(mStats); logApfProgramEventLocked(nowMs / DateUtils.SECOND_IN_MILLIS); } } } } } Loading Loading @@ -218,6 +216,8 @@ public class ApfFilter { 4, // Protocol size: 4 4, // Protocol size: 4 }; }; private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; // Do not log ApfProgramEvents whose actual lifetimes was less than this. private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2; private final ApfCapabilities mApfCapabilities; private final ApfCapabilities mApfCapabilities; private final IpManager.Callback mIpManagerCallback; private final IpManager.Callback mIpManagerCallback; Loading Loading @@ -247,6 +247,7 @@ public class ApfFilter { mMulticastFilter = multicastFilter; mMulticastFilter = multicastFilter; mMetricsLog = log; mMetricsLog = log; // TODO: ApfFilter should not generate programs until IpManager sends provisioning success. maybeStartFilter(); maybeStartFilter(); } } Loading Loading @@ -661,14 +662,19 @@ public class ApfFilter { // How long should the last installed filter program live for? In seconds. // How long should the last installed filter program live for? In seconds. @GuardedBy("this") @GuardedBy("this") private long mLastInstalledProgramMinLifetime; private long mLastInstalledProgramMinLifetime; @GuardedBy("this") private ApfProgramEvent mLastInstallEvent; // For debugging only. The last program installed. // For debugging only. The last program installed. @GuardedBy("this") @GuardedBy("this") private byte[] mLastInstalledProgram; private byte[] mLastInstalledProgram; // For debugging only. How many times the program was updated since we started. // How many times the program was updated since we started. @GuardedBy("this") private int mNumProgramUpdates = 0; // How many times the program was updated since we started for allowing multicast traffic. @GuardedBy("this") @GuardedBy("this") private int mNumProgramUpdates; private int mNumProgramUpdatesAllowingMulticast = 0; /** /** * Generate filter code to process ARP packets. Execution of this code ends in either the * Generate filter code to process ARP packets. Execution of this code ends in either the Loading Loading @@ -947,7 +953,8 @@ public class ApfFilter { Log.e(TAG, "Failed to generate APF program.", e); Log.e(TAG, "Failed to generate APF program.", e); return; return; } } mLastTimeInstalledProgram = currentTimeSeconds(); final long now = currentTimeSeconds(); mLastTimeInstalledProgram = now; mLastInstalledProgramMinLifetime = programMinLifetime; mLastInstalledProgramMinLifetime = programMinLifetime; mLastInstalledProgram = program; mLastInstalledProgram = program; mNumProgramUpdates++; mNumProgramUpdates++; Loading @@ -956,9 +963,26 @@ public class ApfFilter { hexDump("Installing filter: ", program, program.length); hexDump("Installing filter: ", program, program.length); } } mIpManagerCallback.installPacketFilter(program); mIpManagerCallback.installPacketFilter(program); int flags = ApfProgramEvent.flagsFor(mIPv4Address != null, mMulticastFilter); logApfProgramEventLocked(now); mMetricsLog.log(new ApfProgramEvent( mLastInstallEvent = new ApfProgramEvent(); programMinLifetime, rasToFilter.size(), mRas.size(), program.length, flags)); mLastInstallEvent.lifetime = programMinLifetime; mLastInstallEvent.filteredRas = rasToFilter.size(); mLastInstallEvent.currentRas = mRas.size(); mLastInstallEvent.programLength = program.length; mLastInstallEvent.flags = ApfProgramEvent.flagsFor(mIPv4Address != null, mMulticastFilter); } private void logApfProgramEventLocked(long now) { if (mLastInstallEvent == null) { return; } ApfProgramEvent ev = mLastInstallEvent; mLastInstallEvent = null; ev.actualLifetime = now - mLastTimeInstalledProgram; if (ev.actualLifetime < APF_PROGRAM_EVENT_LIFETIME_THRESHOLD) { return; } mMetricsLog.log(ev); } } /** /** Loading Loading @@ -1078,11 +1102,15 @@ public class ApfFilter { mRas.clear(); mRas.clear(); } } public synchronized void setMulticastFilter(boolean enabled) { public synchronized void setMulticastFilter(boolean isEnabled) { if (mMulticastFilter != enabled) { if (mMulticastFilter == isEnabled) { mMulticastFilter = enabled; return; installNewProgramLocked(); } } mMulticastFilter = isEnabled; if (!isEnabled) { mNumProgramUpdatesAllowingMulticast++; } installNewProgramLocked(); } } /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */ /** Find the single IPv4 LinkAddress if there is one, otherwise return null. */ Loading
tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java +6 −3 Original line number Original line Diff line number Diff line Loading @@ -304,6 +304,7 @@ public class IpConnectivityEventBuilderTest extends TestCase { ConnectivityMetricsEvent ev = describeIpEvent( ConnectivityMetricsEvent ev = describeIpEvent( aType(ApfProgramEvent.class), aType(ApfProgramEvent.class), aLong(200), aLong(200), aLong(18), anInt(7), anInt(7), anInt(9), anInt(9), anInt(2048), anInt(2048), Loading @@ -320,7 +321,7 @@ public class IpConnectivityEventBuilderTest extends TestCase { " apf_program_event <", " apf_program_event <", " current_ras: 9", " current_ras: 9", " drop_multicast: true", " drop_multicast: true", " effective_lifetime: 0", " effective_lifetime: 18", " filtered_ras: 7", " filtered_ras: 7", " has_ipv4_addr: true", " has_ipv4_addr: true", " lifetime: 200", " lifetime: 200", Loading @@ -343,6 +344,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { anInt(1), anInt(1), anInt(2), anInt(2), anInt(4), anInt(4), anInt(7), anInt(3), anInt(2048)); anInt(2048)); String want = joinLines( String want = joinLines( Loading @@ -360,8 +363,8 @@ public class IpConnectivityEventBuilderTest extends TestCase { " max_program_size: 2048", " max_program_size: 2048", " parse_errors: 2", " parse_errors: 2", " program_updates: 4", " program_updates: 4", " program_updates_all: 0", " program_updates_all: 7", " program_updates_allowing_multicast: 0", " program_updates_allowing_multicast: 3", " received_ras: 10", " received_ras: 10", " zero_lifetime_ras: 1", " zero_lifetime_ras: 1", " >", " >", Loading