Я написал следующий код, я хочу создать VPN-соединение для получения пакетов (локальный трафик установленных приложений) и затем отпустить их, если они соответствуют моим правилам (Source и Dest IP и т. Д.). поэтому я закодировал это приложение (VPN-соединение), но когда я его запускаю, на панели уведомлений появляется значок ключа, и спустя почти 10 секунд значок ключа исчезает (VPN-соединение отключено) без причины. кроме того, при подключении VPN никакие данные (лучше сказать PACKET
) не передаются (я имею в виду, что такие приложения для устройств, как WhatsApp, не имеют доступа к Интернету)
версия устройства для Android: 8
Устройство (телефон) WIFI адаптер IP это: 192.168.1.101
Шлюз домашнего маршрута (модема): 192.168.1.1
мой код:
public class MyVpnService extends VpnService {
private Thread mThread;
private ParcelFileDescriptor mInterface;
private static final int MAX_PACKET_SIZE = 32767;
//a. Configure a builder for the interface.
Builder builder = new Builder();
// Services interface
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Start a new session by creating a new thread.
mThread = new Thread(new Runnable() {
@Override
public void run() {
try {
//a. Configure the TUN and get the interface.
mInterface = builder.setSession("MyVPNService")
.addAddress("192.168.1.0", 24)
.addDnsServer("8.8.8.8")
.addRoute("0.0.0.0", 0).establish();
//b. Packets to be sent are queued in this input stream.
FileInputStream in = new FileInputStream(
mInterface.getFileDescriptor());
//b. Packets received need to be written to this output stream.
FileOutputStream out = new FileOutputStream(
mInterface.getFileDescriptor());
//c. The UDP channel can be used to pass/get ip package to/from server
DatagramChannel tunnel = DatagramChannel.open();
tunnel.configureBlocking(false);
// Connect to the server, localhost is used for demonstration only.
tunnel.connect(new InetSocketAddress("127.0.0.1", 8087));
//d. Protect this socket, so package send by it will not be feedback to the vpn service.
protect(tunnel.socket());
ByteBuffer packet = ByteBuffer.allocate(MAX_PACKET_SIZE);
//e. Use a loop to pass packets.
int length=0;
while (true) {
Log.d("VPNservice", "5");
length= in.read(packet.array());
if (length > 0) {
packet.limit(length);
tunnel.write(packet);
// There might be more outgoing packets.
Log.d("VPNservice", "6");
}
Log.d("VPNservice", "7");
length = tunnel.read(packet);
Log.d("VPNservice", "8");
if (length > 0) {
if (packet.get(0) != 0) {
out.write(packet.array(), 0, length);
Log.d("VPNservice", "9");
}
packet.clear();
Log.d("VPNservice", "10");
}
Thread.sleep(100);
Log.d("VPNservice", "11");
}
} catch (Exception e) {
Log.d("VPNservice", "20");
e.printStackTrace();
} finally {
try {
if (mInterface != null) {
mInterface.close();
mInterface = null;
}
} catch (Exception e) {
}
}
}
}, "MyVpnRunnable");
//start the service
mThread.start();
return START_STICKY;
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
if (mThread != null) {
mThread.interrupt();
}
super.onDestroy();
}
}
результат logcat:
2019-06-27 15:24:32.697 21338-21640/? D/VPNservice: 5
2019-06-27 15:24:32.698 21338-21640/? D/VPNservice: 7
2019-06-27 15:24:32.698 21338-21640/? D/VPNservice: 8
2019-06-27 15:24:34.699 21338-21640/? D/VPNservice: 11
2019-06-27 15:24:34.699 21338-21640/? D/VPNservice: 5
2019-06-27 15:24:34.700 21338-21640/? D/VPNservice: 6
2019-06-27 15:24:34.700 21338-21640/? D/VPNservice: 7
2019-06-27 15:24:34.700 21338-21640/? D/VPNservice: 8
2019-06-27 15:24:36.700 21338-21640/? D/VPNservice: 11
2019-06-27 15:24:36.700 21338-21640/? D/VPNservice: 5
2019-06-27 15:24:36.701 21338-21640/? D/VPNservice: 20
2019-06-27 15:25:43.121 21863-21885/? D/VPNservice: 5
2019-06-27 15:25:43.121 21863-21885/? D/VPNservice: 7
2019-06-27 15:25:43.122 21863-21885/? D/VPNservice: 8
2019-06-27 15:25:45.122 21863-21885/? D/VPNservice: 11
2019-06-27 15:25:45.122 21863-21885/? D/VPNservice: 5
2019-06-27 15:25:45.124 21863-21885/? D/VPNservice: 6
2019-06-27 15:25:45.124 21863-21885/? D/VPNservice: 7
2019-06-27 15:25:45.124 21863-21885/? D/VPNservice: 8
2019-06-27 15:25:47.124 21863-21885/? D/VPNservice: 11
2019-06-27 15:25:47.124 21863-21885/? D/VPNservice: 5
2019-06-27 15:25:47.125 21863-21885/? D/VPNservice: 6
2019-06-27 15:25:47.125 21863-21885/? D/VPNservice: 7
2019-06-27 15:25:47.125 21863-21885/? D/VPNservice: 8
2019-06-27 15:25:49.125 21863-21885/? D/VPNservice: 11
2019-06-27 15:25:49.126 21863-21885/? D/VPNservice: 5
2019-06-27 15:25:49.127 21863-21885/? D/VPNservice: 20
MainActivity.java:
package com.example.vpn_test;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.VpnService;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn= findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view)
{
Intent intent = VpnService.prepare(MainActivity.this);
if (intent != null) {
startActivityForResult(intent, 0);
} else {
onActivityResult(0, RESULT_OK, null);
}
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
Intent intent = new Intent(this, MyVpnService.class);
startService(intent);
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vpn_test">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.example.vpn_test.MyVpnService"
android:permission="android.permission.BIND_VPN_SERVICE" >
<intent-filter>
<action android:name="android.net.VpnService" />
</intent-filter>
</service>
</application>