Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf429084 authored by Paul Hu's avatar Paul Hu Committed by Automerger Merge Worker
Browse files

Merge "Use IDnsResolverUnsolicitedEventListener" am: a476ef4d am: 77a35d12

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1542744

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Iabcc9dc41b5e51920c7d67d89c90e1e2c7e3e45c
parents 5e62891a 77a35d12
Loading
Loading
Loading
Loading
+30 −43
Original line number Diff line number Diff line
@@ -142,10 +142,13 @@ import android.net.UnderlyingNetworkInfo;
import android.net.Uri;
import android.net.VpnManager;
import android.net.VpnTransportInfo;
import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.NetworkEvent;
import android.net.netlink.InetDiagMessage;
import android.net.resolv.aidl.DnsHealthEventParcel;
import android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener;
import android.net.resolv.aidl.Nat64PrefixEventParcel;
import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
import android.net.util.NetdService;
@@ -2037,25 +2040,24 @@ public class ConnectivityService extends IConnectivityManager.Stub
        return true;
    }

    private class NetdEventCallback extends INetdEventListener.Stub {
    class DnsResolverUnsolicitedEventCallback extends
            IDnsResolverUnsolicitedEventListener.Stub {
        @Override
        public void onPrivateDnsValidationEvent(int netId, String ipAddress,
                String hostname, boolean validated) {
        public void onPrivateDnsValidationEvent(final PrivateDnsValidationEventParcel event) {
            try {
                mHandler.sendMessage(mHandler.obtainMessage(
                        EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
                        new PrivateDnsValidationUpdate(netId,
                                InetAddresses.parseNumericAddress(ipAddress),
                                hostname, validated)));
                        new PrivateDnsValidationUpdate(event.netId,
                                InetAddresses.parseNumericAddress(event.ipAddress),
                                event.hostname, event.validation)));
            } catch (IllegalArgumentException e) {
                loge("Error parsing ip address in validation event");
            }
        }

        @Override
        public void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
                String hostname,  String[] ipAddresses, int ipAddressesCount, int uid) {
            NetworkAgentInfo nai = getNetworkAgentInfoForNetId(netId);
        public void onDnsHealthEvent(final DnsHealthEventParcel event) {
            NetworkAgentInfo nai = getNetworkAgentInfoForNetId(event.netId);
            // Netd event only allow registrants from system. Each NetworkMonitor thread is under
            // the caller thread of registerNetworkAgent. Thus, it's not allowed to register netd
            // event callback for certain nai. e.g. cellular. Register here to pass to
@@ -2064,34 +2066,18 @@ public class ConnectivityService extends IConnectivityManager.Stub
            // callback from each caller type. Need to re-factor NetdEventListenerService to allow
            // multiple NetworkMonitor registrants.
            if (nai != null && nai.satisfies(mDefaultRequest.mRequests.get(0))) {
                nai.networkMonitor().notifyDnsResponse(returnCode);
                nai.networkMonitor().notifyDnsResponse(event.healthResult);
            }
        }

        @Override
        public void onNat64PrefixEvent(int netId, boolean added,
                                       String prefixString, int prefixLength) {
            mHandler.post(() -> handleNat64PrefixEvent(netId, added, prefixString, prefixLength));
        public void onNat64PrefixEvent(final Nat64PrefixEventParcel event) {
            mHandler.post(() -> handleNat64PrefixEvent(event.netId, event.prefixOperation,
                    event.prefixAddress, event.prefixLength));
        }

        @Override
        public void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port,
                int uid) {
        }

        @Override
        public void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader,
                byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort,
                long timestampNs) {
        }

        @Override
        public void onTcpSocketStatsEvent(int[] networkIds, int[] sentPackets, int[] lostPackets,
                int[] rttsUs, int[] sentAckDiffsMs) {
        }

        @Override
        public int getInterfaceVersion() throws RemoteException {
        public int getInterfaceVersion() {
            return this.VERSION;
        }

@@ -2099,16 +2085,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
        public String getInterfaceHash() {
            return this.HASH;
        }
    };
    }

    @VisibleForTesting
    protected final INetdEventListener mNetdEventCallback = new NetdEventCallback();
    protected final DnsResolverUnsolicitedEventCallback mResolverUnsolEventCallback =
            new DnsResolverUnsolicitedEventCallback();

    private void registerNetdEventCallback() {
    private void registerDnsResolverUnsolicitedEventListener() {
        try {
            mDnsResolver.registerEventListener(mNetdEventCallback);
            mDnsResolver.registerUnsolicitedEventListener(mResolverUnsolEventCallback);
        } catch (Exception e) {
            loge("Error registering DnsResolver callback: " + e);
            loge("Error registering DnsResolver unsolicited event callback: " + e);
        }
    }

@@ -2439,7 +2426,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
        // to ensure the tracking will be initialized correctly.
        mPermissionMonitor.startMonitoring();
        mProxyTracker.loadGlobalProxy();
        registerNetdEventCallback();
        registerDnsResolverUnsolicitedEventListener();

        synchronized (this) {
            mSystemReady = true;
@@ -3370,21 +3357,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
        handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
    }

    private void handleNat64PrefixEvent(int netId, boolean added, String prefixString,
    private void handleNat64PrefixEvent(int netId, int operation, String prefixAddress,
            int prefixLength) {
        NetworkAgentInfo nai = mNetworkForNetId.get(netId);
        if (nai == null) return;

        log(String.format("NAT64 prefix %s on netId %d: %s/%d",
                          (added ? "added" : "removed"), netId, prefixString, prefixLength));
        log(String.format("NAT64 prefix changed on netId %d: operation=%d, %s/%d",
                netId, operation, prefixAddress, prefixLength));

        IpPrefix prefix = null;
        if (added) {
        if (operation == IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED) {
            try {
                prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixString),
                prefix = new IpPrefix(InetAddresses.parseNumericAddress(prefixAddress),
                        prefixLength);
            } catch (IllegalArgumentException e) {
                loge("Invalid NAT64 prefix " + prefixString + "/" + prefixLength);
                loge("Invalid NAT64 prefix " + prefixAddress + "/" + prefixLength);
                return;
            }
        }
+14 −8
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.server.connectivity;
import static android.net.ConnectivityManager.PRIVATE_DNS_DEFAULT_MODE_FALLBACK;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
import static android.provider.Settings.Global.DNS_RESOLVER_MAX_SAMPLES;
import static android.provider.Settings.Global.DNS_RESOLVER_MIN_SAMPLES;
import static android.provider.Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS;
@@ -147,17 +149,18 @@ public class DnsManager {
    }

    public static class PrivateDnsValidationUpdate {
        final public int netId;
        final public InetAddress ipAddress;
        final public String hostname;
        final public boolean validated;
        public final int netId;
        public final InetAddress ipAddress;
        public final String hostname;
        // Refer to IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_*.
        public final int validationResult;

        public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress,
                String hostname, boolean validated) {
                String hostname, int validationResult) {
            this.netId = netId;
            this.ipAddress = ipAddress;
            this.hostname = hostname;
            this.validated = validated;
            this.validationResult = validationResult;
        }
    }

@@ -216,10 +219,13 @@ public class DnsManager {
            if (!mValidationMap.containsKey(p)) {
                return;
            }
            if (update.validated) {
            if (update.validationResult == VALIDATION_RESULT_SUCCESS) {
                mValidationMap.put(p, ValidationStatus.SUCCEEDED);
            } else {
            } else if (update.validationResult == VALIDATION_RESULT_FAILURE) {
                mValidationMap.put(p, ValidationStatus.FAILED);
            } else {
                Log.e(TAG, "Unknown private dns validation operation="
                        + update.validationResult);
            }
        }

+54 −24
Original line number Diff line number Diff line
@@ -90,6 +90,10 @@ import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PAID_
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_OEM_PRIVATE_ONLY;
import static android.net.OemNetworkPreferences.OEM_NETWORK_PREFERENCE_UNINITIALIZED;
import static android.net.RouteInfo.RTN_UNREACHABLE;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_ADDED;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.PREFIX_OPERATION_REMOVED;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_FAILURE;
import static android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener.VALIDATION_RESULT_SUCCESS;
import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.IPPROTO_TCP;
@@ -217,6 +221,8 @@ import android.net.Uri;
import android.net.VpnManager;
import android.net.VpnTransportInfo;
import android.net.metrics.IpConnectivityLog;
import android.net.resolv.aidl.Nat64PrefixEventParcel;
import android.net.resolv.aidl.PrivateDnsValidationEventParcel;
import android.net.shared.NetworkMonitorUtils;
import android.net.shared.PrivateDnsConfig;
import android.net.util.MultinetworkPolicyTracker;
@@ -5919,6 +5925,16 @@ public class ConnectivityServiceTest {
        assertEquals("strict.example.com", cbi.getLp().getPrivateDnsServerName());
    }
    private PrivateDnsValidationEventParcel makePrivateDnsValidationEvent(
            final int netId, final String ipAddress, final String hostname, final int validation) {
        final PrivateDnsValidationEventParcel event = new PrivateDnsValidationEventParcel();
        event.netId = netId;
        event.ipAddress = ipAddress;
        event.hostname = hostname;
        event.validation = validation;
        return event;
    }
    @Test
    public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception {
        // The default on Android is opportunistic mode ("Automatic").
@@ -5949,8 +5965,9 @@ public class ConnectivityServiceTest {
        // Send a validation event for a server that is not part of the current
        // resolver config. The validation event should be ignored.
        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
                mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true);
        mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
                makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId, "",
                        "145.100.185.18", VALIDATION_RESULT_SUCCESS));
        cellNetworkCallback.assertNoCallback();
        // Add a dns server to the LinkProperties.
@@ -5967,20 +5984,23 @@ public class ConnectivityServiceTest {
        // Send a validation event containing a hostname that is not part of
        // the current resolver config. The validation event should be ignored.
        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
                mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true);
        mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
                makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
                        "145.100.185.16", "hostname", VALIDATION_RESULT_SUCCESS));
        cellNetworkCallback.assertNoCallback();
        // Send a validation event where validation failed.
        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
                mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false);
        mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
                makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
                        "145.100.185.16", "", VALIDATION_RESULT_FAILURE));
        cellNetworkCallback.assertNoCallback();
        // Send a validation event where validation succeeded for a server in
        // the current resolver config. A LinkProperties callback with updated
        // private dns fields should be sent.
        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
                mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true);
        mService.mResolverUnsolEventCallback.onPrivateDnsValidationEvent(
                makePrivateDnsValidationEvent(mCellNetworkAgent.getNetwork().netId,
                        "145.100.185.16", "", VALIDATION_RESULT_SUCCESS));
        cbi = cellNetworkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED,
                mCellNetworkAgent);
        cellNetworkCallback.assertNoCallback();
@@ -7824,6 +7844,16 @@ public class ConnectivityServiceTest {
        return stacked;
    }
    private Nat64PrefixEventParcel makeNat64PrefixEvent(final int netId, final int prefixOperation,
            final String prefixAddress, final int prefixLength) {
        final Nat64PrefixEventParcel event = new Nat64PrefixEventParcel();
        event.netId = netId;
        event.prefixOperation = prefixOperation;
        event.prefixAddress = prefixAddress;
        event.prefixLength = prefixLength;
        return event;
    }
    @Test
    public void testStackedLinkProperties() throws Exception {
        final LinkAddress myIpv4 = new LinkAddress("1.2.3.4/24");
@@ -7908,8 +7938,8 @@ public class ConnectivityServiceTest {
        // When NAT64 prefix discovery succeeds, LinkProperties are updated and clatd is started.
        Nat464Xlat clat = getNat464Xlat(mCellNetworkAgent);
        assertNull(mCm.getLinkProperties(mCellNetworkAgent.getNetwork()).getNat64Prefix());
        mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
                kNat64PrefixString, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
                makeNat64PrefixEvent(cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96));
        LinkProperties lpBeforeClat = networkCallback.expectCallback(
                CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent).getLp();
        assertEquals(0, lpBeforeClat.getStackedLinks().size());
@@ -7949,8 +7979,8 @@ public class ConnectivityServiceTest {
                .thenReturn(getClatInterfaceConfigParcel(myIpv4));
        // Change the NAT64 prefix without first removing it.
        // Expect clatd to be stopped and started with the new prefix.
        mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
                kOtherNat64PrefixString, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
                cellNetId, PREFIX_OPERATION_ADDED, kOtherNat64PrefixString, 96));
        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
                (lp) -> lp.getStackedLinks().size() == 0);
        verify(mMockNetd, times(1)).clatdStop(MOBILE_IFNAME);
@@ -7998,8 +8028,8 @@ public class ConnectivityServiceTest {
                .thenReturn(getClatInterfaceConfigParcel(myIpv4));
        // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.
        mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
                kOtherNat64PrefixString, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
                cellNetId, PREFIX_OPERATION_REMOVED, kOtherNat64PrefixString, 96));
        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
                (lp) -> lp.getNat64Prefix() == null);
@@ -8011,8 +8041,8 @@ public class ConnectivityServiceTest {
        networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
        assertRoutesRemoved(cellNetId, ipv4Subnet);  // Directly-connected routes auto-added.
        verify(mMockDnsResolver, times(1)).startPrefix64Discovery(cellNetId);
        mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */,
                kNat64PrefixString, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
                cellNetId, PREFIX_OPERATION_ADDED, kNat64PrefixString, 96));
        networkCallback.expectCallback(CallbackEntry.LINK_PROPERTIES_CHANGED, mCellNetworkAgent);
        verify(mMockNetd, times(1)).clatdStart(MOBILE_IFNAME, kNat64Prefix.toString());
@@ -8024,8 +8054,8 @@ public class ConnectivityServiceTest {
        verify(mMockNetd, times(1)).networkAddInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME);
        // NAT64 prefix is removed. Expect that clat is stopped.
        mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */,
                kNat64PrefixString, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(makeNat64PrefixEvent(
                cellNetId, PREFIX_OPERATION_REMOVED, kNat64PrefixString, 96));
        networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,
                (lp) -> lp.getStackedLinks().size() == 0 && lp.getNat64Prefix() == null);
        assertRoutesRemoved(cellNetId, ipv4Subnet, stackedDefault);
@@ -8113,8 +8143,8 @@ public class ConnectivityServiceTest {
        inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
        inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
        mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
                pref64FromDnsStr, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
                makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96));
        expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns);
        inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
@@ -8147,8 +8177,8 @@ public class ConnectivityServiceTest {
        inOrder.verify(mMockDnsResolver).stopPrefix64Discovery(netId);
        // Stopping prefix discovery results in a prefix removed notification.
        mService.mNetdEventCallback.onNat64PrefixEvent(netId, false /* added */,
                pref64FromDnsStr, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
                makeNat64PrefixEvent(netId, PREFIX_OPERATION_REMOVED, pref64FromDnsStr, 96));
        inOrder.verify(mMockNetd).clatdStart(iface, pref64FromRa.toString());
        inOrder.verify(mMockDnsResolver).setPrefix64(netId, pref64FromRa.toString());
@@ -8186,8 +8216,8 @@ public class ConnectivityServiceTest {
        inOrder.verify(mMockNetd).clatdStop(iface);
        inOrder.verify(mMockDnsResolver).setPrefix64(netId, "");
        inOrder.verify(mMockDnsResolver).startPrefix64Discovery(netId);
        mService.mNetdEventCallback.onNat64PrefixEvent(netId, true /* added */,
                pref64FromDnsStr, 96);
        mService.mResolverUnsolEventCallback.onNat64PrefixEvent(
                makeNat64PrefixEvent(netId, PREFIX_OPERATION_ADDED, pref64FromDnsStr, 96));
        expectNat64PrefixChange(callback, mWiFiNetworkAgent, pref64FromDns);
        inOrder.verify(mMockNetd).clatdStart(iface, pref64FromDns.toString());
        inOrder.verify(mMockDnsResolver, never()).setPrefix64(eq(netId), any());
+23 −12

File changed.

Preview size limit exceeded, changes collapsed.