直径 | diameter
直径
模块
直径
模块摘要
主要API的直径应用。
描述
该模块提供用户可以使用RFC 6733中定义的使用Diameter协议发送和接收消息的Diameter节点的接口。
基本用法包括创建本地实现的Diameter节点及其功能的表示start_service/2
,通过使用add_transport/2
和发送Diameter请求并接收Diameter答案来增加传输能力call/4
。传入的Diameter请求diameter_app(3)
按照服务配置中指定的方式作为回调传递给回调模块。
请注意直径
(不是大写)和Diameter
(大写)之间的差异。前者是指名为Diameter
的Erlang应用程序,其主API是在此定义的,后者是RFC 6733中的Diameter
协议。
在调用此模块中的大多数功能之前,必须启动直径应用程序。
数据类型
Address()DiameterIdentity()Grouped()OctetString()Time()Unsigned32()UTF8String()
对应于RFC 6733 AVP数据格式的类型。定义于diameter_dict(4)
。
application_alias() = term()
在服务配置中标识Diameter应用程序的名称。call/4
在发送由应用程序定义的请求时传递给它。
application_module() = Mod | [Mod | ExtraArgs] | #diameter_callback{}
Mod = atom()
ExtraArgs = list()
实现在其中定义的回调接口的模块diameter_app(3)
,以及附加到那些记录的任何额外参数。请注意,可以指定特定于传出请求的额外参数call/4
,在这种情况下,这些参数会附加到任何特定于模块的额外参数。
指定一条#diameter_callback{}
记录允许将各个函数配置为代替通常的diameter_app(3)
回调。详情请参阅diameter_callback.erl
。
application_opt()
定义Diameter应用程序的选项。有以下一种类型。
{alias,
application_alias()
}
服务范围内的应用程序的唯一标识符。默认为dictionary
选项的值。
{dictionary, atom()}
应用程序定义的Diameter消息的编码/解码模块的名称。这些模块由其格式记录在其中的文件生成diameter_dict(4)
。
{module,
application_module()
}
回调模块,其中处理Diameter应用程序的消息。请参阅diameter_app(3)
所需的接口和语义。
{state, term()}
初始回调状态。普遍的状态被传递给一些diameter_app(3)
回调,然后可以返回一个新的状态。默认为alias
选项的值。
{call_mutates_state, true|false}
pick_peer/4
应用程序回调是否可以修改应用程序状态。默认为false
。
警告
pick_peer/4
当这个选项是回调串行化true
,这是一个潜在的性能瓶颈。一个简单的Diameter客户端可能不会受到使用可变状态的不良影响,但响应传入请求的服务器或代理程序应该可能避免。
{answer_errors, callback|report|discard}
处理包含解码错误的传入应答消息的方式。
如果callback
错误导致handle_answer/4
回调的方式handle_request/3
与传递给回调的errors
字段中#diameter_packet{}
传递的错误相同。如果report
那么包含错误的回答在没有回调的情况下被丢弃,并且警告报告被写入日志。如果discard
那么包含错误的回答在没有回调的情况下被默默丢弃。在这两个report
和discard
案件的返回值call/4
的问题调用是因为如果回调已经发生并返回{error, failure}
。
默认为discard
。
{request_errors, answer_3xxx|answer|callback}
检测到错误不是3007(DIAMETER_APPLICATION_UNSUPPORTED,不能与应用程序回调模块关联)时处理传入请求的方式。
如果answer_3xxx
那么请求在没有handle_request/3
回调的情况下被回答。如果answer
那么甚至5xxx错误在没有回调的情况下被回答,除非有问题的连接已经配置RFC 3588通用字典,如下所述。如果callback
再handle_request/3
回调总是发生和它的返回值来确定发送到对等的答案,如果有的话。
默认为answer_3xxx
。
注
通过直径发送的答案在Diameter标题中设置E位。由于RFC 3588只允许在一个3xxx结果代码中使用answer-message
,它answer
具有与有answer_3xxx
问题的传输已配置diameter_gen_base_rfc3588
为其常用字典时相同的语义。由于RFC 6733允许在一个3xxx和5xxx结果代码中answer-message
,所以一个传输使用diameter_gen_base_rfc6733
它作为其通用字典来区分answer_3xxx
和answer
。
call_opt()
call/4
发送传出Diameter请求时可用的选项。有以下类型之一。
{extra, list()}
额外的参数将追加到回调模块的问题。这些附加到在回调本身上配置的任何额外参数。多个选项附加到参数列表。
{filter,
peer_filter()
}
筛选器在将其pick_peer/4
传递给相关应用程序的回调之前应用于可用对等项的列表。多个选项相当于all
相应的过滤器列表上的单个过滤器。默认为none
。
{peer, diameter_app:peer_ref()}
可以发送有问题的请求的对等方,抢先选择支持相关Diameter应用程序的对等方。可以指定多个选项,并且在传递给后续pick_peer/4
回调的候选列表中遵守其顺序。
{timeout,
Unsigned32()
}
请求超时后的毫秒数。默认为5000。
detach
原因call/4
返回ok
只要有问题的请求已被编码,而不是等待,结果从随后的恢复,handle_answer/4
或handle_error/4
回调。
无效的选项将导致call/4
失败。
capability()
在功能交换期间传出的CER或CEA消息中发送的AVP值。可以在服务和传输上配置,后者的值优先。有以下类型之一。
{'Origin-Host',
DiameterIdentity()
}{'Origin-Realm',
DiameterIdentity()
}{'Host-IP-Address', [
Address()
]}
一个地址列表可用于a的开始函数transport module
,它可以返回一个新的列表供后续的CER或CEA使用。如果有问题的传输模块按照中所述传送地址列表,则不需要指定主机IP地址diameter_transport(3)
{'Vendor-Id',
Unsigned32()
}{'Product-Name',
UTF8String()
}{'Origin-State-Id',
Unsigned32()
}
Origin-State-Id是可选的,但如果已配置,则将包含在传出的CER / CEA和DWR / DWA消息中。设置值0
(零)等同于不设置值,如RFC 6733中所述。该函数origin_state_id/0
可用于检索直径应用程序启动时计算的值。
{'Supported-Vendor-Id', [
Unsigned32()
]}{'Auth-Application-Id', [
Unsigned32()
]}{'Inband-Security-Id', [
Unsigned32()
]}
Inband-Security-Id默认为空列表,相当于只包含0(NO_INBAND_SECURITY)的列表。如果指定了1(TLS),那么如果从对等方收到的CER / CEA提供TLS,则选择TLS。
{'Acct-Application-Id', [
Unsigned32()
]}{'Vendor-Specific-Application-Id', [
Grouped()
]}{'Firmware-Revision',
Unsigned32()
}
请注意,每个元组传递一个或多个AVP值。指定重复的元组是错误的。
eval() = {M,F,A} | fun() | [eval() | A]
表达式可以在下列意义上作为函数进行评估。
eval([{M,F,A} | T]) ->
apply(M, F, T ++ A
eval([[F|A] | T]) ->
eval([F | T ++ A]
eval([F|A]) ->
apply(F, A
eval(F) ->
eval([F]).
将eval()
E
参数列表应用于参数列表A
意味着eval([E|A])
。
警告
注意fun Name/Arity
在趣味不是短暂的情况下使用有趣的表达式,并且代码将在运行时升级,因为任何保留这种乐趣的过程都会引用旧代码。特别是,这样的值在传递给start_service/2
或的配置中通常是不适当的add_transport/2
。
peer_filter() = term()
过滤器传递给call/4
为pick_peer/4
回调选择候选对等。有以下类型之一。
none
匹配任何同行。这是一种方便,提供了一个相当于没有过滤器的过滤器。
host
只匹配那些Origin-Host与出口请求中的Destination-Host具有相同值的那些对等体,或者如果请求不包含Destination-Host AVP,则匹配任何对等体。
realm
只匹配Origin-Realm在所涉及的传出请求中与Destination-Realm具有相同值的那些对等项,或者在请求中不包含Destination-Realm AVP的情况下匹配任何对等项。
{host, any|
DiameterIdentity()
}
只匹配Origin-Host具有指定值的那些对等体,或者匹配原子的所有对等体any
。
{realm, any|
DiameterIdentity()
}
只匹配Origin-Realm具有指定值的对等体,或者匹配原子的所有对等体any
。
{eval,
eval()
}
仅匹配应用于连接记录时指定eval()
返回的那些对等体。任何其他返回值或异常相当于。truediameter_capsfalse
{neg,
peer_filter()
}
只匹配那些未被指定过滤器匹配的对等体。
{all, [
peer_filter()
]}
只匹配指定列表中每个过滤器匹配的对等点。
{any, [
peer_filter()
]}
仅匹配由指定列表中的至少一个过滤器匹配的对等项。结果列表将按匹配顺序排列,匹配列表中第一个筛选器的匹配对象排在第二个筛选器匹配的匹配序列之前,依此类推。
{first, [
peer_filter()
]}
就像any
,但是在有匹配的第一个过滤器处停下来,这在有许多对等点时效率会更高。例如,以下过滤器只会导致与主机和领域过滤器最匹配的对等体出现。
{first, [{all, [host, realm]}, realm]}
一个无效的过滤器相当于{any,[]}
一个不匹配任何对等体的过滤器。
注
的host
和realm
过滤器使得所述目的主机和目标的境界的AVP从呼出请求被提取,假设它是一个record-或列表值diameter_codec:message()
每个AVP的,并假设至多一个。如果不是这种情况,那么{host|realm,
DiameterIdentity()}
必须使用过滤器来达到预期的结果。一个空的DiameterIdentity()
(这不应该是典型的)匹配所有的主机/领域用于过滤。
警告
一个host
滤波器不是设置目的主机时通常需要的,因为它会从候选列表中删除对等代理。
service_event() = #diameter_event{service =
service_name()
, info =
service_event_info()
}
将事件消息发送给订阅了这些消息的进程subscribe/1
。
service_event_info() = term()
记录的info
领域service_event()
。可以有以下类型之一。
startstop
该服务正在启动或停止。没有事件发生在事件之前start
。事件之后没有事件stop
发生,并且此事件意味着终止所有运输过程。
{up, Ref, Peer, Config, Pkt}{up, Ref, Peer, Config}{down, Ref, Peer, Config}
Ref = transport_ref()
Peer = diameter_app:peer()
Config = {connect|listen, [transport_opt()]}
Pkt = #diameter_packet{}
RFC 3539看门狗状态机已经转换成(up
)或退出(down
)OKAY状态。如果#diameter_packet{}
存在的up
事件,然后又有了新建立的传输连接上的能力交换和记录包含接收到的CER或CEA。
请注意,给定对等体的单个up
或down
事件对应于多个peer_up/3
或peer_up/3
回调,对于在能力交换期间协商的每个Diameter应用程序都有一个。也就是说,该事件与整个对等体进行通信连接,而回调则与各个Diameter应用程序进行通信连接。
{reconnect, Ref, Opts}
Ref = transport_ref()
Opts = [transport_opt()]
连接传输正试图建立/重新建立与对等体之后connect_timer
或watchdog_timer
到期的传输连接。
{closed, Ref, Reason, Config}
Ref = transport_ref()
Config = {connect|listen, [transport_opt()]}
功能交换失败。Reason
可以有以下类型之一。
{'CER', Result, Caps, Pkt}
Result = ResultCode | {capabilities_cb, CB, ResultCode|discard}
Caps = #diameter_caps{}
Pkt = #diameter_packet{}
ResultCode = integer()
CB = eval()
进入的CER已经用指示的结果码回答,或丢弃。Caps
包含分别为本地节点和远程节点的值对。Pkt
包含有问题的CER。在通过能力回调拒绝的情况下,该元组包含拒绝回调。
{'CER', Caps, {ResultCode, Pkt}}
ResultCode = integer()
Caps = #diameter_caps{}
Pkt = #diameter_packet{}
传入的CER包含错误,并已用指示的结果代码回答。Caps
仅包含本地节点的值。Pkt
包含有问题的CER。
{'CER', timeout}
在capx_timeout
建立连接时未收到预期的CER 。
{'CEA', Result, Caps, Pkt}
Result = ResultCode | atom() | {capabilities_cb, CB, ResultCode|discard}
Caps = #diameter_caps{}
Pkt = #diameter_packet{}
ResultCode = integer()
由于上述原因,传入的CEA已被拒绝。整数值Result
表示对等体发送的结果码。Caps
包含本地节点和远程对等的值对。Pkt
包含有问题的CEA。在通过能力回调拒绝的情况下,该元组包含拒绝回调。
{'CEA', Caps, Pkt}
Caps = #diameter_caps{}
Pkt = #diameter_packet{}
传入的CEA包含错误并被拒绝。Caps
仅包含本地节点的值。Pkt
包含有问题的CEA。
{'CEA', timeout}
在capx_timeout
连接建立期间没有收到预期的CEA 。
{watchdog, Ref, PeerRef, {From, To}, Config}
Ref = transport_ref()
PeerRef = diameter_app:peer_ref()
From, To = initial | okay | suspect | down | reopen
Config = {connect|listen, [transport_opt()]}
RFC 3539看门狗状态机已更改状态。
any()
为了向前兼容,用户应该准备好接收除上述以外的表单的信息字段。
service_name() = term()
传递给服务的服务的名称start_service/2
以及与服务相关的服务的名称。在给定节点上最多可以有一个给定名称的服务。请注意,erlang:make_ref/0
可用于生成有点独特的服务名称。
service_opt()
选项传递给start_service/2
。可以是任何capability()
以及以下。
{application, [
application_opt()
]}
服务支持的Diameter应用程序。
服务必须为其打算支持的每个Diameter应用程序配置一个元组。对于传出请求,application_alias()
传递相关信息call/4
;对于传入请求,消息头中的应用程序标识符确定应用程序,标识符在应用程序dictionary
文件中指定。
警告
节点通告的功能必须与其配置的应用程序匹配。特别是,application
配置必须与capability()
* -Application-Id AVP 的相应配置相匹配。
{decode_format, record | list | map | none}
解码消息的格式和分组的AVP分别在msg
diameter_packet记录的字段和diameter_avp记录的value
字段中。如果record
那么一个记录的定义是从有问题的字典文件生成的。如果list
或map
然后一[Name | Avps]
对分别Avps
是AVP名称/值对列表或AVP名称上分别键入的映射。如果none
接着是原子值消息名称或undefined
分组AVP。另见diameter_codec:message()
。
默认为record
。
注
AVP被独立地解码成直径分组记录avps
字段中的diameter_avp记录列表decode_format
。
{restrict_connections, false | node | nodes | [node()] | eval()}
服务允许多个传输连接到相同对等体的程度,正如它的Origin-Host在能力交换时所标识的那样。
如果[node()]
连接被拒绝,如果任何指定节点上已经存在另一个连接。类型false
,node
,nodes
和eval()
等同于[]
,[node()]
,[node()|nodes()]
和的评价值分别各表达发生每当一个新的连接将被建立的评估。请注意,false
允许使用相同的对等方建立无限数量的连接。
多个连接是独立的,并由他们自己的对等和看门狗状态机管理。
默认为nodes
。
{sequence, {H,N} |
eval()
}
由服务生成的32位端到端和逐跳标识符H
的最高32-N
位的常数值,显式地或作为函数的返回值在此处进行评估start_service/2
。具体而言,标识符Id
如下映射到新的标识符。
(H bsl N) bor (Id band ((1 bsl N) - 1))
请注意,RFC 6733要求端到端标识符在至少4分钟的时间内保持唯一性,并且此和呼叫速率将适当值的下限设置为N:以每秒R请求速率,N位计数器在(1 bsl N) div (R*60)几分钟内遍历所有的值,所以绑定是4*R*60 =< 1 bsl N。
N
必须位于范围内,0..32
并且H
必须是小于的非负整数1 bsl (32-N)
。
默认为{0,32}
。
警告
实现相同Diameter节点的多个Erlang节点应该配置不同的序列掩码,以确保每个节点对传出请求使用唯一范围的端到端和逐跳标识符。
{share_peers, boolean() | [node()] | eval()}
通信在本地Erlang节点上建立对等连接的节点。远程候选列表中的远程候选列表中可以使用共享对等方,这些远程对象pick_peer/4
的服务被配置为使用它们:请参见use_shared_peers
下文。
如果false
那么同行不共享。如果[node()]
那么对等体与指定的节点列表共享。如果eval()
对等方与指定函数返回的节点共享,则每当对等连接变为可用或远程服务请求有关本地连接的信息时进行评估。该值true
相当于fun erlang:nodes/0
。node()
列表中的值将被忽略,因此可以将所有服务都配置为与同一个节点列表共享。
默认为false
。
注
为了发送传出请求,对等方只与同名的服务共享。由于application_opt()
alias
传递给的值call/4
是用于将对等方识别为合适候选人的句柄,因此共享对等方的服务必须使用相同的别名来标识其支持的应用程序。它们通常也应该配置相同capabilities()
,因为通过共享对等连接,它们将分布在多个Erlang节点上的单个Diameter节点的实现。
{strict_arities, boolean() | encode | decode}
将消息传递给diameter_app(3)
回调函数时,是否要求消息或分组AVP中的AVP数量与字典中指定的AVP数量一致。如果true
传出消息中的不匹配导致消息编码失败,则传入消息中的不匹配会报告为传递到handle_request/3
或handle_answer/4
回调的diameter_packet记录的错误字段中的5005/5009错误。如果false
那么这两个错误都不会被执行/检测到。如果encode
或decode
之后分别仅对传出或传入消息强制执行/检测到错误。
默认为true
。
注
禁用参数检查将影响编码/解码时的消息形式。具体而言,解码后的AVP被表示为值列表,而不管AVP的属性(即所讨论的消息/ AVP语法中的预期号码),并且预期值将作为编码列表提供。这不同于将arity 1的AVP表示为裸值而不包含在列表中的历史解码行为。
{string_decode, boolean()}
是否解码类型的AVP OctetString()
及其派生类型DiameterIdentity()
,DiameterURI()
,IPFilterRule()
,QoSFilterRule()
,和UTF8String()
。如果true
这些类型的AVP被解码为string()。如果false
那么值保留为binary(。
默认为true
。
警告
应该设置此选项,false
因为足够恶意的对等体可能会导致在解析的Diameter消息在进程之间传递时消耗大量内存。默认值是为了向后兼容。
{traffic_counters, boolean()}
是否计算特定于应用程序的消息; 那些diameter_app(3)
回调发生。如果为false,那么只有直径本身处理的消息才会被计数:CER/CEA,DWR/DWA,DPR/DPA。
默认为true
。
注
禁用计数器是一种性能改进,但意味着省略计数器不会被返回service_info/2
。
{use_shared_peers, boolean() | [node()] | eval()}
通信对等体的节点在远程候选pick_peer/4
回调列表中可用。
如果false
不使用远程对等体。如果[node()]
那么只使用指定的节点列表中的对等体。如果eval()
仅使用由指定函数返回的对等项,则只要远程服务传递有关可用对等连接的信息,就对其进行评估。该值true
相当于fun erlang:nodes/0
。node()
列表中的值将被忽略。
默认为false
。
注
不使用共享对等方的服务将始终通过空列表作为pick_peer/4
回调的第二个参数。
警告
通过远程节点上的对等连接发送请求的效率低于通过本地连接发送请求的效率。service_opt()
restrict_connections
在发送请求的每个节点上使用并保持专用连接可能更好。
transport_opt()
任何运输选项除外applications
或capabilities
。用作传输配置的默认值,传递给add_transport/2
覆盖服务上配置的值的值。
transport_opt()
选项传递给add_transport/2
。有以下类型之一。
{applications, [
application_alias()
]}
应限制运输的直径应用程序。默认为在有问题的服务上配置的所有应用程序。未在相关服务上配置的应用程序将被忽略。
警告
节点通告的功能必须与其配置的应用程序匹配。特别是,设置applications
传输通常意味着必须在capabilities()
元组中设置匹配* -Application-Id AVP 。
{avp_dictionaries, [module()]}
用于对AVP进行编码/解码的备用字典模块的列表,该AVP未由相关应用的字典定义。在解码时,这样的AVP在'AVP'
解码消息或分组AVP 的字段中被表示为diameter_avp记录,第一个替代方案成功解码设置记录的值字段的AVP。在编码时,'AVP'
列表中的值可以作为AVP名称/值2元组传递,并且这是一个编码错误,因为没有替代方法来定义此元组的AVP。
默认为空列表。
注
替代字典的动机是RFC 7683,Diameter Overload Indication Conveyance(DOIC),它将AVP定义为搭载到现有的应用程序消息上,而不是定义它自己的应用程序。DOIC字典由直径应用程序作为模块提供diameter_gen_doic_rfc7683
,但可以使用备用字典对应用程序字典中未知的任何AVP集进行编码/解码。
{capabilities, [
capability()
]}
用于构建传出CER / CEA消息的AVP。值优先于有关服务上指定的任何值。
将传输选项指定为传输选项可能特别适合Inband-Security-Id,如果TLS是由TCP实现的,则需要使用TLS diameter_tcp(3)
。
{capabilities_cb,
eval()
}
在功能交换期间接收CER/CEA时调用回调,以询问是否应接受连接。应用于连接transport_ref()
和#diameter_caps{}
记录。
返回值可以有以下类型之一。
ok
接受连接。
integer()
使传入的CER使用指定的结果代码来回答。
discard
使传入的CER在没有发送CEA的情况下被丢弃。
unknown
相当于返回3010
,DIAMETER_UNKNOWN_PEER。
返回除ok
2xxx系列结果码以外的任何结果码都会导致传输连接中断。capabilities_cb
可以指定多个选项,在这种情况下,将应用相应的回调,直到全部返回ok
或者一个都没有。
{capx_timeout,
Unsigned32()
}
如果未从对等方收到期望的功能交换消息(CER或CEA),则终止具有已建立的传输连接的传输进程的毫秒数。对于连接运输,连接尝试的时间受到connect_timer
或watchdog_timer
期满。对于监听传输,对等方确定时间。
默认为10000。
{connect_timer, Tc}
Tc = Unsigned32()
对于连接传输,RFC 6733 Tc计时器,以毫秒为单位。此计时器确定传输尝试与其对等传输配置建立初始连接的频率。一旦建立了初始连接,watchdog_timer
根据RFC 3539的要求确定重新连接尝试的频率。
对于监听传输,计时器指定之前连接的对等体将被忘记的时间:在此时间之后的连接被视为初始连接而不是重新建立,导致RFC 3539状态机传递到OKAY状态而不是REOPEN。请注意,这些语义不受RFC的约束,并且监听传输的语义connect_timer
应该大于其对等的Tw +抖动。
连接传输默认为30000,听音传输默认为60000。
{disconnect_cb,
eval()
}
在终止具有看门狗状态的传输连接的传输过程之前调用回调OKAY
。适用于application|service|transport
与transport_ref()
和diameter_app:peer()
问题:application
表示该应用程序的直径被停止,service
有问题的服务正在被停止stop_service/1
,并且transport
有问题的运输被去除remove_transport/2
。
返回值可以有以下类型之一。
{dpr, [option()]}
向对等方发送断开对等请求,在接收到断开对等应答或超时后,传输过程终止。An option()
可以是以下之一。
{cause, 0|rebooting|1|busy|2|goaway}
断开 - 分别发送REBOOTING
,BUSY
,和的原因DO_NOT_WANT_TO_TALK_TO_YOU
。默认为rebooting
for Reason=service|application
和goaway
for Reason=transport
。
{timeout,
Unsigned32()
}
如果没有收到DPA,传输过程终止的毫秒数。缺省值为dpa_timeout
。
dpr
相当于{dpr, []}
。
close
终止传输过程而不将Disconnect-Peer-Request发送给对等体。
ignore
相当于没有配置回调。
disconnect_cb
可以指定多个选项,在这种情况下,将应用相应的回调,直到其中一个返回非ignore
。返回的所有回调ignore
相当于未配置它们。
默认返回一个回调dpr
。
{dpa_timeout,
Unsigned32()
}
如果没有收到DPA,传输连接终止在传出DPR之后的毫秒数。
默认为1000。
{dpr_timeout,
Unsigned32()
}
如果对等方不关闭连接,则在传入DPR之后终止传输连接的毫秒数。
默认为5000。
{incoming_maxlen, 0..16777215}
绑定在传入直径消息的预期大小上。大于指定字节数的消息将被丢弃。
默认为16777215
,直径标头中24位消息长度字段的最大值.
{length_errors, exit|handle|discard}
如何处理传入消息中Diameter标题的消息长度字段中的错误。在这种情况下的错误是,长度不是至少20个字节(标题的长度),不是4的倍数(有效长度),或者不是所讨论的消息的长度,如通过传输所接收的界面记录在diameter_transport(3)
。
如果exit
那么运输过程就退出了。如果handle
那么消息像往常一样进行处理,则产生handle_request/3
或handle_answer/4
回调(如果发生的话)指示5015
错误(DIAMETER_INVALID_MESSAGE_LENGTH)。如果discard
那么这个消息就会被默默地抛弃。
默认为exit
。
注
默认值反映了如下事实:用于面向流的传输(如TCP)的传输模块可能无法从消息长度错误中恢复,因为此类传输必须使用消息长度标头将传入的字节流划分为独立的Diameter消息。无效的长度使得它没有可靠的方式来重新发现消息边界,这可能导致后续消息的失败。查看diameter_tcp(3)
该模块的行为。
{pool_size, pos_integer()}
要启动的传输进程的数量。对于监听传输,确定接受传输进程池的大小,对于处理多个并发对等连接尝试而言,需要更大的数量。对于连接传输,确定将尝试建立的对等连接的数量service_opt()
:restrict_connections
应该也在有问题的服务上配置,以允许多个连接到同一对等体。
{spawn_opt, [term()]}
erlang:spawn_opt/2
当为进入的Diameter请求产生进程时传递给它的选项。选项monitor
并被link
忽略。
默认为空列表。
{strict_capx, boolean()]}
是否强制执行RFC 6733要求在能力交换之前的任何消息应关闭对等连接。如果为false,则意外消息将被丢弃。
默认为true。改变这种结果会导致非标准行为,但在已知对方行为不佳的情况下可能会有用。
{strict_mbit, boolean()}
当有问题的命令语法不明确允许AVP时,是否将AVP设置为M-位是错误的。如果true
这样的AVP被认为是5001错误,则DIAMETER_AVP_UNSUPPORTED。如果false
M位被忽略并且监管它成为接收方的责任。
默认为true
。
警告
RFC 6733不清楚M位的语义。一个在一个命令语法为意指一方面,在部分中的CCF规范3.2文件AVP 任何
任意AVP; 另一方面,1.3.4规定设置M位的AVP不能添加到现有命令中:修改后的命令必须放置在新的Diameter应用程序中。
后者的原因大概是互操作性:允许任意AVP
设置命令中的M位使其解释实现相关,因为不能保证所有实现都将在给定命令的上下文中理解同一组任意AVP
。然而,AVP
无论M位如何,在命令语法中将命令语法解释为任何AVP
都会使1.3.4无意义,因为无论发送者的意图如何,接收者都可以简单地忽略它认为不相关的任何AVP
。
请注意,在命令语法的意义上,必须将M位与强制性混淆起来。前者是一个语义要求:接收者在上下文中理解AVP的语义。后者是一个语法要求:AVP是否必须发生在有问题的消息中。
{transport_config, term()}{transport_config, term(),
Unsigned32()
| infinity}
为了启动运输过程start/3
,作为相关职能的第三个参数通过了期限transport module
。缺省为空列表。
三元组格式额外指定了一个时间间隔(以毫秒为单位),在此之后,如果尚未建立连接,则应该终止已启动的传输过程。例如,连接传输上的以下选项通过TCP请求与一个对等节点的连接,或通过TCP请求与另一个对等节点(通常相同)的连接。
{transport_module, diameter_sctp}
{transport_config, SctpOpts, 5000}
{transport_module, diameter_tcp}
{transport_config, TcpOpts}
要侦听SCTP和TCP,请为每个传输定义一个传输。
{transport_module, atom()}
执行运输过程的模块按照定义diameter_transport(3)
。默认为diameter_tcp
。
多transport_module
和transport_config
选项是允许的。在这种情况下(仅在这种情况下),这些顺序是重要的,transport_module
与transport_config
选项列表中的第一个匹配,或者跟踪模块的默认值。每个模块都会尝试传输启动,直到在相应的超时(请参阅下文)中建立连接或全部失败。
{watchdog_config, [{okay|suspect, non_neg_integer()}]}
改变看门狗状态机行为的配置。关键时okay
,在从REOPEN转换到OKAY之前,应答DWR消息的非负数。关键suspect
时,DWR未应答时,从OKAY切换到SUSPECT之前的看门狗超时数,或者0不进行转换。
默认为[{okay, 3}, {suspect, 1}]
。不指定密钥相当于指定该密钥的默认值。
警告
默认值是RFC 3539所要求的:更改它会导致非标准行为,这些行为只应用于模拟测试期间行为不当的节点。
{watchdog_timer, TwInit}
TwInit = Unsigned32()
| {M,F,A}
RFC 3539看门狗定时器。整数值被解释为RFC的TwInit(以毫秒为单位),在计时器的每次重新计算时添加±2秒的抖动以计算RFC的Tw。预计MFA将直接返回RFC的Tw,并应用抖动,从而允许通过回调执行抖动计算。
整数值必须至少为RFC 3539所要求的6000。默认为30000。
无法识别的选项会默默忽略,但会被未修改的返回,service_info/2
并且可以在传递给谓词的函数中引用remove_transport/2
。
transport_ref() = reference()
返回的参考add_transport/2
标识了配置。
出口
add_transport(SvcName, {connect|listen, [Opt]}) -> {ok, Ref} | {error, Reason}
类型
将传输能力添加到服务。
该服务将根据需要启动传输过程,以便通过连接到对等端(connect
)或接受传入连接请求(listen
)来建立与对等端的连接。连接传输与最多一个对等端建立传输连接,可能与多个对等端进行监听传输。
直径应用程序负责与同行交换CER / CEA。成功完成功能交换后,服务会调用每个相关应用程序模块的peer_up/3
回调,之后主叫方可以通过传输方与对端交换Diameter消息。除CER / CEA外,该服务还负责处理DWR / DWA,并且符合RFC 3539以及DPR / DPA的要求。
返回的引用唯一标识服务范围内的传输。请注意,该功能在传输连接建立之前返回。
注
将传输添加到尚未配置的服务中并不是错误:可以在配置传输后启动服务。
call(SvcName, App, Request, [Opt]) -> Answer | ok | {error, Reason}
类型
发送直径请求消息。
App
指定Diameter应用程序,在该应用程序中定义了请求,并按照以下和在中所述的方式,对相应的回调模块执行回调diameter_app(3)
。除非detach
指定该选项,否则当从对等方收到答复消息或发生错误时,呼叫返回。在答案中,返回值是由handle_answer/4
回调返回的。在错误情况下,错误是直接由handle_error/4
回调函数还是回调函数直接返回,取决于传出请求是否被成功编码以传输给对等方,这些情况将在下文中介绍。
如果没有合适的同伴,或者如果pick_peer/4
通过返回拒绝他们false
,则{error,no_connection}
返回。否则pick_peer/4
后面跟着prepare_request/3
回调,消息被编码然后发送。
有几种错误情况可能会阻止接收和传递给handle_answer/4
回调的答案:
- 如果传出请求的初始编码失败,则请求处理失败并
{error,encode}
返回。
- 如果请求被成功编码并发送,但答案超时,则会发生
handle_error/4
回调Reason = timeout
。
- 如果请求被成功编码并发送,但在接收到答案之前有问题的服务停止,则会发生
handle_error/4
回调Reason = cancel
。
- 如果在发送请求之后但收到答复之前,与对等方的传输连接断开,则尝试将请求重新发送给备用对等方。如果没有这样的对等体可用,或者如果后续
pick_peer/4
回调拒绝候选人,则会发生handle_error/4
回调Reason = failover
。如果选择了一个对等方,则会发生prepare_retransmit/3
回调,之后的语义与初始prepare_request/3
回调之后的语义相同。
- 如果在重新传输期间发生编码错误,则请求处理失败并
{error,failure}
返回。
- 如果在处理请求时发生的应用程序回调失败(pick_peer,prepare_request,prepare_retransmit,handle_answer或handle_error),则根据是否尝试通过传输发送请求返回
{error,encode}
或{error,failure}
返回。
请注意,这{error,encode}
是保证请求未
通过传输连接发送的唯一返回值。
origin_state_id() ->Unsigned32()
返回一个合理的值用作传出消息中的Origin-State-Id。
返回的值是19680120T031408Z以来的秒数,这是Time()
在直径应用程序启动时第一个可编码为直径的值。
remove_transport(SvcName, Pred) -> ok | {error, Reason}
类型
删除以前添加的传输。
Pred
确定要删除哪些传输。一元数-3-值Pred
消除了其中所有传输Pred(Ref, Type, Opts)
返回true
,其中Type
和Opts
被传递给add_transport/2
和Ref
作为通过它返回。其余表格相当于一个arity-3乐趣如下。
Pred = fun(transport_ref(), list()): fun(Ref, _, Opts) -> Pred(Ref, Opts) end
Pred = fun(list()): fun(_, _, Opts) -> Pred(Opts) end
Pred = transport_ref(): fun(Ref, _, _) -> Pred == Ref end
Pred = list(): fun(_, _, Opts) -> [] == Pred -- Opts end
Pred = true: fun(_, _, _) -> true end
Pred = false: fun(_, _, _) -> false end
Pred = {M,F,A}: fun(Ref, Type, Opts) -> apply(M, F, [Ref, Type, Opts | A]) end
移除传输会导致相应的传输进程终止。DPR消息是否发送到对等体由disconnect_cb
传输器上配置的值控制。
service_info(SvcName, Info) -> term()
类型
返回有关已启动服务的信息。请求有关未知服务的信息会导致undefined
返回。请求项目列表会导致返回带标签的列表。
Item
可以是下列之一。
'Origin-Host'
'Origin-Realm'
'Vendor-Id'
'Product-Name'
'Origin-State-Id'
'Host-IP-Address'
'Supported-Vendor'
'Auth-Application-Id'
'Inband-Security-Id'
'Acct-Application-Id'
'Vendor-Specific-Application-Id'
'Firmware-Revision'
返回配置的能力值start_service/2
。
applications
返回配置的应用程序列表start_service/2
。
capabilities
返回配置的所有功能值的标记列表start_service/2
。
transport
返回一个列表,其中包含每个配置的服务传输的一个条目add_transport/2
。每个条目都是一个标记列表,其中包含有关建立的对等连接的配置和信息 带有连接到“server.example.com”的单个传输配置的Origin-Host“client.example.com”的客户端服务的示例返回值可能如下所示。
[[{ref,#Ref<0.0.0.93>},
{type,connect},
{options,[{transport_module,diameter_tcp},
{transport_config,[{ip,{127,0,0,1}},
{raddr,{127,0,0,1}},
{rport,3868},
{reuseaddr,true}]}]},
{watchdog,{<0.66.0>,{1346,171491,996448},okay}},
{peer,{<0.67.0>,{1346,171491,999906}}},
{apps,[{0,common}]},
{caps,[{origin_host,{"client.example.com","server.example.com"}},
{origin_realm,{"example.com","example.com"}},
{host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
{vendor_id,{0,193}},
{product_name,{"Client","Server"}},
{origin_state_id,{[],[]}},
{supported_vendor_id,{[],[]}},
{auth_application_id,{[0],[0]}},
{inband_security_id,{[],[0]}},
{acct_application_id,{[],[]}},
{vendor_specific_application_id,{[],[]}},
{firmware_revision,{[],[]}},
{avp,{[],[]}}]},
{port,[{owner,<0.69.0>},
{module,diameter_tcp},
{socket,{{127,0,0,1},48758}},
{peer,{{127,0,0,1},3868}},
{statistics,[{recv_oct,656},
{recv_cnt,6},
{recv_max,148},
{recv_avg,109},
{recv_dvi,19},
{send_oct,836},
{send_cnt,6},
{send_max,184},
{send_avg,139},
{send_pend,0}]}]},
{statistics,[{{{0,258,0},recv},3},
{{{0,258,1},send},3},
{{{0,258,0},recv,{'Result-Code',2001}},3},
{{{0,257,0},recv},1},
{{{0,257,1},send},1},
{{{0,257,0},recv,{'Result-Code',2001}},1},
{{{0,280,1},recv},2},
{{{0,280,0},send},2},
{{{0,280,0},send,{'Result-Code',2001}},2}]}]]
这里ref
是一个transport_ref()
和options
相应的transport_opt()
列表传递给add_transport/2
。该watchdog
条目显示连接的RFC 3539监视状态机的状态。该peer
条目标识diameter_app:peer_ref()
对此有将已经peer_up/3
回调了由确定的直径应用apps
条目common
作为application_alias()
。该caps
条目标识在功能交换期间由本地节点发送并从对方接收的功能。该port
条目显示有关传输连接的套接字级别信息。该statistics
条目提供Diameter级别的计数器,类似于{{{0,280,1},recv},2}
表示客户端已收到2条DWR消息的条目:{0,280,1} = {Application_Id, Command_Code, R_Flag}
。
需要注意的是watchdog
,peer
,apps
,caps
和port
项依赖与对等连接,可能不存在。还要注意,该statistics
条目表示在传输配置的生命周期期间积累的值。
监听交通工具的信息略有不同,因为可能有多个相同的连接transport_ref()
。transport
具有单个客户端连接的服务器返回的信息可能如下所示。
[[{ref,#Ref<0.0.0.61>},
{type,listen},
{options,[{transport_module,diameter_tcp},
{transport_config,[{reuseaddr,true},
{ip,{127,0,0,1}},
{port,3868}]}]},
{accept,[[{watchdog,{<0.56.0>,{1346,171481,226895},okay}},
{peer,{<0.58.0>,{1346,171491,999511}}},
{apps,[{0,common}]},
{caps,[{origin_host,{"server.example.com","client.example.com"}},
{origin_realm,{"example.com","example.com"}},
{host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
{vendor_id,{193,0}},
{product_name,{"Server","Client"}},
{origin_state_id,{[],[]}},
{supported_vendor_id,{[],[]}},
{auth_application_id,{[0],[0]}},
{inband_security_id,{[],[]}},
{acct_application_id,{[],[]}},
{vendor_specific_application_id,{[],[]}},
{firmware_revision,{[],[]}},
{avp,{[],[]}}]},
{port,[{owner,<0.62.0>},
{module,diameter_tcp},
{socket,{{127,0,0,1},3868}},
{peer,{{127,0,0,1},48758}},
{statistics,[{recv_oct,1576},
{recv_cnt,16},
{recv_max,184},
{recv_avg,98},
{recv_dvi,26},
{send_oct,1396},
{send_cnt,16},
{send_max,148},
{send_avg,87},
{send_pend,0}]}]}],
[{watchdog,{<0.72.0>,{1346,171491,998404},initial}}]]},
{statistics,[{{{0,280,0},recv},7},
{{{0,280,1},send},7},
{{{0,280,0},recv,{'Result-Code',2001}},7},
{{{0,258,1},recv},3},
{{{0,258,0},send},3},
{{{0,258,0},send,{'Result-Code',2001}},3},
{{{0,280,1},recv},5},
{{{0,280,0},send},5},
{{{0,280,0},send,{'Result-Code',2001}},5},
{{{0,257,1},recv},1},
{{{0,257,0},send},1},
{{{0,257,0},send,{'Result-Code',2001}},1}]}]]
此处介绍的信息与此connect
情况相同,只是客户端连接分组在一个accept
元组下。
transport_opt()
pool_size
在连接传输的情况下,是否已配置影响列表的格式,因为大于1的值意味着多个传输过程相同transport_ref()
,如在监听情况下。这种情况下的格式类似于侦听情况,用pool
元组代替accept
元组。
connections
为每个建立的传输连接返回一个包含一个条目的列表,该传输连接的监视状态机不处于该down
状态。这是信息的平面视图,transport
其中仅列出活动连接并仅针对传输连接的整个生命周期积累Diameter级统计信息。上述服务器的返回值可能如下所示。
[[{ref,#Ref<0.0.0.61>},
{type,accept},
{options,[{transport_module,diameter_tcp},
{transport_config,[{reuseaddr,true},
{ip,{127,0,0,1}},
{port,3868}]}]},
{watchdog,{<0.56.0>,{1346,171481,226895},okay}},
{peer,{<0.58.0>,{1346,171491,999511}}},
{apps,[{0,common}]},
{caps,[{origin_host,{"server.example.com","client.example.com"}},
{origin_realm,{"example.com","example.com"}},
{host_ip_address,{[{127,0,0,1}],[{127,0,0,1}]}},
{vendor_id,{193,0}},
{product_name,{"Server","Client"}},
{origin_state_id,{[],[]}},
{supported_vendor_id,{[],[]}},
{auth_application_id,{[0],[0]}},
{inband_security_id,{[],[]}},
{acct_application_id,{[],[]}},
{vendor_specific_application_id,{[],[]}},
{firmware_revision,{[],[]}},
{avp,{[],[]}}]},
{port,[{owner,<0.62.0>},
{module,diameter_tcp},
{socket,{{127,0,0,1},3868}},
{peer,{{127,0,0,1},48758}},
{statistics,[{recv_oct,10124},
{recv_cnt,132},
{recv_max,184},
{recv_avg,76},
{recv_dvi,9},
{send_oct,10016},
{send_cnt,132},
{send_max,148},
{send_avg,75},
{send_pend,0}]}]},
{statistics,[{{{0,280,0},recv},62},
{{{0,280,1},send},62},
{{{0,280,0},recv,{'Result-Code',2001}},62},
{{{0,258,1},recv},3},
{{{0,258,0},send},3},
{{{0,258,0},send,{'Result-Code',2001}},3},
{{{0,280,1},recv},66},
{{{0,280,0},send},66},
{{{0,280,0},send,{'Result-Code',2001}},66},
{{{0,257,1},recv},1},
{{{0,257,0},send},1},
{{{0,257,0},send,{'Result-Code',2001}},1}]}]]
请注意,可能有多个条目具有相同的ref
,与transport
信息。
statistics
返回{{Counter, Ref}, non_neg_integer()}
计数器值列表。Ref
可以是一个transport_ref()
或一个diameter_app:peer_ref()
。后者的条目在对等连接关闭时被折叠为前者的对应条目。两人的参赛作品都在去除remove_transport/2
。由info transport
和connections
info 返回的Diameter级统计信息基于这些条目。
diameter_app:peer_ref()
返回与传递到的单个对等关联的传输配置add_transport/2
。如果对方未知,则返回的列表为空。否则,它包含了ref
,type
和options
元组在transport
和connections
上述信息。例如:
[{ref,#Ref<0.0.0.61>},
{type,accept},
{options,[{transport_module,diameter_tcp},
{transport_config,[{reuseaddr,true},
{ip,{127,0,0,1}},
{port,3868}]}]}]
services() -> [SvcName]
类型
返回已启动服务的列表。
session_id(Ident) ->OctetString()
类型
返回会话ID AVP的值。
该值具有RFC 6733第8.8节所要求的格式。Ident应该是发送包含返回值的消息的对等方的Origin-Host。
start() -> ok | {error, Reason}
启动直径应用程序。
直径应用程序必须在开始服务之前启动。在生产系统中,这通常由启动文件完成,而不是通过start/0
明确调用完成。
start_service(SvcName, Options) -> ok | {error, Reason}
类型
启动直径服务。
服务定义了一个本地实施的Diameter节点,指定在功能交换期间要公布的功能。传输被添加到服务使用add_transport/2
。
注
传输既可以覆盖其服务的功能,也可以限制其支持的Diameter应用程序,以便“Origin =主机标识的Diameter节点”不一定是这种情况。
stop() -> ok | {error, Reason}
停止直径应用程序。
stop_service(SvcName) -> ok | {error, Reason}
类型
停止直径服务。
停止服务会导致所有关联的传输连接中断。一个DPR消息与发送一样remove_transport/2
。
注
停止服务不会删除任何关联的传输:remove_transport/2
必须调用该命令才能删除传输配置。
subscribe(SvcName) -> true
类型
订阅service_event()
来自服务的消息。
订阅尚不存在的服务中的事件并不是错误。在增加运输之前这样做是为了保证接收所有与运输有关的事件。
unsubscribe(SvcName) -> true
类型
取消订阅来自服务的事件消息。
另见
diameter_app(3)
,diameter_transport(3)
,diameter_dict(4)