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");
}
}