--
cgit v1.2.3
From d78891e4e1566923164185894beee5e25151399f Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Wed, 14 Nov 2012 20:06:42 +0100
Subject: Add simple DPR suite
---
lib/diameter/test/diameter_dpr_SUITE.erl | 196 +++++++++++++++++++++++++++++++
lib/diameter/test/modules.mk | 5 +-
2 files changed, 199 insertions(+), 2 deletions(-)
create mode 100644 lib/diameter/test/diameter_dpr_SUITE.erl
diff --git a/lib/diameter/test/diameter_dpr_SUITE.erl b/lib/diameter/test/diameter_dpr_SUITE.erl
new file mode 100644
index 0000000000..9252650bf7
--- /dev/null
+++ b/lib/diameter/test/diameter_dpr_SUITE.erl
@@ -0,0 +1,196 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2012. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+%%
+%% Tests of the disconnect_cb configuration.
+%%
+
+-module(diameter_dpr_SUITE).
+
+-export([suite/0,
+ all/0,
+ groups/0,
+ init_per_group/2,
+ end_per_group/2]).
+
+%% testcases
+-export([start/1,
+ connect/1,
+ remove_transport/1,
+ stop_service/1,
+ check/1,
+ stop/1]).
+
+%% disconnect_cb
+-export([disconnect/5]).
+
+-include("diameter.hrl").
+
+%% ===========================================================================
+
+-define(util, diameter_util).
+
+-define(ADDR, {127,0,0,1}).
+
+-define(CLIENT, "CLIENT").
+-define(SERVER, "SERVER").
+
+-define(DICT_COMMON, ?DIAMETER_DICT_COMMON).
+-define(APP_ID, ?DICT_COMMON:id()).
+
+%% Config for diameter:start_service/2.
+-define(SERVICE(Host),
+ [{'Origin-Host', Host},
+ {'Origin-Realm', "erlang.org"},
+ {'Host-IP-Address', [?ADDR]},
+ {'Vendor-Id', hd(Host)}, %% match this in disconnect/5
+ {'Product-Name', "OTP/diameter"},
+ {'Acct-Application-Id', [?APP_ID]},
+ {restrict_connections, false},
+ {application, [{dictionary, ?DICT_COMMON},
+ {module, #diameter_callback{_ = false}}]}]).
+
+%% Disconnect reasons that diameter passes as the first argument of a
+%% function configured as disconnect_cb.
+-define(REASONS, [transport, service, application]).
+
+%% Valid values for Disconnect-Cause.
+-define(CAUSES, [0, rebooting, 1, busy, 2, goaway]).
+
+%% Establish one client connection for element of this list,
+%% configured with disconnect/5 as disconnect_cb and returning the
+%% specified value.
+-define(RETURNS,
+ [[close, {dpr, [{cause, invalid}]}], [ignore, close], []]
+ ++ [[{dpr, [{timeout, 5000}, {cause, T}]}] || T <- ?CAUSES]).
+
+%% ===========================================================================
+
+suite() ->
+ [{timetrap, {seconds, 60}}].
+
+all() ->
+ [{group, R} || R <- ?REASONS].
+
+%% The group determines how transports are terminated: by remove_transport,
+%% stop_service or application stop.
+groups() ->
+ Ts = tc(),
+ [{R, [], Ts} || R <- ?REASONS].
+
+init_per_group(Name, Config) ->
+ [{group, Name} | Config].
+
+end_per_group(_, _) ->
+ ok.
+
+tc() ->
+ [start, connect, remove_transport, stop_service, check, stop].
+
+%% ===========================================================================
+%% start/stop testcases
+
+start(_Config) ->
+ ok = diameter:start(),
+ ok = diameter:start_service(?SERVER, ?SERVICE(?SERVER)),
+ ok = diameter:start_service(?CLIENT, ?SERVICE(?CLIENT)).
+
+connect(Config) ->
+ Pid = spawn(fun init/0), %% process for disconnect_cb to bang
+ Grp = group(Config),
+ LRef = ?util:listen(?SERVER, tcp),
+ Refs = [?util:connect(?CLIENT, tcp, LRef, opts(RCs, {Grp, Pid}))
+ || RCs <- ?RETURNS],
+ ?util:write_priv(Config, config, [Pid | Refs]).
+
+%% Remove all the client transports only in the transport group.
+remove_transport(Config) ->
+ transport == group(Config)
+ andalso (ok = diameter:remove_transport(?CLIENT, true)).
+
+%% Stop the service only in the service group.
+stop_service(Config) ->
+ service == group(Config)
+ andalso (ok = diameter:stop_service(?CLIENT)).
+
+%% Check for callbacks and stop the service. (Not the other way around
+%% for the timing reason explained below.)
+check(Config) ->
+ Grp = group(Config),
+ [Pid | Refs] = ?util:read_priv(Config, config),
+ Pid ! self(), %% ask for dictionary
+ Dict = receive {Pid, D} -> D end, %% get it
+ check(Refs, ?RETURNS, Grp, Dict). %% check for callbacks
+
+stop(_Config) ->
+ ok = diameter:stop().
+
+%% Whether or not there are callbacks after diameter:stop() depends on
+%% timing as long as the server runs on the same node: a server
+%% transport could close the connection before the client has chance
+%% to apply its callback. Therefore, just check that there haven't
+%% been any callbacks yet.
+check(_, _, application, Dict) ->
+ [] = dict:to_list(Dict);
+
+check([], [], _, _) ->
+ ok;
+
+check([Ref | Refs], CBs, Grp, Dict) ->
+ check1(Ref, hd(CBs), Grp, Dict),
+ check(Refs, tl(CBs), Grp, Dict).
+
+check1(Ref, [ignore | RCs], Reason, Dict) ->
+ check1(Ref, RCs, Reason, Dict);
+
+check1(Ref, [_|_], Reason, Dict) ->
+ {ok, Reason} = dict:find(Ref, Dict); %% callback with expected reason
+
+check1(Ref, [], _, Dict) ->
+ error = dict:find(Ref, Dict). %% no callback
+
+%% ----------------------------------------
+
+group(Config) ->
+ {group, Grp} = lists:keyfind(group, 1, Config),
+ Grp.
+
+%% Configure the callback with the group name (= disconnect reason) as
+%% extra argument.
+opts(RCs, T) ->
+ [{disconnect_cb, {?MODULE, disconnect, [T, RC]}} || RC <- RCs].
+
+%% Match the group name with the disconnect reason to ensure the
+%% callback is being called as expected.
+disconnect(Reason, Ref, Peer, {Reason, Pid}, RC) ->
+ io:format("disconnect: ~p ~p~n", [Ref, Reason]),
+ {_, #diameter_caps{vendor_id = {$C,$S}}} = Peer,
+ Pid ! {Reason, Ref},
+ RC.
+
+init() ->
+ exit(recv(dict:new())).
+
+recv(Dict) ->
+ receive
+ Pid when is_pid(Pid) ->
+ Pid ! {self(), Dict};
+ {Reason, Ref} ->
+ recv(dict:store(Ref, Reason, Dict))
+ end.
diff --git a/lib/diameter/test/modules.mk b/lib/diameter/test/modules.mk
index 7f163536fb..5898e125ae 100644
--- a/lib/diameter/test/modules.mk
+++ b/lib/diameter/test/modules.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2011. All Rights Reserved.
+# Copyright Ericsson AB 2010-2012. All Rights Reserved.
#
# The contents of this file are subject to the Erlang Public License,
# Version 1.1, (the "License"); you may not use this file except in
@@ -39,7 +39,8 @@ MODULES = \
diameter_traffic_SUITE \
diameter_relay_SUITE \
diameter_tls_SUITE \
- diameter_failover_SUITE
+ diameter_failover_SUITE \
+ diameter_dpr_SUITE
HRL_FILES = \
diameter_ct.hrl
--
cgit v1.2.3
From 91a223d37d6b57f53d26135a4cbaf4ac22854ba2 Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Thu, 15 Nov 2012 10:52:58 +0100
Subject: Allow a handle_request callback to return a #diameter_packet{}
This allows it to set transport_data and header, inappropriately so
even.
---
lib/diameter/doc/src/diameter_app.xml | 24 ++++++++++-----
lib/diameter/src/base/diameter_service.erl | 49 ++++++++++++++++++------------
2 files changed, 46 insertions(+), 27 deletions(-)
diff --git a/lib/diameter/doc/src/diameter_app.xml b/lib/diameter/doc/src/diameter_app.xml
index ac056c2d39..b6870f7c28 100644
--- a/lib/diameter/doc/src/diameter_app.xml
+++ b/lib/diameter/doc/src/diameter_app.xml
@@ -382,7 +382,7 @@ communicate transport (or any other) data to the callback.
A returned packet() can set
the header field to a
-#diameter_header{} in order to specify values that should
+#diameter_header{} to specify values that should
be preserved in the outgoing request, values otherwise being those in
the header record contained in Packet.
A returned length, cmd_code or application_id is
@@ -537,7 +537,8 @@ not selected.
| {relay, [Opt]}
| discard
| {eval|eval_packet, Action, PostF}
-Reply = {reply, message()}
+Reply = {reply, packet()
+ | message()}
| {protocol_error, 3000..3999}
Opt = diameter:call_opt()
PostF = diameter:evaluable()
@@ -568,7 +569,7 @@ The argument packet() has the following sign
-The msg field will be undefined only in case the request has
+The msg field will be undefined in case the request has
been received in the relay application.
Otherwise it contains the record representing the request as outlined
in
The transport_data field contains an arbitrary term passed into
diameter from the transport module in question, or the atom
undefined if the transport specified no data.
-The term is preserved in the packet() containing any answer message
-sent back to the transport process unless another value is explicitly
-specified.
+The term is preserved if a message() is returned but must be set
+explicitly in a returned packet().
The semantics of each of the possible return values are as follows.
-{reply, message()}
+{reply, packet()
+ | message()}
-
-Send the specified answer message to the peer.
+Send the specified answer message to the peer.
+In the case of a packet(), the
+message to be sent must be set in the
+msg field and the header field can be set to a
+#diameter_header{} to specify values that should be
+preserved in the outgoing answer, appropriate values otherwise
+being set by diameter.
{protocol_error, 3000..3999}
diff --git a/lib/diameter/src/base/diameter_service.erl b/lib/diameter/src/base/diameter_service.erl
index 0a0fd6ded1..467bb585cd 100644
--- a/lib/diameter/src/base/diameter_service.erl
+++ b/lib/diameter/src/base/diameter_service.erl
@@ -2175,15 +2175,13 @@ reply([Msg], Dict, TPid, Fs, Pkt)
reply(Msg, Dict, TPid, Fs, Pkt#diameter_packet{errors = []});
%% No errors or a diameter_header/avp list.
-reply(Msg, Dict, TPid, Fs, #diameter_packet{errors = Es,
- transport_data = TD}
- = ReqPkt)
+reply(Msg, Dict, TPid, Fs, #diameter_packet{errors = Es} = ReqPkt)
when [] == Es;
is_record(hd(Msg), diameter_header) ->
Pkt = diameter_codec:encode(Dict, make_answer_packet(Msg, ReqPkt)),
eval_packet(Pkt, Fs),
incr(send, Pkt, Dict, TPid), %% count result codes in sent answers
- send(TPid, Pkt#diameter_packet{transport_data = TD});
+ send(TPid, Pkt);
%% Or not: set Result-Code and Failed-AVP AVP's.
reply(Msg, Dict, TPid, Fs, #diameter_packet{errors = [H|_] = Es} = Pkt) ->
@@ -2198,23 +2196,36 @@ eval_packet(Pkt, Fs) ->
%% make_answer_packet/2
+%% A reply message clears the R and T flags and retains the P flag.
+%% The E flag will be set at encode. 6.2 of 3588 requires the same P
+%% flag on an answer as on the request. A #diameter_packet{} returned
+%% from a handle_request callback can circumvent this by setting its
+%% own header values.
+make_answer_packet(#diameter_packet{header = Hdr,
+ msg = Msg,
+ transport_data = TD},
+ #diameter_packet{header = ReqHdr}) ->
+ Hdr0 = ReqHdr#diameter_header{version = ?DIAMETER_VERSION,
+ is_request = false,
+ is_error = undefined,
+ is_retransmitted = false},
+ #diameter_packet{header = fold_record(Hdr0, Hdr),
+ msg = Msg,
+ transport_data = TD};
+
%% Binaries and header/avp lists are sent as-is.
-make_answer_packet(Bin, _)
+make_answer_packet(Bin, #diameter_packet{transport_data = TD})
when is_binary(Bin) ->
- #diameter_packet{bin = Bin};
-make_answer_packet([#diameter_header{} | _] = Msg, _) ->
- #diameter_packet{msg = Msg};
-
-%% Otherwise a reply message clears the R and T flags and retains the
-%% P flag. The E flag will be set at encode. 6.2 of 3588 requires the
-%% same P flag on an answer as on the request.
-make_answer_packet(Msg, #diameter_packet{header = ReqHdr}) ->
- Hdr = ReqHdr#diameter_header{version = ?DIAMETER_VERSION,
- is_request = false,
- is_error = undefined,
- is_retransmitted = false},
- #diameter_packet{header = Hdr,
- msg = Msg}.
+ #diameter_packet{bin = Bin,
+ transport_data = TD};
+make_answer_packet([#diameter_header{} | _] = Msg,
+ #diameter_packet{transport_data = TD}) ->
+ #diameter_packet{msg = Msg,
+ transport_data = TD};
+
+%% Otherwise, preserve transport_data.
+make_answer_packet(Msg, #diameter_packet{transport_data = TD} = Pkt) ->
+ make_answer_packet(#diameter_packet{msg = Msg, transport_data = TD}, Pkt).
%% rc/1
--
cgit v1.2.3
From 9c941ef6215bea79f910a202a686d97b7ef5a238 Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Thu, 15 Nov 2012 12:22:45 +0100
Subject: Add a testcase
---
lib/diameter/test/diameter_traffic_SUITE.erl | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/lib/diameter/test/diameter_traffic_SUITE.erl b/lib/diameter/test/diameter_traffic_SUITE.erl
index 5744ff0307..fa9333a226 100644
--- a/lib/diameter/test/diameter_traffic_SUITE.erl
+++ b/lib/diameter/test/diameter_traffic_SUITE.erl
@@ -38,6 +38,7 @@
result_codes/1,
send_ok/1,
send_nok/1,
+ send_bad_answer/1,
send_arbitrary/1,
send_unknown/1,
send_unknown_mandatory/1,
@@ -208,6 +209,7 @@ end_per_testcase(_, _) ->
tc() ->
[send_ok,
send_nok,
+ send_bad_answer,
send_arbitrary,
send_unknown,
send_unknown_mandatory,
@@ -308,6 +310,14 @@ send_nok(Config) ->
#'diameter_base_answer-message'{'Result-Code' = ?INVALID_AVP_BITS}
= call(Config, Req).
+%% Send an accounting ACR that the server tries to answer with an
+%% inappropriate header, resulting in no answer being sent and the
+%% request timing out.
+send_bad_answer(Config) ->
+ Req = ['ACR', {'Accounting-Record-Type', ?EVENT_RECORD},
+ {'Accounting-Record-Number', 2}],
+ {error, timeout} = call(Config, Req).
+
%% Send an ASR with an arbitrary AVP and expect success and the same
%% AVP in the reply.
send_arbitrary(Config) ->
@@ -768,6 +778,21 @@ request(#diameter_base_accounting_ACR{'Accounting-Record-Number' = 0},
_) ->
{eval_packet, {protocol_error, ?INVALID_AVP_BITS}, [fun log/2, invalid]};
+request(#diameter_base_accounting_ACR{'Session-Id' = SId,
+ 'Accounting-Record-Type' = RT,
+ 'Accounting-Record-Number' = 2 = RN},
+ #diameter_caps{origin_host = {OH, _},
+ origin_realm = {OR, _}}) ->
+ Ans = ['ACA', {'Result-Code', ?SUCCESS},
+ {'Session-Id', SId},
+ {'Origin-Host', OH},
+ {'Origin-Realm', OR},
+ {'Accounting-Record-Type', RT},
+ {'Accounting-Record-Number', RN}],
+
+ {reply, #diameter_packet{header = #diameter_header{is_error = true},%% not
+ msg = Ans}};
+
request(#diameter_base_accounting_ACR{'Session-Id' = SId,
'Accounting-Record-Type' = RT,
'Accounting-Record-Number' = RN},
--
cgit v1.2.3
From 4ddc8f40399d7c4856d0c8f9463832012c25002f Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Thu, 15 Nov 2012 14:57:18 +0100
Subject: Add check of End-to-End and Hop-by-Hop identfiers in received CEA
---
lib/diameter/src/base/diameter_peer_fsm.erl | 43 ++++++++++++++++++++---------
1 file changed, 30 insertions(+), 13 deletions(-)
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index 4acfd8313b..3cf1129d59 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -90,15 +90,20 @@
%% timeout used to be hardcoded. (So it could be worse.)
-define(DPA_TIMEOUT, 1000).
+-type uint32() :: diameter:'Unsigned32'().
+
-record(state,
{state = 'Wait-Conn-Ack' %% state of RFC 3588 Peer State Machine
- :: 'Wait-Conn-Ack' | recv_CER | 'Wait-CEA' | 'Open',
+ :: 'Wait-Conn-Ack'
+ | recv_CER
+ | 'Wait-CEA' %% old code
+ | {'Wait-CEA', uint32(), uint32()}
+ | 'Open',
mode :: accept | connect | {connect, reference()},
parent :: pid(), %% watchdog process
transport :: pid(), %% transport process
service :: #diameter_service{},
- dpr = false :: false | {diameter:'Unsigned32'(),
- diameter:'Unsigned32'()}}).
+ dpr = false :: false | {uint32(), uint32()}}).
%% | hop by hop and end to end identifiers
%% There are non-3588 states possible as a consequence of 5.6.1 of the
@@ -455,8 +460,12 @@ send_CER(#state{mode = {connect, Remote},
close({already_connected, Remote, LCaps}, S),
CER = build_CER(S),
?LOG(send, 'CER'),
- send(TPid, encode(CER)),
- start_timer(S#state{state = 'Wait-CEA'}).
+ #diameter_packet{header = #diameter_header{end_to_end_id = Eid,
+ hop_by_hop_id = Hid}}
+ = Pkt
+ = encode(CER),
+ send(TPid, Pkt),
+ start_timer(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
@@ -487,10 +496,8 @@ encode(Rec) ->
Hdr = #diameter_header{version = ?DIAMETER_VERSION,
end_to_end_id = Seq,
hop_by_hop_id = Seq},
- Pkt = #diameter_packet{header = Hdr,
- msg = Rec},
- #diameter_packet{bin = Bin} = diameter_codec:encode(?BASE, Pkt),
- Bin.
+ diameter_codec:encode(?BASE, #diameter_packet{header = Hdr,
+ msg = Rec}).
sequence() ->
case getr(?SEQUENCE_KEY) of
@@ -558,7 +565,14 @@ discard(Reason, F, A) ->
%% rcv/3
%% Incoming CEA.
-rcv('CEA', Pkt, #state{state = 'Wait-CEA'} = S) ->
+rcv('CEA',
+ #diameter_packet{header = #diameter_header{end_to_end_id = Eid,
+ hop_by_hop_id = Hid}}
+ = Pkt,
+ #state{state = {'Wait-CEA' = T, Hid, Eid}}
+ = S) ->
+ handle_CEA(Pkt, S#state{state = T});
+rcv('CEA', Pkt, #state{state = 'Wait-CEA'} = S) -> %% old code
handle_CEA(Pkt, S);
%% Incoming CER
@@ -1055,13 +1069,16 @@ send_dpr(Reason, Opts, #state{transport = TPid,
origin_realm = {OR, _}}
= Caps,
- Bin = encode(['DPR', {'Origin-Host', OH},
+ #diameter_packet{header = #diameter_header{end_to_end_id = Eid,
+ hop_by_hop_id = Hid}}
+ = Pkt
+ = encode(['DPR', {'Origin-Host', OH},
{'Origin-Realm', OR},
{'Disconnect-Cause', Cause}]),
- send(TPid, Bin),
+ send(TPid, Pkt),
dpa_timer(Tmo),
?LOG(send, 'DPR'),
- S#state{dpr = diameter_codec:sequence_numbers(Bin)}.
+ S#state{dpr = {Hid, Eid}}.
opt({timeout, Tmo}, Rec)
when ?IS_TIMEOUT(Tmo) ->
--
cgit v1.2.3
From 62403f98c887a1b2e99e41da576c171c29d59193 Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Thu, 15 Nov 2012 15:05:26 +0100
Subject: Add check of End-to-End and Hop-by-Hop identfiers in received DPA
---
lib/diameter/src/base/diameter_peer_fsm.erl | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/lib/diameter/src/base/diameter_peer_fsm.erl b/lib/diameter/src/base/diameter_peer_fsm.erl
index 3cf1129d59..e06dc136ce 100644
--- a/lib/diameter/src/base/diameter_peer_fsm.erl
+++ b/lib/diameter/src/base/diameter_peer_fsm.erl
@@ -592,16 +592,16 @@ rcv(N, Pkt, S)
N == 'DPR' ->
handle_request(N, Pkt, S);
-%% DPA even though we haven't sent DPR: ignore.
-rcv('DPA', _Pkt, #state{dpr = false}) ->
- ok;
-
-%% DPA in response to DPR. We could check the sequence numbers but
-%% don't bother, just close.
-rcv('DPA' = N, _Pkt, #state{transport = TPid}) ->
+%% DPA in response to DPR and with the expected identifiers.
+rcv('DPA' = N,
+ #diameter_packet{header = #diameter_header{end_to_end_id = Eid,
+ hop_by_hop_id = Hid}},
+ #state{transport = TPid,
+ dpr = {Hid, Eid}}) ->
diameter_peer:close(TPid),
{stop, N};
+%% Ignore anything else, an unsolicited DPA in particular.
rcv(_, _, _) ->
ok.
--
cgit v1.2.3
From 81e2c30e1dd83974e6a41f0988124501da1e8ad6 Mon Sep 17 00:00:00 2001
From: Anders Svensson
Date: Thu, 15 Nov 2012 15:47:02 +0100
Subject: Add comment about lack of identifier checks on DWA
---
lib/diameter/src/base/diameter_watchdog.erl | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/lib/diameter/src/base/diameter_watchdog.erl b/lib/diameter/src/base/diameter_watchdog.erl
index d6a2d2833b..243ad0a986 100644
--- a/lib/diameter/src/base/diameter_watchdog.erl
+++ b/lib/diameter/src/base/diameter_watchdog.erl
@@ -487,6 +487,14 @@ throwaway(S) ->
throw({?MODULE, throwaway, S}).
%% rcv/2
+%%
+%% The lack of Hop-by-Hop and End-to-End Identifiers checks in a
+%% received DWA is intentional. The purpose of the message is to
+%% demonstrate life but a peer that consistently bungles it by sending
+%% the wrong identifiers causes the connection to toggle between OPEN
+%% and SUSPECT, with failover and failback as result, despite there
+%% being no real problem with connectivity. Thus, relax and accept any
+%% incoming DWA as being in response to an outgoing DWR.
%% INITIAL Receive DWA Pending = FALSE
%% Throwaway() INITIAL
--
cgit v1.2.3
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.