From 2e87fc716360c3bdbfa2e5122fca37e1bc47ab53 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Thu, 15 Nov 2012 16:45:55 +0100 Subject: Minor doc fixes Presentation (order, cross-references), not content. --- lib/diameter/doc/src/diameter.xml | 180 +++++++++++++++++---------------- lib/diameter/doc/src/diameter_sctp.xml | 3 +- 2 files changed, 97 insertions(+), 86 deletions(-) diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml index b40161045d..64c983d4a6 100644 --- a/lib/diameter/doc/src/diameter.xml +++ b/lib/diameter/doc/src/diameter.xml @@ -693,7 +693,8 @@ well as the following.

Defines a Diameter application supported by the service.

-A service must configure one application for each Diameter +A service must configure one application for each Diameter application it intends to support. For an outgoing Diameter request, the relevant application_alias() is @@ -708,7 +709,7 @@ file.

| node | nodes | [node()] - | diameter:evaluable()} + | evaluable()}

Specifies the degree to which multiple transport connections to the @@ -718,10 +719,10 @@ same peer are accepted by the service.

If type [node()] then a connection is rejected if another already exists on any of the specified nodes. Values of type false, node, nodes or -diameter:evaluable() are equivalent to values [], -[node()], [node()|nodes()] and the evaluated value, -respectively, evaluation of each expression taking place whenever a -new connection is to be established. +evaluable() are equivalent to +values [], [node()], [node()|nodes()] and the +evaluated value, respectively, evaluation of each expression taking +place whenever a new connection is to be established. Note that false allows an unlimited number of connections to be established with the same peer.

@@ -734,14 +735,14 @@ Defaults to nodes.

{sequence, {H,N} | diameter:evaluable()} + marker="#evaluable">evaluable()}

Specifies a constant value H for the topmost 32-N bits of of 32-bit End-to-End and Hop-by-Hop identifiers generated by the service, either explicity or as a return value of a function to be evaluated at diameter:start_service/2. +marker="#start_service">start_service/2. In particular, an identifier Id is mapped to a new identifier as follows.

@@ -775,53 +776,6 @@ marker="#add_transport">add_transport/2. Has one of the following types.

-{transport_module, atom()} - -

-A module implementing a transport process as defined in diameter_transport(3). -Defaults to diameter_tcp if unspecified.

- -

-Multiple transport_module and transport_config -options are allowed. -The order of these is significant in this case (and only in this case), -a transport_module being paired with the first -transport_config following it in the options list, or the -default value for trailing modules. -Transport starts will be attempted with each of the -modules in order until one establishes a connection within the -corresponding timeout (see below) or all fail.

-
- -{transport_config, term()} -{transport_config, term(), Unsigned32()} - -

-A term passed as the third argument to the start/3 function of -the relevant transport_module in order to start a transport process. -Defaults to the empty list if unspecified.

- -

-The 3-tuple form additionally specifies an interval, in milliseconds, -after which a started transport process should be terminated if it has -not yet established a connection. -For example, the following options on a connecting transport -request a connection with one peer over SCTP or another -(typically the same) over TCP.

- - -{transport_module, diameter_sctp} -{transport_config, SctpOpts, 5000} -{transport_module, diameter_tcp} -{transport_config, TcpOpts} - - -

-To listen on both SCTP and TCP, define one transport for each.

-
- {applications, [application_alias()]} @@ -890,7 +844,8 @@ Equivalent to returning 3010, DIAMETER_UNKNOWN_PEER.

Returning anything but ok or a 2xxx series result code causes the transport connection to be broken. -Multiple capabilities_cb options can be specified, in which +Multiple capabilities_cb +options can be specified, in which case the corresponding callbacks are applied until either all return ok or one does not.

@@ -908,9 +863,9 @@ Applied to Reason=transport|service|application and the in question, Reason indicating whether the the diameter application is being stopped, the service in question is being stopped at diameter:stop_service/1 or +marker="#stop_service">stop_service/1 or the transport in question is being removed at diameter:remove_transport/2, +marker="#remove_transport">remove_transport/2, respectively.

@@ -966,7 +921,8 @@ Equivalent to not having configured the callback.

-Multiple disconnect_cb options can be specified, in which +Multiple disconnect_cb +options can be specified, in which case the corresponding callbacks are applied until one of them returns a value other than ignore. All callbacks returning ignore is equivalent to not having @@ -976,28 +932,6 @@ configured them.

Defaults to a single callback returning dpr.

- -{watchdog_timer, TwInit} - - -TwInit = Unsigned32() - | {M,F,A} - - -

-The RFC 3539 watchdog timer. -An integer value is interpreted as the RFC's TwInit in milliseconds, -a jitter of ± 2 seconds being added at each rearming of the -timer to compute the RFC's Tw. -An MFA is expected to return the RFC's Tw directly, with jitter -applied, allowing the jitter calculation to be performed by -the callback.

- -

-An integer value must be at least 6000 as required by RFC 3539. -Defaults to 30000 if unspecified.

-
- {reconnect_timer, Tc} @@ -1010,8 +944,9 @@ For a connecting transport, the RFC 3588 Tc timer, in milliseconds. Note that this timer determines the frequency with which a transport will attempt to establish a connection with its peer only before an initial connection is established: once there is an initial -connection it's watchdog_timer that determines the frequency of -reconnection attempts, as required by RFC 3539.

+connection it's watchdog_timer that determines the +frequency of reconnection attempts, as required by RFC 3539.

For a listening transport, the timer specifies the time after which a @@ -1019,14 +954,89 @@ previously connected peer will be forgotten: a connection after this time is regarded as an initial connection rather than a reestablishment, causing the RFC 3539 state machine to pass to state OKAY rather than REOPEN. -Note that these semantics are not goverened by the RFC and -that a listening transport's reconnect_timer should be greater +Note that these semantics are not governed by the RFC and +that a listening transport's reconnect_timer should be greater than its peer's Tw plus jitter.

Defaults to 30000 for a connecting transport and 60000 for a listening transport.

+
+ +{transport_config, term()} +{transport_config, term(), Unsigned32()} + +

+A term passed as the third argument to the start/3 function of +the relevant transport_module in order to +start a transport process. +Defaults to the empty list if unspecified.

+ +

+The 3-tuple form additionally specifies an interval, in milliseconds, +after which a started transport process should be terminated if it has +not yet established a connection. +For example, the following options on a connecting transport +request a connection with one peer over SCTP or another +(typically the same) over TCP.

+ + +{transport_module, diameter_sctp} +{transport_config, SctpOpts, 5000} +{transport_module, diameter_tcp} +{transport_config, TcpOpts} + + +

+To listen on both SCTP and TCP, define one transport for each.

+
+ + +{transport_module, atom()} + +

+A module implementing a transport process as defined in diameter_transport(3). +Defaults to diameter_tcp if unspecified.

+ +

+Multiple transport_module and transport_config +options are allowed. +The order of these is significant in this case (and only in this case), +a transport_module being paired with the first +transport_config +following it in the options list, or the default value for trailing +modules. +Transport starts will be attempted with each of the +modules in order until one establishes a connection within the +corresponding timeout (see below) or all fail.

+
+ + +{watchdog_timer, TwInit} + + +TwInit = Unsigned32() + | {M,F,A} + + +

+The RFC 3539 watchdog timer. +An integer value is interpreted as the RFC's TwInit in milliseconds, +a jitter of ± 2 seconds being added at each rearming of the +timer to compute the RFC's Tw. +An MFA is expected to return the RFC's Tw directly, with jitter +applied, allowing the jitter calculation to be performed by +the callback.

+ +

+An integer value must be at least 6000 as required by RFC 3539. +Defaults to 30000 if unspecified.

diff --git a/lib/diameter/doc/src/diameter_sctp.xml b/lib/diameter/doc/src/diameter_sctp.xml index 955169349c..709b17c0d2 100644 --- a/lib/diameter/doc/src/diameter_sctp.xml +++ b/lib/diameter/doc/src/diameter_sctp.xml @@ -38,7 +38,8 @@ under the License.

-This module implements diameter transport over SCTP using gen_sctp. +This module implements diameter transport over SCTP using gen_sctp. It can be specified as the value of a transport_module option to diameter:add_transport/2 -- cgit v1.2.3 From 3b1b9e110e9db2ee0fcfad2b5d558c4d6a82700d Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Thu, 15 Nov 2012 16:52:16 +0100 Subject: Document transport_opt() capx_timeout --- lib/diameter/doc/src/diameter.xml | 62 ++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/diameter/doc/src/diameter.xml b/lib/diameter/doc/src/diameter.xml index 64c983d4a6..f545b2c9ad 100644 --- a/lib/diameter/doc/src/diameter.xml +++ b/lib/diameter/doc/src/diameter.xml @@ -606,6 +606,14 @@ indicated result code. Pkt contains the CER in question.

+{'CER', timeout} + +

+An expected CER was not received within capx_timeout of +connection establishment.

+
+ {'CEA', Result, Caps, Pkt} @@ -639,6 +647,14 @@ An incoming CEA contained errors and has been rejected. Pkt contains the CEA in question.

+{'CEA', timeout} + +

+An expected CEA was not received within capx_timeout +of connection establishment.

+
+ @@ -850,13 +866,30 @@ case the corresponding callbacks are applied until either all return ok or one does not.

+ +{capx_timeout, + Unsigned32()} + +

+The number of milliseconds after which a transport process having an +established transport connection will be terminated if the expected +capabilities exchange message (CER or CEA) is not received from the peer. +For a connecting transport, the timing reconnection attempts is +governed by watchdog_timer or +reconnect_timer expiry. +For a listening transport, the peer determines the timing.

+ +

+Defaults to 10000.

+
+ {disconnect_cb, evaluable()}

-A callback invoked prior to requesting shutdown of a transport process -for a transport connection having watchdog state OKAY. +A callback invoked prior to terminating the transport process of a +transport connection having watchdog state OKAY. Applied to Reason=transport|service|application and the transport_ref() and diameter_app:peer() @@ -875,20 +908,12 @@ The return value can have one of the following types.

{dpr, [option()]}

-Causes Disconnect-Peer-Request to be sent to the peer, transport -process shutdown being requested after reception of +Causes Disconnect-Peer-Request to be sent to the peer, the transport +process being terminated following reception of Disconnect-Peer-Answer or timeout. An option() can be one of the following.

-{timeout, integer()} - -

-Transport process shutdown will be requested after this number of -milliseconds if DPA is not received. -Defaults to 1000.

-
- {cause, 0|rebooting|1|busy|2|goaway}

@@ -897,6 +922,15 @@ The Disconnect-Cause to send, REBOOTING, BUSY and Defaults to rebooting for Reason=service|application and goaway for Reason=transport.

+ +{timeout, + Unsigned32()} + +

+The number of milliseconds after which the transport process is +terminated if DPA has not been received. +Defaults to 1000.

+
@@ -909,7 +943,7 @@ Equivalent to {dpr, []}.

close

-Causes transport process shutdown to be requested without +Causes the transport process to be terminated without Disconnect-Peer-Request being sent to the peer.

@@ -1301,7 +1335,7 @@ Pred = {M,F,A}: fun(Ref, Type, Opts) -> apply(M, F, [Ref, Type, Opts | A]) end

Removing a transport causes the corresponding transport processes to -be asked to terminate. +be terminated. Whether or not a DPR message is sent to a peer is controlled by value of disconnect_cb -- cgit v1.2.3 From 23925103bfb66268113e533e701eb3865d6c1085 Mon Sep 17 00:00:00 2001 From: Anders Svensson Date: Thu, 15 Nov 2012 18:39:54 +0100 Subject: Implement transport_opt() capx_timeout --- lib/diameter/src/base/diameter.erl | 1 + lib/diameter/src/base/diameter_peer_fsm.erl | 43 +++++++++++++++++++---------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lib/diameter/src/base/diameter.erl b/lib/diameter/src/base/diameter.erl index 95702f03d4..8f9901907a 100644 --- a/lib/diameter/src/base/diameter.erl +++ b/lib/diameter/src/base/diameter.erl @@ -330,6 +330,7 @@ call(SvcName, App, Message) -> | {applications, [app_alias()]} | {capabilities, [capability()]} | {capabilities_cb, evaluable()} + | {capx_timeout, 'Unsigned32'()} | {disconnect_cb, evaluable()} | {watchdog_timer, 'Unsigned32'() | {module(), atom(), list()}} | {reconnect_timer, 'Unsigned32'()} diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl index e06dc136ce..c4320fcb99 100644 --- a/lib/diameter/src/base/diameter_peer_fsm.erl +++ b/lib/diameter/src/base/diameter_peer_fsm.erl @@ -73,7 +73,7 @@ -define(IS_SUCCESS(N), 2 == (N) div 1000). %% Guards. --define(IS_UINT32(N), (0 =< N andalso 0 == N bsr 32)). +-define(IS_UINT32(N), (is_integer(N) andalso 0 =< N andalso 0 == N bsr 32)). -define(IS_TIMEOUT(N), ?IS_UINT32(N)). -define(IS_CAUSE(N), N == ?REBOOT; N == rebooting; N == ?GOAWAY; N == goaway; @@ -85,6 +85,7 @@ %% for some event. %% -define(EVENT_TIMEOUT, 10000). +%% Default timeout for reception of CER/CEA. %% Default timeout for DPA in response to DPR. A bit short but the %% timeout used to be hardcoded. (So it could be worse.) @@ -93,8 +94,9 @@ -type uint32() :: diameter:'Unsigned32'(). -record(state, - {state = 'Wait-Conn-Ack' %% state of RFC 3588 Peer State Machine - :: 'Wait-Conn-Ack' + {state %% of RFC 3588 Peer State Machine + :: 'Wait-Conn-Ack' %% old code + | {'Wait-Conn-Ack', uint32()} | recv_CER | 'Wait-CEA' %% old code | {'Wait-CEA', uint32(), uint32()} @@ -191,7 +193,10 @@ i({WPid, T, Opts, {Mask, Nodes, #diameter_service{applications = Apps, putr(?RESTRICT_KEY, Nodes), erlang:monitor(process, WPid), {TPid, Addrs} = start_transport(T, Rest, Svc), - #state{parent = WPid, + Tmo = proplists:get_value(capx_timeout, Opts, ?EVENT_TIMEOUT), + ?IS_TIMEOUT(Tmo) orelse ?ERROR({invalid, {capx_timeout, Tmo}}), + #state{state = {'Wait-Conn-Ack', Tmo}, + parent = WPid, transport = TPid, mode = M, service = svc(Svc, Addrs)}. @@ -329,13 +334,17 @@ eraser(Key) -> %% transition/2 +%% Started in old code. +transition(T, #state{state = 'Wait-Conn-Ack' = PS} = S) -> + transition(T, S#state{state = {PS, ?EVENT_TIMEOUT}}); + %% Connection to peer. transition({diameter, {TPid, connected, Remote}}, #state{transport = TPid, state = PS, mode = M} = S) -> - 'Wait-Conn-Ack' = PS, %% assert + {'Wait-Conn-Ack', _} = PS, %% assert connect = M, %% keep_transport(TPid), send_CER(S#state{mode = {M, Remote}}); @@ -347,11 +356,11 @@ transition({diameter, {TPid, connected}}, mode = M, parent = Pid} = S) -> - 'Wait-Conn-Ack' = PS, %% assert + {'Wait-Conn-Ack', Tmo} = PS, %% assert accept = M, %% keep_transport(TPid), Pid ! {accepted, self()}, - start_timer(S#state{state = recv_CER}); + start_timer(Tmo, S#state{state = recv_CER}); %% Connection established after receiving a connection_timeout %% message. This may be followed by an incoming message which arrived @@ -365,7 +374,7 @@ transition({diameter, {_, connected, _}}, _) -> %% Connection has timed out: start an alternate. transition({connection_timeout = T, TPid}, #state{transport = TPid, - state = 'Wait-Conn-Ack'} + state = {'Wait-Conn-Ack', _}} = S) -> exit(TPid, {shutdown, T}), start_next(S); @@ -380,7 +389,7 @@ transition({diameter, {recv, Pkt}}, S) -> %% Timeout when still in the same state ... transition({timeout, PS}, #state{state = PS}) -> - stop; + {stop, {capx(PS), timeout}}; %% ... or not. transition({timeout, _}, _) -> @@ -435,6 +444,11 @@ transition({state, Pid}, #state{state = S, transport = TPid}) -> %% Crash on anything unexpected. +capx(recv_CER) -> + 'CER'; +capx({'Wait-CEA', _, _}) -> + 'CEA'. + %% start_next/1 start_next(#state{service = Svc0} = S) -> @@ -450,7 +464,8 @@ start_next(#state{service = Svc0} = S) -> %% send_CER/1 -send_CER(#state{mode = {connect, Remote}, +send_CER(#state{state = {'Wait-Conn-Ack', Tmo}, + mode = {connect, Remote}, service = #diameter_service{capabilities = LCaps}, transport = TPid} = S) -> @@ -465,7 +480,7 @@ send_CER(#state{mode = {connect, Remote}, = Pkt = encode(CER), send(TPid, Pkt), - start_timer(S#state{state = {'Wait-CEA', Hid, Eid}}). + start_timer(Tmo, S#state{state = {'Wait-CEA', Hid, Eid}}). %% Register ourselves as connecting to the remote endpoint in %% question. This isn't strictly necessary since a peer implementing @@ -477,10 +492,10 @@ send_CER(#state{mode = {connect, Remote}, req_send_CER(OriginHost, Remote) -> register_everywhere({?MODULE, connection, OriginHost, {remote, Remote}}). -%% start_timer/1 +%% start_timer/2 -start_timer(#state{state = PS} = S) -> - erlang:send_after(?EVENT_TIMEOUT, self(), {timeout, PS}), +start_timer(Tmo, #state{state = PS} = S) -> + erlang:send_after(Tmo, self(), {timeout, PS}), S. %% build_CER/1 -- cgit v1.2.3