查看源代码 diameter (diameter v2.4.1)
diameter 应用程序的主要 API。
该模块提供了用户可以用来实现 Diameter 节点的接口,该节点使用 RFC 6733 中定义的 Diameter 协议发送和接收消息。
基本用法包括使用 start_service/2
创建本地实现的 Diameter 节点及其功能的表示形式,使用 add_transport/2
添加传输功能,以及使用 call/4
发送 Diameter 请求并接收 Diameter 应答。传入的 Diameter 请求会作为回调传达给 diameter_app
回调模块,如服务配置中所指定。
请注意diameter(未大写)和 Diameter(已大写)之间的区别。前者指的是名为 diameter 的 Erlang 应用程序,其主要 api 在此处定义,后者指的是 RFC 6733 意义上的 Diameter 协议。
在调用此模块中的大多数函数之前,必须先启动 diameter 应用程序。
数据类型
Address()
DiameterIdentity()
Grouped()
OctetString()
Time()
Unsigned32()
UTF8String()
- 与 RFC 6733 AVP 数据格式对应的类型。在 diameter_dict(4) 中定义。elapsed_time()
- 自给定时间起经过的时间。application_alias() = term()
- 在服务配置中标识 Diameter 应用程序的名称。在发送由应用程序定义的请求时,传递给call/4
。application_module() = Mod | [Mod | ExtraArgs] | #diameter_callback{}
Mod = atom() ExtraArgs = list()
实现
diameter_app
中定义的回调接口的模块,以及要附加到文档中的任何额外参数。请注意,可以在call/4
中指定特定于传出请求的额外参数,在这种情况下,这些参数将附加到任何特定于模块的额外参数。指定
#diameter_callback{}
记录允许配置单个函数来代替通常的diameter_app
回调。有关详细信息,请参见diameter_callback.erl
。application_opt()
- 定义 Diameter 应用程序的选项。具有以下类型之一。{alias,
application_alias()
}
- 服务范围内应用程序的唯一标识符。默认为dictionary
选项的值。{dictionary, atom()}
- 由应用程序定义的 Diameter 消息的编码/解码模块的名称。这些模块由文件的格式生成,该格式记录在 diameter_dict(4) 中。{module,
application_module()
}
- 在其中处理 Diameter 应用程序消息的回调模块。有关所需的接口和语义,请参见diameter_app
。{state, term()}
- 初始回调状态。将当前状态传递给某些diameter_app
回调,然后这些回调可以返回新状态。默认为alias
选项的值。{call_mutates_state, true|false}
- pick_peer/4 应用程序回调是否可以修改应用程序状态。默认为false
。警告
当此选项为
true
时,pick_peer/4 回调会被序列化,这可能会成为性能瓶颈。简单的 Diameter 客户端可能不会因使用可变状态而受到不良影响,但是响应传入请求的服务器或代理程序可能应避免使用可变状态。{answer_errors, callback|report|discard}
- 处理包含解码错误的传入应答消息的方式。如果为
callback
,则错误会像 handle_request/3 一样导致 handle_answer/4 回调,并在传递给回调的#diameter_packet{}
的errors
字段中传递错误。如果为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 发送的应答会在 Diameter 标头中设置 E 位。由于 RFC 3588 只允许在
answer-message
中使用 3xxx 结果代码,因此当相关传输已配置diameter_gen_base_rfc3588
作为其通用字典时,answer
与answer_3xxx
的语义相同。由于 RFC 6733 允许在answer-message
中使用 3xxx 和 5xxx 结果代码,因此使用diameter_gen_base_rfc6733
作为其通用字典的传输区分answer_3xxx
和answer
。
call_opt()
- 发送传出 Diameter 请求时,call/4
可用的选项。具有以下类型之一。{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()
]}
- 地址列表可用于 传输模块 的启动函数,该函数可以返回新列表以用于后续的 CER 或 CEA。如果相关传输模块按diameter_transport
中所述传递地址列表,则无需指定 Host-IP-Address。{'Vendor-Id',
Unsigned32()
}
{'Product-Name',
UTF8String()
}
{'Origin-State-Id',
Unsigned32()
}
- Origin-State-Id 是可选的,但如果配置,它将包含在传出的 CER/CEA 和 DWR/DWA 消息中。如 RFC 6733 中所述,将值设置为0
(零) 等效于不设置值。当启动 diameter 应用程序时,可以使用函数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()
应用于连接的diameter_caps
记录时返回true
的那些对等体。任何其他返回值或异常都等效于false
。{neg,
peer_filter()
}
- 仅匹配未被指定过滤器匹配的那些对等体。{all, [
peer_filter()
]}
- 仅匹配指定列表中每个过滤器匹配的那些对等体。{any, [
peer_filter()
]}
- 仅匹配指定列表中至少一个过滤器匹配的那些对等体。结果列表将按匹配顺序排列,匹配列表中第一个过滤器的对等体排在匹配第二个过滤器的对等体之前,以此类推。{first, [
peer_filter()
]}
- 与any
类似,但在存在匹配项的第一个过滤器处停止,当存在许多对等体时,这可以更有效率。例如,以下过滤器仅显示最匹配主机和领域过滤器的对等体。{first, [{all, [host, realm]}, realm]}
无效的过滤器等效于
{any,[]}
,一个不匹配任何对等体的过滤器。注意
host
和realm
过滤器导致从传出的请求中提取 Destination-Host 和 Destination-Realm AVP,假设它是一个记录值或列表值的diameter_codec:message()
,并且假设每个 AVP 最多一个。如果不是这种情况,则必须使用{host|realm,
DiameterIdentity()
}
过滤器来实现所需的结果。一个空的DiameterIdentity()
(通常不应如此)为了过滤的目的匹配所有主机/领域。警告
设置 Destination-Host 时,通常不希望使用
host
过滤器,因为它会从候选列表删除对等代理。service_event() = #diameter_event{service =
service_name()
, info =
service_event_info()
}
- 发送给使用subscribe/1
订阅这些事件的进程的事件消息。service_event_info() = term()
- service_event() 记录的info
字段。可以具有以下类型之一。start
stop
- 服务正在启动或停止。没有事件先于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 状态。如果up
事件中存在#diameter_packet{}
,则表示在新建立的传输连接上进行了能力交换,并且该记录包含接收到的 CER 或 CEA。请注意,给定对等体的单个
up
或down
事件对应于多个 peer_up/3 或 peer_down/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/0
- 为了向前兼容,订阅者应准备好接收除上述形式以外的其他形式的信息字段。
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}
- 在 diameter_packet 记录的msg
字段和 diameter_avp 记录的value
字段中,解码消息和分组 AVP 的格式。如果为record
,则为从相关字典文件中生成的记录。如果为list
或map
,则为[Name | Avps]
对,其中Avps
是 AVP 名称/值对的列表或分别以 AVP 名称为键的映射。如果为none
,则为原子值消息名称,或者对于分组 AVP 为undefined
。另请参见 diameter_codec:message()。默认为
record
。注意
AVP 被解码为 diameter_packet 记录的
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 位端到端和逐跳标识符的最高32-N
位的常量值H
,可以显式给出,也可以作为在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/0
将被忽略,因此可以配置一组服务以与同一节点列表共享。默认为
false
。注意
对等方仅与具有相同名称的服务共享,目的是发送传出请求。由于传递给
call/4
的 application_opt()alias
的值是用于将对等方标识为合适候选者的句柄,因此共享对等方的服务必须使用相同的别名来标识其支持的应用程序。它们通常还应配置相同的 capabilities(),因为通过共享对等连接,它们正在多个 Erlang 节点上分发单个 Diameter 节点的实现。{strict_arities, boolean() | encode | decode}
- 在将消息传递给diameter_app
回调时,是否要求消息或分组 AVP 中的 AVP 数量与相关字典中指定的数量一致。如果true
,则传出消息中的不匹配会导致消息编码失败,而传入消息中的不匹配将作为 5005/5009 错误报告给传递给 handle_request/3 或 handle_answer/4 回调的 diameter_packet 记录的错误字段中。如果false
,则不会强制执行/检测到任何错误。如果encode
或decode
,则仅在传出或传入消息上强制执行/检测到错误。默认为
true
。注意
禁用 arity 检查会影响编码/解码时消息的形式。特别是,解码后的 AVP 表示为值列表,而不管 AVP 的 arity(即,相关消息/AVP 语法中的预期数量)如何,并且值应以列表形式提供以进行编码。这与历史解码行为不同,历史解码行为将 arity 为 1 的 AVP 表示为裸值,而不是包装在列表中。
{string_decode, boolean()}
- 是否解码类型为 OctetString() 及其派生类型 DiameterIdentity()、DiameterURI()、IPFilterRule()、QoSFilterRule() 和 UTF8String() 的 AVP。如果true
,则这些类型的 AVP 被解码为 string()。如果false
,则值保留为 binary()。默认为
true
。警告
此选项应设置为
false
,因为如果不是这样,足够恶意的对等方可能会在解码后的 Diameter 消息在进程之间传递时消耗大量内存。默认值是为了向后兼容。{traffic_counters, boolean()}
- 是否计数特定于应用程序的消息;那些发生diameter_app
回调的消息。如果为 false,则仅计算 diameter 本身处理的消息: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/0
将被忽略。默认为
false
。注意
不使用共享对等方的服务将始终传递空列表作为 pick_peer/4 回调的第二个参数。
警告
通过远程节点上的对等连接发送请求的效率不如通过本地连接发送请求。最好利用 service_opt()
restrict_connections
并在发送请求的每个节点上维护专用连接。transport_opt()
- 除applications
、capabilities
、transport_config
和transport_module
之外的任何传输选项。用作传输配置的默认值,传递给add_transport/2
的值会覆盖在服务上配置的值。
transport_opt()
- 传递给add_transport/2
的选项。具有以下类型之一。{applications, [
application_alias()
]}
- 传输应限制到的 Diameter 应用程序。默认为相关服务上配置的所有应用程序。忽略未在相关服务上配置的应用程序。警告
节点通告的功能必须与其配置的应用程序匹配。特别是,在传输上设置
applications
通常意味着必须在 capabilities() 元组中设置匹配的 *-Application-Id AVP。{avp_dictionaries, [module()]}
- 用于编码/解码相关应用程序字典未定义的 AVP 的备用字典模块列表。在解码时,此类 AVP 在解码消息或分组 AVP 的'AVP'
字段中表示为 diameter_avp 记录,第一个成功解码 AVP 的备用模块设置记录的值字段。在编码时,'AVP'
列表中的值可以作为 AVP 名称/值 2 元组传递,如果没有任何备用模块定义此类元组的 AVP,则会发生编码错误。默认为空列表。
注意
备用字典的动机是 RFC 7683,Diameter 过载指示传输 (DOIC),它定义了要搭载到现有应用程序消息上的 AVP,而不是定义它自己的应用程序。DOIC 字典由 diameter 应用程序提供,作为模块
diameter_gen_doic_rfc7683
,但备用字典可用于编码/解码任何应用程序字典未知的 AVP 集。{capabilities, [
capability()
]}
- 用于构造传出 CER/CEA 消息的 AVP。值优先于在相关服务上指定的任何值。将功能指定为传输选项可能特别适用于带内安全性 ID,以防希望在 TCP 上使用 TLS,如
diameter_tcp
所实现的那样。{capabilities_cb,
eval()
}
- 在功能交换期间接收到 CER/CEA 时调用的回调,以便询问是否应接受连接。应用于连接的transport_ref()
和#diameter_caps{}
记录。返回值可以具有以下类型之一。
ok
- 接受连接。integer/0
- 导致传入的 CER 以指定的 Result-Code 回答。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
表示 Diameter 应用程序正在停止,service
表示相关服务正在被stop_service/1
停止,transport
表示相关传输正在被remove_transport/2
移除。返回值可以具有以下类型之一。
{dpr, [option()]}
- 向对等方发送断开连接请求,在收到断开连接应答或超时后终止传输进程。一个option()
可以是以下之一。{cause, 0|rebooting|1|busy|2|goaway}
- 要发送的断开连接原因,分别为REBOOTING
、BUSY
和DO_NOT_WANT_TO_TALK_TO_YOU
。对于Reason=service|application
,默认为rebooting
,对于Reason=transport
,默认为goaway
。{timeout,
Unsigned32()
}
- 如果未收到 DPA,则传输进程终止的毫秒数。默认为 dpa_timeout 的值。
dpr
- 等效于{dpr, []}
。close
- 终止传输进程,而不会向对等方发送断开连接请求。ignore
- 等效于未配置回调。
可以指定多个 disconnect_cb 选项,在这种情况下,将应用相应的回调,直到其中一个回调返回除
ignore
之外的值。所有返回ignore
的回调等效于未配置它们。默认为返回
dpr
的单个回调。{dpa_timeout,
Unsigned32()
}
- 如果未收到 DPA,则在发出传出的 DPR 后终止传输连接的毫秒数。默认为 1000。
{dpr_timeout,
Unsigned32()
}
- 如果对等方未关闭连接,则在收到传入的 DPR 后终止传输连接的毫秒数。默认为 5000。
{incoming_maxlen, 0..16777215}
- 对传入 Diameter 消息的预期大小的限制。大于指定字节数的消息将被丢弃。默认为
16777215
,即 Diameter 标头中 24 位消息长度字段的最大值。{length_errors, exit|handle|discard}
- 如何处理传入消息中 Diameter 标头的消息长度字段中的错误。此上下文中的错误是指长度不是至少 20 个字节(标头的长度),不是 4 的倍数(有效长度),或者不是通过diameter_transport
中记录的传输接口接收到的相关消息的长度。如果
exit
,则相关传输进程退出。如果handle
,则像往常一样处理消息,生成的 handle_request/3 或 handle_answer/4 回调(如果发生)会指示5015
错误 (DIAMETER_INVALID_MESSAGE_LENGTH)。如果discard
,则会静默丢弃相关消息。默认为
exit
。注意
默认值反映了一个事实,即像 TCP 这样的面向流传输的传输模块可能无法从消息长度错误中恢复,因为这样的传输必须使用消息长度标头将传入的字节流划分为单独的 Diameter 消息。无效长度使其无法可靠地重新发现消息边界,这可能会导致后续消息失败。有关该模块的行为,请参阅
diameter_tcp
。{pool_size, pos_integer()}
- 要启动的传输进程数。对于侦听传输,确定接受传输进程池的大小,对于处理多个并发对等方连接尝试,较大的数字是可取的。对于连接中的传输,确定将尝试建立的与相关对等方的连接数:还应在相关服务上配置 service_opt():restrict_connections
,以允许多个连接到同一对等方。{spawn_opt, [term()] | {M,F,A}}
- 传递给erlang:spawn_opt/2
的选项列表,用于在本地节点上为传入的 Diameter 请求生成处理程序进程,或返回处理程序进程的 pid 的 MFA。在列表值情况下,将忽略选项
monitor
和link
。MFA 应用于附加前置到其参数列表的附加术语,并且应返回调用diameter_traffic:request/1
参数以处理请求的处理程序进程的 pid,或返回原子discard
。处理程序进程不必是本地的,并且不必在远程节点上启动 Diameter,但 Diameter 和相关的应用程序回调必须在代码路径上。默认为空列表。
{strict_capx, boolean()]}
- 是否强制执行 RFC 6733 的要求,即在能力交换之前的任何消息都应关闭对等连接。如果为 false,则会丢弃意外消息。默认为 true。更改此设置会导致非标准行为,但在已知对等方行为不佳的情况下可能很有用。
{strict_mbit, boolean()}
- 当相关命令语法未明确允许 AVP 时,是否将设置 M 位的 AVP 视为错误。如果true
,则此类 AVP 被视为 5001 错误,即 DIAMETER_AVP_UNSUPPORTED。如果false
,则忽略 M 位,并且由接收方负责执行策略。默认为
true
。警告
RFC 6733 对 M 位的语义不明确。一方面,3.2 节中的 CCF 规范将命令语法中的 AVP 记录为表示任何任意 AVP;另一方面,1.3.4 指出,不能将设置 M 位的 AVP 添加到现有命令:必须将修改后的命令放在新的 Diameter 应用程序中。
后者的原因可能是互操作性:允许在命令中设置 M 位的任意 AVP 使其解释依赖于实现,因为不能保证所有实现都会理解给定命令上下文中同一组任意 AVP。但是,将命令语法中的
AVP
解释为任何 AVP,无论 M 位如何,都会使 1.3.4 毫无意义,因为接收方可以简单地忽略它认为不相关的任何 AVP,而不管发送方的意图如何。注意不要将 M 位意义上的强制与命令语法意义上的强制混淆。前者是语义要求:即接收方理解相关上下文中 AVP 的语义。后者是语法要求:AVP 是否必须出现在相关消息中。
{transport_config, term()}
{transport_config, term(),
Unsigned32()
| infinity}
- 作为第三个参数传递给相关 传输模块 的 start/3 函数的术语,以启动传输进程。默认为空列表。3 元组形式另外指定一个时间间隔(以毫秒为单位),在此时间间隔之后,如果启动的传输进程尚未建立连接,则应终止该进程。例如,以下连接传输上的选项请求通过 SCTP 或另一个(通常是同一个)通过 TCP 与一个对等方建立连接。
{transport_module, diameter_sctp} {transport_config, SctpOpts, 5000} {transport_module, diameter_tcp} {transport_config, TcpOpts}
要同时侦听 SCTP 和 TCP,请为每个协议定义一个传输。
{transport_module, atom()}
- 实现diameter_transport
中定义的传输过程的模块。默认为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
返回的,用于标识配置的引用。
另请参阅
摘要
函数
向服务添加传输能力。
发送 Diameter 请求消息。
返回一个可用作传出消息中 Origin-State-Id 的合理值。
删除先前添加的传输。
返回有关已启动服务的信息。请求未知服务的信息会导致返回 undefined
。请求项目列表会导致返回一个带标记的列表。
返回已启动服务的列表。
返回 Session-Id AVP 的值。
启动 diameter 应用程序。
启动 diameter 服务。
停止 diameter 应用程序。
停止 diameter 服务。
订阅来自服务的 service_event()
消息。
取消订阅来自服务的事件消息。
返回按其关联的服务分组的所有连接的列表。
返回与服务 'SvcName' 关联的连接列表。
返回所有传输的列表。
返回与服务 'SvcName' 关联的传输列表。
返回所有看门狗的列表。
返回与服务 'SvcName' 关联的看门狗列表。
类型
-type 'Address'() :: inet:ip_address() | string().
-type app_alias() :: any().
-type app_module() :: module() | maybe_improper_list(module(), list()) | #diameter_callback{peer_up :: term(), peer_down :: term(), pick_peer :: term(), prepare_request :: term(), prepare_retransmit :: term(), handle_request :: term(), handle_answer :: term(), handle_error :: term(), default :: term(), extra :: term()}.
-type application_opt() :: {alias, app_alias()} | {answer_errors, callback | report | discard} | {call_mutates_state, boolean()} | {dictionary, module()} | {module, app_module()} | {request_errors, answer_3xxx | answer | callback} | {state, any()}.
-type call_opt() :: detach | {extra, list()} | {filter, peer_filter()} | {peer, peer_ref()} | {timeout, 'Unsigned32'()}.
-type capability() :: {'Origin-Host', 'DiameterIdentity'()} | {'Origin-Realm', 'DiameterIdentity'()} | {'Host-IP-Address', ['Address'()]} | {'Vendor-Id', 'Unsigned32'()} | {'Product-Name', 'UTF8String'()} | {'Supported-Vendor-Id', ['Unsigned32'()]} | {'Auth-Application-Id', ['Unsigned32'()]} | {'Vendor-Specific-Application-Id', ['Grouped'()]} | {'Firmware-Revision', 'Unsigned32'()}.
-type common_opt() :: {avp_dictionaries, [module()]} | {capabilities_cb, eval()} | {capx_timeout, 'Unsigned32'()} | {connect_timer, 'Unsigned32'()} | {disconnect_cb, eval()} | {dpa_timeout, 'Unsigned32'()} | {dpr_timeout, 'Unsigned32'()} | {incoming_maxlen, message_length()} | {length_errors, exit | handle | discard} | {pool_size, pos_integer()} | {spawn_opt, list() | mfa()} | {strict_capx, boolean()} | {strict_mbit, boolean()} | {watchdog_config, [{okay | suspect, non_neg_integer()}]} | {watchdog_timer, 'Unsigned32'() | {module(), atom(), list()}}.
-type 'DiameterIdentity'() :: 'OctetString'().
-type 'DiameterURI'() :: 'OctetString'().
-type decode_format() :: record | list | map | none | record_from_map.
-type 'Enumerated'() :: 'Integer32'().
-type elapsed_time() :: {Hours :: non_neg_integer(), Mins :: 0..59, Secs :: 0..59, MicroSecs :: 0..999999}.
-type evaluable() :: eval().
-type 'Float32'() :: '-infinity' | float() | infinity.
-type 'Float64'() :: '-infinity' | float() | infinity.
-type 'Integer32'() :: -2147483647..2147483647.
-type 'Integer64'() :: -9223372036854775807..9223372036854775807.
-type 'IPFilterRule'() :: 'OctetString'().
-type message_length() :: 0..16777215.
-type 'OctetString'() :: iolist().
-type peer_filter() :: none | host | realm | {host, any | 'DiameterIdentity'()} | {realm, any | 'DiameterIdentity'()} | {eval, eval()} | {neg, peer_filter()} | {first, [peer_filter()]} | {all, [peer_filter()]} | {any, [peer_filter()]}.
-opaque peer_ref()
-type 'QoSFilterRule'() :: 'OctetString'().
-type sequence() :: {'Unsigned32'(), 0..32}.
-type service_name() :: any().
-type service_opt() :: capability() | {application, [application_opt()]} | {decode_format, decode_format()} | {restrict_connections, restriction()} | {sequence, sequence() | eval()} | {share_peers, remotes()} | {strict_arities, true | strict_arities()} | {string_decode, boolean()} | {traffic_counters, boolean()} | {use_shared_peers, remotes()} | {bins_info, boolean() | non_neg_integer()} | common_opt().
-type strict_arities() :: false | encode | decode.
-type 'Time'() :: {{integer(), 1..12, 1..31}, {0..23, 0..59, 0..59}}.
-type transport_opt() :: {applications, [app_alias()]} | {capabilities, [capability()]} | {transport_config, any()} | {transport_config, any(), 'Unsigned32'() | infinity} | {transport_module, atom()} | common_opt() | {private, any()}.
-type transport_pred() :: fun((transport_ref(), connect | listen, list()) -> boolean()) | fun((transport_ref(), list()) -> boolean()) | fun((list()) -> boolean()) | transport_ref() | boolean() | list() | {connect | listen, transport_pred()} | {atom(), atom(), list()}.
-type transport_ref() :: reference().
-type 'Unsigned32'() :: 0..4294967295.
-type 'Unsigned64'() :: 0..18446744073709551615.
-type 'UTF8String'() :: iolist().
函数
-spec add_transport(SvcName, Transport) -> {ok, TRef} | {error, Reason} when SvcName :: service_name(), Transport :: {T, Opts}, T :: listen | connect, Opts :: [transport_opt()], TRef :: transport_ref(), Reason :: term().
向服务添加传输能力。
该服务将根据需要启动传输进程,以便与对等方建立连接,或者通过连接到对等方(connect
)或者通过接受传入的连接请求(listen
)。连接传输最多与一个对等方建立传输连接,而监听传输可能与多个对等方建立连接。
Diameter 应用程序负责与对等方交换 CER/CEA。成功完成能力交换后,该服务会调用每个相关应用程序模块的 peer_up/3 回调,之后调用者可以通过传输与对等方交换 Diameter 消息。除了 CER/CEA 之外,该服务还负责处理 RFC 3539 所需的 DWR/DWA 以及 DPR/DPA。
返回的引用在服务范围内唯一标识传输。请注意,该函数在建立传输连接之前返回。
注意
将传输添加到尚未配置的服务并非错误:可以在配置其传输后启动服务。
-spec call(SvcName, App, Request, CallOpts) -> Result when SvcName :: service_name(), App :: app_alias(), Request :: diameter_codec:message() | diameter_codec:packet(), CallOpts :: [call_opt()], Result :: ok | {error, Reason} | Answer, Answer :: term(), Reason :: term().
发送 Diameter 请求消息。
App
指定定义请求的 Diameter 应用程序,并且对相应的回调模块的回调将按照如下所述以及在 diameter_app
中进行。除非指定 detach
选项,否则该调用会在从对等方收到应答消息或发生错误时返回。在应答的情况下,返回值由 handle_answer/4 回调返回。在错误的情况下,错误是由 diameter 直接返回还是由 handle_error/4 回调返回,取决于传出请求是否成功编码以传输到对等方,以下将记录这两种情况。
如果没有合适的对等方,或者如果 pick_peer/4 通过返回 false
拒绝它们,则返回 {error,no_connection}
。否则,在 pick_peer/4 之后是 prepare_request/3 回调,对消息进行编码,然后发送。
有几种错误情况可能会阻止接收应答并将其传递给 handle_answer/4 回调
- 如果传出请求的初始编码失败,则请求进程失败,并返回
{error,encode}
。 - 如果请求已成功编码并发送,但应答超时,则会使用
Reason = timeout
进行 handle_error/4 回调。 - 如果请求已成功编码并发送,但在收到应答之前相关服务已停止,则会使用
Reason = cancel
进行 handle_error/4 回调。 - 如果与对等方的传输连接在发送请求后但在收到应答之前断开,则会尝试将请求重新发送到备用对等方。如果没有这样的对等方可用,或者如果后续 pick_peer/4 回调拒绝候选者,则会使用
Reason = failover
进行 handle_error/4 回调。如果选择了对等方,则会进行 prepare_retransmit/3 回调,之后,其语义与初始 prepare_request/3 回调相同。 - 如果在重传期间发生编码错误,则请求进程失败,并返回
{error,failure}
。 - 如果在处理请求时进行应用程序回调失败(pick_peer、prepare_request、prepare_retransmit、handle_answer 或 handle_error),则会返回
{error,encode}
或{error,failure}
,具体取决于是否尝试通过传输发送请求。
请注意,{error,encode}
是唯一保证请求未通过传输连接发送的返回值。
-spec origin_state_id() -> 'Unsigned32'().
返回一个可用作传出消息中 Origin-State-Id 的合理值。
返回值是自 19680120T031408Z 以来(这是可以编码为 Diameter Time()
的第一个值)的秒数,时间是启动 diameter 应用程序时的时间。
-spec remove_transport(SvcName, Pred) -> ok | {error, Reason} when SvcName :: service_name(), Pred :: transport_pred(), Reason :: term().
删除先前添加的传输。
Pred
确定要删除哪些传输。arity-3 值的 Pred
将删除所有 Pred(Ref, Type, Opts)
返回 true
的传输,其中 Type
和 Opts
与传递给 add_transport/2
的相同,Ref
与其返回的相同。其余形式等效于 arity-3 fun,如下所示。
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 的值控制。
-spec service_info(SvcName, Item | [Item]) -> term() when SvcName :: service_name(), Item :: atom() | peer_ref().
返回有关已启动服务的信息。请求未知服务的信息会导致返回 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>,-576460736368485571,okay}}, {peer,{<0.67.0>,-576460736357885808}}, {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
是传递给add_transport/2
的相应的transport_opt()
列表。watchdog
条目显示连接的 RFC 3539 看门狗状态机的状态。peer
条目标识diameter_app:peer_ref()
,对于该条目,将为apps
条目标识的 Diameter 应用程序提供 peer_up/3 回调,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>,-576460739249514012,okay}}, {peer,{<0.58.0>,-576460638229179167}}, {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>,-576460638229717546,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>,-576460739249514012,okay}}, {peer,{<0.58.0>,-576460638229179167}}, {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}]}]]
请注意,与
transport
信息相比,可能存在多个具有相同ref
的条目。statistics
- 返回一个{{Counter, Ref}, non_neg_integer()}
计数器值列表。Ref
可以是transport_ref()
或diameter_app:peer_ref()
。后者的条目在对等连接断开时折叠到前者的相应条目中。两者的条目都在remove_transport/2
时被删除。transport
和connections
信息返回的 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}]}]}]
-spec services() -> [SvcName] when SvcName :: service_name().
返回已启动服务的列表。
-spec session_id(Ident) -> SessionId when Ident :: 'DiameterIdentity'(), SessionId :: 'OctetString'().
返回 Session-Id AVP 的值。
该值具有 RFC 6733 第 8.8 节要求的格式。Ident 应该是将发送包含返回值的消息的对等方的 Origin-Host。
-spec start() -> ok | {error, Reason} when Reason :: term().
启动 diameter 应用程序。
必须先启动 Diameter 应用程序,然后再启动服务。在生产系统中,这通常通过引导文件完成,而不是显式调用 start/0
。
-spec start_service(SvcName, Opts) -> ok | {error, Reason} when SvcName :: service_name(), Opts :: [service_opt()], Reason :: term().
启动 diameter 服务。
服务定义一个本地实现的 Diameter 节点,指定在能力交换期间要通告的能力。使用 add_transport/2
将传输添加到服务。
注意
传输可以同时覆盖其服务的功能并限制其支持的 Diameter 应用程序,因此“服务 = 由 Origin-Host 标识的 Diameter 节点”不一定成立。
-spec stop() -> ok | {error, Reason} when Reason :: term().
停止 diameter 应用程序。
-spec stop_service(SvcName) -> ok | {error, Reason} when SvcName :: service_name(), Reason :: term().
停止 diameter 服务。
停止服务会导致所有关联的传输连接断开。将发送 DPR 消息,如 remove_transport/2
的情况一样。
注意
停止服务不会删除任何关联的传输:必须调用
remove_transport/2
来删除传输配置。
-spec subscribe(SvcName) -> true when SvcName :: service_name().
订阅来自服务的 service_event()
消息。
订阅尚不存在的服务的事件不是错误。在添加传输之前执行此操作是保证接收所有传输相关事件所必需的。
-spec unsubscribe(SvcName) -> true when SvcName :: service_name().
取消订阅来自服务的事件消息。
-spec which_connections() -> [{SvcName, [#{peer := PeerInfo, wd := WDInfo, peername := {inet:ip_address(), inet:port_number()}, sockname := {inet:ip_address(), inet:port_number()}}]}] when SvcName :: string(), PeerInfo :: #{pid := pid(), uptime := elapsed_time()}, WDInfo :: #{ref := reference(), type := atom(), pid := pid(), state := diameter_service:wd_state(), uptime := elapsed_time()}.
返回按其关联的服务分组的所有连接的列表。
-spec which_connections(SvcName) -> [#{peer := PeerInfo, wd := WDInfo, peername := {inet:ip_address(), inet:port_number()}, sockname := {inet:ip_address(), inet:port_number()}}] when SvcName :: string(), PeerInfo :: #{pid := pid(), uptime := elapsed_time()}, WDInfo :: #{ref := reference(), type := atom(), pid := pid(), state := diameter_service:wd_state(), uptime := elapsed_time()}.
返回与服务 'SvcName' 关联的连接列表。
返回所有传输的列表。
-spec which_transports(SvcName) -> [#{ref := reference(), type := atom()}] when SvcName :: string().
返回与服务 'SvcName' 关联的传输列表。
-spec which_watchdogs() -> [#{ref := reference(), type := atom(), pid := pid(), state := diameter_service:wd_state(), peer := boolean() | pid(), uptime := elapsed_time(), service := SvcName}] when SvcName :: string().
返回所有看门狗的列表。
-spec which_watchdogs(SvcName) -> [#{ref := reference(), type := atom(), pid := pid(), state := diameter_service:wd_state(), peer := boolean() | pid(), uptime := elapsed_time()}] when SvcName :: string().
返回与服务 'SvcName' 关联的看门狗列表。