From 4fb738f0db9e7364a4d8162affd70d173ee70a5c Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Sat, 13 Mar 2021 09:24:22 +0800 Subject: [PATCH 1/5] add interface: InteractWithField --- src/main/java/packet/InteractWithFiled.java | 22 +++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/main/java/packet/InteractWithFiled.java diff --git a/src/main/java/packet/InteractWithFiled.java b/src/main/java/packet/InteractWithFiled.java new file mode 100644 index 0000000..923fbeb --- /dev/null +++ b/src/main/java/packet/InteractWithFiled.java @@ -0,0 +1,22 @@ +package packet; + +/* + * @Author: Wang Feng + * @Description: 定义了一个网络包应该实现哪些和分区交互的方法 + * @Version: 1.0.0 + * @Date: 9:21 2021/3/13 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public interface InteractWithFiled { + /** + * 将包的属性填充到网络包的四个分区当中 + * @return + */ + boolean fillDataToFields(); + + /** + * 从网络包的四个分区当中提取出特定网络包的相关属性 + * @return + */ + boolean extraDataFromFields(); +} From 997eaa12ac40601def9c6354c711eb921ded4fe2 Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Sat, 13 Mar 2021 09:24:50 +0800 Subject: [PATCH 2/5] add interface: InteractWithField --- .../packet/{InteractWithFiled.java => InteractWithField.java} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/main/java/packet/{InteractWithFiled.java => InteractWithField.java} (94%) diff --git a/src/main/java/packet/InteractWithFiled.java b/src/main/java/packet/InteractWithField.java similarity index 94% rename from src/main/java/packet/InteractWithFiled.java rename to src/main/java/packet/InteractWithField.java index 923fbeb..de8f03c 100644 --- a/src/main/java/packet/InteractWithFiled.java +++ b/src/main/java/packet/InteractWithField.java @@ -7,7 +7,7 @@ package packet; * @Date: 9:21 2021/3/13 * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ -public interface InteractWithFiled { +public interface InteractWithField { /** * 将包的属性填充到网络包的四个分区当中 * @return From 0a945ada8ec1a537b2ee154335c1ed3ee56d02a0 Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Mon, 15 Mar 2021 12:58:17 +0800 Subject: [PATCH 3/5] finish packet: MINPacket --- src/main/java/packet/MINPacket.java | 159 ++++++++++++++++++++++++++++ src/main/java/packet/Packet.java | 12 --- 2 files changed, 159 insertions(+), 12 deletions(-) create mode 100644 src/main/java/packet/MINPacket.java delete mode 100644 src/main/java/packet/Packet.java diff --git a/src/main/java/packet/MINPacket.java b/src/main/java/packet/MINPacket.java new file mode 100644 index 0000000..0c8fac4 --- /dev/null +++ b/src/main/java/packet/MINPacket.java @@ -0,0 +1,159 @@ +package packet; + +import component.IdentifierField; +import component.MutableField; +import component.ReadOnlyField; +import encoding.*; + +/* + * @Author: Wang Feng + * @Description: 表示一个MIN网络层包的通用结构 + * todo: 需要在signature完成之后取消signatureField的注释 + * @Version: 1.0.0 + * @Date: 22:07 2021/3/13 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class MINPacket implements IEncodingAble { + private IdentifierField identifierField; // 标识区 +// private SignatureField signatureField; // 签名区 + private ReadOnlyField readOnlyField; // 只读区 + private MutableField mutableField; // 可变区 + private VlInt packetType; // 包类型 + + /** + * 判断 MIN 包是否是一个有效的包 + * @return + */ + public boolean isPacketValid(){ + return TLV.isValidPacketType(packetType); + } + + + /** + * 将 Packet 线速编码为 TLV + * @param encoder + * @return + */ + @Override + public int wireEncode(Encoder encoder) { + if(!this.isPacketValid()){ + return 0; + } + int totalLength=0; + + // 编码 TLV-VALUE + + // 可变区 + int tmplen=this.mutableField.wireEncode(encoder); + if(tmplen<=0){ + return 0; + } + totalLength+=tmplen; + + // 只读区 + tmplen=this.readOnlyField.wireEncode(encoder); + if(tmplen<=0){ + return 0; + } + totalLength+=tmplen; + + // 签名区 +// tmplen=this.signatureField.wireEncode(encoder); +// if(tmplen<=0){ +// return 0; +// } +// totalLength+=tmplen; + + // 标识区 + tmplen=this.identifierField.wireEncode(encoder); + if(tmplen<=0){ + return 0; + } + totalLength+=tmplen; + + // 编码包 TLV-LENGTH + tmplen=encoder.prependVarNumber(new VlInt(totalLength)); + if(tmplen<=0){ + return 0; + } + totalLength+=tmplen; + + // 编码包 TLV-TYPE + tmplen=encoder.prependVarNumber(this.packetType); + if(tmplen<=0){ + return 0; + } + totalLength+=tmplen; + + return totalLength; + } + + /** + * 线速解码,将 MIN包 TLV 中的四个区域分别解析出来 + * @param block + * @return + */ + @Override + public boolean wireDecode(Block block) { + // 首先判断包是否有效 + if(!block.isValid()){ + return false; + } + // 首先解析子 Block + if(!block.parseSubElements()){ + return false; + } + + // 标记,用来记录是否满足必要条件 + boolean existIdentifier=false; + + // 解析四个标识区 + int elementSize=block.getSubElements().length(); + for (int i=0;i Date: Mon, 15 Mar 2021 17:00:05 +0800 Subject: [PATCH 4/5] finish encoding: SelfEncodingBase --- src/main/java/component/MutableField.java | 4 +- src/main/java/component/TTL.java | 3 + src/main/java/encoding/SelfEncodingBase.java | 97 ++++++++++++++++++++ src/main/java/packet/CPacket.java | 80 +++++++++++++++- src/main/java/packet/MINPacket.java | 14 ++- src/test/java/others/TestCallBack.java | 19 ++++ 6 files changed, 209 insertions(+), 8 deletions(-) create mode 100644 src/main/java/encoding/SelfEncodingBase.java create mode 100644 src/test/java/others/TestCallBack.java diff --git a/src/main/java/component/MutableField.java b/src/main/java/component/MutableField.java index 822623a..9a0b082 100644 --- a/src/main/java/component/MutableField.java +++ b/src/main/java/component/MutableField.java @@ -10,8 +10,8 @@ import encoding.*; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ public class MutableField implements TlvComponentBase,IEncodingAble { - private MutableProtectField mutableProtectField; - private MutableDangerousField mutableDangerousField; + public MutableProtectField mutableProtectField; + public MutableDangerousField mutableDangerousField; public MutableField(){ mutableProtectField=new MutableProtectField(); diff --git a/src/main/java/component/TTL.java b/src/main/java/component/TTL.java index b12b33f..b5c02b8 100644 --- a/src/main/java/component/TTL.java +++ b/src/main/java/component/TTL.java @@ -19,6 +19,9 @@ public class TTL implements IEncodingAble { */ private long ttl; + public TTL(){ + } + public TTL(Block block){ buildTTLByBlock(block); } diff --git a/src/main/java/encoding/SelfEncodingBase.java b/src/main/java/encoding/SelfEncodingBase.java new file mode 100644 index 0000000..cfff5d6 --- /dev/null +++ b/src/main/java/encoding/SelfEncodingBase.java @@ -0,0 +1,97 @@ +package encoding; + +import component.CanBePrefix; + +/* + * @Author: Wang Feng + * @Description: 利用对接口的函数回调,实现对任意实现了 IEncodingAble 接口的对象进行自编码 + * @Version: 1.0.0 + * @Date: 16:17 2021/3/15 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class SelfEncodingBase { + + // 用来实现自编码的辅助结构 + private Block rawBlock; + // 存放回调的函数 +// private IEncodingAble iEncodingAble; + + public SelfEncodingBase(){ + } + + /** + * 获取编码后的Block + * @return + */ + public Block getRawBlock(){ + return rawBlock; + } + + /** + * 设置回调函数(接口的函数) + * @param iEncodingAble + */ +// public void setiEncodingAble(IEncodingAble iEncodingAble) { +// this.iEncodingAble = iEncodingAble; +// } + + /** + * 对一个实现了 IEncodingAble 接口的对象进行自编码 + * // @Description: + * // 1. 用 rawBlock缓存编码的结果; + * // 2. 如果 rawBlock不为空,且指向一个有效的 Block,则直接返回raw + * // 3. 如果 rawBlock为空,或者指向的不是一个有效的 Block,则将对象编码为 Block 之后返回,同时用 raw指针缓存编码的结果 + * @param iEncodingAble + * @return + */ + public Block selfWireEncode(IEncodingAble iEncodingAble){ +// this.setiEncodingAble(iEncodingAble); + if((this.rawBlock!=null)&&this.rawBlock.isValid()){ + return this.rawBlock; + } + + Block block=easyEncoder(iEncodingAble); + if(block==null){ + return null; + } + this.rawBlock=block; + return block; + } + + /** + * 自编码辅助函数 + * 利用对接口的函数回调,实现对任意实现了 IEncodingAble 接口的对象进行自编码 + * @param iEncodingAble + * @return + */ + private Block easyEncoder(IEncodingAble iEncodingAble){ + Encoder encoder=new Encoder(); + + // 首先测量目标 TLV 的大小 + encoder.estimatorReset(); + int targetLen=iEncodingAble.wireEncode(encoder); + if(targetLen<=0){ + return null; + } + + // 编码初始化 + if(!encoder.encoderReset(new SizeT(targetLen),new SizeT(0))){ + return null; + } + + // 实际执行编码 + targetLen=iEncodingAble.wireEncode(encoder); + if(targetLen<=0){ + return null; + } + + byte[] buffer=encoder.getBuffer(); + if((buffer==null)||buffer.length==0){ + return null; + } + + // 返回编码的结果 + return Block.createBlockByBuffer(buffer,true); + } + +} diff --git a/src/main/java/packet/CPacket.java b/src/main/java/packet/CPacket.java index 60e4034..4ae8dbb 100644 --- a/src/main/java/packet/CPacket.java +++ b/src/main/java/packet/CPacket.java @@ -1,5 +1,10 @@ package packet; +import component.IdentifierWrapper; +import component.Payload; +import component.TTL; +import encoding.*; + /* * @Author: Wang Feng * @Description: @@ -27,6 +32,79 @@ package packet; // } // } // -public class CPacket { +public class CPacket implements InteractWithField, IEncodingAble { + private MINPacket minPacket; + private TTL ttl; + private Payload payload; + private String flatIdentifier; // 推式包拥有一个扁平的标识 + public CPacket(){ + minPacket=new MINPacket(); + ttl=new TTL(); + payload=new Payload(); + } + + /** + * 将 CPacket 的各项属性填充到 MINPacket 中定义的对应分区当中 + * @Description: + * // 1. 主要填充标识区、只读区和可变区 + * @return + */ + @Override + public boolean fillDataToFields() { + // 可变区 => 受保护区(无) + + // 填充可变区 => 非受保护区 + // 首先清除所有的Block + this.minPacket.mutableField.mutableDangerousField.clearBlocks(); +// Block block + return true; + } + + /** + * 从 MINPacket 的分区当中提取出 CPacket 的各项属性 + * @return + */ + @Override + public boolean extraDataFromFields() { + // 提取 Payload + Block payloadBlock=this.minPacket.readOnlyField.getBlockByType(new VlInt(TLV.TlvPayload)); + if(payloadBlock==null){ + return false; + } + if(this.payload.wireDecode(payloadBlock)){ + return false; + } + + // 提取 TTL + Block ttlBlock=this.minPacket.mutableField.mutableDangerousField.getBlockByType(new VlInt(TLV.TlvTTL)); + if(ttlBlock==null){ + return false; + } + if(this.ttl.wireDecode(ttlBlock)){ + return false; + } + + // 提取标识 + IdentifierWrapper commonIdentifier=this.minPacket.identifierField.getIdentifierByType(new VlInt(TLV.TlvIdentifierCommon)); + if(commonIdentifier==null){ + return false; + } + String identifierString=commonIdentifier.toUri(); + if((identifierString.length()>0)&&(identifierString.startsWith("/"))){ + this.flatIdentifier=identifierString.substring(1); + } + + return true; + } + + @Override + public int wireEncode(Encoder encoder) { + return 0; + } + + @Override + public boolean wireDecode(Block block) { + return false; + } } diff --git a/src/main/java/packet/MINPacket.java b/src/main/java/packet/MINPacket.java index 0c8fac4..94825da 100644 --- a/src/main/java/packet/MINPacket.java +++ b/src/main/java/packet/MINPacket.java @@ -6,7 +6,7 @@ import component.ReadOnlyField; import encoding.*; /* - * @Author: Wang Feng + * @Author: Wang Fengs * @Description: 表示一个MIN网络层包的通用结构 * todo: 需要在signature完成之后取消signatureField的注释 * @Version: 1.0.0 @@ -14,11 +14,11 @@ import encoding.*; * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 */ public class MINPacket implements IEncodingAble { - private IdentifierField identifierField; // 标识区 + public IdentifierField identifierField; // 标识区 // private SignatureField signatureField; // 签名区 - private ReadOnlyField readOnlyField; // 只读区 - private MutableField mutableField; // 可变区 - private VlInt packetType; // 包类型 + public ReadOnlyField readOnlyField; // 只读区 + public MutableField mutableField; // 可变区 + public VlInt packetType; // 包类型 /** * 判断 MIN 包是否是一个有效的包 @@ -90,6 +90,10 @@ public class MINPacket implements IEncodingAble { /** * 线速解码,将 MIN包 TLV 中的四个区域分别解析出来 + * // @Description: + * // 1. 解析出四个区的TLV; + * // 2. 检查必要的TLV是否存在,不存在则抛出异常,以下为必须条件: + * // a. 必须包含标识区,且标识区至少包含一个标识 * @param block * @return */ diff --git a/src/test/java/others/TestCallBack.java b/src/test/java/others/TestCallBack.java new file mode 100644 index 0000000..7459ef9 --- /dev/null +++ b/src/test/java/others/TestCallBack.java @@ -0,0 +1,19 @@ +package others; + +import component.CanBePrefix; +import encoding.Block; +import encoding.SelfEncodingBase; + +/* + * @Author: Wang Feng + * @Description: + * @Version: 1.0.0 + * @Date: 16:36 2021/3/15 + * @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室 + */ +public class TestCallBack { + public static void main(String[] args){ + CanBePrefix canBePrefix=new CanBePrefix(); + Block block=new SelfEncodingBase().selfWireEncode(canBePrefix); + } +} From 7a6ce6e6a5c75683930dca8782c164aedf3ddb93 Mon Sep 17 00:00:00 2001 From: free will <2647778488@qq.com> Date: Mon, 15 Mar 2021 17:18:26 +0800 Subject: [PATCH 5/5] finish Packet: CPacket --- src/main/java/packet/CPacket.java | 91 ++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 3 deletions(-) diff --git a/src/main/java/packet/CPacket.java b/src/main/java/packet/CPacket.java index 4ae8dbb..d493e2c 100644 --- a/src/main/java/packet/CPacket.java +++ b/src/main/java/packet/CPacket.java @@ -57,7 +57,31 @@ public class CPacket implements InteractWithField, IEncodingAble { // 填充可变区 => 非受保护区 // 首先清除所有的Block this.minPacket.mutableField.mutableDangerousField.clearBlocks(); -// Block block + Block block=new SelfEncodingBase().selfWireEncode(this.ttl); + if(block==null){ + return false; + } + this.minPacket.mutableField.mutableDangerousField.addBlock(block); + + // 填充只读区 + // 首先清除所有的Block + this.minPacket.readOnlyField.clearBlocks(); + block=new SelfEncodingBase().selfWireEncode(this.payload); + if(block==null){ + return false; + } + this.minPacket.readOnlyField.addBlock(block); + + // 填充标识区 + // 首先清除所有的标识 + this.minPacket.identifierField.clearIdentifiers(); + IdentifierWrapper identifierWrapper= + new IdentifierWrapper().createCommonIdentifierByString(this.flatIdentifier); + if(identifierWrapper==null){ + return false; + } + this.minPacket.identifierField.addIdentifier(identifierWrapper); + return true; } @@ -98,13 +122,74 @@ public class CPacket implements InteractWithField, IEncodingAble { return true; } + /** + * 将 CPacket 编码成 TLV + * @param encoder + * @return + */ @Override public int wireEncode(Encoder encoder) { - return 0; + // 首先将属性填充到分区当中 + if(!this.fillDataToFields()){ + return 0; + } + + // 指定包类型 + this.minPacket.packetType=new VlInt(TLV.TlvPacketMINCommon); + + return this.minPacket.wireEncode(encoder); } + /** + * 从 TLV Block 中解码出一个 CPacket + * @param block + * @return + */ @Override public boolean wireDecode(Block block) { - return false; + if(!this.minPacket.wireDecode(block)){ + return false; + } + return this.extraDataFromFields(); + } + + /** + * 展示平面标识 + * @return + */ + public String toUri(){ + return this.flatIdentifier; + } + + /** + * 设置推式包的平面标识,eg: asdfsvnjweivnjsdcs + * @param identifier + */ + public void setIdentifier(String identifier){ + this.flatIdentifier=identifier; + } + + /** + * 获取推式包的平面标识 + * @return + */ + public String getIdentifier(){ + return this.flatIdentifier; + } + + /** + * 得到 TTL + * @return + */ + public TTL getTtl() { + return ttl; + } + + /** + * 设置 TTL + * @param ttl + */ + public void setTtl(TTL ttl) { + this.ttl = ttl; } }