DSF 私有协议编码分析

DSF 消息序列化与反序列解析

DSF框架消息序列化与反序列化 ProtoBuff协议 , 是通过拓展Netty的ByteBuf实现的, 具体实现类名为com.huawei.csc.remoting.common.buf.impl.NettyBuffer

com.huawei.csc.usf.framework.bus.MsgCoder 实现了com.huawei.csc.remoting.common.encode.MessageEncoder和 com.huawei.csc.remoting.common.decode.MessageDecoder两个接口,com.huawei.csc.usf.framework.bus.DSFMsgCoder 继承了MsgCoder实现了对DSF协议的编解码器。

协议编码

对象编码方式

ID Type
-1 null
1 string
2 protostaff bytes
3 USFCtxObject
4 byte[]

string 对象编码方法:

length | UTF8 bytes

byte[] 对象编码方法 :

length | bytes

USFCtxObject 对象编码方式

USFObjType | Obj

protostaff bytes 编码方式

length | bytes

Obj 编码方法:

id | obj

其他泛型的编码方式:

map 编码方式

mapsize | Key(string) | Value(obj) | key2|value2...

array of obj[]

length |obj1 | obj2

UsfObjType: 0 LOCAL, 1 REMOTE, 2 LOCAL_MANUAL;
| 仅为了便于阅读,并未使用分割符

协议的编码方式是典型的变长编码法:所有对象的编码方式都是 id|obj的方式进行编码,先向buffer中写对象类型,然后紧跟着写对象序列化后的的bytes,中间的“|”仅为了便于阅读,并不是分隔符。string、byte[],除sting、byte[] 和USFCtxObject 之外,其他自定义的对象都是通过protostaff进行序列化,string\byte[]\USFCtxObject、Map、Array 的序列化方法见表格,一般是 Lenght|bytes的方法进行序列化。

DSF协议定义:

magic msgType msg encode(type val name -> )
4 bindrequest int MsgLen

byte 4 MsgMagic

int seqid

string payload

string version
5 bindresponse,bindVersionV1 int MsgLen

byte 5 MsgMagic

int seqid

string PayLoad
5 bindresponse,otherversion int MsgLen

byte 5 Msg Magic

int SeqId

Object PayLoad
0 request int MsgLen

byte 0 MsgMagic

string ReqId

int isAsync :0-> no 1->yes

int 0 msgType: 0->request 1->reply

string serviceName

string operationName

Long Long Int : 0L0L0d MsgSeprator

Obj[] payload

string group

map attachement (with sendtime)

Object reqobj

Object null(0xffffffff) excption
0 reply int MsgLen

byte 0 Msg Magic

string ReqId

int isAsync

int 1 msgType:0->request 1->reply

string serviceName

string operation

Long 0L |Long 0L|int 0 MsgSeprator

payload:null(-1,0xfffffffff)

string group

map attachement(with sendtime)

Object rspObj

Object exception

msgtype : 0 request 1 respons
isSync : 0 no 1 yes
len-4 是因为 java int 为32位 占4个byte
报文中的 0xffffffff 是 表示对象为 null

从抓包分析来看,DSF协议并没有按照其父类的设计,写 magic、servicegroup、src、des 等等,估计是开发人员没有按照大师的设计来,进行了一部分简化。另外本身协议设计也是根据固定读写顺序来的,协议拓展性并不高;协议内容中因为大量使用int类型传输数据,协议压缩率可以进一步提升。

DSF 抓包分析

--request bigend ?

0000008b00000000013100000000000000000000000853657276696365410000000873617948656c6c6f000000000000000000000000000000000000000000000001000000010000000568656c6c6f0000000764656661756c74000000010000000873656e6454696d650000000300000000000000010000000d31353031333739303237393037ffffffffffffffff

--request hex

           0  1  2  3  4  5  6  6   8  9  a  b  c  d  e  f
           -----------------------------------------------
00000000  00 00 00 8b 00 00 00 00  01 31 00 00 00 00 00 00   ........ .1......
00000010  00 00 00 00 00 08 53 65  72 76 69 63 65 41 00 00   ......Se rviceA..
00000020  00 08 73 61 79 48 65 6c  6c 6f 00 00 00 00 00 00   ..sayHel lo......
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ........ ........
00000040  00 01 00 00 00 01 00 00  00 05 68 65 6c 6c 6f 00   ........ ..hello.
00000050  00 00 07 64 65 66 61 75  6c 74 00 00 00 01 00 00   ...defau lt......
00000060  00 08 73 65 6e 64 54 69  6d 65 00 00 00 03 00 00   ..sendTi me......
00000070  00 00 00 00 00 01 00 00  00 0d 31 35 30 31 33 37   ........ ..150137
00000080  39 30 32 37 39 30 37 ff  ff ff ff ff ff ff ff      9027907. .......

request 解析


           0  1  2  3  4  5  6  7   8  9  a  b  c  d  e  f            ascii msg
           -----------------------------------------------
00000000  00 00 00 8b|00 00 00 00| 01|31|00 00 00 00|00 00   ........ .1......
       package len 8b|msg type 0 |len|id| is async  |msg   
00000010  00 00|00 00 00 08|53 65  72 76 69 63 65 41|00 00   ......Se rviceA..
     send    0 |string len8| S  e   r  v  i  c  e  A|str len 8
                           |Servicename             |
00000020  00 08|73 61 79 48 65 6c  6c 6f|00 00 00 00 00 00   ..sayHel lo......
               | s  a  y  H  e  l   l  o|          OL
               |operation name          |OL 0L 0d seprator
00000030  00 00|00 00 00 00 00 00  00 00|00 00 00 00|00 00   ........ ........
               |         OL             |     Od    |obj len 1
00000040  00 01|00 00 00 01|00 00  00 05|68 65 6c 6c 6f|00   ........ ..hello.
               | obj type 1|string len 5| h  e  l  l  o| 
               |ref objtype|in param                   |   
00000050  00 00 07|64 65 66 61 75  6c 74|00 00 00 01|00 00   ...defau lt......
         str len 7| d  e  f  a  u   l  t|map size  1|
                  |group name           |attachment map 
00000060  00 08|73 65 6e 64 54 69  6d 65|00 00 00 03|00 00   ..sendTi me......
      str len 8| s  e  n  d  T  i   m  e|           |
               |key :sendTime           |USFCtxObject|USFOBjType                
00000070  00 00|00 00 00 01|00 00  00 0d|31 35 30 31 33 37   ........ ..150137
               |string    1|            | 1  5  0  1  3  7 
               |obj type   |str  len 10 |string content 
00000080  39 30 32 37 39 30 37|ff ff  ff ff |ff ff ff ff   9027907. .......
           9  0  2  7  9  0  8|req obj      |exception

--reply

0000008d00000000013100000000000000010000000853657276696365410000000873617948656c6c6f0000000000000000000000000000000000000000ffffffff0000000764656661756c74000000010000000873656e6454696d650000000300000000000000010000000d31353031333739303237393131000000010000000b68656c6c6f3a68656c6c6fffffffff

--reply hex


              0  1  2  3  4  5  6  6   8  9  a  b  c  d  e  f
   00000000  00 00 00 8d|00 00 00 00| 01|31|00 00 00 00|00 00   ........ .1......
               len 8d   |type     0 |len|id|isAsync    | msg
   00000010  00 01|00 00 00 08|53 65  72 76 69 63 65 41|00 00   ......Se rviceA..
          reply 01| str len   |servicename             |str len 
   00000020  00 08|73 61 79 48 65 6c  6c 6f|00 00 00 00 00 00   ..sayHel lo......
                  |operation name          |  0L   
   00000030  00 00|00 00 00 00 00 00  00 00|00 00 00 00|ff ff   ........ ........
                  |          0L            |     0d    |null -1 reply has in params
   00000040  ff ff|00 00 00 07|64 65  66 61 75 6c 74|00 00 00   ......de fault...
                  | str len  7| d  e   f  a  u  l  t|
                  |groupname                        |attachement map size  1
   00000050  01|00 00 00 08|73 65 6e  64 54 69 6d 65|00 00 00   .....sen dTime...
               |str len    |    key                 |obj type usfctxobj 03
   00000060  03 |00 00 00 00|00 00 00 01|00 00 00 0d|31 35 30   ........ .....150
                | local     |obj type string  len 0d|
   00000070  31 33 37 39 30 32 37 39  31 31|00 00 00 01|00 00   13790279 11......
            rsptime                        |resp obj   |
                                           |obj type 1 |string len 0x0b
   00000080  00 0b|68 65 6c 6c 6f 3a  68 65 6c 6c 6f|ff ff ff   ..hello: hello...
                  |                                 |Null exception 
                  |response   content               |
   00000090  ff                                              .

通过以上研究,可以在后期使用跨语言访问dsf,详细抓包文件请使用 tcp.port eq 50254 ,另外可能是gitea存在bug,无法正常查看部分表格。

Next: DSF zookeeper的Node 组织



结构:
DSFCtxObject
--type : int( LOCAL,REMOTE,LOCAL_MANUAL)
--Obj : protostaff bytes
-------- length: int
-------- ObjectCompressBytes :gziped bytes,用protostaff.GraphIOUtil.writeTo 方法产生ObjectPack 的bytes,然后gzip
---ObjectPack
--Object

DSFCtxObject 解码方法:

  1. read type
  2. read length
  3. read byte[length]
    4.unzip
    5.GraphIOUtil.mergeFrom
    6.gen DSFCtxObject

DSFCtxObject编码方法:
0.write byte 4
1.write DSFCtxObject.type
2.ObjectPack(DSFCtxObject.obj)
3.protostaff.GraphIOUtil.writeTo(objpack) 生成待压缩bytes
4.gzip compress
5.write length of compress bytes
6.write compressed bytes

你可能感兴趣的:(DSF 私有协议编码分析)