Diameter 是一个由IETF发布的下一代信令协议,见文档RFC3588。
Diameter协议的设计目的是创建一个能够充分满足网络访问控制要求的AAA协议(认证,授权,计费)。Diameter设计要求的具体内容如下:
具有良好的网络适应性和可扩展性;
统一且良好的失败控制和检测机制;
完整的传送层安全保证(包括域内和域间);
数据传输可靠性保证机制;
支持各种类型的代理,包括Proxy代理,重定向代理以及中继代理等;
与现有网络协议的良好可互操作性;‘
支持节点间的能力协商机制;
支持动态对等端发现和配置机制;
支持安全和可扩展的漫游。
Diameter包含基础协议,传送协议,不同的应用扩展。所有应用和服务共用的基本功能都在基础协议中实现,而应用特定的功能则会在不同的应用中实施。
OpenBloX 是一个轻便的,可扩展的基于标准协议栈的,使用C++和Java的简单有效的Diameter实现。OpenBloX的体系架构与RFC3588中定义的Diameter层次模型一致。
图1 Diameter层次模型
1.Connectivity Layer:
节点发现
节点存活和关闭连接
节点能力协商
传输
2.Routing Layer:
智能路由和服务请求的重定向
Diameter节点角色,包括中继,代理,翻译
3,Session Layer
有状态和无状态会话的支持
客户端和服务器端的会话终止
4,Types of Diameter nodes
Diameter客户端和服务器端,请求和回复源节点
Diameter代理,请求和回复转发和重定向。
5,Application development framework
基本的请求/应答应用程序
扩展协议定义,允许定义新的应用程序,给定应用程序定义新的信息,给定信息定义新的属性。
分析OpenBloX的代码,需要理解以下重要对象。
Stack是一个负责在Diameter的客户端,服务器端和代理间的数据转换的类。Stack的生命周期包括:创建,使用配置数据初始化,开始和停止。它可以完全的动态配置。
Network表示本地Diameter节点的Diameter控制面板的一个展示。它使用PeerTable和RoutingTable来寻找每条信息的下一个节点
一个Peer对象表示一个远程的Diameter客户端,服务器或者代理。本地的客户端或者服务器端能够与远程的那些节点对象进行双向连接,关闭连接以及数据转换。Peer对象管理P2P连接建立,保持和关闭的一个状态机。Peers能够并行连接,每一个Peer与一个Diameter 连接对应。Peer的生命周期通过两个状态机来保持:
1,如RFC 3588,章节5.6所描述的Peer状态机。它负责交换和选举的能力。
2,PCB(Peer Control Block)状态机,如RFC3539,附录A所描述。它通过实现watchdog算法来监控peer的活动。
PeerTable用来管理Peer table。能通过Diameter表示来添加,移除,标识Peers。应用程序能通过注册一个PeerTableListener来通知peer table 的改变。
Routing Table 是相关的节点以及节点的本地动作在Realm和ApplicationID之间的一个对应。本地的动作可能为本地处理,代理,中继或者重定向。Routing table 用来路由本地和远程创建的请求,这个是根据请求头中的终端主机,终端Realm AVPs,以及application ID。
Session负责一个独立的用户session,通过session ID唯一标识。
这个一个在应用层上的逻辑概念,共享与访问设备和服务器端,通过session ID AVP来标识。
一个session用来创建请求,发送请求以及应答。SessionEventListener类用来执行接收的应答。一个session接收指定请求的应答,SessionEventListener将被通知。这个用来满足应用层的动作。Session通过SessionFactory创建。
AppSession一个特定应用程序的用户Session。通过唯一的application session ID标识。 AppSession API 用来创建特定的应用请求以及发送信息。AppSession可以是无状态的或者有状态的,主要视应用程序而定。
例如,一个3GPP定义的Sh接口的session称为OpenBlox中的AppSession,使用认证/授权的ID 16777217。针对Sh接口有两个这样的AppSessions:AppSessionShClient和AppSessionShServer。既然AppSessions自动生成,只支持标准定义的动作。
AppEvent表示一个特定的Diameter命令(请求或者应答)。每个命令在不同的Diameter标准中都使用ABNF格式定义。对应标准定义的AVPs,它有不同的add和get的方法。既然AppEvents是自动生成的,我们只能添加或者移除标准定义的AVPs。我们能从AppEvents添加或者移除自定义的AVPs,使用addAVP(avp),getAvp(code)方法。
例如:3GPP定义RF命令Account-Request(ACR),在OpenBlox中成为AppEvents。它有方法addAccountingRecordType(EnumValue,pFlag)用来添加AVP类型的帐号记录,它有两个参数:枚举的帐号记录类型和可选的pFlag。
Grouped AVPs存储在容器中,与AppEvents类似,容器能自动生成API,运行我们添加或者移除基于标准的AVPs。当不同的addGroupedXXX 方法调用时,这些容器能返回AppEvents和其他的GroupedAvpContainers。
SessionFactory用来创建AppSessions对象,stack在初始化时创建SessionFactory对象。SessionFactory用来生成唯一的session IDs。
DiameterAvpSet 包含一个或多个AVPs。一个Diameter信息(存储在AppEvent)有一个唯一的DiameterAvpSet。DiameterAvpSet可能包含其他的DiameterAvpSets作为其AVPs。例如,在RFC 3588中AvpProxyInfo类定义如下:
Proxy-Info::=
{Proxy-Host}
{Proxy-State}
*[AVP]
它包含一个独立的Proxy-Host AVP,一个独立的Proxy-State AVP,和一个未知数量的自定义AVPs。
DiameterAvp类展示了DiameterAvp。
有很多各种类型的AVPs,Diameter基本协议中定义的:Integer32,Integer64,Unsigned32,Unsigned64,Float32,Float64,Enumerated,Grouped,OctetString。基本Diameter协议也定义了附加的AVPs,扩展了基本的AVP类型;这些AVPs保持了一个树形的结构。按如下的功能性,每个类型的AVP 都有自己的类:
1, AVP code通过静态方式访问或者动态映射。
2, AVP flag 控制规则和加密功能(RFC 3588 ,章节4.5)。
每个Diameter节点(客户端,服务器端,或者代理)都可以通过一个包含键值对的xml或者属性文件来配置,当想创建一个configuration对象时,提供一个xml文件作为参数即可。
由MutableConfiguration派生的类能够动态的改变或者更新配置信息。
ConfigurationListener类监控Stack和其他类的配置更改。当配置参数更新了,注册的listeners 将收到通知。
SessionEventListener类监控待处理请求的应答。
NetworkRequestListener类管理远程节点上新到达的请求。这种Listener必须通过应用程序初始化,并注册到network。
PeerStateListener监控peer状态机的改变,也监控PCB状态机的改变。
StateChangeListener监控用户的session状态机的改变,可通过调用AppSession.addStateChagenNoification()方法来完成。
PeerTableListener通知Peer table 中peers的创建和移除。
The diameterURI MUST follow the Uniform Resource Identifies(URI)syntax[URI]rules specified below:
“aaa://”FQDN[port][transport][protocol]
;No transport security
“aaas://”FQDN[port][transport][protocol]
;Transport security used
FQDN = Fully Qualified Host Name
Port = “:”1*DIGIT
;One of the ports used to listen for incoming connections,If absent,the default
;Diameter port(3868) is assumed.
Transport =”;transport=”transport-protocol
;One of the transports used to listen for incoming connections.If absent,the default
;SCTP[SCTP] protocol is assumed.UDP MUST NOT be used when the aaa-protocol
; field is set to diameter.
Transport-protocol ={“tcp”/”sctp”/”udp”}
Protocol = “;protocol=”aaa-protocol
;If absent,the default AAA protocol is diameter.
Aaa-protocol ={“diameter”/”radius”/”tacacs+”}
The following are examples of valid Diameter host identities:
aaa://host.example.com:6666;transport=tcp;protocol=diameter
自动机中的转移和动作由事件引起,我们忽略—I和—R前缀,因为实际事件将会是相同的,只是仅会在两个可能的连接中的一个上发生。
I为前缀:表示发起侧(连接)连接;R为前缀:表示应答侧(监听)连接。没有前缀意味着事件或者动作是相同的,不管事件发生在哪个连接上。
Start Diameter 应用发出信号,应该发起与对等端的连接。
R-Conn-CER 接收到的确认消息声明传输连接已经建立,相关的CER消息也已经到达。
Rcv-Conn-Ack 接收到一个肯定的确认消息,证实传输连接已经建立。
Rcv-Conn-Nack 接收到否定的确认消息声明传输连接未被建立。
Timeout 一个定义的应用定时器在等待某些事件时超时。
Rcv-CER 接收到对等端发来的CER消息。
Rcv-CEA 接收到对等端发来的CEA消息
Rcv-Non-CEA 接收到对等端发来的非CEA的消息。
Peer-Disc 接收到对等端发来的拆除连接指令
Rcv-DPR 接收到对等端发来的DPR消息。
Rcv-DPA 接收到对等端发来的DPA消息。
Win-Election 举行选举时,本地节点为获胜者。
Send-Message 消息要被发送。
Rcv-Message 接收到除了CER,CEA,DPR,DPA,DWR,DWA消息外的消息。
Stop Diameter 应用程序发出信号,通知应该中断一个连接(例如,系统关闭)。
其中:
CER/CEA:能力交换请求/应答
DPR/DPA:拆除对等端连接请求/应答
DWR/DWA:设备监控请求/应答消息
在自动机中的动作由事件引发,并且指示分组传输和将要在连接上采取的动作。我们忽略了I—和R—前缀,因为实际动作将会是相同的,只是将会在两个可能的连接中的一个上发生。
Snd-Conn-Req 开始发起与对等端的一个传输连接。
Accept 接受作为应答侧连接的与R-Conn-CER相关联的输入连接。
Reject 拆除与R-Conn-CER相关联的输入连接。
Process-CER 处理与R-Conn-CER相关联的CER消息。
Snd-CER 将CER消息发送至对等端。
Snd-CEA 将CEA消息发送至对等端。
Cleanup 如果需要,连接被关闭,任何本地资源均被释放。
Error 传输层连接可以被politely或者abortively拆除,以响应一个错误条件condition。 本地资源被释放。
Process-CEA 处理接收到的CEA消息。
Snd-DPR 将一条DPR消息发送至对等端。
Snd-DPA 将一条DPA消息发送至对等端。
Disc 拆除传输层连接,本地资源被释放。
Elect 一次选举发生。
Snd-Message 一条消息被发送。
Snd-DWR 一条DWR消息被发送。
Snd-DWA 一条DWA消息被发送。
Process-DWR DWR消息被处理。
Process-DWA DWA消息被处理。
Process 消息被处理。
附件为OpenBlox源码包: