非常教程

Erlang 20参考手册

直径 | diameter

diameter_dict

档案

diameter_dict

文件摘要

直径应用程序的字典接口。

描述

用配置的直径服务diameter:start_service/2指定一个或多个支持的Diameter应用程序。每个Diameter应用程序指定一个知道如何对其消息和AVP进行编码和解码的字典模块。字典模块又由定义这些消息和AVP的文件生成。这种文件的格式在FILE FORMAT下面定义。用户通过创建字典文件添加对其特定应用程序的支持,使用或者将它们编译到Erlang模块,diameterc(1)或者diameter_make(3)在服务上配置生成的字典模块。

字典模块生成还会生成一个hrl文件,该文件定义了字典定义的消息和分组AVP的记录,这些记录是直径应用程序的用户发送和接收的内容,以其他可能的格式为模,如上所述diameter_app(3)。这些记录和对应于直径的数据格式的底层的Erlang数据类型中讨论MESSAGE RECORDSDATA TYPES分别。生成的hrl还包含Enumerated类型AVP的可能值的宏定义。

直径应用程序包括与RFC 6733第2.4节中定义的应用程序相对应的五个字典模块,diameter_gen_base_rfc3588以及diameter_gen_base_rfc6733具有应用程序标识符0的Diameter公共消息应用程序diameter_gen_accounting(对于RFC 3588)以及diameter_gen_acct_rfc6733具有应用程序标识符3和diameter_gen_relay中继应用程序的Diameter基本会计应用程序应用程序标识符为0xFFFFFFFF。

通用消息和中继应用程序是直径本身具有任何特定知识的唯一应用程序。通用消息应用程序用于直径本身处理的消息:CER / CEA,DWR / DWA和DPR / DPA。由于它处理的消息和AVP没有具体定义,因此中继应用程序在编码/解码方面给予特殊处理。

文件格式

字典文件由不同的部分组成。每个部分以一个标记开始,后面跟着零个或多个参数,结束于下一节的开头或文件的末尾。标记由一个符号和字符组成,后面跟着一个关键字,并通过空格将其参数与参数分隔开。空格分隔单个标记,但在其他方面是不重要的。

标签、它们的参数和每个对应部分的内容如下。除非另有规定,否则每个区段可以发生多次。指定节的顺序是不重要的。

@id Number

将整数定义为有关应用程序的直径应用程序ID。最多只能发生一次,如果字典定义了@messages.该节的内容为空。

应用程序ID设置在应用程序的传出消息的直径头中,传入消息的头中的值用于标识相关的字典模块。

例子:

@id 16777231

@name Mod

定义生成的字典模块的名称。最多只能出现一次,默认为字典文件的名称减去任何扩展名。该节的内容为空。

注意,字典模块应该有一个唯一的名称,这样就不会与系统中的现有模块发生冲突。

例子:

@name etsi_e2

@prefix Name

将名称定义为要添加到'_'生成的字典模块和hrl中的记录和常量名称(后跟一个字符)的前缀。最多可以发生一次。该部分有空的内容。

前缀是可选的,但可用于消除不同直径应用程序中由同名消息和AVP产生的记录名称和常量名称之间的歧义。

例子:

@prefix etsi_e2

@vendor Number Name

将整数Number定义为设置V标志的AVP的默认Vendor-Id。将文件命名为申请的所有者,但未被使用。最多可发生一次,如果AVP设置了V标志并且没有另外分配供应商ID,则需要这样做。该部分有空的内容。

例子:

@vendor 13019 ETSI

@avp_vendor_id Number

将整数定义为节内容中列出的avp的供应商ID,覆盖@vendor默认。节内容由AVP名称组成。

例子:

@avp_vendor_id 2937

WWW-Auth
Domain-Index
Region-Set

@inherits Mod

定义包含应该导入到当前字典中的AVP定义的字典模块的名称。节内容由那些应该从字典中导入定义的AVP的名称组成,这是一个导致所有被导入的空列表。任何列出的AVP都不能在当前字典中定义,并且从多个字典继承相同的AVP是错误的。

请注意,设置V标志的继承的avp将从任意一个获取其vendor-id。@avp_vendor_id在继承字典或@vendor在继承的字典里。特别是,@avp_vendor_id在继承的字典中被忽略。从指定所需的字典继承@vendor等于使用@avp_vendor_id使用字典%27s定义的副本,但前者更容易重用。

所有字典通常应该继承RFC 6733 AVP diameter_gen_base_rfc6733

例子:

@inherits diameter_gen_base_rfc6733

@avp_types

定义各个AVP的名称、代码、类型和标志。这一节由表单的定义组成。

Name Code Type Flags

其中Code是整数AVP代码,Type代表DATA TYPES下面部分定义的AVP数据格式,Flags是V,M和P字符串,表示要在传出AVP上设置的标志或者在发送AVP或单个'-'(减号)字符时设置的标志if没有设置。

例子:

@avp_types

Location-Information   350  Grouped     MV
Requested-Information  353  Enumerated   V

警告

P标志已被RFC 6733所反对。

@custom_types Mod

指定模块MOD提供编解码功能的AVP。该节内容由AVP名称组成。每个这样的名字,Mod:Name(encode|decode, Type, Data, Opts)应该为AVP的值提供编码/解码,其中名称是AVP的名称,类型是在@avp_types节中,数据是要编码/解码的值,opts是通过编码/解码传递的术语。

例子:

@custom_types rfc4005_avps

Framed-IP-Address

@codecs Mod

@custom_types但需要指定的模块导出Mod:Type(encode|decode, Name, Data, Opts)而不是Mod:Name(encode|decode, Type, Data, Opts)

例子:

@codecs rfc4005_avps

Framed-IP-Address

@messages

定义应用程序的消息。本节内容包括RFC 6733第3.2节“命令代码格式规范”中指定的表单的定义。

@messages

RTR ::= < Diameter Header: 287, REQ, PXY >
        < Session-Id >
        { Auth-Application-Id }
        { Auth-Session-State }
        { Origin-Host }
        { Origin-Realm }
        { Destination-Host }
        { SIP-Deregistration-Reason }
        [ Destination-Realm ]
        [ User-Name ]
      * [ SIP-AOR ]
      * [ Proxy-Info ]
      * [ Route-Record ]
      * [ AVP ]

RTA ::= < Diameter Header: 287, PXY >
        < Session-Id >
        { Auth-Application-Id }
        { Result-Code }
        { Auth-Session-State }
        { Origin-Host }
        { Origin-Realm }
        [ Authorization-Lifetime ]
        [ Auth-Grace-Period ]
        [ Redirect-Host ]
        [ Redirect-Host-Usage ]
        [ Redirect-Max-Cache-Time ]
      * [ Proxy-Info ]
      * [ Route-Record ]
      * [ AVP ]

@grouped

定义具有分组类型的应用程序的AVP的内容。本节内容由RFC 6733第4.4节“分组AVP值”中指定的格式的定义组成。

例子:

@grouped

SIP-Deregistration-Reason ::= < AVP Header: 383 >
                              { SIP-Reason-Code }
                              [ SIP-Reason-Info ]
                            * [ AVP ]

在分组AVP的定义中指定供应商ID等同于使用指定@avp_vendor_id

@enum Name

定义类型为Enumerated的AVP Name的值。部分内容由名称和相应的整数值组成。整数值可以用0x作为前缀来解释为十六进制。

请注意,可以在继承字典中定义所讨论的AVP,以便向另一个字典中定义的枚举引入附加值。

例子:

@enum SIP-Reason-Code

PERMANENT_TERMINATION    0
NEW_SIP_SERVER_ASSIGNED  1
SIP_SERVER_CHANGE        2
REMOVE_SIP_SERVER        3

@end

导致对字典的解析终止:任何剩余的内容都会被忽略。

注释可以使用分号包含在字典文件中:忽略从分号到行尾的字符。

讯息记录

从字典规范生成的hrl定义了在@messages@grouped各部分。对于每个消息或分组avp定义,定义一个记录,其名称为消息或avp名称,前缀为@prefix,其字段是包含在消息中的AVP的名称,或按所述定义中指定的顺序分组AVP的名称。例如,分组AVP

SIP-Deregistration-Reason ::= < AVP Header: 383 >
                              { SIP-Reason-Code }
                              [ SIP-Reason-Info ]
                            * [ AVP ]

将导致以下记录定义给空前缀。

-record('SIP-Deregistration-Reason' {'SIP-Reason-Code',
                                     'SIP-Reason-Info',
                                     'AVP'}).

编码在生成记录字段中的值取决于AVP可能发生的类型和次数。特别是,指定为正好出现一次的AVP被编码为AVP类型的值,而具有任何其他指定的AVP则被编码为AVP类型的值的列表。AVP的类型如AVP定义中所指定,RFC 6733类型如下所述。

数据类型

RFC 6733的第4.2节(“基本AVP数据格式”)和第4.3节(“派生的AVP数据格式”)中定义的数据格式被编码为这里定义的类型的值。diameter:call/4在发送请求时将值传递到请求记录中,并在返回结果记录中返回并handle_request/3在接收到传入请求时传递给回调。

在OctetString()和派生类型的string()和binary()类型之间进行选择的情况下,表示形式由值diameter:service_opt() string_decode

基本AVP数据格式

OctetString() = string() | binary()
Integer32()   = -2147483647..2147483647
Integer64()   = -9223372036854775807..9223372036854775807
Unsigned32()  = 0..4294967295
Unsigned64()  = 0..18446744073709551615
Float32()     = '-infinity' | float() | infinity
Float64()     = '-infinity' | float() | infinity
Grouped()     = record()

在编码时,可以将OctetString()指定为iolist(),过大的浮点数(绝对值)等于infinity或等于'-infinity'过大的整数,导致编码失败。分组AVP的记录如前一节所述。

导出AVP数据格式

Address() = OctetString()
          | tuple()

在编码时,OctetString()IPv4地址以通常的xxxx格式进行分析,而IPv6地址则以RFC 2373“地址的文本表示”第2.2节规定的任何格式进行解析。IPv4元组()的长度为4,包含类型0..255的值。IPv6元组()的长度为8,包含0..65535类型的值。元组表示用于解码。

Time() = {date(), time()}

where

  date() = {Year, Month, Day}
  time() = {Hour, Minute, Second}

  Year   = integer()
  Month  = 1..12
  Day    = 1..31
  Hour   = 0..23
  Minute = 0..59
  Second = 0..59

此外,可以编码的值通过将其编码为四个八位位组而受到限制,如RFC 6733所要求的,并且具有RFC 2030所需的扩展。特别是,只有{{1968,1,20},{3,14,8}}{{2104,2,26},{9,42,23}}(包括两者)之间的值才能被编码。

UTF8String() = [integer()] | binary()

列表元素是字符串中单个字符的UTF-8编码。无效的代码点将导致编码/解码失败。在编码时,可以将UTF8String()指定为二进制文件,也可以将其指定为二进制文件和代码点的嵌套列表。

DiameterIdentity() = OctetString()

值的长度必须至少为1。

DiameterURI() = OctetString()
              | #diameter_URI{type = Type,
                              fqdn = FQDN,
                              port = Port,
                              transport = Transport,
                              protocol  = Protocol}

where

  Type = aaa | aaas
  FQDN = OctetString()
  Port = integer()
  Transport = sctp | tcp
  Protocol  = diameter | radius | 'tacacs+'

在编码时,字段端口,传输和协议默认分别默认为3868,sctp和直径。OctetString型DiameterURI()的语法如RFC 6733的4.3节所述。记录表示用于解码。

Enumerated() = Integer32()

在编码时,可以使用字典的hrl文件中定义的宏来指定值。

IPFilterRule()  = OctetString()
QoSFilterRule() = OctetString()

这些类型的值目前不按直径进行解析。

另见

diameterc(1), diameter(3), diameter_app(3), diameter_codec(3), diameter_make(3)

Erlang 20

Erlang 是一种通用的面向并发的编程语言,可应付大规模开发活动的程序设计语言和运行环境。

主页 https://www.erlang.org/
源码 https://github.com/erlang/otp
版本 20
发布版本 20.1