mirror of
https://gitee.com/willfree/min-vpn-client_v2.git
synced 2026-10-04 19:42:00 +08:00
增加心跳包线程;规范了localFacePrefix(/边界路由器前缀/用户名/当前系统时间)
This commit is contained in:
1 parent
0c4a1bb7ec
commit
f112bd94b4
2 files changed
+76
-100
No files matched your search
@@ -21,7 +21,7 @@ public enum MINVpnSettingAPI {
|
||||
// 用户名 & 密码 & 客户端服务前缀
|
||||
private final String SP_LOCAL_USERNAME = "SP_LOCAL_USERNAME";
|
||||
private final String SP_LOCAL_PASSWORD = "SP_LOCAL_PASSWORD";
|
||||
private final String SP_LOCAL_LOCAL_PREFIX = "SP_LOCAL_LOCAL_PREFIX";
|
||||
// private final String SP_LOCAL_LOCAL_PREFIX = "SP_LOCAL_LOCAL_PREFIX";
|
||||
// MIR地址
|
||||
private final String SP_LOCAL_SETTING_MIR_IP_ADDRESS = "SP_LOCAL_SETTING_MIR_IP_ADDRESS";
|
||||
private final String SP_LOCAL_SETTING_MIR_PORT = "SP_LOCAL_SETTING_MIR_PORT";
|
||||
@@ -42,11 +42,14 @@ public enum MINVpnSettingAPI {
|
||||
// private final String SP_LOCAL_SERVER_SWITCH = "SP_LOCAL_SERVER_SWITCH";
|
||||
// 代理模式
|
||||
private final String SP_PROXY_MODE = "SP_PROXY_MODE";
|
||||
// 第一跳路由器的服务前缀
|
||||
private final String SP_LOCAL_FIRSTROUTERPREFIX="SP_LOCAL_FIRSTROUTERPREFIX";
|
||||
|
||||
// 用户名 & 密码 & 客户端服务前缀
|
||||
private String username="wefree";
|
||||
private String password="123";
|
||||
private String localPrefix="/vpn/client";
|
||||
private String password="12345";
|
||||
private String firstRouterPrefix="/min/gdcni19";
|
||||
// private String localPrefix="/vpn/client";
|
||||
// MIR/VPN-Server的IP地址及服务前缀
|
||||
private String mirIpAddress="1.1.1.1";
|
||||
private Integer mirPort=1;
|
||||
@@ -97,8 +100,11 @@ public enum MINVpnSettingAPI {
|
||||
case SP_LOCAL_PASSWORD:
|
||||
password=(String) v;
|
||||
break;
|
||||
case SP_LOCAL_LOCAL_PREFIX:
|
||||
localPrefix=(String) v;
|
||||
// case SP_LOCAL_LOCAL_PREFIX:
|
||||
// localPrefix=(String) v;
|
||||
// break;
|
||||
case SP_LOCAL_FIRSTROUTERPREFIX:
|
||||
firstRouterPrefix=(String) v;
|
||||
break;
|
||||
case SP_LOCAL_ISENCTRYPTED:
|
||||
String flag=(String) v;
|
||||
@@ -137,18 +143,16 @@ public enum MINVpnSettingAPI {
|
||||
}
|
||||
|
||||
// ----------VPN Service--------------
|
||||
public String getLocalPrefix(){
|
||||
// public String getLocalPrefix(){
|
||||
// return EncryptedSharedPreferenceUtil.get(context,
|
||||
// SP_LOCAL_LOCAL_PREFIX,"/vpn/client");
|
||||
return EncryptedSharedPreferenceUtil.get(context,
|
||||
SP_LOCAL_LOCAL_PREFIX,"/min/gdcni19"+"/"+this.username);
|
||||
}
|
||||
|
||||
public void updateLocalPrefix(String localPrefix){
|
||||
this.localPrefix=localPrefix;
|
||||
EncryptedSharedPreferenceUtil.put(context,
|
||||
SP_LOCAL_LOCAL_PREFIX,localPrefix);
|
||||
}
|
||||
// }
|
||||
//
|
||||
// public void updateLocalPrefix(String localPrefix){
|
||||
// this.localPrefix=localPrefix;
|
||||
// EncryptedSharedPreferenceUtil.put(context,
|
||||
// SP_LOCAL_LOCAL_PREFIX,localPrefix);
|
||||
// }
|
||||
// -------账号密码-------------
|
||||
|
||||
public String getUsername(){
|
||||
@@ -257,10 +261,21 @@ public enum MINVpnSettingAPI {
|
||||
SP_LOCAL_ISENCTRYPTED,String.valueOf(isEncrypted));
|
||||
}
|
||||
|
||||
public String getFirstRouterPrefix(){
|
||||
return EncryptedSharedPreferenceUtil.get(context,
|
||||
SP_LOCAL_FIRSTROUTERPREFIX,"/min/gdcni19");
|
||||
}
|
||||
|
||||
public void updateFirstRouterPrefix(String firstRouterPrefix){
|
||||
this.firstRouterPrefix=firstRouterPrefix;
|
||||
EncryptedSharedPreferenceUtil.put(context,
|
||||
SP_LOCAL_FIRSTROUTERPREFIX,firstRouterPrefix);
|
||||
}
|
||||
|
||||
public String toString(){
|
||||
return "username: "+this.getUsername()+"\n"+
|
||||
"password: "+this.getPassword()+"\n"+
|
||||
"local prefix: "+this.getLocalPrefix()+"\n"+
|
||||
"first router prefix: "+this.getFirstRouterPrefix()+"\n"+
|
||||
"mir ip: "+this.getMirIpAddress()+"\n"+
|
||||
"mir port: "+this.getMirPort()+"\n"+
|
||||
"vpnServer prefix: "+this.getServicePrefix()+"\n"+
|
||||
|
||||
@@ -23,8 +23,6 @@ import com.pkusz.min_vpn_client.utils.IPPackageUtil;
|
||||
import com.pkusz.min_vpn_client.utils.KeyManager;
|
||||
import com.pkusz.min_vpn_client.utils.RuleUtil;
|
||||
import com.pkusz.min_vpn_client.utils.SM2HelperForConnection;
|
||||
import com.pkusz.min_vpn_client.utils.SM3HelperForConnection;
|
||||
import com.pkusz.min_vpn_client.utils.SM4HelperForConnection;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -53,7 +51,6 @@ public class MINVpnConnection implements Runnable{
|
||||
private String handshakeResponse = null; // 握手应答
|
||||
private ParcelFileDescriptor mParcelFileDescriptor = null; // 读出写入流
|
||||
private boolean stop = false; // 标记本次连接是否停止
|
||||
String fuck; // src地址
|
||||
|
||||
// 最大包长度
|
||||
private static final int MAX_PACKET_SIZE = Short.MAX_VALUE;
|
||||
@@ -61,7 +58,10 @@ public class MINVpnConnection implements Runnable{
|
||||
// VPNService、 连接ID、 本地服务前缀
|
||||
private final VpnService mService;
|
||||
private final int mConnectionId;
|
||||
private String localPrefix;
|
||||
// face的注册前缀 格式为:/{边界路由器的服务前缀}/{用户名}/{当前系统时间},
|
||||
// 如:"/min/gdcni19/wefree/"+System.currentTimeMillis();
|
||||
// 在执行initFace的时候初始化
|
||||
private String localFacePrefix;
|
||||
|
||||
// 服务器地址、密钥
|
||||
private final String mServerName;
|
||||
@@ -69,8 +69,6 @@ public class MINVpnConnection implements Runnable{
|
||||
private final byte[] mSharedSecret;
|
||||
private final String mSharedSecretString;
|
||||
private byte[] mEncryptedAESSeed;
|
||||
// 实际使用的密钥是:随机产生的密钥经过sm3哈希,取前16字节
|
||||
// private byte[] realSecret;
|
||||
|
||||
// 代理地址 todo:??
|
||||
private String mProxyHostName;
|
||||
@@ -119,9 +117,6 @@ public class MINVpnConnection implements Runnable{
|
||||
// VPNService 及 连接ID
|
||||
mService=service;
|
||||
mConnectionId=connectionId;
|
||||
// 本地前缀
|
||||
this.localPrefix= MINVpnSettingAPI.INSTANCE.getLocalPrefix()+"/"+ MINVpnSettingAPI.INSTANCE.getUsername()
|
||||
+System.currentTimeMillis();
|
||||
|
||||
// 服务器地址 及 密钥
|
||||
mServerName=serverName;
|
||||
@@ -132,7 +127,6 @@ public class MINVpnConnection implements Runnable{
|
||||
mEncryptedAESSeed= SM2HelperForConnection.encryptWithSM2(mSharedSecretString);
|
||||
// realSecret= SM3HelperForConnection.getSM3Hash16(mSharedSecret);
|
||||
|
||||
|
||||
// 测试AES
|
||||
// System.out.println("!!!密钥:"+mSharedSecretString);
|
||||
// byte[] res=AESHelperForConnection.encryptWithAES(mSharedSecretString,
|
||||
@@ -186,72 +180,42 @@ public class MINVpnConnection implements Runnable{
|
||||
LoggerHelper.severe("vpn connection run error: handle shake error");
|
||||
return;
|
||||
}
|
||||
|
||||
// TestTransferData(face);
|
||||
|
||||
// 3. 进行数据中转操作
|
||||
transferData(face);
|
||||
|
||||
// 4. 开启心跳包,间隔时间为0.5s
|
||||
startHeartBeatThread(face,500);
|
||||
}
|
||||
|
||||
// 测试加解密
|
||||
private void TestTransferData(LogicFace face){
|
||||
FileInputStream inputStream=new FileInputStream(
|
||||
this.mParcelFileDescriptor.getFileDescriptor());
|
||||
FileOutputStream outputStream=new FileOutputStream(
|
||||
this.mParcelFileDescriptor.getFileDescriptor());
|
||||
|
||||
ByteBuffer buff1 = ByteBuffer.allocate(MAX_PACKET_SIZE);
|
||||
ByteBuffer buff2 = ByteBuffer.allocate(MAX_PACKET_SIZE);
|
||||
/**
|
||||
* 开启心跳包
|
||||
* @param face
|
||||
* @param timeInterval 间隔多少毫秒
|
||||
*/
|
||||
private void startHeartBeatThread(LogicFace face,int timeInterval){
|
||||
Thread heartBeatThread = new Thread(() -> {
|
||||
// 1. 构造心跳包负载:{3}+{allocateIP}+{localPrefix}
|
||||
int len=1+allocatedAddress.length()+ localFacePrefix.length();
|
||||
byte[] heartBeatPacketValue=new byte[len];
|
||||
heartBeatPacketValue[0]=3;
|
||||
System.arraycopy(allocatedAddress.getBytes(StandardCharsets.UTF_8),0,
|
||||
heartBeatPacketValue,1,allocatedAddress.length());
|
||||
System.arraycopy(localFacePrefix.getBytes(StandardCharsets.UTF_8),0,
|
||||
heartBeatPacketValue,1+allocatedAddress.length(), localFacePrefix.length());
|
||||
|
||||
Thread recvFromTunAndSendThread = new Thread(() -> {
|
||||
// while (!this.stop) {
|
||||
buff1.clear();
|
||||
buff2.clear();
|
||||
int readLen = 0;
|
||||
int encryptedLen;
|
||||
// 1. 读取tun网卡数据,放入buff1
|
||||
// 2. 将heartBeatPacket通过face发送出去,每隔半秒发一次
|
||||
while (!this.stop) {
|
||||
sendInterestPkt(face, ByteBuffer.wrap(heartBeatPacketValue), len);
|
||||
try {
|
||||
readLen = inputStream.read(buff1.array(), 0, MAX_PACKET_SIZE);
|
||||
} catch (Exception e) {
|
||||
Thread.sleep(timeInterval);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
// break;
|
||||
System.out.println("heartbeat thread sleep error: "+e.getMessage());
|
||||
}
|
||||
if (readLen > 0) {
|
||||
System.out.println("read from tun , readLen = " + readLen);
|
||||
buff1.position(0);
|
||||
buff1.limit(readLen);
|
||||
|
||||
// 2. 对数据做AES加密,然后将服务器分配的地址[allocatedAddress]和加密数据一起放入buff2
|
||||
buff2.put(Objects.requireNonNull(IPPackageUtil.StringAddress2byteAddress(allocatedAddress)));
|
||||
byte[] ipPackageData = new byte[readLen];
|
||||
System.arraycopy(buff1.array(), 0, ipPackageData, 0, readLen);
|
||||
System.out.println("mSharedSecretString length: "+mSharedSecretString.length());
|
||||
System.out.println("raw ipPackageData: "+ Arrays.toString(ipPackageData));
|
||||
System.out.println("raw ipPackageData: "+ new String(ipPackageData));
|
||||
System.out.println("raw ipPackageData len: "+ ipPackageData.length);
|
||||
// System.out.println("realSecret length: "+realSecret.length);
|
||||
// byte[] encrytedIPPackage = SM4HelperForConnection.encryptWithSM4(realSecret, ipPackageData);
|
||||
byte[] encrytedIPPackage = AESHelperForConnection.encryptWithAES(mSharedSecretString, ipPackageData);
|
||||
if(encrytedIPPackage==null){
|
||||
System.out.println("AES加密错误!!!");
|
||||
return;
|
||||
}
|
||||
System.out.println("encryptedIPPackage len: " + encrytedIPPackage.length);
|
||||
System.out.println("encryptedIPPackage: "+ Arrays.toString(encrytedIPPackage));
|
||||
System.out.println("encryptedIPPackage: "+ new String(encrytedIPPackage));
|
||||
System.out.println("buff2 position: " + buff2.position());
|
||||
buff2.put(encrytedIPPackage);
|
||||
encryptedLen = buff2.position();
|
||||
buff2.position(0);
|
||||
buff2.limit(encryptedLen);
|
||||
|
||||
// 3. 将buff2通过face发送出去
|
||||
sendInterestPkt(face, buff2,encryptedLen);
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
});
|
||||
recvFromTunAndSendThread.start();
|
||||
heartBeatThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -320,11 +284,7 @@ public class MINVpnConnection implements Runnable{
|
||||
Thread recvFromServerAndReadThread = new Thread(() -> {
|
||||
while (!this.stop) {
|
||||
try {
|
||||
// 1. 注册标识到服务器 => 新版是在初始化face时进行注册!!
|
||||
// RegisterPrefixHelper helper=new RegisterPrefixHelper();
|
||||
// face.registerIdentifier(new Identifier(this.localPrefix),5000,helper);
|
||||
|
||||
// 2. 接收服务器返回的数据包,放入buf2
|
||||
// 1. 接收服务器返回的数据包,放入buf2
|
||||
CPacket interest;
|
||||
try {
|
||||
interest = face.receiveCPacket(10000);
|
||||
@@ -338,16 +298,16 @@ public class MINVpnConnection implements Runnable{
|
||||
buf2.put(interest.payload.getValue());
|
||||
System.out.println("buf2 data len = " + buf2.position());
|
||||
|
||||
// 3. 将buf2数据解密,然后放入buf3,通过tun网卡进行写出
|
||||
// 2. 将buf2数据解密,然后放入buf3,通过tun网卡进行写出
|
||||
byte[] decrpytedIPPackage = new byte[buf2.position()];
|
||||
System.arraycopy(buf2.array(), 0, decrpytedIPPackage, 0, buf2.position());
|
||||
ByteBuffer buf3 = ByteBuffer.allocate(5000);
|
||||
System.out.println("要解密啦,要解密的包是:"+ Arrays.toString(decrpytedIPPackage));
|
||||
System.out.println("要解密啦,要解密的包长度是:"+decrpytedIPPackage.length);
|
||||
// System.out.println("要解密啦,要解密的包是:"+ Arrays.toString(decrpytedIPPackage));
|
||||
// System.out.println("要解密啦,要解密的包长度是:"+decrpytedIPPackage.length);
|
||||
buf3.put(Objects.requireNonNull(AESHelperForConnection.decryptWithAES(mSharedSecretString, decrpytedIPPackage)));
|
||||
// buf3.put(Objects.requireNonNull(SM4HelperForConnection.decryptWithSM4(realSecret, decrpytedIPPackage)));
|
||||
System.out.println("解密结果:"+ Arrays.toString(buf3.array()));
|
||||
System.out.println("解密结果-len:"+ buf3.position());
|
||||
// System.out.println("解密结果:"+ Arrays.toString(buf3.array()));
|
||||
// System.out.println("解密结果-len:"+ buf3.position());
|
||||
int decryptedDataLen = buf3.position();
|
||||
byte firstByte = buf3.get(0);
|
||||
if (firstByte == 0) {
|
||||
@@ -394,7 +354,7 @@ public class MINVpnConnection implements Runnable{
|
||||
Identifier clientIdentifier;
|
||||
try {
|
||||
// clientIdentifier = new Identifier(MINVpnSettingAPI.INSTANCE.getLocalPrefix());
|
||||
clientIdentifier = new Identifier(fuck);
|
||||
clientIdentifier = new Identifier(localFacePrefix);
|
||||
} catch (ComponentException e) {
|
||||
e.printStackTrace();
|
||||
LoggerHelper.warning("sendInterestPkt error 1: clientIdentifier init error: "+e.getMessage());
|
||||
@@ -454,7 +414,7 @@ public class MINVpnConnection implements Runnable{
|
||||
// 构造兴趣包负载字段:加密密钥 & 本地前缀
|
||||
ByteBuffer requestBuf = ByteBuffer.allocate(1024);
|
||||
byte len= ByteHelper.uint8ToByte(mEncryptedAESSeed.length);
|
||||
requestBuf.put((byte) 4).put(len).put(mEncryptedAESSeed).put(fuck.getBytes()).flip();
|
||||
requestBuf.put((byte) 4).put(len).put(mEncryptedAESSeed).put(localFacePrefix.getBytes()).flip();
|
||||
// requestBuf.put((byte) 1).put(len).put(mEncryptedAESSeed).put(this.localPrefix.getBytes()).flip();
|
||||
// 构造目的标识:/{service prefix}/{cPacket seq}/{defraudString}
|
||||
Identifier serverIdentifier;
|
||||
@@ -471,7 +431,7 @@ public class MINVpnConnection implements Runnable{
|
||||
Identifier clientIdentifier;
|
||||
try {
|
||||
// clientIdentifier = new Identifier(MINVpnSettingAPI.INSTANCE.getLocalPrefix());
|
||||
clientIdentifier = new Identifier(fuck);
|
||||
clientIdentifier = new Identifier(localFacePrefix);
|
||||
} catch (ComponentException e) {
|
||||
e.printStackTrace();
|
||||
LoggerHelper.warning("handshake error 1: clientIdentifier init error: "+e.getMessage());
|
||||
@@ -500,7 +460,7 @@ public class MINVpnConnection implements Runnable{
|
||||
cPacket.setDstIdentifier(serverIdentifier);
|
||||
cPacket.ttl.setTtl(64);
|
||||
// 从requestBuf取出有效字段到writeBytes
|
||||
int writeLen=1+1+mEncryptedAESSeed.length+fuck.length();
|
||||
int writeLen=1+1+mEncryptedAESSeed.length+ localFacePrefix.length();
|
||||
byte[] writeBytes=new byte[writeLen];
|
||||
System.arraycopy(requestBuf.array(),0,writeBytes,0,writeLen);
|
||||
System.out.println("array: "+ Arrays.toString(requestBuf.array()));
|
||||
@@ -683,10 +643,11 @@ public class MINVpnConnection implements Runnable{
|
||||
// 2. 注册标识
|
||||
RegisterPrefixHelper helper=new RegisterPrefixHelper();
|
||||
try {
|
||||
// String timestamp="/"+System.currentTimeMillis();
|
||||
fuck="/min/gdcni19/wefree/"+System.currentTimeMillis();
|
||||
System.out.println("注册前缀:"+fuck);
|
||||
face.registerIdentifier(new Identifier(fuck),5000,helper);
|
||||
localFacePrefix =MINVpnSettingAPI.INSTANCE.getFirstRouterPrefix()
|
||||
+"/"+MINVpnSettingAPI.INSTANCE.getUsername()
|
||||
+"/"+System.currentTimeMillis();
|
||||
System.out.println("注册前缀:"+ localFacePrefix);
|
||||
face.registerIdentifier(new Identifier(localFacePrefix),5000,helper);
|
||||
} catch (LogicFaceException | ComponentException e) {
|
||||
e.printStackTrace();
|
||||
LoggerHelper.warning("tcp logic face register identifier error: "+e.getMessage());
|
||||
|
||||
Reference in new issue
Block a user