博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Diameter XML 与C++的故事(一)

Posted on 2012-02-28 17:13  Sylvain的小屋  阅读(1884)  评论(1编辑  收藏  举报

 

著名的Diameter协议功能很强大,可以完好的支持AAA(认证,授权以及计费)功能,公司之前完成了java版本的Diameter路由,现在改用C++实现Diameter对等端,并使用XML作为中介报文调用后台的服务。我便负责了实现Diameter报文与XML的互转的功能。

参考java的源码和Diameter协议规范,为了摸清解析流程和报文结构,便开始了自己造轮子的过程。当时opendiameter并未能成功编译出来,自己造轮子的话,能够在万不得已的情况下还有模块能用。

这个原型在win7下用vs2010来开发,借用了c++开源库POCO来协助开发。在原java的程序下,因为java完全OO的架构下,不同类型的AVP的数据内容都可以放在object这个类型下,而且多个接口和派生类以及各种工厂类让我一下无所适从。最后再代码堆中找出了最底层的实体类的代码,AVP和树形的GroupedAVP,解析的过程还是很明显的,解包AVP,根据AVP头值和长度,读取一个AVP,若是GroupedAVP的话,内容依然是一个AVP包。对于常规的AVP包,通过查找字典的获得该AVP的类型,动态调用类型解析工厂,获得解释器来解包。若果是一个嵌套的GroupedAVP,就把内容放入了GroupAVPmap成员和list成员,方便查找并获得其中的值。并且java的设计用了两个接口加一个基类来分离操作和数据。当这一切要用c++来实现的时候遇到了几个问题,第一个问题是那个解释器工厂如何构建,第二是AVPGroupedAVP之间怎么样互调组成一棵树,第三便是如何释放掉资源的过程。显然这些问题是在代码构建中出现的,之前只考虑了原型的话取消那个解释器工厂,完全模拟java程序的后果就是C++的多态使用比较混乱,调试起来脑子相当崩溃,因为开始没有考虑好及时释放内存以致程序出现多处内存泄露。同时由于对局部变量处理不当,导致有时候内存无端端的被释放了,显然这都是C++用得不熟练导致的。

此时,决定放弃山寨java程序的念头,重写解析的函数,在解析的过程中同时在构建XML的文件,实体类AVPGroupedAVP基本上只使用了AVP,做获得字典内容用,用完后及时释放,java使用mina的协议解包接口来完成指针的前进,我便封装了一个字符数组来模仿mina的工作,理顺思路后,代码开发非常顺利,很快完成从二进制内容转成XML文件。

XML转成二进制内容,倒是一个比较麻烦的过程,Diameter协议包的结构和XML倒是有点像的,都是使用带树形的结构来存储,想了一段时间,采用了POCOSAXParser来构造,在遍历完一次XML后就可以生成对应的二进制码流,但是从SAXParser解析出的XML内容是没有树形结构的,这样的话,是没有办法生成具有树形结构的二进制协议包,而且包头带有整个包的长度,所有还必须有回写这一操作除了长度还必须要有起始的地址,虽然这个可以通过现在的位置回退长度完成,不过增加一个栈会简化我们的操作,一共引入3vector当做栈来用,一个是保持树形的栈,一个是维护回写入口的栈,一个是维护回写包长的栈,另外封装了一个可变长的char数组以及相关操作的辅助类,调试了几天后,这个功能也顺利实现。

此时传来捷报,opendiameterAIX上编译通过了,意味着我要修改opendiameter上解包和封包的流程。第一次认真的读开源框架的代码,看着那一堆堆的模板,让我实在是头疼了一把,但是有了写原型的经验,阅读这个框架的多少还是有点思路,但是看到那个配置的XML字典,猜想是不是代码会完全按照XML来解析,若是字典没有的是不是会出错,另外我们主要是扩展DiameterCC这个报文,一个同名的GroupedAVP对应不同的树形有没有问题,经过测试框架已经很好支持这样的配置。框架做得很好,但是从代码着手,确实难度很大,但是在老大的指引下,硬是这样也大致整理出个流程出来,发现这个框架的层次架构得还是比较精巧的,虽然嵌套了6层,但是代码风格倒是很像,还是蛮优雅的,然而要看明白其中的构架也是不容易的,虽然其提供了一个diameter报文转xml的测试函数,但是显然是没有测试过,因为里头的低级错误实在太多,包括用错变量,变量赋值错误等等。读懂了流程未必能完全写出对应的代码,网上搜索资料后在官网找到了相当重要的资料,真是及时雨哇。参考文档以及程序架构图,终于完成了从xml转成opendiameter的报文。

完成了这个模块,其实感触还是蛮多的,从大一学完C++后,基本上就没再做过复杂的C++程序,然后学习java,再到C#,到最后回到C++,真是一个轮回。虽然一直从事C++开发,但是基于现有的框架,完成业务流程,是不需要有太多的代码量的,写着那些和javaC#非常类似的C++代码,C++本身是获得不了太大的提高,毕竟关注的业务逻辑,稳定的构架能够让大家更关注业务,计算机到底还是为业务服务的,并不是为了炫耀的。这很关键,明白了这些,其实这两年也没白过。基于自己接触POCO以及OpenDiameter艰难的入门,接下来发点自己的学习成果吧,也算是方便后人了。