Ostrich VPN v1.19.0222版本的 MD5 值为:1b442e5f3dd93fd660d88d6f4b94ace3

以下内容为反编译后的 CharonVpnService.java 源代码,内容仅作参考


package org.strongswan.android.logic;

import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.net.VpnService;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
import android.security.KeyChain;
import android.security.KeyChainException;
import android.system.OsConstants;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.security.PrivateKey;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.SortedSet;
import org.strongswan.android.data.VpnProfile;
import org.strongswan.android.data.VpnProfileDataSource;
import org.strongswan.android.data.VpnType;
import org.strongswan.android.logic.VpnStateService;
import org.strongswan.android.logic.imc.ImcState;
import org.strongswan.android.logic.imc.RemediationInstruction;
import org.strongswan.android.utils.IPRange;
import org.strongswan.android.utils.IPRangeSet;
import org.strongswan.android.utils.SettingsWriter;
import org.strongswan.android.utils.Utils;

public class CharonVpnService extends VpnService implements Runnable, VpnStateService.VpnStateListener {
    public static final String DISCONNECT_ACTION = "org.strongswan.android.CharonVpnService.DISCONNECT";
    public static final String KEY_IS_RETRY = "retry";
    public static final String LOG_FILE = "charon.log";
    private static final String NOTIFICATION_CHANNEL = "org.strongswan.android.CharonVpnService.VPN_STATE_NOTIFICATION";
    static final int STATE_AUTH_ERROR = 3;
    static final int STATE_CERTIFICATE_UNAVAILABLE = 7;
    static final int STATE_CHILD_SA_DOWN = 2;
    static final int STATE_CHILD_SA_UP = 1;
    static final int STATE_GENERIC_ERROR = 8;
    static final int STATE_LOOKUP_ERROR = 5;
    static final int STATE_PEER_AUTH_ERROR = 4;
    static final int STATE_UNREACHABLE_ERROR = 6;
    private static final String TAG = "CharonVpnService";
    private static final String VPN_SERVICE_ACTION = "android.net.VpnService";
    public static final int VPN_STATE_NOTIFICATION_ID = 1;
    private Ikev2Callback callback;
    private List<String> ignoreApp;
    private String mAppDir;
    private BuilderAdapter mBuilderAdapter;
    private Thread mConnectionHandler;
    private volatile String mCurrentCertificateAlias;
    private VpnProfile mCurrentProfile;
    private volatile String mCurrentUserCertificateAlias;
    private VpnProfileDataSource mDataSource;
    private Handler mHandler;
    private volatile boolean mIsDisconnecting;
    private String mLogFile;
    private VpnProfile mNextProfile;
    private volatile boolean mProfileUpdated;
    private VpnStateService mService;
    private final ServiceConnection mServiceConnection;
    private final Object mServiceLock;
    private volatile boolean mTerminate;
    private boolean proxySelf;
    private VpnService vpnService;

    public native void deinitializeCharon();

    public native boolean initializeCharon(BuilderAdapter builderAdapter, String str, String str2, boolean z);

    public native void initiate(String str);

    public CharonVpnService() {
        this.mBuilderAdapter = new BuilderAdapter();
        this.mServiceLock = new Object();
        this.mServiceConnection = new ServiceConnection() {
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                synchronized (CharonVpnService.this.mServiceLock) {
                    CharonVpnService.this.mService = null;
                }
            }

            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                synchronized (CharonVpnService.this.mServiceLock) {
                    CharonVpnService.this.mService = ((VpnStateService.LocalBinder) iBinder).getService();
                }
                CharonVpnService.this.mService.registerListener(CharonVpnService.this);
                CharonVpnService.this.mConnectionHandler.start();
            }
        };
        this.proxySelf = true;
    }

    public CharonVpnService(VpnService vpnService) {
        this.mBuilderAdapter = new BuilderAdapter();
        this.mServiceLock = new Object();
        ServiceConnection serviceConnection = new ServiceConnection() {
            @Override
            public void onServiceDisconnected(ComponentName componentName) {
                synchronized (CharonVpnService.this.mServiceLock) {
                    CharonVpnService.this.mService = null;
                }
            }

            @Override
            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
                synchronized (CharonVpnService.this.mServiceLock) {
                    CharonVpnService.this.mService = ((VpnStateService.LocalBinder) iBinder).getService();
                }
                CharonVpnService.this.mService.registerListener(CharonVpnService.this);
                CharonVpnService.this.mConnectionHandler.start();
            }
        };
        this.mServiceConnection = serviceConnection;
        this.proxySelf = true;
        this.vpnService = vpnService;
        this.mLogFile = this.vpnService.getFilesDir().getAbsolutePath() + File.separator + LOG_FILE;
        this.mAppDir = this.vpnService.getFilesDir().getAbsolutePath();
        this.mHandler = new Handler();
        VpnProfileDataSource vpnProfileDataSource = new VpnProfileDataSource(this.vpnService);
        this.mDataSource = vpnProfileDataSource;
        vpnProfileDataSource.open();
        this.mConnectionHandler = new Thread(this);
        this.vpnService.bindService(new Intent(this.vpnService, (Class<?>) VpnStateService.class), serviceConnection, 1);
    }

    public void start(VpnProfile vpnProfile, boolean z, List<String> list, Ikev2Callback ikev2Callback) {
        if (vpnProfile != null) {
            if (ikev2Callback != null) {
                this.callback = ikev2Callback;
            }
            this.proxySelf = z;
            this.ignoreApp = list;
            setNextProfile(vpnProfile);
        }
    }

    public void stop() {
        setNextProfile(null);
    }

    public void destroy() {
        this.mTerminate = true;
        setNextProfile(null);
        try {
            this.mConnectionHandler.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        VpnStateService vpnStateService = this.mService;
        if (vpnStateService != null) {
            vpnStateService.unregisterListener(this);
            this.vpnService.unbindService(this.mServiceConnection);
        }
        this.mDataSource.close();
    }

    private void setNextProfile(VpnProfile vpnProfile) {
        synchronized (this) {
            this.mNextProfile = vpnProfile;
            this.mProfileUpdated = true;
            notifyAll();
        }
    }

    @Override
    public void run() {
        while (true) {
            synchronized (this) {
                while (!this.mProfileUpdated) {
                    try {
                        wait();
                    } catch (InterruptedException unused) {
                        stopCurrentConnection();
                        setState(VpnStateService.State.DISABLED);
                    }
                }
                this.mProfileUpdated = false;
                stopCurrentConnection();
                VpnProfile vpnProfile = this.mNextProfile;
                if (vpnProfile == null) {
                    setState(VpnStateService.State.DISABLED);
                    if (this.mTerminate) {
                        return;
                    }
                } else {
                    this.mCurrentProfile = vpnProfile;
                    this.mNextProfile = null;
                    this.mCurrentCertificateAlias = vpnProfile.getCertificateAlias();
                    this.mCurrentUserCertificateAlias = this.mCurrentProfile.getUserCertificateAlias();
                    startConnection(this.mCurrentProfile);
                    this.mIsDisconnecting = false;
                    SimpleFetcher.enable();
                    this.mBuilderAdapter.setProfile(this.mCurrentProfile);
                    if (initializeCharon(this.mBuilderAdapter, this.mLogFile, this.mAppDir, this.mCurrentProfile.getVpnType().has(VpnType.VpnTypeFeature.BYOD))) {
                        Log.i(TAG, "charon started");
                        if (this.mCurrentProfile.getVpnType().has(VpnType.VpnTypeFeature.USER_PASS) && this.mCurrentProfile.getPassword() == null) {
                            setError(VpnStateService.ErrorState.PASSWORD_MISSING);
                        } else {
                            SettingsWriter settingsWriter = new SettingsWriter();
                            settingsWriter.setValue("global.language", Locale.getDefault().getLanguage());
                            settingsWriter.setValue("global.mtu", this.mCurrentProfile.getMTU());
                            settingsWriter.setValue("global.nat_keepalive", this.mCurrentProfile.getNATKeepAlive());
                            settingsWriter.setValue("global.rsa_pss", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 16) != 0));
                            settingsWriter.setValue("global.crl", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 2) == 0));
                            settingsWriter.setValue("global.ocsp", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 4) == 0));
                            settingsWriter.setValue("connection.type", this.mCurrentProfile.getVpnType().getIdentifier());
                            settingsWriter.setValue("connection.server", this.mCurrentProfile.getGateway());
                            settingsWriter.setValue("connection.port", this.mCurrentProfile.getPort());
                            settingsWriter.setValue("connection.username", this.mCurrentProfile.getUsername());
                            settingsWriter.setValue("connection.password", this.mCurrentProfile.getPassword());
                            settingsWriter.setValue("connection.local_id", this.mCurrentProfile.getLocalId());
                            settingsWriter.setValue("connection.remote_id", this.mCurrentProfile.getRemoteId());
                            settingsWriter.setValue("connection.certreq", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 1) == 0));
                            settingsWriter.setValue("connection.strict_revocation", Boolean.valueOf((this.mCurrentProfile.getFlags().intValue() & 8) != 0));
                            settingsWriter.setValue("connection.ike_proposal", this.mCurrentProfile.getIkeProposal());
                            settingsWriter.setValue("connection.esp_proposal", this.mCurrentProfile.getEspProposal());
                            initiate(settingsWriter.serialize());
                        }
                    } else {
                        Log.e(TAG, "failed to start charon");
                        setError(VpnStateService.ErrorState.GENERIC_ERROR);
                        setState(VpnStateService.State.DISABLED);
                        this.mCurrentProfile = null;
                    }
                }
            }
        }
    }

    private void stopCurrentConnection() {
        synchronized (this) {
            if (this.mNextProfile != null) {
                this.mBuilderAdapter.setProfile(this.mNextProfile);
                this.mBuilderAdapter.establishBlocking();
            }
            if (this.mCurrentProfile != null) {
                setState(VpnStateService.State.DISCONNECTING);
                this.mIsDisconnecting = true;
                SimpleFetcher.disable();
                deinitializeCharon();
                Log.i(TAG, "charon stopped");
                this.mCurrentProfile = null;
                if (this.mNextProfile == null) {
                    this.mBuilderAdapter.closeBlocking();
                }
            }
        }
    }

    @Override
    public void stateChanged() {
        if (this.callback != null) {
            VpnStateService.State state = this.mService.getState();
            VpnStateService.ErrorState errorState = this.mService.getErrorState();
            if (errorState != VpnStateService.ErrorState.NO_ERROR) {
                this.callback.onFailed(errorState);
            } else if (state == VpnStateService.State.CONNECTED) {
                this.callback.onSuccess();
            }
        }
    }

    private void startConnection(VpnProfile vpnProfile) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.startConnection(vpnProfile);
            }
        }
    }

    private void setState(VpnStateService.State state) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.setState(state);
            }
        }
    }

    private void setError(VpnStateService.ErrorState errorState) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.setError(errorState);
            }
        }
    }

    private void setImcState(ImcState imcState) {
        synchronized (this.mServiceLock) {
            VpnStateService vpnStateService = this.mService;
            if (vpnStateService != null) {
                vpnStateService.setImcState(imcState);
            }
        }
    }

    private void setErrorDisconnect(VpnStateService.ErrorState errorState) {
        synchronized (this.mServiceLock) {
            if (this.mService != null && !this.mIsDisconnecting) {
                this.mService.setError(errorState);
            }
        }
    }

    public void updateStatus(int i) {
        switch (i) {
            case 1:
                setState(VpnStateService.State.CONNECTED);
                return;
            case 2:
                if (this.mIsDisconnecting) {
                    return;
                }
                setState(VpnStateService.State.CONNECTING);
                return;
            case 3:
                setErrorDisconnect(VpnStateService.ErrorState.AUTH_FAILED);
                return;
            case 4:
                setErrorDisconnect(VpnStateService.ErrorState.PEER_AUTH_FAILED);
                return;
            case 5:
                setErrorDisconnect(VpnStateService.ErrorState.LOOKUP_FAILED);
                return;
            case 6:
                setErrorDisconnect(VpnStateService.ErrorState.UNREACHABLE);
                return;
            case 7:
                setErrorDisconnect(VpnStateService.ErrorState.CERTIFICATE_UNAVAILABLE);
                return;
            case 8:
                setErrorDisconnect(VpnStateService.ErrorState.GENERIC_ERROR);
                return;
            default:
                Log.e(TAG, "Unknown status code received");
                return;
        }
    }

    public void updateImcState(int i) {
        ImcState fromValue = ImcState.fromValue(i);
        if (fromValue != null) {
            setImcState(fromValue);
        }
    }

    public void addRemediationInstruction(String str) {
        for (RemediationInstruction remediationInstruction : RemediationInstruction.fromXml(str)) {
            synchronized (this.mServiceLock) {
                VpnStateService vpnStateService = this.mService;
                if (vpnStateService != null) {
                    vpnStateService.addRemediationInstruction(remediationInstruction);
                }
            }
        }
    }

    private byte[][] getTrustedCertificates() {
        ArrayList arrayList = new ArrayList();
        TrustedCertificateManager load = TrustedCertificateManager.getInstance().load();
        try {
            String str = this.mCurrentCertificateAlias;
            if (str != null) {
                X509Certificate cACertificateFromAlias = load.getCACertificateFromAlias(str);
                if (cACertificateFromAlias == null) {
                    return null;
                }
                arrayList.add(cACertificateFromAlias.getEncoded());
            } else {
                Iterator<X509Certificate> it = load.getAllCACertificates().values().iterator();
                while (it.hasNext()) {
                    arrayList.add(it.next().getEncoded());
                }
            }
            return (byte[][]) arrayList.toArray(new byte[arrayList.size()]);
        } catch (CertificateEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    private byte[][] getUserCertificate() throws KeyChainException, InterruptedException, CertificateEncodingException {
        ArrayList arrayList = new ArrayList();
        X509Certificate[] certificateChain = KeyChain.getCertificateChain(this.vpnService.getApplicationContext(), this.mCurrentUserCertificateAlias);
        if (certificateChain == null || certificateChain.length == 0) {
            return null;
        }
        for (X509Certificate x509Certificate : certificateChain) {
            arrayList.add(x509Certificate.getEncoded());
        }
        return (byte[][]) arrayList.toArray(new byte[arrayList.size()]);
    }

    private PrivateKey getUserKey() throws KeyChainException, InterruptedException {
        return KeyChain.getPrivateKey(this.vpnService.getApplicationContext(), this.mCurrentUserCertificateAlias);
    }

    public class BuilderAdapter {
        private VpnService.Builder mBuilder;
        private BuilderCache mCache;
        private PacketDropper mDropper = new PacketDropper();
        private BuilderCache mEstablishedCache;
        private VpnProfile mProfile;

        public BuilderAdapter() {
        }

        public synchronized void setProfile(VpnProfile vpnProfile) {
            this.mProfile = vpnProfile;
            VpnService.Builder createBuilder = createBuilder(vpnProfile.getName());
            this.mBuilder = createBuilder;
            addDisallowApps(createBuilder);
            this.mCache = new BuilderCache(this.mProfile);
        }

        private VpnService.Builder createBuilder(String str) {
            VpnService vpnService = CharonVpnService.this.vpnService;
            Objects.requireNonNull(vpnService);
            VpnService.Builder builder = new VpnService.Builder(vpnService);
            builder.setSession(str);
            return builder;
        }

        private void addDisallowApps(VpnService.Builder builder) {
            try {
                if (!CharonVpnService.this.proxySelf) {
                    builder.addDisallowedApplication(CharonVpnService.this.vpnService.getPackageName());
                }
                if (CharonVpnService.this.ignoreApp != null) {
                    Iterator it = CharonVpnService.this.ignoreApp.iterator();
                    while (it.hasNext()) {
                        builder.addDisallowedApplication((String) it.next());
                    }
                }
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodError e2) {
                e2.printStackTrace();
            }
        }

        public synchronized boolean addAddress(String str, int i) {
            try {
                this.mCache.addAddress(str, i);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean addDnsServer(String str) {
            try {
                this.mCache.addDnsServer(str);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean addRoute(String str, int i) {
            try {
                this.mCache.addRoute(str, i);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean addSearchDomain(String str) {
            try {
                this.mBuilder.addSearchDomain(str);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        public synchronized boolean setMtu(int i) {
            try {
                this.mCache.setMtu(i);
            } catch (IllegalArgumentException unused) {
                return false;
            }
            return true;
        }

        private synchronized ParcelFileDescriptor establishIntern() {
            try {
                this.mCache.applyData(this.mBuilder);
                ParcelFileDescriptor establish = this.mBuilder.establish();
                if (establish != null) {
                    closeBlocking();
                }
                if (establish == null) {
                    return null;
                }
                this.mBuilder = createBuilder(this.mProfile.getName());
                this.mEstablishedCache = this.mCache;
                this.mCache = new BuilderCache(this.mProfile);
                return establish;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

        public synchronized int establish() {
            ParcelFileDescriptor establishIntern;
            establishIntern = establishIntern();
            return establishIntern != null ? establishIntern.detachFd() : -1;
        }

        public synchronized void establishBlocking() {
            this.mCache.addAddress("172.16.252.1", 32);
            this.mCache.addAddress("fd00::fd02:1", 128);
            this.mCache.addRoute("0.0.0.0", 0);
            this.mCache.addRoute("::", 0);
            this.mBuilder.addDnsServer("8.8.8.8");
            this.mBuilder.addDnsServer("2001:4860:4860::8888");
            this.mBuilder.setBlocking(true);
            ParcelFileDescriptor establishIntern = establishIntern();
            if (establishIntern != null) {
                this.mDropper.start(establishIntern);
            }
        }

        public synchronized void closeBlocking() {
            this.mDropper.stop();
        }

        public synchronized int establishNoDns() {
            if (this.mEstablishedCache == null) {
                return -1;
            }
            try {
                VpnService.Builder createBuilder = createBuilder(this.mProfile.getName());
                this.mEstablishedCache.applyData(createBuilder);
                ParcelFileDescriptor establish = createBuilder.establish();
                if (establish == null) {
                    return -1;
                }
                return establish.detachFd();
            } catch (Exception e) {
                e.printStackTrace();
                return -1;
            }
        }

        public class PacketDropper implements Runnable {
            private ParcelFileDescriptor mFd;
            private Thread mThread;

            private PacketDropper() {
            }

            public void start(ParcelFileDescriptor parcelFileDescriptor) {
                this.mFd = parcelFileDescriptor;
                Thread thread = new Thread(this);
                this.mThread = thread;
                thread.start();
            }

            public void stop() {
                if (this.mFd != null) {
                    try {
                        this.mThread.interrupt();
                        this.mThread.join();
                        this.mFd.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (InterruptedException e2) {
                        e2.printStackTrace();
                    }
                    this.mFd = null;
                }
            }

            @Override
            public synchronized void run() {
                try {
                    FileInputStream fileInputStream = new FileInputStream(this.mFd.getFileDescriptor());
                    ByteBuffer allocate = ByteBuffer.allocate(BuilderAdapter.this.mCache.mMtu);
                    while (true) {
                        if (Build.VERSION.SDK_INT >= 24) {
                            int read = fileInputStream.getChannel().read(allocate);
                            allocate.clear();
                            if (read < 0) {
                                break;
                            }
                        } else if (fileInputStream.available() > 0) {
                            int read2 = fileInputStream.read(allocate.array());
                            allocate.clear();
                            if (read2 < 0 || Thread.interrupted()) {
                                break;
                            }
                        } else {
                            Thread.sleep(250L);
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException | ClosedByInterruptException unused) {
                }
            }
        }
    }

    public class BuilderCache {
        private final VpnProfile.SelectedAppsHandling mAppHandling;
        private boolean mDnsServersConfigured;
        private final IPRangeSet mExcludedSubnets;
        private boolean mIPv4Seen;
        private boolean mIPv6Seen;
        private int mMtu;
        private final SortedSet<String> mSelectedApps;
        private final int mSplitTunneling;
        private final List<IPRange> mAddresses = new ArrayList();
        private final List<IPRange> mRoutesIPv4 = new ArrayList();
        private final List<IPRange> mRoutesIPv6 = new ArrayList();
        private final IPRangeSet mIncludedSubnetsv4 = new IPRangeSet();
        private final IPRangeSet mIncludedSubnetsv6 = new IPRangeSet();
        private final List<InetAddress> mDnsServers = new ArrayList();

        public void setMtu(int i) {
            this.mMtu = i;
        }

        public BuilderCache(VpnProfile vpnProfile) {
            Iterator<IPRange> it = IPRangeSet.fromString(vpnProfile.getIncludedSubnets()).iterator();
            while (it.hasNext()) {
                IPRange next = it.next();
                if (next.getFrom() instanceof Inet4Address) {
                    this.mIncludedSubnetsv4.add(next);
                } else if (next.getFrom() instanceof Inet6Address) {
                    this.mIncludedSubnetsv6.add(next);
                }
            }
            this.mExcludedSubnets = IPRangeSet.fromString(vpnProfile.getExcludedSubnets());
            Integer splitTunneling = vpnProfile.getSplitTunneling();
            this.mSplitTunneling = splitTunneling != null ? splitTunneling.intValue() : 0;
            VpnProfile.SelectedAppsHandling selectedAppsHandling = vpnProfile.getSelectedAppsHandling();
            SortedSet<String> selectedAppsSet = vpnProfile.getSelectedAppsSet();
            this.mSelectedApps = selectedAppsSet;
            int i = AnonymousClass2.$SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[selectedAppsHandling.ordinal()];
            if (i == 1) {
                selectedAppsHandling = VpnProfile.SelectedAppsHandling.SELECTED_APPS_EXCLUDE;
                selectedAppsSet.clear();
            } else if (i != 2) {
                if (i == 3) {
                    selectedAppsSet.remove(CharonVpnService.this.vpnService.getPackageName());
                }
                this.mAppHandling = selectedAppsHandling;
                if (vpnProfile.getDnsServers() != null) {
                    for (String str : vpnProfile.getDnsServers().split("\\s+")) {
                        try {
                            this.mDnsServers.add(Utils.parseInetAddress(str));
                            recordAddressFamily(str);
                            this.mDnsServersConfigured = true;
                        } catch (UnknownHostException e) {
                            e.printStackTrace();
                        }
                    }
                }
                Integer mtu = vpnProfile.getMTU();
                this.mMtu = mtu != null ? 1500 : mtu.intValue();
            }
            selectedAppsSet.add(CharonVpnService.this.vpnService.getPackageName());
            this.mAppHandling = selectedAppsHandling;
            if (vpnProfile.getDnsServers() != null) {
            }
            Integer mtu2 = vpnProfile.getMTU();
            this.mMtu = mtu2 != null ? 1500 : mtu2.intValue();
        }

        public void addAddress(String str, int i) {
            try {
                this.mAddresses.add(new IPRange(str, i));
                recordAddressFamily(str);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void addDnsServer(String str) {
            if (this.mDnsServersConfigured) {
                return;
            }
            try {
                this.mDnsServers.add(Utils.parseInetAddress(str));
                recordAddressFamily(str);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void addRoute(String str, int i) {
            try {
                if (isIPv6(str)) {
                    this.mRoutesIPv6.add(new IPRange(str, i));
                } else {
                    this.mRoutesIPv4.add(new IPRange(str, i));
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void recordAddressFamily(String str) {
            try {
                if (isIPv6(str)) {
                    this.mIPv6Seen = true;
                } else {
                    this.mIPv4Seen = true;
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }

        public void applyData(VpnService.Builder builder) {
            for (IPRange iPRange : this.mAddresses) {
                builder.addAddress(iPRange.getFrom(), iPRange.getPrefix().intValue());
            }
            Iterator<InetAddress> it = this.mDnsServers.iterator();
            while (it.hasNext()) {
                builder.addDnsServer(it.next());
            }
            if ((this.mSplitTunneling & 1) == 0) {
                if (this.mIPv4Seen) {
                    IPRangeSet iPRangeSet = new IPRangeSet();
                    if (this.mIncludedSubnetsv4.size() > 0) {
                        iPRangeSet.add(this.mIncludedSubnetsv4);
                    } else {
                        iPRangeSet.addAll(this.mRoutesIPv4);
                    }
                    iPRangeSet.remove(this.mExcludedSubnets);
                    for (IPRange iPRange2 : iPRangeSet.subnets()) {
                        try {
                            builder.addRoute(iPRange2.getFrom(), iPRange2.getPrefix().intValue());
                        } catch (IllegalArgumentException e) {
                            if (!iPRange2.getFrom().isMulticastAddress()) {
                                throw e;
                            }
                        }
                    }
                } else {
                    builder.allowFamily(OsConstants.AF_INET);
                }
            } else if (this.mIPv4Seen) {
                builder.addRoute("0.0.0.0", 0);
            }
            if ((this.mSplitTunneling & 2) == 0) {
                if (this.mIPv6Seen) {
                    IPRangeSet iPRangeSet2 = new IPRangeSet();
                    if (this.mIncludedSubnetsv6.size() > 0) {
                        iPRangeSet2.add(this.mIncludedSubnetsv6);
                    } else {
                        iPRangeSet2.addAll(this.mRoutesIPv6);
                    }
                    iPRangeSet2.remove(this.mExcludedSubnets);
                    for (IPRange iPRange3 : iPRangeSet2.subnets()) {
                        try {
                            builder.addRoute(iPRange3.getFrom(), iPRange3.getPrefix().intValue());
                        } catch (IllegalArgumentException e2) {
                            if (!iPRange3.getFrom().isMulticastAddress()) {
                                throw e2;
                            }
                        }
                    }
                } else {
                    builder.allowFamily(OsConstants.AF_INET6);
                }
            } else if (this.mIPv6Seen) {
                builder.addRoute("::", 0);
            }
            if (this.mSelectedApps.size() > 0) {
                int i = AnonymousClass2.$SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[this.mAppHandling.ordinal()];
                if (i == 2) {
                    Iterator<String> it2 = this.mSelectedApps.iterator();
                    while (it2.hasNext()) {
                        try {
                            builder.addDisallowedApplication(it2.next());
                        } catch (PackageManager.NameNotFoundException unused) {
                        } catch (NoSuchMethodError e3) {
                            e3.printStackTrace();
                        }
                    }
                } else if (i == 3) {
                    Iterator<String> it3 = this.mSelectedApps.iterator();
                    while (it3.hasNext()) {
                        try {
                            builder.addAllowedApplication(it3.next());
                        } catch (PackageManager.NameNotFoundException unused2) {
                        }
                    }
                }
            }
            builder.setMtu(this.mMtu);
        }

        private boolean isIPv6(String str) throws UnknownHostException {
            InetAddress parseInetAddress = Utils.parseInetAddress(str);
            return !(parseInetAddress instanceof Inet4Address) && (parseInetAddress instanceof Inet6Address);
        }
    }

    public static class AnonymousClass2 {
        static final int[] $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling;

        static {
            int[] iArr = new int[VpnProfile.SelectedAppsHandling.values().length];
            $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling = iArr;
            try {
                iArr[VpnProfile.SelectedAppsHandling.SELECTED_APPS_DISABLE.ordinal()] = 1;
            } catch (NoSuchFieldError unused) {
            }
            try {
                $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[VpnProfile.SelectedAppsHandling.SELECTED_APPS_EXCLUDE.ordinal()] = 2;
            } catch (NoSuchFieldError unused2) {
            }
            try {
                $SwitchMap$org$strongswan$android$data$VpnProfile$SelectedAppsHandling[VpnProfile.SelectedAppsHandling.SELECTED_APPS_ONLY.ordinal()] = 3;
            } catch (NoSuchFieldError unused3) {
            }
        }
    }

    private static String getAndroidVersion() {
        String str;
        String str2 = "Android " + Build.VERSION.RELEASE + " - " + Build.DISPLAY;
        if (Build.VERSION.SDK_INT < 23) {
            return str2;
        }
        StringBuilder sb = new StringBuilder();
        sb.append(str2);
        sb.append("/");
        str = Build.VERSION.SECURITY_PATCH;
        sb.append(str);
        return sb.toString();
    }

    private static String getDeviceString() {
        return Build.MODEL + " - " + Build.BRAND + "/" + Build.PRODUCT + "/" + Build.MANUFACTURER;
    }

    static {
        System.loadLibrary("androidbridge");
    }
}