查看源代码 diameter_app 行为 (diameter v2.4.1)

Diameter 应用程序的回调模块。

diameter:start_service/2 启动的 Diameter 服务配置一个或多个 Diameter 应用程序,每个应用程序的配置指定一个回调来处理特定于该应用程序的消息。应用程序的消息和 AVP 定义在字典文件中,该文件的格式在 diameter_dict(4) 中进行了说明,而回调模块在此处进行了说明。回调模块实现了服务的 Diameter 应用程序特定功能。

回调模块必须导出下面文档中的所有函数。这些函数本身具有三种不同的类型

此处回调函数的参数数量假设没有额外的参数。所有函数还将传递在调用 diameter:start_service/2 配置回调模块本身时配置的任何额外参数,以及对于特定于调用的回调,传递给 diameter:call/4 的任何额外参数。

概要

类型

一个记录,包含本地 Diameter 节点和具有已建立传输连接的远程 Diameter 对等端的身份,以及由能力交换确定的能力。记录的每个字段都是一个二元组,由(本地)主机和(远程)对等端的值组成。可选或可能有多个值编码为值列表,强制值编码为裸值。

Diameter 消息的表示形式,传递给 diameter:call/4 或从 handle_request/3 回调返回。

传入和传出 Diameter 消息的容器,通过编码/解码和传输传递。除非另有说明,否则不应在返回值中设置字段。

表示 Diameter 对等连接的元组。

标识与 Diameter 对等端的传输连接的术语。

应用程序回调函数 peer_up/3peer_down/3 和(可选)pick_peer/4 维护的状态。初始状态在调用 diameter:start_service/2 时配置,该调用在服务上配置应用程序。返回状态的回调函数在通用的特定于服务的进程中评估,而那些不返回状态的回调函数在特定于请求的进程中评估。

回调

当从对等端收到应答消息时调用。返回值从 diameter:call/4 返回,除非指定了 detach 选项。

当在收到对传出请求的应答消息之前发生错误时调用。返回值从 diameter:call/4 返回,除非指定了 detach 选项。

当从对等端收到请求消息时调用。回调发生的应用程序(即,通过 diameter:start_service/2 配置的回调模块)由传入请求消息的标头中的应用程序标识符确定,选择的模块是声明自己定义了相关应用程序或中继应用程序的模块。

在先前调用 peer_up/3 之后,调用以指示本地 Erlang 节点上的对等连接不再可用。特别是,连接的 RFC 3539 监视状态机已离开 OKAY 状态,并且对等端将不再是 pick_peer/4 回调中的候选者。

调用以指示本地 Erlang 节点上对等连接的可用性。特别是,与对等端的能力交换已指示支持相关应用程序,连接的 RFC 3539 监视状态机已达到 OKAY 状态,并且可以发送和接收 Diameter 消息。

由于调用 diameter:call/4 而调用,以选择传出请求的目标对等端。返回值指示选择的对等端。

调用以返回用于编码和传输的请求。允许发送者使用所选对等端的能力来修改传出的请求。许多实现可能只想简单地返回 {send, Packet}

调用以返回用于编码和重新传输的请求。在对等连接丢失并选择了备用对等端的情况下,具有与 prepare_request/3 相同的作用,但是参数 packet() 是由初始 prepare_request/3 返回的。

类型

链接到此类型

capabilities()

查看源代码 (未导出) (自 OTP R14B03 起)
-type capabilities() ::
          #diameter_caps{origin_host :: term(),
                         origin_realm :: term(),
                         host_ip_address :: term(),
                         vendor_id :: term(),
                         product_name :: term(),
                         origin_state_id :: term(),
                         supported_vendor_id :: term(),
                         auth_application_id :: term(),
                         inband_security_id :: term(),
                         acct_application_id :: term(),
                         vendor_specific_application_id :: term(),
                         firmware_revision :: term(),
                         avp :: term()}.

一个记录,包含本地 Diameter 节点和具有已建立传输连接的远程 Diameter 对等端的身份,以及由能力交换确定的能力。记录的每个字段都是一个二元组,由(本地)主机和(远程)对等端的值组成。可选或可能有多个值编码为值列表,强制值编码为裸值。

链接到此类型

message()

查看源代码 (未导出) (自 OTP R14B03 起)
-type message() :: diameter_codec:message().

Diameter 消息的表示形式,传递给 diameter:call/4 或从 handle_request/3 回调返回。

链接到此类型

packet()

查看源代码 (未导出) (自 OTP R14B03 起)
-type packet() :: diameter_codec:packet().

传入和传出 Diameter 消息的容器,通过编码/解码和传输传递。除非另有说明,否则不应在返回值中设置字段。

链接到此类型

peer()

查看源代码 (未导出) (自 OTP R14B03 起)
-type peer() :: {peer_ref(), capabilities()}.

表示 Diameter 对等连接的元组。

链接到此类型

peer_ref()

查看源代码 (未导出) (自 OTP R14B03 起)
-type peer_ref() :: term().

标识与 Diameter 对等端的传输连接的术语。

链接到此类型

state()

查看源代码 (未导出) (自 OTP R14B03 起)
-type state() :: term().

应用程序回调函数 peer_up/3peer_down/3 和(可选)pick_peer/4 维护的状态。初始状态在调用 diameter:start_service/2 时配置,该调用在服务上配置应用程序。返回状态的回调函数在通用的特定于服务的进程中评估,而那些不返回状态的回调函数在特定于请求的进程中评估。

回调

链接到此回调

handle_answer(Packet, Request, SvcName, Peer)

查看源代码 (自 OTP R14B03 起)
-callback handle_answer(Packet, Request, SvcName, Peer) -> Result
                           when
                               Packet :: packet(),
                               Request :: message(),
                               SvcName :: diameter:service_name(),
                               Peer :: peer(),
                               Result :: term().

当从对等端收到应答消息时调用。返回值从 diameter:call/4 返回,除非指定了 detach 选项。

解码后的应答记录和未解码的二进制文件分别位于参数 packet()msgbin 字段中。Request 是从 prepare_request/3prepare_retransmit/3 返回的传出请求消息。

对于对 diameter:call/4 的任何给定调用,最多有一个 handle_answer/4 回调:任何重复的应答(由于重新传输或其他原因)都会被丢弃。同样,只会调用 handle_answer/4handle_error/4 中的一个。

默认情况下,无法成功解码的传入应答消息会导致请求进程失败,从而导致 diameter:call/4 返回 {error, failure},除非指定了 detach 选项。特别是,在这种情况下没有 handle_error/4 回调。可以设置 diameter:application_opt() answer_errors 以更改此行为。

链接到此回调

handle_error(Reason, Request, SvcName, Peer)

查看源代码 (自 OTP R14B03 起)
-callback handle_error(Reason, Request, SvcName, Peer) -> Result
                          when
                              Reason :: timeout | failover | term(),
                              Request :: message(),
                              SvcName :: diameter:service_name(),
                              Peer :: peer(),
                              Result :: term().

当在收到对传出请求的应答消息之前发生错误时调用。返回值从 diameter:call/4 返回,除非指定了 detach 选项。

Reason timeout 表示在相应的 diameter:call_opt() 中指定的时间内未收到应答消息。Reason failover 表示已发送请求的对等端的传输连接变得不可用,并且未选择备用对等端。

链接到此回调

handle_request(Packet, SvcName, Peer)

查看源代码 (自 OTP R14B03 起)
-callback handle_request(Packet, SvcName, Peer) -> Action
                            when
                                Packet :: packet(),
                                SvcName :: term(),
                                Peer :: peer(),
                                Action ::
                                    Reply | {relay, [Opt]} | discard | {eval | eval_packet, Action, PostF},
                                Reply ::
                                    {reply, packet() | message()} |
                                    {answer_message, 3000..3999 | 5000..5999} |
                                    {protocol_error, 3000..3999},
                                Opt :: diameter:call_opt(),
                                PostF :: diameter:eval().

当从对等端收到请求消息时调用。回调发生的应用程序(即,通过 diameter:start_service/2 配置的回调模块)由传入请求消息的标头中的应用程序标识符确定,选择的模块是声明自己定义了相关应用程序或中继应用程序的模块。

参数 packet() 具有以下签名。

#diameter_packet{header = #diameter_header{},
                 avps   = [#diameter_avp{}],
                 msg    = record() | undefined,
                 errors = [Unsigned32() | {Unsigned32(), #diameter_avp{}}],
                 bin    = binary(),
                 transport_data = term()}

如果请求已在中继应用程序中接收,则 msg 字段将为 undefined。否则,它包含表示请求的记录,如 diameter_dict(4) 中所述。

errors 字段指定在解码请求时发现的任何错误代码。这用于在返回的应答中设置 Result-Code 和/或 Failed-AVP,除非回调返回一个 #diameter_packet{},其 errors 字段设置为自己的非空列表,在这种情况下,将使用此列表,或者使用原子 false 来禁用 Result-Code 和 Failed-AVP 的任何设置。请注意,diameter 检测到的错误属于 3xxx 和 5xxx 系列,分别是协议错误和永久性故障。errors 列表为空,如果请求已在中继应用程序中接收。

transport_data 字段包含一个任意项,该项从相关的传输模块传递到 Diameter,或者如果传输模块没有指定数据,则为原子 undefined。如果返回 message(),则该项会被保留,但必须在返回的 packet() 中显式设置。

每个可能的返回值的语义如下。

  • {reply,packet()|message()} - 将指定的应答消息发送给对等方。对于 packet(),要发送的消息必须设置在 msg 字段中,并且可以将 header 字段设置为 #diameter_header{} 以指定应该在传出的应答中保留的值,否则由 Diameter 设置适当的值。

  • {answer_message, 3000..3999|5000..5999} - 向对等方发送包含指定 Result-Code 的应答消息。等效于

    {reply, ['answer-message' | Avps]

    其中 Avps 设置 Origin-Host、Origin-Realm、指定的 Result-Code 以及(如果请求包含)Session-Id AVP,并且可能包含如下所述的 Failed-AVP。

    返回 3xxx 或 5xxx 以外的值将导致相关的请求进程失败,如果对等连接配置了 RFC 3588 通用字典 diameter_gen_base_rfc3588,则返回 5xxx 值也会导致失败。(因为 RFC 3588 只允许在应答消息中使用 3xxx 值。)

    当返回 5xxx 时,如果找到,则 Failed-AVP 将使用参数 packet()errors 字段中第一个匹配的 Result-Code/AVP 对的 AVP 进行填充。如果这不合适,则应显式构造应答消息,并在 reply 元组中返回。

  • {relay, Opts} - 将请求中继到另一个对等方,充当 Diameter 中继代理。如果检测到路由循环,则使用 3005 (DIAMETER_LOOP_DETECTED) 回答请求。否则,将 Route-Record AVP(包含发送对等方的 Origin-Host)添加到请求中,并且 pick_peer/4 和后续回调的发生方式与显式调用 diameter:call/4 时相同。传入请求的端到端标识符保留在中继请求的标头中。

    返回的 Opts 不应指定 detach。中继请求的后续 handle_answer/4 回调必须返回其第一个参数,即包含应答消息的 packet()。请注意,可以指定 extra 选项以提供参数,以便在需要时将中继情况与其他情况区分开来。任何其他返回值(例如,来自 handle_error/4 回调的值)都会导致使用 3002 (DIAMETER_UNABLE_TO_DELIVER) 回答请求。

  • discard - 丢弃请求。不向对等方发送应答消息。

  • {eval, Action, PostF} - 处理请求,如同已返回 Action,然后在请求进程中评估 PostF。返回值被忽略。

  • {eval_packet, Action, PostF} - 与 eval 类似,但在传输之前,在任何编码的 #diameter_packet{} 上评估 PostF,其中 bin 字段包含编码的二进制数据。返回值被忽略。

  • {protocol_error, 3000..3999} - 等效于 {answer_message, 3000..3999}

注意

包含错误的请求可能由 Diameter 回答,而无需执行回调,具体取决于 diameter:application_opt() request_errors 的值。

链接到此回调

peer_down(SvcName, Peer, State)

View Source (自 OTP R14B03 起)
-callback peer_down(SvcName, Peer, State) -> NewState
                       when
                           SvcName :: diameter:service_name(),
                           Peer :: peer(),
                           State :: state(),
                           NewState :: state().

在先前调用 peer_up/3 之后,调用以指示本地 Erlang 节点上的对等连接不再可用。特别是,连接的 RFC 3539 监视状态机已离开 OKAY 状态,并且对等端将不再是 pick_peer/4 回调中的候选者。

链接到此回调

peer_up(SvcName, Peer, State)

View Source (自 OTP R14B03 起)
-callback peer_up(SvcName, Peer, State) -> NewState
                     when
                         SvcName :: diameter:service_name(),
                         Peer :: peer(),
                         State :: state(),
                         NewState :: state().

调用以指示本地 Erlang 节点上对等连接的可用性。特别是,与对等端的能力交换已指示支持相关应用程序,连接的 RFC 3539 监视状态机已达到 OKAY 状态,并且可以发送和接收 Diameter 消息。

注意

看门狗状态机可以在不进行新的能力交换的情况下,从状态 SUSPECT 到达状态 OKAY。新的传输连接(和能力交换)会产生新的 peer_ref()。

注意

不要求回调在收到传入请求之前返回:handle_request/3 回调必须独立于 peer_up/3peer_down/3 进行处理。

链接到此回调

pick_peer(LocalCandidates, RemoteCandidates, SvcName, State)

View Source (自 OTP R14B03 起)
-callback pick_peer(LocalCandidates, RemoteCandidates, SvcName, State) -> Selection | false
                       when
                           LocalCandidates :: [peer()],
                           RemoteCandidates :: [peer()],
                           SvcName :: diameter:service_name(),
                           State :: state(),
                           NewState :: state(),
                           Selection :: {ok, Peer} | {Peer, NewState},
                           Peer :: peer() | false.

由于调用 diameter:call/4 而调用,以选择传出请求的目标对等端。返回值指示选择的对等端。

候选列表仅包含在能力交换期间声明支持相关 Diameter 应用程序、未被调用 diameter:call/4filter 选项排除,并且其看门狗状态机处于 OKAY 状态的对等方。元素的顺序未指定,但任何其 Origin-Host 和 Origin-Realm 与传出请求匹配的对等方(在 diameter:call/4{filter, {all, [host, realm]}} 选项的意义上)将放置在列表的开头。LocalCandidates 包含其传输进程位于本地 Erlang 节点上的对等方,而 RemoteCandidates 包含由具有相同名称的服务从其他节点传递的对等方。

返回 peer() 的回调将之后是 prepare_request/3 回调,并且如果后者指示应发送请求,则取决于是否从对等方收到应答消息,之后是 handle_answer/4handle_error/4。如果在 prepare_request/3 之后传输变得不可用,则可能会发生新的 pick_peer/4 回调以故障转移到备用对等方,之后 prepare_retransmit/3 将取代 prepare_request/3 来重新发送请求。无法保证选择备用对等方的 pick_peer/4 回调之后会进行任何其他回调,因为如果从先前选择的对等方收到应答,则会放弃向备用对等方重新传输。

返回值 false{false, State}(即 NewState = State)是等效的,{ok, Peer}{Peer, State} 也是等效的。

注意

diameter:service_opt() use_shared_peers 确定服务是否使用从其他节点共享的对等方。如果不是,则 RemoteCandidates 为空列表。

警告

仅当相关 Diameter 应用程序配置了 diameter:application_opt() {call_mutates_state, true} 时,才允许返回值 {Peer, NewState}。否则,State 参数始终是在应用程序上配置的初始值,而不是 peer_up/3peer_down/3 回调返回的任何后续值。

链接到此回调

prepare_request(Packet, SvcName, Peer)

View Source (自 OTP R14B03 起)
-callback prepare_request(Packet, SvcName, Peer) -> Action
                             when
                                 Packet :: packet(),
                                 SvcName :: diameter:service_name(),
                                 Peer :: peer(),
                                 Action :: Send | Discard | {eval_packet, Action, PostF},
                                 Send :: {send, packet() | message()},
                                 Discard :: {discard, Reason :: term()} | discard,
                                 PostF :: diameter:eval().

调用以返回用于编码和传输的请求。允许发送者使用所选对等端的能力来修改传出的请求。许多实现可能只想简单地返回 {send, Packet}

返回的 packet() 应将要编码的请求设置在其 msg 字段中,并且可以设置 transport_data 字段以将信息传递给传输进程。传递给 diameter:call/4 的额外参数可用于将传输(或任何其他)数据传递给回调。

返回的 packet() 可以将 header 字段设置为 #diameter_header{} 以指定应在传出请求中保留的值,否则这些值将是 Packet 中包含的标头记录中的值。返回的 lengthcmd_codeapplication_id 将被忽略。

返回的 PostF 将在传输之前,在任何编码的 #diameter_packet{} 上进行评估,其中 bin 字段包含编码的二进制数据。返回值被忽略。

返回 {discard, Reason} 会导致请求中止,并且调用该回调的 diameter:call/4 会返回 {error, Reason}。返回 discard 等效于返回 {discard, discarded}

链接到此回调

prepare_retransmit(Packet, SvcName, Peer)

View Source (自 OTP R14B03 起)
-callback prepare_retransmit(Packet, SvcName, Peer) -> Action
                                when
                                    Packet :: packet(),
                                    SvcName :: diameter:service_name(),
                                    Peer :: peer(),
                                    Action :: Send | Discard | {eval_packet, Action, PostF},
                                    Send :: {send, packet() | message()},
                                    Discard :: {discard, Reason :: term()} | discard,
                                    PostF :: diameter:eval().

调用以返回用于编码和重新传输的请求。在对等连接丢失并选择了备用对等端的情况下,具有与 prepare_request/3 相同的作用,但是参数 packet() 是由初始 prepare_request/3 返回的。

返回 {discard, Reason} 会导致请求中止,并使用 Reason 作为初始参数执行 handle_error/4 回调。返回 discard 等效于返回 {discard, discarded}