-在此方法中,我尝试将 google dns 服务器添加到 vpn 接口,但它根本不起作用。它
仅适用于本地 dns,这是 gsm 的默认 dns 服务器。
@覆盖
公共int onStartCommand(Intent意图,int标志,int startId){
localAddress = CommonMethods.ipStringToInt(ipAddress);
packet = new byte[20000];
ipHeader = new IPHeader(packet, 0);
tcpHeader = new TCPHeader(packet, 20);
udpHeader = new UDPHeader(packet, 20);
dnsBuffer = ((ByteBuffer) ByteBuffer.wrap(packet).position(28)).slice();
proxy = new Proxy(this, 0);
proxy.start();
dnsProxy = new DnsProxy(this);
dnsProxy.start();
vpnThread = new Thread(new Runnable(){
@Override
public void run(){
mInterface = builder.setSession("VPNtoSocket")
.addAddress(ipAddress,32)
.addRoute("0.0.0.0", 0)
.addDnsServer("8.8.8.8");
//.addRoute("194.163.43.216", 32)
.establish();
FileInputStream vpnin = new FileInputStream(mInterface.getFileDescriptor());
vpnout = new FileOutputStream(mInterface.getFileDescriptor());
onStatusChanged(true);
try{
int size = 0;
while(size != -1 && !vpnThread.isInterrupted()){
while((size = vpnin.read(packet)) > 0 && !vpnThread.isInterrupted()){
if(dnsProxy.isInterrupted() || proxy.isInterrupted()){ //KILL SWITCH
vpnin.close();
throw new Exception("Server stopped.");
}
onIPPacketReceived(ipHeader, size);
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
try{
vpnin.close();
vpnout.close();
if(mInterface != null){
mInterface.close();
mInterface = null;
}
kill();
}catch(Exception e){
}
}
}
}, "VPNtoSocket");
vpnThread.start();
return super.onStartCommand(intent, flags, startId);//START_STICKY;
}
我知道答案太晚了,但我最近遇到了这个问题。 将此答案留给稍后看到此内容的人。
因此,由于某种原因,Android 并不总是根据“活动”网络的 DNS 服务器来解析 DNS。 这在我身上发生过两种情况:
最奇怪的事情是,在这个 VPN 场景中,我在不同的 Android 设备和版本上的行为不一致。有些使用正确的 VPN DNS 服务器,有些使用默认的 Android DNS 解析器..
长话短说:对我来说解决此问题并确保使用来自 VPN(或其他网络)的 DNS 解析器而不是默认解析器的唯一方法是将进程绑定到网络,在这种情况下, VPN 网络。
具体操作方法如下: 启动 VPN 之前:
val builder = NetworkRequest.Builder()
builder.addTransportType(NetworkCapabilities.TRANSPORT_VPN)
val request = builder.build()
connectivityManager.requestNetwork(request, object : NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
Log.i(TAG,"Binding to VPN Network!")
val bindResult = connectivityManager.bindProcessToNetwork(network)
Log.i(TAG,"Bind to VPN result = $bindResult")
}
})
如果下面的代码在启动VPN时没有触发回调,你也可以从activeNetwork中获取网络对象:
val activeNetwork = connectivityManager.activeNetwork
if (activeNetwork != null) {
val networkCapabilities = connectivityManager.getNetworkCapabilities(activeNetwork)
val isVpn = networkCapabilities?.hasTransport(
NetworkCapabilities.TRANSPORT_VPN
) ?: false
if (isVpn) {
Log.i(TAG,"Binding to VPN Network!")
val bindResult = connectivityManager.bindProcessToNetwork(activeNetwork)
Log.i(TAG,"Bind to VPN result = $bindResult")
}
}