增加心跳包线程;规范了localFacePrefix(/边界路由器前缀/用户名/当前系统时间)

This commit is contained in:
free will committed 2021-07-27 15:11:48 +08:00
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());