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

Commit 769a50b5 authored by Jack Yu's avatar Jack Yu
Browse files

Fixed duplicate interface detector

When clearing the dangling network agent, the interface
name is not availalbe because the handover destination
data connection was not succesfully setup, so there is no
valid interface name.

Changed the detection logic to use netId/iface-name map
to make sure all live agents do not have duplicate interface
name.

Fix: 161074519
Test: Manual
Merged-In: I7b0f20bb499cd50978206265707a806521f08437
Change-Id: I7b0f20bb499cd50978206265707a806521f08437
(cherry picked from commit c327587d)
parent 308ef12e
Loading
Loading
Loading
Loading
+39 −30
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony.dataconnection;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.KeepalivePacketData;
import android.net.LinkProperties;
import android.net.NattKeepalivePacketData;
@@ -32,7 +33,7 @@ import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.AnomalyReporter;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.SparseArray;

@@ -46,8 +47,8 @@ import com.android.telephony.Rlog;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.HashSet;
import java.util.Set;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
@@ -63,6 +64,8 @@ import java.util.UUID;
public class DcNetworkAgent extends NetworkAgent {
    private final String mTag;

    private final int mId;

    private Phone mPhone;

    private int mTransportType;
@@ -77,8 +80,8 @@ public class DcNetworkAgent extends NetworkAgent {

    private NetworkInfo mNetworkInfo;

    // For debugging duplicate interface issue. Remove before R released.
    private static Set<String> sInterfaceNames = new HashSet<>();
    // For interface duplicate detection. Key is the net id, value is the interface name in string.
    private static Map<Integer, String> sInterfaceNames = new ArrayMap<>();

    DcNetworkAgent(DataConnection dc, Phone phone, NetworkInfo ni, int score,
            NetworkAgentConfig config, NetworkProvider networkProvider, int transportType) {
@@ -86,33 +89,38 @@ public class DcNetworkAgent extends NetworkAgent {
                dc.getNetworkCapabilities(), dc.getLinkProperties(), score, config,
                networkProvider);
        register();
        mTag = "DcNetworkAgent" + "-" + getNetwork().netId;
        mId = getNetwork().netId;
        mTag = "DcNetworkAgent" + "-" + mId;
        mPhone = phone;
        mNetworkCapabilities = dc.getNetworkCapabilities();
        mTransportType = transportType;
        mDataConnection = dc;
        mNetworkInfo = new NetworkInfo(ni);
        setLegacyExtraInfo(ni.getExtraInfo());
        // TODO: Remove before R is released.
        if (dc.getLinkProperties() != null
                && !TextUtils.isEmpty(dc.getLinkProperties().getInterfaceName())) {
            checkDuplicateInterface(dc.getLinkProperties().getInterfaceName());
        if (dc.getLinkProperties() != null) {
            checkDuplicateInterface(mId, dc.getLinkProperties().getInterfaceName());
            logd("created for data connection " + dc.getName() + ", "
                    + dc.getLinkProperties().getInterfaceName());
        } else {
            loge("The connection does not have a valid link properties.");
        }
        logd(mTag + " created for data connection " + dc.getName());
    }

    // This is a temp code to catch the duplicate network interface issue.
    // TODO: Remove before R is released.
    private void checkDuplicateInterface(String interfaceName) {
        if (sInterfaceNames.contains(interfaceName)) {
            String message = "Duplicate interface " + interfaceName + " is detected.";
            log(message);
    private void checkDuplicateInterface(int netId, @Nullable String interfaceName) {
        for (Map.Entry<Integer, String> entry: sInterfaceNames.entrySet()) {
            if (Objects.equals(interfaceName, entry.getValue())) {
                String message = "Duplicate interface " + interfaceName
                        + " is detected. DcNetworkAgent-" + entry.getKey()
                        + " already used this interface name.";
                loge(message);
                // Using fixed UUID to avoid duplicate bugreport notification
                AnomalyReporter.reportAnomaly(
                        UUID.fromString("02f3d3f6-4613-4415-b6cb-8d92c8a938a6"),
                        message);
                return;
            }
        sInterfaceNames.add(interfaceName);
        }
        sInterfaceNames.put(netId, interfaceName);
    }

    /**
@@ -143,7 +151,7 @@ public class DcNetworkAgent extends NetworkAgent {
            loge("releaseOwnership called on no-owner DcNetworkAgent!");
            return;
        } else if (mDataConnection != dc) {
            log("releaseOwnership: This agent belongs to "
            loge("releaseOwnership: This agent belongs to "
                    + mDataConnection.getName() + ", ignored the request from " + dc.getName());
            return;
        }
@@ -252,9 +260,11 @@ public class DcNetworkAgent extends NetworkAgent {
     * @param linkProperties The link properties
     * @param dc The data connection that invokes this method.
     */
    public synchronized void sendLinkProperties(LinkProperties linkProperties,
    public synchronized void sendLinkProperties(@NonNull LinkProperties linkProperties,
                                                DataConnection dc) {
        if (!isOwned(dc, "sendLinkProperties")) return;

        sInterfaceNames.put(mId, dc.getLinkProperties().getInterfaceName());
        sendLinkProperties(linkProperties);
    }

@@ -277,11 +287,8 @@ public class DcNetworkAgent extends NetworkAgent {
    public synchronized void unregister(DataConnection dc) {
        if (!isOwned(dc, "unregister")) return;

        if (dc.getLinkProperties() != null
                && !TextUtils.isEmpty(dc.getLinkProperties().getInterfaceName())) {
            sInterfaceNames.remove(dc.getLinkProperties().getInterfaceName());
        }
        logd("Unregister from connectivity service");
        logd("Unregister from connectivity service. " + sInterfaceNames.get(mId) + " removed.");
        sInterfaceNames.remove(mId);
        super.unregister();
    }

@@ -347,11 +354,13 @@ public class DcNetworkAgent extends NetworkAgent {

    @Override
    public String toString() {
        return "DcNetworkAgent:"
        return "DcNetworkAgent-"
                + mId
                + " mDataConnection="
                + ((mDataConnection != null) ? mDataConnection.getName() : null)
                + " mTransportType="
                + AccessNetworkConstants.transportTypeToString(mTransportType)
                + " " + ((mDataConnection != null) ? mDataConnection.getLinkProperties() : null)
                + " mNetworkCapabilities=" + mNetworkCapabilities;
    }