TH-CONECT 3.0 v版本的 MD5 值为:96be240369c9625eef513b9a5e2c5153
以下内容为反编译后的 Tunnel.java 源代码,内容仅作参考
package com.romzkie.ultrasshservice.tunnel.vpn;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.VpnService;
import android.os.Build;
import android.os.ParcelFileDescriptor;
import com.romzkie.ultrasshservice.SocksHttpService;
import com.romzkie.ultrasshservice.logger.SkStatus;
import com.romzkie.ultrasshservice.tunnel.vpn.NetworkSpace;
import com.romzkie.ultrasshservice.tunnel.vpn.Pdnsd;
import com.romzkie.ultrasshservice.tunnel.vpn.Tun2Socks;
import com.romzkie.ultrasshservice.tunnel.vpn.VpnUtils;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
public class Tunnel {
private static final String DNS_RESOLVER_IP = "8.8.8.8";
private static final int DNS_RESOLVER_PORT = 53;
private static final String VPN_INTERFACE_NETMASK = "255.255.255.0";
private static Tunnel mTunnel;
private final HostService mHostService;
private Pdnsd mPdnsd;
private VpnUtils.PrivateAddress mPrivateAddress;
private Tun2Socks mTun2Socks;
private int mMtu = TunnelConstants.VPN_INTERFACE_MTU;
private AtomicReference<ParcelFileDescriptor> mTunFd = new AtomicReference<>();
private AtomicBoolean mRoutingThroughTunnel = new AtomicBoolean(false);
private NetworkSpace mRoutes = new NetworkSpace();
public interface HostService {
String getAppName();
Context getContext();
Object getVpnService();
Object newVpnServiceBuilder();
void onDiagnosticMessage(String str);
void onTunnelConnected();
void onVpnEstablished();
}
public static synchronized Tunnel newTunnel(HostService hostService) {
Tunnel tunnel;
synchronized (Tunnel.class) {
Tunnel tunnel2 = mTunnel;
if (tunnel2 != null) {
tunnel2.stop();
}
tunnel = new Tunnel(hostService);
mTunnel = tunnel;
}
return tunnel;
}
private Tunnel(HostService hostService) {
this.mHostService = hostService;
}
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
public synchronized boolean startRouting(TunnelVpnSettings tunnelVpnSettings) throws Exception {
return startVpn(tunnelVpnSettings.mDnsForward, tunnelVpnSettings.mDnsResolver, tunnelVpnSettings.mExcludeIps, tunnelVpnSettings.mEnableFilterApps, tunnelVpnSettings.mFilterBypassMode, tunnelVpnSettings.mFilterApps, tunnelVpnSettings.mTetheringSubnet);
}
public synchronized boolean startTunneling(String str, String[] strArr, boolean z, String str2, boolean z2) throws Exception {
return routeThroughTunnel(str, strArr, z, str2, z2);
}
public synchronized void stopTunneling() {
stopRoutingThroughTunnel();
}
public synchronized void stop() {
stopVpn();
}
private boolean startVpn(boolean z, String[] strArr, String[] strArr2, boolean z2, boolean z3, String[] strArr3, boolean z4) throws Exception {
int i;
String[] strArr4 = strArr;
StringBuilder sb = new StringBuilder("Routes: ");
StringBuilder sb2 = new StringBuilder("Routes Excluded: ");
this.mPrivateAddress = VpnUtils.selectPrivateAddress();
int length = strArr2.length;
int i2 = 0;
while (true) {
i = 32;
if (i2 >= length) {
break;
}
this.mRoutes.addIP(new CIDRIP(strArr2[i2], 32), false);
i2++;
}
Locale locale = Locale.getDefault();
try {
try {
try {
Locale.setDefault(new Locale("en"));
VpnService.Builder addAddress = ((VpnService.Builder) this.mHostService.newVpnServiceBuilder()).addAddress(this.mPrivateAddress.mIpAddress, this.mPrivateAddress.mPrefixLength);
this.mRoutes.addIP(new CIDRIP("0.0.0.0", 0), true);
this.mRoutes.addIP(new CIDRIP("10.0.0.0", 8), false);
this.mRoutes.addIP(new CIDRIP(this.mPrivateAddress.mSubnet, this.mPrivateAddress.mPrefixLength), false);
if (z4) {
this.mRoutes.addIP(new CIDRIP("192.168.42.0", 23), false);
this.mRoutes.addIP(new CIDRIP("192.168.44.0", 24), false);
this.mRoutes.addIP(new CIDRIP("192.168.49.0", 24), false);
}
int length2 = strArr4.length;
int i3 = 0;
while (i3 < length2) {
String str = strArr4[i3];
try {
addAddress.addDnsServer(str);
try {
this.mRoutes.addIP(new CIDRIP(str, i), z);
} catch (IllegalArgumentException e) {
e = e;
this.mHostService.onDiagnosticMessage(String.format("Erro ao adicinar dns %s, %s", str, e.getLocalizedMessage()));
i3++;
strArr4 = strArr;
i = 32;
}
} catch (IllegalArgumentException e2) {
e = e2;
}
i3++;
strArr4 = strArr;
i = 32;
}
String str2 = Build.VERSION.RELEASE;
if (Build.VERSION.SDK_INT == 19 && !str2.startsWith("4.4.3") && !str2.startsWith("4.4.4") && !str2.startsWith("4.4.5") && !str2.startsWith("4.4.6") && this.mMtu < 1280) {
SkStatus.logInfo(String.format(Locale.US, "Forcing MTU to 1280 instead of %d to workaround Android Bug #70916", Integer.valueOf(this.mMtu)));
this.mMtu = 1280;
}
addAddress.setMtu(this.mMtu);
for (NetworkSpace.IpAddress ipAddress : this.mRoutes.getNetworks(true)) {
sb.append(String.format("%s/%d", ipAddress.getIPv4Address(), Integer.valueOf(ipAddress.networkMask)));
sb.append(", ");
}
sb.deleteCharAt(sb.lastIndexOf(", "));
for (NetworkSpace.IpAddress ipAddress2 : this.mRoutes.getNetworks(false)) {
sb2.append(String.format("%s/%d", ipAddress2.getIPv4Address(), Integer.valueOf(ipAddress2.networkMask)));
sb2.append(", ");
}
sb2.deleteCharAt(sb2.lastIndexOf(", "));
this.mHostService.onDiagnosticMessage(sb.toString());
this.mHostService.onDiagnosticMessage(sb2.toString());
NetworkSpace.IpAddress ipAddress3 = new NetworkSpace.IpAddress(new CIDRIP("224.0.0.0", 3), true);
for (NetworkSpace.IpAddress ipAddress4 : this.mRoutes.getPositiveIPList()) {
try {
if (ipAddress3.containsNet(ipAddress4)) {
SkStatus.logDebug("VPN: Ignoring multicast route: " + ipAddress4.toString());
} else {
addAddress.addRoute(ipAddress4.getIPv4Address(), ipAddress4.networkMask);
}
} catch (IllegalArgumentException e3) {
this.mHostService.onDiagnosticMessage("Route rejeitada: " + ipAddress4 + " " + e3.getLocalizedMessage());
}
}
if (Build.VERSION.SDK_INT >= 21 && z2) {
for (String str3 : strArr3) {
if (z3) {
try {
addAddress.addDisallowedApplication(str3);
this.mHostService.onDiagnosticMessage(String.format("Filtro de Apps: Vpn desativada para \"%s\"", str3));
} catch (PackageManager.NameNotFoundException unused) {
this.mHostService.onDiagnosticMessage("Aplicativo \"" + str3 + "\" não encontrado. Filtro de Apps não irá funcionar, verifique as configurações.");
}
} else {
addAddress.addAllowedApplication(str3);
this.mHostService.onDiagnosticMessage(String.format("Filtro de Apps: Vpn ativada para \"%s\"", str3));
}
}
}
ParcelFileDescriptor establish = addAddress.setSession(this.mHostService.getAppName()).setConfigureIntent(SocksHttpService.getGraphPendingIntent(this.mHostService.getContext())).establish();
if (establish != null) {
this.mTunFd.set(establish);
this.mRoutingThroughTunnel.set(false);
this.mHostService.onVpnEstablished();
this.mRoutes.clear();
Locale.setDefault(locale);
return true;
}
Locale.setDefault(locale);
return false;
} catch (Throwable th) {
Locale.setDefault(locale);
throw th;
}
} catch (IllegalArgumentException e4) {
throw new Exception("startVpn failed", e4);
}
} catch (IllegalStateException e5) {
throw new Exception("startVpn failed", e5);
} catch (SecurityException e6) {
throw new Exception("startVpn failed", e6);
}
}
private boolean routeThroughTunnel(String str, String[] strArr, boolean z, String str2, boolean z2) {
ParcelFileDescriptor parcelFileDescriptor;
if (this.mRoutingThroughTunnel.compareAndSet(false, true) && (parcelFileDescriptor = this.mTunFd.get()) != null) {
String str3 = null;
if (z) {
int findAvailablePort = VpnUtils.findAvailablePort(8091, 10);
str3 = String.format("%s:%d", this.mPrivateAddress.mIpAddress, Integer.valueOf(findAvailablePort));
Pdnsd pdnsd = new Pdnsd(this.mHostService.getContext(), strArr, 53, this.mPrivateAddress.mIpAddress, findAvailablePort);
this.mPdnsd = pdnsd;
pdnsd.setOnPdnsdListener(new Pdnsd.OnPdnsdListener() {
@Override
public void onStart() {
Tunnel.this.mHostService.onDiagnosticMessage("pdnsd started");
}
@Override
public void onStop() {
Tunnel.this.mHostService.onDiagnosticMessage("pdnsd stopped");
Tunnel.this.stop();
}
});
this.mPdnsd.start();
}
Tun2Socks tun2Socks = new Tun2Socks(this.mHostService.getContext(), parcelFileDescriptor, this.mMtu, this.mPrivateAddress.mRouter, "255.255.255.0", str, str2, str3, z2);
this.mTun2Socks = tun2Socks;
tun2Socks.setOnTun2SocksListener(new Tun2Socks.OnTun2SocksListener() {
@Override
public void onStart() {
Tunnel.this.mHostService.onDiagnosticMessage("tunnel core started");
}
@Override
public void onStop() {
Tunnel.this.mHostService.onDiagnosticMessage("tunnel core stopped");
Tunnel.this.stop();
}
});
this.mTun2Socks.start();
this.mHostService.onTunnelConnected();
this.mHostService.onDiagnosticMessage("routing through tunnel");
return true;
}
return false;
}
private void stopRoutingThroughTunnel() {
Tun2Socks tun2Socks = this.mTun2Socks;
if (tun2Socks != null && tun2Socks.isAlive()) {
this.mTun2Socks.interrupt();
}
this.mTun2Socks = null;
Pdnsd pdnsd = this.mPdnsd;
if (pdnsd != null && pdnsd.isAlive()) {
this.mPdnsd.interrupt();
}
this.mPdnsd = null;
}
private void stopVpn() {
stopRoutingThroughTunnel();
ParcelFileDescriptor andSet = this.mTunFd.getAndSet(null);
if (andSet != null) {
try {
this.mHostService.onDiagnosticMessage("VPN service stopped");
andSet.close();
} catch (IOException unused) {
}
}
}
}