对收包操作进行了去解码化的简化处理,网速又有了明显提升

This commit is contained in:
free will committed 2021-10-28 16:31:01 +08:00
1 parent ebfccef80d
commit e9638f6215
5 files changed
+102 -12

No files matched your search

@@ -314,7 +314,7 @@ public class MINVpnService extends VpnService implements Handler.Callback{
// }
// 灌包测试-灌IP包
// for (int i = 0; i < 10000; i++) {
// for (int i = 0; i < 10000*1; i++) {
// ByteBuffer buffer=ByteBufferPool.acquire();
// buffer.put(pay);
// buffer.flip();
@@ -364,7 +364,7 @@ public class MINVpnService extends VpnService implements Handler.Callback{
// 新
executorService.submit(new ReceiveQuickTask(writeTunLpPackets, vpnConnectionInfo.face));
executorService.submit(new Min2IpQuickTask(writeTunLpPackets, writeTunDataQueue));
executorService.submit(new Min2IpQuickTask(writeTunLpPackets, writeTunDataQueue, vpnConnectionInfo.allocatedAddress));
executorService.submit(new WriteTunTask(writeTunDataQueue, tunOutput));
// executorService.submit(new ReceiveTask(writeTunCPackets, vpnConnectionInfo.face));
@@ -12,7 +12,7 @@ import android.util.Pair;
import com.pkusz.min_vpn_client.model.MINVpnSettingAPI;
import com.pkusz.min_vpn_client.services.ByteBufferPool;
import com.pkusz.min_vpn_client.utils.IPPackageUtil;
import com.pkusz.min_vpn_client.utils.StringUtil;
import com.pkusz.min_vpn_client.utils.StringUtilForCPacketEncoding;
import java.nio.ByteBuffer;
import java.util.Arrays;
@@ -21,7 +21,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import component.ComponentException;
import component.Identifier;
import component.IdentifierComponent;
import encoding.VlIntException;
import packet.CPacket;
@@ -132,7 +131,7 @@ public class Ip2MinTask implements Runnable{
tlvTail=new byte[7];
System.arraycopy(genRes.getRawData(),genRes.getRawData().length-7,tlvTail,0,7);
// 初始化随机数字字符串位置信息
randomPos=StringUtil.findThePos(genRes.rawData);
randomPos= StringUtilForCPacketEncoding.findThePos(genRes.rawData);
readPos=randomPos+10;
System.out.println("初始化 random pos: "+randomPos);
System.out.println("初始化 head array: "+ Arrays.toString(tlvHead));
@@ -141,7 +140,7 @@ public class Ip2MinTask implements Runnable{
// 更新tlvHead的目的地址字段(随机字符串)&负载头部字段
Pair<byte[],Integer> calculateRes;
try {
calculateRes=StringUtil.replaceRandomPos(tlvHead,randomPos,readPos,buf.length);
calculateRes= StringUtilForCPacketEncoding.replaceRandomPos(tlvHead,randomPos,readPos,buf.length);
} catch (VlIntException e) {
System.out.println("tlv计算报错了: "+e.getMessage());
return null;
@@ -182,7 +181,7 @@ public class Ip2MinTask implements Runnable{
// serverIdentifier = new Identifier(serverPrefix
// +"/"+ StringUtil.getFixLenthString(10));
serverIdentifier = new Identifier(serverPrefix
+"/"+ StringUtil.getAll0String()); // 第一个包作为典型包,其随机字符串是全0字符串。
+"/"+ StringUtilForCPacketEncoding.getAll0String()); // 第一个包作为典型包,其随机字符串是全0字符串。
} catch (ComponentException e) {
e.printStackTrace();
System.out.println("genInterestPkt error 1: serverIdentifier init error: " + e.getMessage());
@@ -8,7 +8,11 @@ package com.pkusz.min_vpn_client.services.Runnables;
*/
import com.pkusz.min_vpn_client.services.ByteBufferPool;
import com.pkusz.min_vpn_client.utils.IPPackageUtil;
import com.pkusz.min_vpn_client.utils.StringUtilForLpPacketDecoding;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedQueue;
import packet.LpPacket;
@@ -16,11 +20,14 @@ public class Min2IpQuickTask implements Runnable{
private ConcurrentLinkedQueue<LpPacket> writeTunLpPackets;
private ConcurrentLinkedQueue<ByteBuffer> writeTunDataQueue;
private boolean isSM4=false; // 加密方式
private byte[] tunAddress; // tun地址(服务器给分配的地址)
public Min2IpQuickTask(ConcurrentLinkedQueue<LpPacket> writeTunLpPackets,
ConcurrentLinkedQueue<ByteBuffer> writeTunDataQueue){
ConcurrentLinkedQueue<ByteBuffer> writeTunDataQueue,
String tunAddress){
this.writeTunLpPackets=writeTunLpPackets;
this.writeTunDataQueue=writeTunDataQueue;
this.tunAddress = IPPackageUtil.StringAddress2byteAddress(tunAddress);
}
@Override
@@ -49,8 +56,21 @@ public class Min2IpQuickTask implements Runnable{
System.out.println("debug min2ip len: "+pendingProcessLpPacket.payload.getValue().length); // 测试
// 2.读取负载字段
pendingProcessLpPacket.decodeSelf();
byte[] rawIpDataBytes = pendingProcessLpPacket.getRawPayload();
// pendingProcessLpPacket.decodeSelf();
// byte[] rawIpDataBytes = pendingProcessLpPacket.getRawPayload();
byte[] rawIpDataBytes=getRawIpData(pendingProcessLpPacket.payload.getValue(),tunAddress);
if(rawIpDataBytes==null){
System.out.println("你的分析代码出错了!!!");
continue;
}
// todo: 分析LpPacket包结构
System.out.println("LpPacket负载字段: "+ Arrays.toString(pendingProcessLpPacket.payload.getValue()));
System.out.println("LpPacket负载字段len: "+ pendingProcessLpPacket.payload.getValue().length);
// System.out.println("负载字段中的负载字段: "+ Arrays.toString(pendingProcessLpPacket.getRawPayload()));
// System.out.println("负载字段中的负载字段len: "+ pendingProcessLpPacket.getRawPayload().length);
System.out.println("负载字段中的负载字段(分析提取): "+ Arrays.toString(rawIpDataBytes));
System.out.println("负载字段中的负载字段(分析提取)len: "+ rawIpDataBytes.length);
// Thread.sleep(1000);
// 解密
ByteBuffer ipData= ByteBufferPool.acquire();
if(isSM4){ //解密
@@ -67,4 +87,22 @@ public class Min2IpQuickTask implements Runnable{
e.printStackTrace();
}
}
/**
* 从LpPacket的负载字段中取出IP地址
* @param lpPacketPayload
* @param tunAddress
* @return
*/
private byte[] getRawIpData(byte[] lpPacketPayload,byte[] tunAddress){
int startPos = StringUtilForLpPacketDecoding.findTheStartPos(lpPacketPayload,tunAddress);
if(startPos<0){
return null;
}
int endPos=lpPacketPayload.length-7;
int ipLen=endPos-startPos;
byte[] ipData=new byte[ipLen];
System.arraycopy(lpPacketPayload,startPos,ipData,0,ipLen);
return ipData;
}
}
@@ -1,7 +1,8 @@
package com.pkusz.min_vpn_client.utils;
/*
* @Author: Wang Feng
* @Description:脏类。方法仅供一时之需。
* @Description:脏类。方法有局限性。
* 用于实现CPacket的快速编码,从而快速发包。
* @Version: 1.0.0
* @Date: 16:15 2021/10/27
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
@@ -21,7 +22,7 @@ import encoding.TLVException;
import encoding.VlInt;
import encoding.VlIntException;
public class StringUtil {
public class StringUtilForCPacketEncoding {
public static String getFixLenthString(int strLength) {
Random rm = new Random();
// 获得随机数
@@ -49,6 +50,12 @@ public class StringUtil {
//100, 11, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 100, 2, 4, 10, 52, 12, -52, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, 5, 55, 3, -44, 1, 64
// 要找的字符数组是:100, 11, 0, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48
// 分析其特点,找到连续的五个48,且前面依次是11、0,即可。假定是10个连续随机数
/**
* 查找CPacket编码结构中的目的标识的变化字段(长度为10的变化字段)
* @param targetArray
* @return
*/
public static int findThePos(byte[] targetArray){
byte[] matchArray=new byte[]{(byte)11,(byte) 0,(byte) 48};
System.out.println("target: "+ Arrays.toString(targetArray));
@@ -74,6 +81,17 @@ public class StringUtil {
// | 总包长 | 标识区 | 负载区 | TTL |
// 注意,这里返回的数组不包括TTL区,以及负载区的真实负载
/**
* 根据上一个CPacket的编码结果,对本次CPacket进行头部构造。
* 主要涉及:1.目的标识的变化字段的替换;2.TLV中标记L的部分的修改(网络包的长度、负载字段长度、只读区的长度)
* @param targetArray 上一个CPacket的编码结果
* @param randomPos
* @param readPos
* @param payloadLen
* @return
* @throws VlIntException
*/
public static Pair<byte[], Integer> replaceRandomPos(byte[] targetArray, int randomPos, int readPos, int payloadLen)
throws VlIntException {
// System.out.println("ttt1");
@@ -0,0 +1,35 @@
package com.pkusz.min_vpn_client.utils;
/*
* @Author: Wang Feng
* @Description:脏类。方法有局限性。
* 用于实现LpPacket的快速解码,从而快速收包。
* @Version: 1.0.0
* @Date: 15:05 2021/10/28
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
import java.util.Arrays;
public class StringUtilForLpPacketDecoding {
/**
* 根据tun地址,定位到收到的IP包的地址ipPos,而IP包的开始位置startPos=ipPos-12-4,
* 从而快速将LpPacket中的负载字段(其负载实际上是一个CPacket)中实际搭载的IP包给解析出来
* @param targetArray LpPacket.payload
* @param matchArray tun地址,长度为4byte
* @return ip包开始位置
*/
public static int findTheStartPos(byte[] targetArray,byte[] matchArray){
System.out.println("target: "+ Arrays.toString(targetArray));
System.out.println("match: "+ Arrays.toString(matchArray));
for (int i = 0; i < (targetArray.length-4); i++) {
if((targetArray[i]==matchArray[0])
&& (targetArray[i+1]==matchArray[1])
&& (targetArray[i+2]==matchArray[2])
&& (targetArray[i+3]==matchArray[3])){
System.out.println("IP地址,我中了: "+(i-16));
return i-16;
}
}
return -1;
}
}