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