aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstrap/lib/compiler/ebin/beam_asm.beambin11604 -> 11368 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin15860 -> 16328 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin40088 -> 40312 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin11752 -> 11756 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_scan.beambin6664 -> 6684 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin53452 -> 53452 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin54708 -> 54708 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel_pp.beambin12532 -> 12540 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin32464 -> 32472 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin24068 -> 24068 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_boot_server.beambin5760 -> 5760 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_reply.beambin900 -> 900 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/error_logger.beambin6152 -> 6280 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erts_debug.beambin5768 -> 5752 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin13804 -> 13832 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_config.beambin7528 -> 7536 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_dns.beambin19168 -> 19172 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin13812 -> 13812 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin14176 -> 14268 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.app2
-rw-r--r--bootstrap/lib/kernel/ebin/os.beambin4252 -> 4256 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/beam_lib.beambin19488 -> 19488 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_utils.beambin27780 -> 27784 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin.beambin11064 -> 11036 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin27704 -> 27776 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin91624 -> 91616 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin26744 -> 26648 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin27884 -> 27884 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/escript.beambin16820 -> 16840 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin22344 -> 22344 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin29276 -> 29276 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin13932 -> 13932 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_format.beambin13320 -> 13332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin15004 -> 15000 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/otp_internal.beambin10240 -> 10792 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin68960 -> 68960 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin75144 -> 75144 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin29888 -> 29888 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/slave.beambin4744 -> 4744 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin37592 -> 37592 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/string.beambin24444 -> 24752 bytes
-rw-r--r--erts/emulator/beam/erl_io_queue.c7
-rw-r--r--erts/emulator/test/emulator_smoke.spec1
-rw-r--r--erts/emulator/test/iovec_SUITE.erl43
-rw-r--r--lib/common_test/src/common_test.app.src2
-rw-r--r--lib/debugger/src/debugger.app.src2
-rw-r--r--lib/dialyzer/src/dialyzer.app.src4
-rw-r--r--lib/diameter/doc/src/diameter_sctp.xml60
-rw-r--r--lib/diameter/doc/src/diameter_soc.xml1327
-rw-r--r--lib/diameter/doc/src/diameter_soc_rfc6733.xml8693
-rw-r--r--lib/diameter/doc/src/diameter_tcp.xml45
-rw-r--r--lib/diameter/doc/src/files.mk5
-rw-r--r--lib/erl_docgen/src/erl_docgen.app.src2
-rw-r--r--lib/et/src/et.app.src4
-rw-r--r--lib/eunit/src/eunit.app.src2
-rw-r--r--lib/hipe/main/hipe.app.src2
-rw-r--r--lib/kernel/src/erts_debug.erl19
-rw-r--r--lib/kernel/src/inet_res.erl12
-rw-r--r--lib/kernel/src/kernel.app.src2
-rw-r--r--lib/mnesia/src/mnesia.app.src2
-rwxr-xr-xlib/observer/priv/bin/cdv2
-rw-r--r--lib/observer/priv/bin/cdv.bat2
-rw-r--r--lib/observer/src/cdv_detail_wx.erl28
-rw-r--r--lib/observer/src/cdv_html_wx.erl9
-rw-r--r--lib/observer/src/cdv_term_cb.erl8
-rw-r--r--lib/observer/src/cdv_virtual_list_wx.erl2
-rw-r--r--lib/observer/src/cdv_wx.erl38
-rw-r--r--lib/observer/src/crashdump_viewer.erl269
-rw-r--r--lib/observer/src/observer.app.src2
-rw-r--r--lib/observer/src/observer_html_lib.erl29
-rw-r--r--lib/observer/src/observer_lib.erl83
-rw-r--r--lib/observer/src/observer_procinfo.erl2
-rw-r--r--lib/observer/test/Makefile2
-rw-r--r--lib/observer/test/crashdump_viewer_SUITE.erl133
-rw-r--r--lib/observer/test/observer_SUITE.erl9
-rw-r--r--lib/observer/test/ttb_SUITE.erl26
-rw-r--r--lib/public_key/doc/src/public_key.xml86
-rw-r--r--lib/public_key/doc/src/public_key_records.xml6
-rw-r--r--lib/public_key/src/pubkey_cert.erl253
-rw-r--r--lib/public_key/src/public_key.erl51
-rw-r--r--lib/public_key/test/public_key_SUITE.erl144
-rw-r--r--lib/public_key/test/public_key_SUITE_data/ec_key2.pem29
-rw-r--r--lib/public_key/vsn.mk2
-rw-r--r--lib/reltool/src/reltool.app.src2
-rw-r--r--lib/sasl/src/sasl.app.src4
-rw-r--r--lib/ssl/src/ssl.app.src2
-rw-r--r--lib/ssl/test/ssl_ECC_SUITE.erl180
-rw-r--r--lib/ssl/test/ssl_certificate_verify_SUITE.erl90
-rw-r--r--lib/ssl/test/ssl_test_lib.erl341
-rw-r--r--lib/ssl/test/x509_test.erl301
-rw-r--r--lib/ssl/vsn.mk2
-rw-r--r--lib/stdlib/src/otp_internal.erl2
-rw-r--r--lib/syntax_tools/src/syntax_tools.app.src2
-rw-r--r--lib/tools/src/fprof.erl2
-rw-r--r--lib/tools/src/tools.app.src2
-rw-r--r--lib/tools/test/fprof_SUITE.erl17
-rw-r--r--lib/tools/test/fprof_SUITE_data/fprof_unicode.erl36
-rwxr-xr-xmake/fakefop18
-rw-r--r--make/otp.mk.in7
-rw-r--r--system/doc/design_principles/des_princ.xml2
-rw-r--r--system/doc/oam/oam_intro.xml2
101 files changed, 2900 insertions, 9563 deletions
diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam
index 936e6886a6..9f25d31bb2 100644
--- a/bootstrap/lib/compiler/ebin/beam_asm.beam
+++ b/bootstrap/lib/compiler/ebin/beam_asm.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_utils.beam b/bootstrap/lib/compiler/ebin/beam_utils.beam
index 0f44d8e4d7..4d475cd899 100644
--- a/bootstrap/lib/compiler/ebin/beam_utils.beam
+++ b/bootstrap/lib/compiler/ebin/beam_utils.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/compile.beam b/bootstrap/lib/compiler/ebin/compile.beam
index a92341690d..d2f4ed83bb 100644
--- a/bootstrap/lib/compiler/ebin/compile.beam
+++ b/bootstrap/lib/compiler/ebin/compile.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_pp.beam b/bootstrap/lib/compiler/ebin/core_pp.beam
index 8f4137db70..f0573bd200 100644
--- a/bootstrap/lib/compiler/ebin/core_pp.beam
+++ b/bootstrap/lib/compiler/ebin/core_pp.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/core_scan.beam b/bootstrap/lib/compiler/ebin/core_scan.beam
index e9f74a1d1c..398c538178 100644
--- a/bootstrap/lib/compiler/ebin/core_scan.beam
+++ b/bootstrap/lib/compiler/ebin/core_scan.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_codegen.beam b/bootstrap/lib/compiler/ebin/v3_codegen.beam
index c6c1593790..a1047fb87f 100644
--- a/bootstrap/lib/compiler/ebin/v3_codegen.beam
+++ b/bootstrap/lib/compiler/ebin/v3_codegen.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel.beam b/bootstrap/lib/compiler/ebin/v3_kernel.beam
index 6143af9050..189a8c07b2 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
index 6b127e86d0..e1b8c58c8f 100644
--- a/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
+++ b/bootstrap/lib/compiler/ebin/v3_kernel_pp.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log.beam b/bootstrap/lib/kernel/ebin/disk_log.beam
index 4dc0ef29f2..e8a6acd235 100644
--- a/bootstrap/lib/kernel/ebin/disk_log.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/disk_log_1.beam b/bootstrap/lib/kernel/ebin/disk_log_1.beam
index 420a4e818b..bcd3c548a5 100644
--- a/bootstrap/lib/kernel/ebin/disk_log_1.beam
+++ b/bootstrap/lib/kernel/ebin/disk_log_1.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_boot_server.beam b/bootstrap/lib/kernel/ebin/erl_boot_server.beam
index ef3fe6fdea..d9de814e60 100644
--- a/bootstrap/lib/kernel/ebin/erl_boot_server.beam
+++ b/bootstrap/lib/kernel/ebin/erl_boot_server.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erl_reply.beam b/bootstrap/lib/kernel/ebin/erl_reply.beam
index 6266aaa37c..d9dee00b6a 100644
--- a/bootstrap/lib/kernel/ebin/erl_reply.beam
+++ b/bootstrap/lib/kernel/ebin/erl_reply.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/error_logger.beam b/bootstrap/lib/kernel/ebin/error_logger.beam
index 4129e6af6e..2415215395 100644
--- a/bootstrap/lib/kernel/ebin/error_logger.beam
+++ b/bootstrap/lib/kernel/ebin/error_logger.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/erts_debug.beam b/bootstrap/lib/kernel/ebin/erts_debug.beam
index a47aec4a2e..75064d3452 100644
--- a/bootstrap/lib/kernel/ebin/erts_debug.beam
+++ b/bootstrap/lib/kernel/ebin/erts_debug.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/group.beam b/bootstrap/lib/kernel/ebin/group.beam
index 57851fcb6e..5c5f3bfa73 100644
--- a/bootstrap/lib/kernel/ebin/group.beam
+++ b/bootstrap/lib/kernel/ebin/group.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_config.beam b/bootstrap/lib/kernel/ebin/inet_config.beam
index ab06763c7d..6e02c48609 100644
--- a/bootstrap/lib/kernel/ebin/inet_config.beam
+++ b/bootstrap/lib/kernel/ebin/inet_config.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_dns.beam b/bootstrap/lib/kernel/ebin/inet_dns.beam
index cebe72a7f0..8935d52e52 100644
--- a/bootstrap/lib/kernel/ebin/inet_dns.beam
+++ b/bootstrap/lib/kernel/ebin/inet_dns.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index a5b4d7611f..cd27ee7265 100644
--- a/bootstrap/lib/kernel/ebin/inet_parse.beam
+++ b/bootstrap/lib/kernel/ebin/inet_parse.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_res.beam b/bootstrap/lib/kernel/ebin/inet_res.beam
index 74b3a11f59..f203f7c08a 100644
--- a/bootstrap/lib/kernel/ebin/inet_res.beam
+++ b/bootstrap/lib/kernel/ebin/inet_res.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/kernel.app b/bootstrap/lib/kernel/ebin/kernel.app
index b888d914e8..244fad678f 100644
--- a/bootstrap/lib/kernel/ebin/kernel.app
+++ b/bootstrap/lib/kernel/ebin/kernel.app
@@ -120,6 +120,6 @@
{applications, []},
{env, [{error_logger, tty}]},
{mod, {kernel, []}},
- {runtime_dependencies, ["erts-9.1", "stdlib-3.0", "sasl-3.0"]}
+ {runtime_dependencies, ["erts-9.1", "stdlib-3.4", "sasl-3.0"]}
]
}.
diff --git a/bootstrap/lib/kernel/ebin/os.beam b/bootstrap/lib/kernel/ebin/os.beam
index 0bc6403871..cedf7bf49e 100644
--- a/bootstrap/lib/kernel/ebin/os.beam
+++ b/bootstrap/lib/kernel/ebin/os.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/beam_lib.beam b/bootstrap/lib/stdlib/ebin/beam_lib.beam
index 8255fc6f82..39d80d9e36 100644
--- a/bootstrap/lib/stdlib/ebin/beam_lib.beam
+++ b/bootstrap/lib/stdlib/ebin/beam_lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam
index 6840be1e57..d858a59f8b 100644
--- a/bootstrap/lib/stdlib/ebin/dets_utils.beam
+++ b/bootstrap/lib/stdlib/ebin/dets_utils.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/edlin.beam b/bootstrap/lib/stdlib/ebin/edlin.beam
index b6f5e62671..1cabe095b3 100644
--- a/bootstrap/lib/stdlib/ebin/edlin.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index 36c2b2219e..22c0978854 100644
--- a/bootstrap/lib/stdlib/ebin/epp.beam
+++ b/bootstrap/lib/stdlib/ebin/epp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_lint.beam b/bootstrap/lib/stdlib/ebin/erl_lint.beam
index dc4c689263..d018b33132 100644
--- a/bootstrap/lib/stdlib/ebin/erl_lint.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_lint.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam
index e77e0f9136..5c5a46d8bb 100644
--- a/bootstrap/lib/stdlib/ebin/erl_pp.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_pp.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_scan.beam b/bootstrap/lib/stdlib/ebin/erl_scan.beam
index 86307bc790..d36202515a 100644
--- a/bootstrap/lib/stdlib/ebin/erl_scan.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_scan.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/escript.beam b/bootstrap/lib/stdlib/ebin/escript.beam
index 30dea42a21..10982c84ce 100644
--- a/bootstrap/lib/stdlib/ebin/escript.beam
+++ b/bootstrap/lib/stdlib/ebin/escript.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ets.beam b/bootstrap/lib/stdlib/ebin/ets.beam
index 40be147afa..c2b113b79e 100644
--- a/bootstrap/lib/stdlib/ebin/ets.beam
+++ b/bootstrap/lib/stdlib/ebin/ets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/file_sorter.beam b/bootstrap/lib/stdlib/ebin/file_sorter.beam
index f2a1fd74d0..74c7c5ce01 100644
--- a/bootstrap/lib/stdlib/ebin/file_sorter.beam
+++ b/bootstrap/lib/stdlib/ebin/file_sorter.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/filename.beam b/bootstrap/lib/stdlib/ebin/filename.beam
index a94acbb852..13f1c8029e 100644
--- a/bootstrap/lib/stdlib/ebin/filename.beam
+++ b/bootstrap/lib/stdlib/ebin/filename.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/io_lib_format.beam b/bootstrap/lib/stdlib/ebin/io_lib_format.beam
index e85995c1de..c02da85965 100644
--- a/bootstrap/lib/stdlib/ebin/io_lib_format.beam
+++ b/bootstrap/lib/stdlib/ebin/io_lib_format.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/lib.beam b/bootstrap/lib/stdlib/ebin/lib.beam
index 6ad7dff7da..98a7f91ab8 100644
--- a/bootstrap/lib/stdlib/ebin/lib.beam
+++ b/bootstrap/lib/stdlib/ebin/lib.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam
index 912dfba644..166574e0f6 100644
--- a/bootstrap/lib/stdlib/ebin/otp_internal.beam
+++ b/bootstrap/lib/stdlib/ebin/otp_internal.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc.beam b/bootstrap/lib/stdlib/ebin/qlc.beam
index 4a315e8d42..592f7b4740 100644
--- a/bootstrap/lib/stdlib/ebin/qlc.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/qlc_pt.beam b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
index ac343d8abd..1a7d678227 100644
--- a/bootstrap/lib/stdlib/ebin/qlc_pt.beam
+++ b/bootstrap/lib/stdlib/ebin/qlc_pt.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/shell.beam b/bootstrap/lib/stdlib/ebin/shell.beam
index a0e2b73018..fab94d5509 100644
--- a/bootstrap/lib/stdlib/ebin/shell.beam
+++ b/bootstrap/lib/stdlib/ebin/shell.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/slave.beam b/bootstrap/lib/stdlib/ebin/slave.beam
index 299c24448d..abab0acf33 100644
--- a/bootstrap/lib/stdlib/ebin/slave.beam
+++ b/bootstrap/lib/stdlib/ebin/slave.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index a2cc62d4af..aa8ed3d99c 100644
--- a/bootstrap/lib/stdlib/ebin/sofs.beam
+++ b/bootstrap/lib/stdlib/ebin/sofs.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/string.beam b/bootstrap/lib/stdlib/ebin/string.beam
index a281027902..8bb21b24f2 100644
--- a/bootstrap/lib/stdlib/ebin/string.beam
+++ b/bootstrap/lib/stdlib/ebin/string.beam
Binary files differ
diff --git a/erts/emulator/beam/erl_io_queue.c b/erts/emulator/beam/erl_io_queue.c
index a01b676d39..190ba6bbb9 100644
--- a/erts/emulator/beam/erl_io_queue.c
+++ b/erts/emulator/beam/erl_io_queue.c
@@ -973,9 +973,10 @@ static int iol2v_append_binary(iol2v_state_t *state, Eterm bin_term) {
UWord binary_size;
Uint byte_offset, bit_offset, bit_size;
+ byte *binary_data;
+
Eterm *parent_header;
Eterm parent_binary;
- byte *binary_data;
ASSERT(state->bytereds_available > state->bytereds_spent);
@@ -1001,14 +1002,14 @@ static int iol2v_append_binary(iol2v_state_t *state, Eterm bin_term) {
erts_emasculate_writable_binary(pb);
}
- binary_data = pb->bytes;
+ binary_data = &((byte*)pb->bytes)[byte_offset];
} else {
ErlHeapBin *hb = (ErlHeapBin*)parent_header;
ASSERT(thing_subtag(*parent_header) == HEAP_BINARY_SUBTAG);
ASSERT(is_bin_small);
- binary_data = &((unsigned char*)&hb->data)[byte_offset];
+ binary_data = &((byte*)&hb->data)[byte_offset];
}
if (!is_bin_small && (state->acc_size == 0 || !is_acc_small)) {
diff --git a/erts/emulator/test/emulator_smoke.spec b/erts/emulator/test/emulator_smoke.spec
index b2d0de8835..fc98ba6823 100644
--- a/erts/emulator/test/emulator_smoke.spec
+++ b/erts/emulator/test/emulator_smoke.spec
@@ -7,3 +7,4 @@
[consistency],"Not reliable in October and March"}.
{cases,'Dir',crypto_SUITE,[t_md5]}.
{cases,'Dir',float_SUITE,[fpe,cmp_integer]}.
+{cases,'Dir',erts_debug_SUITE,[df]}.
diff --git a/erts/emulator/test/iovec_SUITE.erl b/erts/emulator/test/iovec_SUITE.erl
index 28df36d293..49dc64b0d2 100644
--- a/erts/emulator/test/iovec_SUITE.erl
+++ b/erts/emulator/test/iovec_SUITE.erl
@@ -24,7 +24,8 @@
-export([integer_lists/1, binary_lists/1, empty_lists/1, empty_binary_lists/1,
mixed_lists/1, improper_lists/1, illegal_lists/1, cons_bomb/1,
- iolist_to_iovec_idempotence/1, iolist_to_iovec_correctness/1]).
+ sub_binary_lists/1, iolist_to_iovec_idempotence/1,
+ iolist_to_iovec_correctness/1]).
-include_lib("common_test/include/ct.hrl").
@@ -34,8 +35,8 @@ suite() ->
all() ->
[integer_lists, binary_lists, empty_lists, empty_binary_lists, mixed_lists,
- illegal_lists, improper_lists, cons_bomb, iolist_to_iovec_idempotence,
- iolist_to_iovec_correctness].
+ sub_binary_lists, illegal_lists, improper_lists, cons_bomb,
+ iolist_to_iovec_idempotence, iolist_to_iovec_correctness].
init_per_suite(Config) ->
Config.
@@ -46,15 +47,16 @@ end_per_suite(Config) ->
integer_lists(Config) when is_list(Config) ->
Variations = gen_variations([I || I <- lists:seq(1, 255)]),
+ equivalence_test(fun erlang:iolist_to_iovec/1, Variations).
- equivalence_test(fun erlang:iolist_to_iovec/1, Variations),
-
- ok.
+sub_binary_lists(Config) when is_list(Config) ->
+ Parent = <<0:256/unit:8, "gazurka">>,
+ <<0:196/unit:8, Child/binary>> = Parent,
+ equivalence_test(fun erlang:iolist_to_iovec/1, gen_variations(Child)).
binary_lists(Config) when is_list(Config) ->
Variations = gen_variations([<<I:8>> || I <- lists:seq(1, 255)]),
- equivalence_test(fun erlang:iolist_to_iovec/1, Variations),
- ok.
+ equivalence_test(fun erlang:iolist_to_iovec/1, Variations).
empty_lists(Config) when is_list(Config) ->
Variations = gen_variations([[] || _ <- lists:seq(1, 256)]),
@@ -70,8 +72,7 @@ empty_binary_lists(Config) when is_list(Config) ->
mixed_lists(Config) when is_list(Config) ->
Variations = gen_variations([<<>>, lists:seq(1, 40), <<12, 45, 78>>]),
- equivalence_test(fun erlang:iolist_to_iovec/1, Variations),
- ok.
+ equivalence_test(fun erlang:iolist_to_iovec/1, Variations).
illegal_lists(Config) when is_list(Config) ->
BitStrs = gen_variations(["gurka", <<1:1>>, "gaffel"]),
@@ -82,18 +83,15 @@ illegal_lists(Config) when is_list(Config) ->
Variations =
BitStrs ++ BadInts ++ Atoms ++ BadTails,
- illegality_test(fun erlang:iolist_to_iovec/1, Variations),
-
- ok.
+ illegality_test(fun erlang:iolist_to_iovec/1, Variations).
improper_lists(Config) when is_list(Config) ->
Variations = [
[[[[1 | <<2>>] | <<3>>] | <<4>>] | <<5>>],
- [[<<"test">>, 3] | <<"improper tail">>],
- [1, 2, 3 | <<"improper tail">>]
+ [[<<1>>, 2] | <<3, 4, 5>>],
+ [1, 2, 3 | <<4, 5>>]
],
- equivalence_test(fun erlang:iolist_to_iovec/1, Variations),
- ok.
+ equivalence_test(fun erlang:iolist_to_iovec/1, Variations).
cons_bomb(Config) when is_list(Config) ->
IntBase = gen_variations([I || I <- lists:seq(1, 255)]),
@@ -108,8 +106,7 @@ cons_bomb(Config) when is_list(Config) ->
end,
Variations = gen_variations([IntBase, BinBase, MixBase], Rounds),
- equivalence_test(fun erlang:iolist_to_iovec/1, Variations),
- ok.
+ equivalence_test(fun erlang:iolist_to_iovec/1, Variations).
iolist_to_iovec_idempotence(Config) when is_list(Config) ->
IntVariations = gen_variations([I || I <- lists:seq(1, 255)]),
@@ -134,11 +131,15 @@ iolist_to_iovec_correctness(Config) when is_list(Config) ->
ok.
illegality_test(Fun, Variations) ->
- [{'EXIT',{badarg, _}} = (catch Fun(Variation)) || Variation <- Variations].
+ [{'EXIT',{badarg, _}} = (catch Fun(Variation)) || Variation <- Variations],
+ ok.
equivalence_test(Fun, [Head | _] = Variations) ->
+ %% Check that each variation is equal to the others, and that the sum of
+ %% them is equal to the input.
Comparand = Fun(Head),
- [is_iolist_equal(Comparand, Fun(Variation)) || Variation <- Variations],
+ [true = is_iolist_equal(Comparand, Fun(V)) || V <- Variations],
+ true = is_iolist_equal(Variations, Fun(Variations)),
ok.
is_iolist_equal(A, B) ->
diff --git a/lib/common_test/src/common_test.app.src b/lib/common_test/src/common_test.app.src
index 430a4fa2fb..0aa4aacf16 100644
--- a/lib/common_test/src/common_test.app.src
+++ b/lib/common_test/src/common_test.app.src
@@ -92,7 +92,7 @@
"sasl-2.4.2",
"snmp-5.1.2",
"ssh-4.0",
- "stdlib-2.5",
+ "stdlib-3.4",
"syntax_tools-1.7",
"tools-2.8",
"xmerl-1.3.8"
diff --git a/lib/debugger/src/debugger.app.src b/lib/debugger/src/debugger.app.src
index 446f2b9882..37a41c1a56 100644
--- a/lib/debugger/src/debugger.app.src
+++ b/lib/debugger/src/debugger.app.src
@@ -48,5 +48,5 @@
]},
{registered, [dbg_iserver, dbg_wx_mon, dbg_wx_winman]},
{applications, [kernel, stdlib]},
- {runtime_dependencies, ["wx-1.2","stdlib-2.5","kernel-3.0","erts-6.0",
+ {runtime_dependencies, ["wx-1.2","stdlib-3.4","kernel-5.3","erts-9.0",
"compiler-5.0"]}]}.
diff --git a/lib/dialyzer/src/dialyzer.app.src b/lib/dialyzer/src/dialyzer.app.src
index 5f803875b0..e3a0fc967d 100644
--- a/lib/dialyzer/src/dialyzer.app.src
+++ b/lib/dialyzer/src/dialyzer.app.src
@@ -48,6 +48,6 @@
{registered, []},
{applications, [compiler, hipe, kernel, stdlib, wx]},
{env, []},
- {runtime_dependencies, ["wx-1.2","syntax_tools-2.0","stdlib-3.0",
- "kernel-5.0","hipe-3.15.4","erts-8.0",
+ {runtime_dependencies, ["wx-1.2","syntax_tools-2.0","stdlib-3.4",
+ "kernel-5.3","hipe-3.16.1","erts-9.0",
"compiler-7.0"]}]}.
diff --git a/lib/diameter/doc/src/diameter_sctp.xml b/lib/diameter/doc/src/diameter_sctp.xml
index c9b74a9ec5..62e958870e 100644
--- a/lib/diameter/doc/src/diameter_sctp.xml
+++ b/lib/diameter/doc/src/diameter_sctp.xml
@@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd" [
+ <!ENTITY man_tcp_sender
+ '<seealso marker="diameter_tcp#sender">diameter_tcp(3)</seealso>'>
<!ENTITY gen_sctp '<seealso marker="kernel:gen_sctp">gen_sctp(3)</seealso>'>
<!ENTITY gen_sctp_open1
'<seealso marker="kernel:gen_sctp#open-1">gen_sctp:open/1</seealso>'>
@@ -78,7 +80,11 @@ and implements the behaviour documented in
<v>Reason = term()</v>
<v>OwnOpt = {raddr, &ip_address;}
| {rport, integer()}
- | {accept, Match}</v>
+ | {accept, Match}
+ | {unordered, boolean() | pos_integer()}
+ | {packet, boolean() | raw}
+ | {message_cb, &mod_eval;}
+ | {sender, boolean()}</v>
<v>SctpOpt = term()</v>
<v>Match = &ip_address; | string() | [Match]</v>
</type>
@@ -106,6 +112,41 @@ A string-valued <c>Match</c> that does not parse as an address is
interpreted as a regular expression.</p>
<p>
+Option <c>unordered</c> specifies whether or not to use unordered
+delivery, integer <c>N</c> being equivalent to <c>N =&lt; OS</c>,
+where <c>OS</c> is the number of outbound streams negotiated on the
+association in question.
+Regardless of configuration, sending is ordered on stream 0
+until reception of a second incoming message, to ensure that a peer
+receives capabilities exchange messages before any other.
+Defaults to <c>false</c>.</p>
+
+<p>
+Option <c>packet</c> determines how/if an incoming message is
+packaged into a diameter_packet record.
+If <c>false</c> then messages are received as binary().
+If <c>true</c> then as a record with the binary() message in the
+<c>bin</c> field and a <c>{stream, Id}</c> tuple in the
+<c>transport_data</c> field, where <c>Id</c> is the identifier of the
+inbound stream the message was received on.
+If <c>raw</c> then as a record with the received ancillary
+sctp_sndrcvinfo record in the <c>transport_data</c> field.
+Defaults to <c>true</c>.</p>
+
+<p>
+Options <c>message_cb</c> and <c>sender</c> have semantics identical
+to those documented in &man_tcp_sender;, but with the message argument
+to a <c>recv</c> callback being as directed by the <c>packet</c>
+option.</p>
+
+<p>
+An <c>{outstream, Id}</c> tuple in the <c>transport_data</c> field of
+a outgoing diameter_packet record sets the outbound stream on which
+the message is sent, modulo the negotiated number of outbound streams.
+Any other value causes successive such sends to cycle though all
+outbound streams.</p>
+
+<p>
Remaining options are any accepted by &gen_sctp_open1;, with the exception
of options <c>mode</c>, <c>binary</c>, <c>list</c>, <c>active</c>
and <c>sctp_events</c>.
@@ -121,29 +162,16 @@ connecting transport.</p>
<warning>
<p>
-An insufficiently large receive buffer may result in a peer having to
+An small receive buffer may result in a peer having to
resend incoming messages: set the &inet; option <c>recbuf</c> to increase
the buffer size.</p>
<p>
-An insufficiently large send buffer may result in outgoing messages
+An small send buffer may result in outgoing messages
being discarded: set the &inet; option <c>sndbuf</c> to increase
the buffer size.</p>
</warning>
-<p>
-The <c>transport_data</c> field of record <c>diameter_packet</c>
-is used to communicate the stream on which an inbound message
-has been received, or on which an outbound message should be sent.
-The value will be of the form <c>{stream, Id}</c> for an inbound
-message passed to a &app_handle_request; or &app_handle_answer;
-callback.
-For an outbound message, <c>{outstream, Id}</c> in the return value of
-&app_handle_request; or &app_prepare_retransmit; sets the outbound
-stream, the stream id being interpreted modulo the number of outbound
-streams.
-Any other value, or not setting a value, causes successive such sends
-to cycle though all outbound streams.</p>
</desc>
</func>
diff --git a/lib/diameter/doc/src/diameter_soc.xml b/lib/diameter/doc/src/diameter_soc.xml
index ae404fcda4..28e01ff1be 100644
--- a/lib/diameter/doc/src/diameter_soc.xml
+++ b/lib/diameter/doc/src/diameter_soc.xml
@@ -1,15 +1,22 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd" [
+ <!ENTITY gen_sctp '<seealso marker="kernel:gen_sctp">gen_sctp(3)</seealso>'>
+ <!ENTITY gen_tcp '<seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>'>
+ <!ENTITY service '<seealso marker="diameter#start_service-2">service</seealso>'>
+ <!ENTITY capabilities '<seealso marker="diameter#capability">capabilities</seealso>'>
+ <!ENTITY events '<seealso marker="diameter#service_event">events</seealso>'>
+ <!ENTITY NA '&#8212;'>
+ <!ENTITY BR '<br/>&nbsp;<br/>'>
<!ENTITY % also SYSTEM "seealso.ent" >
%also;
]>
-<chapter xmlns:xi="http://www.w3.org/2001/XInclude">
+<chapter>
<header>
<copyright>
<year>2011</year>
-<year>2016</year>
+<year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
@@ -41,63 +48,1285 @@ limitations under the License.
</header>
<p>
-Known points of questionable or non-compliance.</p>
+The table below summarizes the diameter application's compliance with
+&the_rfc;.
+Since the diameter application isn't a Diameter node on its own,
+compliance is strictly the responsibility of the user in many cases,
+diameter providing the means for the user to be compliant
+rather than being compliant on its own.</p>
-<!-- ===================================================================== -->
-
-<section>
-<title>&the_rfc;</title>
-
-<list>
-
-<item>
-<p>
-There is no support for DTLS over SCTP.</p>
-</item>
-
-<item>
<p>
-There is no explicit support for peer discovery (section 5.2).
-It can possibly be implemented on top of diameter as is but this is
-probably something that diameter should do.</p>
-</item>
+The Compliance column notes <em>C</em> (Compliant) if the required
+functionality is implemented, <em>PC</em> (Partially Compliant) if
+there are limitations, <em>NC</em> (Not Compliant) if functionality is
+not implemented, or a dash if text is informational or only places
+requirements that must be met by the user's implementation.</p>
-<item>
<p>
-The peer state machine's election process (section 5.6.4) isn't
-implemented as specified since it assumes knowledge of a
-peer's Origin-Host before sending it a CER. (The identity becoming known
-upon reception of CEA.)
-The possibility of configuring
-the peer's Origin-Host could be added, along with handling of the case
-that it sends something else, but for many applications this will
-just be unnecessary configuration of a value that it has no control over.</p>
-</item>
-<!-- Transport protocol plus address/port, which we do know when
- sending and receiving CER, is enough to definitely identify
- the peer. However, there's nothing stopping a peer from using
- different identities on different transport protocols, even
- if it's maybe a bit far-fetched. -->
-
-</list>
-
-<xi:include href="diameter_soc_rfc6733.xml"/>
-
-</section>
+Capitalized <em>Diameter</em> refers to the protocol, lowercase
+<em>diameter</em> to the Erlang application.</p>
<!-- ===================================================================== -->
<section>
-<title>RFC 3539</title>
+<title>&the_rfc; - Diameter Base Protocol</title>
-<p>
-RFC 3539 is more difficult to comply to since it discusses
-problems as much as it requires functionality but all the MUST's are
-covered, the watchdog state machine being the primary one.
-Of the optional functionality, load balancing is left to the
-diameter user (since it's the one deciding who to send to) and
-there is no Congestion Manager.</p>
+<table>
+<row>
+ <cell><em>Section</em></cell>
+ <cell><em>Title</em></cell>
+ <cell><em>Compliance</em></cell>
+ <cell><em>Notes</em></cell>
+</row>
+<row>
+ <cell>1</cell>
+ <cell>Introduction</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>1.1</cell>
+ <cell>Diameter Protocol</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>1.1.1</cell>
+ <cell>Description of the Document Set</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>1.1.2</cell>
+ <cell>Conventions Used in This Document</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>1.1.3</cell>
+ <cell>Changes from RFC 3588</cell>
+ <cell>&NA;</cell>
+ <cell>It is possible to configure a 3588 dictionary in
+ order to get 3588 semantics, where the differ from 6733.</cell>
+</row>
+<row>
+ <cell>1.2</cell>
+ <cell>Terminology</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>1.3</cell>
+ <cell>Approach to Extensibility</cell>
+ <cell>&NA;</cell>
+ <cell>The dictionary interface documented in &man_dict; provides
+ extensibility, allowing the user to defined new AVPs, commands, and
+ applications.
+ Ready dictionaries are provided for the &the_rfc; common message, base
+ accounting, and relay applications, as well as for RFC 7683,
+ Diameter Overload Indicator Conveyance.</cell>
+</row>
+<row>
+ <cell>1.3.1</cell>
+ <cell>Defining New AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>1.3.2</cell>
+ <cell>Creating New AVPs</cell>
+ <cell>&NA;</cell>
+ <cell>New AVPs can be defined using the dictionary interface.
+ Both both RFC data formats and extensions are supported.</cell>
+</row>
+<row>
+ <cell>1.3.3</cell>
+ <cell>Creating New Commands</cell>
+ <cell>&NA;</cell>
+ <cell>New commands can be defined using the dictionary interface.</cell>
+</row>
+<row>
+ <cell>1.3.4</cell>
+ <cell>Creating New Diameter Applications</cell>
+ <cell>&NA;</cell>
+ <cell>New applications can be defined using the dictionary interface.</cell>
+</row>
+<row>
+ <cell>2</cell>
+ <cell>Protocol Overview</cell>
+ <cell>&NA;</cell>
+ <cell>Session state is the responsibility of the user.&BR;
+ The role of a Diameter node is determined by the user's
+ implementation.</cell>
+</row>
+<row>
+ <cell>2.1</cell>
+ <cell>Transport</cell>
+ <cell>PC</cell>
+ <cell>Ports are configured by the user: diameter places no
+ restrictions.&BR;
+ The transport interface documented in &man_transport;
+ allows the user to implement their own methods.
+ Ready support is provided for TCP, TCP/TLS, and SCTP, but not
+ DTLS/SCTP.&BR;
+ Multiple connections to the same peer is possible.
+ ICMP messages are not interpreted.</cell>
+</row>
+<row>
+ <cell>2.1.1</cell>
+ <cell>SCTP Guidelines</cell>
+ <cell>C</cell>
+ <cell>Unordered sending is configurable in &man_sctp;.
+ There is no special handling of DPR/DPA: since a user that cares
+ about pending answers should wait for them before initiating
+ DPR.&BR;
+ A PPID can be configured with a a gen_sctp sctp_default_send_param
+ option.</cell>
+</row>
+<row>
+ <cell>2.2</cell>
+ <cell>Securing Diameter Messages</cell>
+ <cell>PC</cell>
+ <cell>DTLS is not supported by &man_sctp;. See also
+ 2.1.</cell>
+</row>
+<row>
+ <cell>2.3</cell>
+ <cell>Diameter Application Compliance</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>2.4</cell>
+ <cell>Application Identifiers</cell>
+ <cell>C</cell>
+ <cell>The user configures diameter with the identifiers to send at
+ capabilities exchange, along with corresponding dictionaries
+ defining the messages of the applications.</cell>
+</row>
+<row>
+ <cell>2.5</cell>
+ <cell>Connections vs. Sessions</cell>
+ <cell>C</cell>
+ <cell>Connections are realized by configuring transport. Sessions
+ are the responsibility of the user.</cell>
+</row>
+<row>
+ <cell>2.6</cell>
+ <cell>Peer Table</cell>
+ <cell>PC</cell>
+ <cell>Routing is implemented by the user in callbacks documented in
+ &man_app;.
+ A peer table of the documented form is not exposed to the user.</cell>
+</row>
+<row>
+ <cell>2.7</cell>
+ <cell>Routing Table</cell>
+ <cell>PC</cell>
+ <cell>See 2.6.
+ A routing table of the documented form is not exposed to
+ the user.</cell>
+</row>
+<row>
+ <cell>2.8</cell>
+ <cell>Role of Diameter Agents</cell>
+ <cell>C</cell>
+ <cell>Most role-specific behaviour is implemented by the user.
+ How a node advertises itself at capabilities exchange is determined
+ by user configuration.</cell>
+</row>
+<row>
+ <cell>2.8.1</cell>
+ <cell>Relay Agents</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>2.8.2</cell>
+ <cell>Proxy Agents</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>2.8.3</cell>
+ <cell>Redirect Agents</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>2.8.4</cell>
+ <cell>Translation Agents</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>2.9</cell>
+ <cell>Diameter Path Authorization</cell>
+ <cell>&NA;</cell>
+ <cell>Authorization is the responsibility of the user.</cell>
+</row>
+<row>
+ <cell>3</cell>
+ <cell>Diameter Header</cell>
+ <cell>C</cell>
+ <cell>Hop-by-Hop and End-to-End Identifiers are set by diameter when
+ sending outgoing requests.</cell>
+</row>
+<row>
+ <cell>3.1</cell>
+ <cell>Command Codes</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>3.2</cell>
+ <cell>Command Code Format Specification</cell>
+ <cell>C</cell>
+ <cell>Commands are defined as CCF specifications in dictionary
+ files.</cell>
+</row>
+<row>
+ <cell>3.3</cell>
+ <cell>Diameter Command Naming Conventions</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>4</cell>
+ <cell>Diameter AVPs</cell>
+ <cell>C</cell>
+ <cell>Any required padding is added by diameter when encoding
+ outgoing messages.</cell>
+</row>
+<row>
+ <cell>4.1</cell>
+ <cell>AVP Header</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>4.1.1</cell>
+ <cell>Optional Header Elements</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>4.2</cell>
+ <cell>Basic AVP Data Formats</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>4.3</cell>
+ <cell>Derived AVP Data Formats</cell>
+ <cell>C</cell>
+ <cell>Arbitrary derived data formats are supported by the dictionary
+ interface.</cell>
+</row>
+<row>
+ <cell>4.3.1</cell>
+ <cell>Common Derived AVP Data Formats</cell>
+ <cell>C</cell>
+ <cell>Beware that RFC 6733 changed the DiameterURI transport/port
+ defaults specified in RFC3588.
+ Relying on the defaults can result in interoperability
+ problems.</cell>
+</row>
+<row>
+ <cell>4.4</cell>
+ <cell>Grouped AVP Values</cell>
+ <cell>C</cell>
+ <cell>The M-bit on a component AVP of a Grouped AVP that does not
+ set M is ignored: such AVPs are not regarded as erroneous at
+ decode.&BR;
+ Grouped AVPs are defined as CCF specifications in dictionary
+ files.</cell>
+</row>
+<row>
+ <cell>4.4.1</cell>
+ <cell>Example AVP with a Grouped Data Type</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>4.5</cell>
+ <cell>Diameter Base Protocol AVPs</cell>
+ <cell>C</cell>
+ <cell>The base AVPs are defined in the common dictionary provided by
+ diameter.
+ There are common dictionaries for both RFC 3588 and RFC 6733 since
+ the latter made changes to both syntax and semantics.</cell>
+</row>
+<row>
+ <cell>5</cell>
+ <cell>Diameter Peers</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.1</cell>
+ <cell>Peer Connections</cell>
+ <cell>PC</cell>
+ <cell>A peer's DiameterIdentity is not required when initiating a
+ connection: the identify is received at capabilities exchange, at
+ which time the connection can be rejected if the identity is
+ objectionable.&BR;
+ The number of connections established depends on the user's
+ configuration. Multiple connections per peer is possible.</cell>
+</row>
+<row>
+ <cell>5.2</cell>
+ <cell>Diameter Peer Discovery</cell>
+ <cell>NC</cell>
+ <cell>No form of peer discovery is implemented.
+ The user can implement this independently of diameter if
+ required.</cell>
+</row>
+<row>
+ <cell>5.3</cell>
+ <cell>Capabilities Exchange</cell>
+ <cell>C</cell>
+ <cell>All supported applications are sent in CEA.
+ The user can reject an incoming CER or CEA in a configured
+ callback.&BR;
+ Both transport security at connection establishment and
+ negotiated via an Inband-Security AVP are supported.</cell>
+</row>
+<row>
+ <cell>5.3.1</cell>
+ <cell>Capabilities-Exchange-Request</cell>
+ <cell>C</cell>
+ <cell>CER is sent and received by diameter.</cell>
+</row>
+<row>
+ <cell>5.3.2</cell>
+ <cell>Capabilities-Exchange-Answer</cell>
+ <cell>C</cell>
+ <cell>CEA is sent and received by diameter.</cell>
+</row>
+<row>
+ <cell>5.3.3</cell>
+ <cell>Vendor-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.3.4</cell>
+ <cell>Firmware-Revision AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.3.5</cell>
+ <cell>Host-IP-Address AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.3.6</cell>
+ <cell>Supported-Vendor-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.3.7</cell>
+ <cell>Product-Name AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.4</cell>
+ <cell>Disconnecting Peer Connections</cell>
+ <cell>C</cell>
+ <cell>DPA will not be answered with error: a peer that wants to a
+ avoid a race can wait for pending answers before sending
+ DPR.</cell>
+</row>
+<row>
+ <cell>5.4.1</cell>
+ <cell>Disconnect-Peer-Request</cell>
+ <cell>C</cell>
+ <cell>DPR is sent by diameter in response to configuration
+ changes requiring a connection to be broken.
+ The user can also send DPR.</cell>
+</row>
+<row>
+ <cell>5.4.2</cell>
+ <cell>Disconnect-Peer-Answer</cell>
+ <cell>C</cell>
+ <cell>DPR is answered by diameter.</cell>
+</row>
+<row>
+ <cell>5.4.3</cell>
+ <cell>Disconnect-Cause AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.5</cell>
+ <cell>Transport Failure Detection</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.5.1</cell>
+ <cell>Device-Watchdog-Request</cell>
+ <cell>C</cell>
+ <cell>DWR is sent and received by diameter.
+ Callbacks notify the user of transitions into and out of the OKAY
+ state.</cell>
+</row>
+<row>
+ <cell>5.5.2</cell>
+ <cell>Device-Watchdog-Answer</cell>
+ <cell>C</cell>
+ <cell>DWA is sent and received by diameter.</cell>
+</row>
+<row>
+ <cell>5.5.3</cell>
+ <cell>Transport Failure Algorithm</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.5.4</cell>
+ <cell>Failover and Failback Procedures</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.6</cell>
+ <cell>Peer State Machine</cell>
+ <cell>PC</cell>
+ <cell>The election process is modified as described in 5.6.4.</cell>
+</row>
+<row>
+ <cell>5.6.1</cell>
+ <cell>Incoming Connections</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.6.2</cell>
+ <cell>Events</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.6.3</cell>
+ <cell>Actions</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>5.6.4</cell>
+ <cell>The Election Process</cell>
+ <cell>PC</cell>
+ <cell>As documented, the election assumes knowledge of a peer's
+ DiameterIdentity when initiating a connection, which diameter
+ doesn't require. Connections will be accepted if configuration
+ allows multiple connections per peer to be established or there is
+ no existing connection. Note that the election process is only
+ applicable when multiple connections per peer is
+ disallowed.</cell>
+</row>
+<row>
+ <cell>6</cell>
+ <cell>Diameter Message Processing</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.1</cell>
+ <cell>Diameter Request Routing Overview</cell>
+ <cell>&NA;</cell>
+ <cell>Routing is performed by the user.
+ A callback from diameter provides a list of available suitable peer
+ connections.</cell>
+</row>
+<row>
+ <cell>6.1.1</cell>
+ <cell>Originating a Request</cell>
+ <cell>C</cell>
+ <cell>Requests are constructed by the user; diameter sets header
+ fields as defined in the relevant dictionary.</cell>
+</row>
+<row>
+ <cell>6.1.2</cell>
+ <cell>Sending a Request</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.1.3</cell>
+ <cell>Receiving Requests</cell>
+ <cell>C</cell>
+ <cell>Loops are detected by diameter when the return value of a
+ request callback asks that a request be forwarded.
+ Loop detection in other cases is the responsibility of the
+ user.</cell>
+</row>
+<row>
+ <cell>6.1.4</cell>
+ <cell>Processing Local Requests</cell>
+ <cell>C</cell>
+ <cell>The user decides whether or not to process a request locally
+ in the request callback from diameter.</cell>
+</row>
+<row>
+ <cell>6.1.5</cell>
+ <cell>Request Forwarding</cell>
+ <cell>PC</cell>
+ <cell>See 2.6.</cell>
+</row>
+<row>
+ <cell>6.1.6</cell>
+ <cell>Request Routing</cell>
+ <cell>PC</cell>
+ <cell>See 2.7.</cell>
+</row>
+<row>
+ <cell>6.1.7</cell>
+ <cell>Predictive Loop Avoidance</cell>
+ <cell>C</cell>
+ <cell>See 6.1.3.</cell>
+</row>
+<row>
+ <cell>6.1.8</cell>
+ <cell>Redirecting Requests</cell>
+ <cell>PC</cell>
+ <cell>See 2.6.</cell>
+</row>
+<row>
+ <cell>6.1.9</cell>
+ <cell>Relaying and Proxying Requests</cell>
+ <cell>C</cell>
+ <cell>A Route-Record AVP is appended by diameter when the return
+ value of a request callback asks that a request be forwarded.
+ Appending the AVP in other cases is the responsibility of the
+ user.</cell>
+</row>
+<row>
+ <cell>6.2</cell>
+ <cell>Diameter Answer Processing</cell>
+ <cell>C</cell>
+ <cell>Answer message are constructed by the user, except in the case
+ of some protocol errors, in which case the procedures are
+ followed.</cell>
+</row>
+<row>
+ <cell>6.2.1</cell>
+ <cell>Processing Received Answers</cell>
+ <cell>C</cell>
+ <cell>Answers with an unknown Hop-by-Hop Identifier are
+ discarded.</cell>
+</row>
+<row>
+ <cell>6.2.2</cell>
+ <cell>Relaying and Proxying Answers</cell>
+ <cell>&NA;</cell>
+ <cell>Modifying answers is the responsibility of the user in
+ callbacks from diameter.</cell>
+</row>
+<row>
+ <cell>6.3</cell>
+ <cell>Origin-Host AVP</cell>
+ <cell>C</cell>
+ <cell>The order of AVPs in an encoded message is determined by
+ the CCF of the message in question.&BR;
+ AVPs defined in the RFC are defined in dictionaries provided by
+ diameter.
+ Their proper use in application messages is the responsibility of
+ the user.</cell>
+</row>
+<row>
+ <cell>6.4</cell>
+ <cell>Origin-Realm AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.5</cell>
+ <cell>Destination-Host AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.6</cell>
+ <cell>Destination-Realm AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.7</cell>
+ <cell>Routing AVPs</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.7.1</cell>
+ <cell>Route-Record AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.7.2</cell>
+ <cell>Proxy-Info AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.7.3</cell>
+ <cell>Proxy-Host AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.7.4</cell>
+ <cell>Proxy-State AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.8</cell>
+ <cell>Auth-Application-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.9</cell>
+ <cell>Acct-Application-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.10</cell>
+ <cell>Inband-Security-Id AVP</cell>
+ <cell>C</cell>
+ <cell>See 2.1.</cell>
+</row>
+<row>
+ <cell>6.11</cell>
+ <cell>Vendor-Specific-Application-Id AVP</cell>
+ <cell>C</cell>
+ <cell>Note that the CCF of this AVP is not the same as in RFC
+ 3588.</cell>
+</row>
+<row>
+ <cell>6.12</cell>
+ <cell>Redirect-Host AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.13</cell>
+ <cell>Redirect-Host-Usage AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>6.14</cell>
+ <cell>Redirect-Max-Cache-Time AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>7</cell>
+ <cell>Error Handling</cell>
+ <cell>C</cell>
+ <cell>Answers are formulated by the user in most cases.
+ Answers setting the E-bit can be sent by diameter itself in response
+ to a request that cannot be handled by the user.</cell>
+</row>
+<row>
+ <cell>7.1</cell>
+ <cell>Result-Code AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>7.1.1</cell>
+ <cell>Informational</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>7.1.2</cell>
+ <cell>Success</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>7.1.3</cell>
+ <cell>Protocol Errors</cell>
+ <cell>C</cell>
+ <cell>Result codes 3001, 3002, 3005, and 3007 can be sent in answers
+ formulated by diameter, if configured to do so.</cell>
+</row>
+<row>
+ <cell>7.1.4</cell>
+ <cell>Transient Failures</cell>
+ <cell>C</cell>
+ <cell>Result code 4003 is sent in CEA if there is an existing
+ connection to the peer in question and configuration does not allow
+ more than one.</cell>
+</row>
+<row>
+ <cell>7.1.5</cell>
+ <cell>Permanent Failures</cell>
+ <cell>C</cell>
+ <cell>Message reception detects 5001, 5004,
+ 5005, 5008, 5009, 5010, 5011, 5014, 5015, and 5017 errors.
+ It ignores 5013 errors at the admonition of sections 3 and 4.1.&BR;
+ Note that RFC 3588 did not allow 5xxx result codes in
+ answers setting the E-bit, while RFC 6733 does.
+ This is a potential interoperability problem since the Diameter
+ protocol version has not changed.</cell>
+</row>
+<row>
+ <cell>7.2</cell>
+ <cell>Error Bit</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>7.3</cell>
+ <cell>Error-Message AVP</cell>
+ <cell>C</cell>
+ <cell>The user can include this AVP as required.</cell>
+</row>
+<row>
+ <cell>7.4</cell>
+ <cell>Error-Reporting-Host AVP</cell>
+ <cell>C</cell>
+ <cell>The user can include this AVP as required.</cell>
+</row>
+<row>
+ <cell>7.5</cell>
+ <cell>Failed-AVP AVP</cell>
+ <cell>C</cell>
+ <cell>The user constructs application-specific messages, but
+ diameter provides failed AVPs in message callbacks. Failed component AVPs
+ are grouped within the relevant Grouped AVPs.</cell>
+</row>
+<row>
+ <cell>7.6</cell>
+ <cell>Experimental-Result AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>7.7</cell>
+ <cell>Experimental-Result-Code AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8</cell>
+ <cell>Diameter User Sessions</cell>
+ <cell>&NA;</cell>
+ <cell>Authorization and accounting AVPs are defined in provided
+ dictionaries. Their proper use is the responsibility of the
+ user.</cell>
+</row>
+<row>
+ <cell>8.1</cell>
+ <cell>Authorization Session State Machine</cell>
+ <cell>&NA;</cell>
+ <cell>Authorization is the responsibility of the user: diameter does
+ not implement this state machine.</cell>
+</row>
+<row>
+ <cell>8.2</cell>
+ <cell>Accounting Session State Machine</cell>
+ <cell>&NA;</cell>
+ <cell>Accounting is the responsibility of the user: diameter does
+ not implement this state machine.</cell>
+</row>
+<row>
+ <cell>8.3</cell>
+ <cell>Server-Initiated Re-Auth</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.3.1</cell>
+ <cell>Re-Auth-Request</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.3.2</cell>
+ <cell>Re-Auth-Answer</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.4</cell>
+ <cell>Session Termination</cell>
+ <cell>&NA;</cell>
+ <cell>Session-related messages and AVPs are defined in provided
+ dictionaries. Their proper use is the user's responsibility.</cell>
+</row>
+<row>
+ <cell>8.4.1</cell>
+ <cell>Session-Termination-Request</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.4.2</cell>
+ <cell>Session-Termination-Answer</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.5</cell>
+ <cell>Aborting a Session</cell>
+ <cell>&NA;</cell>
+ <cell>Session-related messages and AVPs are defined in provided
+ dictionaries. Their proper use is the user's responsibility.</cell>
+</row>
+<row>
+ <cell>8.5.1</cell>
+ <cell>Abort-Session-Request</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.5.2</cell>
+ <cell>Abort-Session-Answer</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.6</cell>
+ <cell>Inferring Session Termination from Origin-State-Id</cell>
+ <cell>&NA;</cell>
+ <cell>Session-related messages and AVPs are defined in provided
+ dictionaries. Their proper use is the user's responsibility.</cell>
+</row>
+<row>
+ <cell>8.7</cell>
+ <cell>Auth-Request-Type AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.8</cell>
+ <cell>Session-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.9</cell>
+ <cell>Authorization-Lifetime AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.10</cell>
+ <cell>Auth-Grace-Period AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.11</cell>
+ <cell>Auth-Session-State AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.12</cell>
+ <cell>Re-Auth-Request-Type AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.13</cell>
+ <cell>Session-Timeout AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.14</cell>
+ <cell>User-Name AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.15</cell>
+ <cell>Termination-Cause AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.16</cell>
+ <cell>Origin-State-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.17</cell>
+ <cell>Session-Binding AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.18</cell>
+ <cell>Session-Server-Failover AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.19</cell>
+ <cell>Multi-Round-Time-Out AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.20</cell>
+ <cell>Class AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>8.21</cell>
+ <cell>Event-Timestamp AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9</cell>
+ <cell>Accounting</cell>
+ <cell>&NA;</cell>
+ <cell>Accounting-related messages and AVPs are defined in provided
+ dictionaries. Their proper use is the user's responsibility.</cell>
+</row>
+<row>
+ <cell>9.1</cell>
+ <cell>Server Directed Model</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.2</cell>
+ <cell>Protocol Messages</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.3</cell>
+ <cell>Accounting Application Extension and Requirements</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.4</cell>
+ <cell>Fault Resilience</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.5</cell>
+ <cell>Accounting Records</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.6</cell>
+ <cell>Correlation of Accounting Records</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.7</cell>
+ <cell>Accounting Command Codes</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.7.1</cell>
+ <cell>Accounting-Request</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.7.2</cell>
+ <cell>Accounting-Answer</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8</cell>
+ <cell>Accounting AVPs</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.1</cell>
+ <cell>Accounting-Record-Type AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.2</cell>
+ <cell>Acct-Interim-Interval AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.3</cell>
+ <cell>Accounting-Record-Number AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.4</cell>
+ <cell>Acct-Session-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.5</cell>
+ <cell>Acct-Multi-Session-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.6</cell>
+ <cell>Accounting-Sub-Session-Id AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>9.8.7</cell>
+ <cell>Accounting-Realtime-Required AVP</cell>
+ <cell>C</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>10</cell>
+ <cell>AVP Occurrence Tables</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>10.1</cell>
+ <cell>Base Protocol Command AVP Table</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>10.2</cell>
+ <cell>Accounting AVP Table</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11</cell>
+ <cell>IANA Considerations</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.1</cell>
+ <cell>AVP Header</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.1.1</cell>
+ <cell>AVP Codes</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.1.2</cell>
+ <cell>AVP Flags</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.2</cell>
+ <cell>Diameter Header</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.2.1</cell>
+ <cell>Command Codes</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.2.2</cell>
+ <cell>Command Flags</cell>
+ <cell></cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3</cell>
+ <cell>AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.1</cell>
+ <cell>Experimental-Result-Code AVP</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.2</cell>
+ <cell>Result-Code AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.3</cell>
+ <cell>Accounting-Record-Type AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.4</cell>
+ <cell>Termination-Cause AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.5</cell>
+ <cell>Redirect-Host-Usage AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.6</cell>
+ <cell>Session-Server-Failover AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.7</cell>
+ <cell>Session-Binding AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.8</cell>
+ <cell>Disconnect-Cause AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.9</cell>
+ <cell>Auth-Request-Type AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.10</cell>
+ <cell>Auth-Session-State AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.11</cell>
+ <cell>Re-Auth-Request-Type AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.12</cell>
+ <cell>Accounting-Realtime-Required AVP Values</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.3.13</cell>
+ <cell>Inband-Security-Id AVP (code 299)</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.4</cell>
+ <cell>_diameters Service Name and Port Number Registration</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.5</cell>
+ <cell>SCTP Payload Protocol Identifiers</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>11.6</cell>
+ <cell>S-NAPTR Parameters</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>12</cell>
+ <cell>Diameter Protocol-Related Configurable Parameters</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>13</cell>
+ <cell>Security Considerations</cell>
+ <cell>PC</cell>
+ <cell>See 2.1.&BR;
+ IPsec is transparent to diameter.</cell>
+</row>
+<row>
+ <cell>13.1</cell>
+ <cell>TLS/TCP and DTLS/SCTP Usage</cell>
+ <cell>PC</cell>
+ <cell>See 2.1.</cell>
+</row>
+<row>
+ <cell>13.2</cell>
+ <cell>Peer-to-Peer Considerations</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>13.3</cell>
+ <cell>AVP Considerations</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>14</cell>
+ <cell>References</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>14.1</cell>
+ <cell>Normative References</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+<row>
+ <cell>14.2</cell>
+ <cell>Informative References</cell>
+ <cell>&NA;</cell>
+ <cell></cell>
+</row>
+
+<tcaption>RFC 6733 Compliance</tcaption>
+</table>
</section>
</chapter>
+
+<!-- LocalWords: AVP AVPs CCF DiameterIdentity CEA CER Inband IP
+-->
+<!-- LocalWords: DPA DPR DWR DWA Failover Failback Proxying Auth
+-->
+<!-- LocalWords: interoperability Multi Timestamp Realtime
+-->
diff --git a/lib/diameter/doc/src/diameter_soc_rfc6733.xml b/lib/diameter/doc/src/diameter_soc_rfc6733.xml
deleted file mode 100644
index 2098965706..0000000000
--- a/lib/diameter/doc/src/diameter_soc_rfc6733.xml
+++ /dev/null
@@ -1,8693 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-
-<!--
-
-<copyright>
-<year>2013</year><year>2016</year>
-<holder>Ericsson AB. All Rights Reserved.</holder>
-</copyright>
-
-<legalnotice>
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-</legalnotice>
-
--->
-
-<!DOCTYPE section SYSTEM "chapter.dtd" [
- <!ENTITY gen_sctp '<seealso marker="kernel:gen_sctp">gen_sctp(3)</seealso>'>
- <!ENTITY gen_tcp '<seealso marker="kernel:gen_tcp">gen_tcp(3)</seealso>'>
- <!ENTITY service '<seealso marker="diameter#start_service-2">service</seealso>'>
- <!ENTITY capabilities '<seealso marker="diameter#capability">capabilities</seealso>'>
- <!ENTITY events '<seealso marker="diameter#service_event">events</seealso>'>
- <!ENTITY nada '<p>No comment.</p>'>
- <!ENTITY % also SYSTEM "seealso.ent" >
- %also;
-]>
-
-<section>
-<title>Commentary</title>
-
-<p>
-A more detailed commentary on &the_rfc; follows.
-Its purpose is to (hopefully) clarify not only what is supported but
-how, given that semantics and features discussed in the RFC are not
-solely the responsibility of the diameter application:
-in many cases much depends on the configuration a user passes to
-diameter, the implementation of &man_app; callback modules in
-particular.</p>
-
-<p>
-Comments apply to all text following the preceding comment.
-Be sure to distinguish between capitalized <em>Diameter</em>, the
-protocol defined by the RFC, and lowercase <em>diameter</em>, the
-Erlang application to which the commentary applies.</p>
-
-<warning>
-<p>
-The commentary is not yet complete.
-Comments currently stop at chapter 4.</p>
-</warning>
-
-<pre>
-Fajardo, et al. Standards Track [Page 6]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-1. Introduction
-
- Authentication, Authorization, and Accounting (AAA) protocols such as
- TACACS [RFC1492] and RADIUS [RFC2865] were initially deployed to
- provide dial-up PPP [RFC1661] and terminal server access. Over time,
- AAA support was needed on many new access technologies, the scale and
- complexity of AAA networks grew, and AAA was also used on new
- applications (such as voice over IP). This led to new demands on AAA
- protocols.
-</pre>
-
-<p>
-Note that diameter implements the Diameter protocol as defined in
-&the_rfc;.
-It also supported the previous version of the protocol, as defined in
-RFC 3588, when there are differences.
-(Which will be noted below.)
-It does not support RADIUS.</p>
-
-<pre>
-
- Network access requirements for AAA protocols are summarized in
- Aboba, et al. [RFC2989]. These include:
-
- Failover
-
- [RFC2865] does not define failover mechanisms and, as a result,
- failover behavior differs between implementations. In order to
- provide well-defined failover behavior, Diameter supports
- application-layer acknowledgements and defines failover algorithms
- and the associated state machine.
-</pre>
-
-&nada;
-
-<pre>
-
- Transmission-level security
-
- RADIUS [RFC2865] defines an application-layer authentication and
- integrity scheme that is required only for use with response
- packets. While [RFC2869] defines an additional authentication and
- integrity mechanism, use is only required during Extensible
- Authentication Protocol (EAP) [RFC3748] sessions. While attribute
- hiding is supported, [RFC2865] does not provide support for per-
- packet confidentiality. In accounting, [RFC2866] assumes that
- replay protection is provided by the backend billing server rather
- than within the protocol itself.
-
- While [RFC3162] defines the use of IPsec with RADIUS, support for
- IPsec is not required. In order to provide universal support for
- transmission-level security, and enable both intra- and inter-
- domain AAA deployments, Diameter provides support for TLS/TCP and
- DTLS/SCTP. Security is discussed in Section 13.
-</pre>
-
-<p>
-Whether or not IPsec is used is transparent to diameter.</p>
-
-<p>
-The transport protocol used on a given peer connection is also
-transparent to diameter in that transport to diameter is simply a
-module that implements the transport protocol documented in
-&man_transport;.
-A diameter user configures this module as the &mod_transport_opt;
-<c>transport_module</c>.</p>
-
-<p>
-While a user can implement their own transport modules, diameter
-includes implementations for TCP and SCTP:
-&man_tcp; based on &gen_tcp; and &man_sctp; based on &gen_sctp;.
-The former supports TLS but the latter does not currently support
-DTLS.</p>
-
-<pre>
-
- Reliable transport
-
- RADIUS runs over UDP, and does not define retransmission behavior;
- as a result, reliability varies between implementations. As
- described in [RFC2975], this is a major issue in accounting, where
- packet loss may translate directly into revenue loss. In order to
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 7]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- provide well-defined transport behavior, Diameter runs over
- reliable transport mechanisms (TCP, Stream Control Transmission
- Protocol (SCTP)) as defined in [RFC3539].
-
- Agent support
-
- RADIUS does not provide for explicit support for agents, including
- proxies, redirects, and relays. Since the expected behavior is
- not defined, it varies between implementations. Diameter defines
- agent behavior explicitly; this is described in Section 2.8.
-</pre>
-
-&nada;
-
-<pre>
-
- Server-initiated messages
-
- While server-initiated messages are defined in RADIUS [RFC5176],
- support is optional. This makes it difficult to implement
- features such as unsolicited disconnect or re-authentication/
- re-authorization on demand across a heterogeneous deployment. To
- address this issue, support for server-initiated messages is
- mandatory in Diameter.
-</pre>
-
-<p>
-A diameter user can both send and receive messages.</p>
-
-<pre>
-
- Transition support
-
- While Diameter does not share a common protocol data unit (PDU)
- with RADIUS, considerable effort has been expended in enabling
- backward compatibility with RADIUS so that the two protocols may
- be deployed in the same network. Initially, it is expected that
- Diameter will be deployed within new network devices, as well as
- within gateways enabling communication between legacy RADIUS
- devices and Diameter agents. This capability enables Diameter
- support to be added to legacy networks, by addition of a gateway
- or server speaking both RADIUS and Diameter.
-</pre>
-
-<p>
-RADIUS Attributes can be redefined as Diameter AVP's using diameter's
-&man_dict; interface but diameter provides no such definitions.</p>
-
-<pre>
-
- In addition to addressing the above requirements, Diameter also
- provides support for the following:
-
- Capability negotiation
-
- RADIUS does not support error messages, capability negotiation, or
- a mandatory/non-mandatory flag for attributes. Since RADIUS
- clients and servers are not aware of each other's capabilities,
- they may not be able to successfully negotiate a mutually
- acceptable service or, in some cases, even be aware of what
- service has been implemented. Diameter includes support for error
- handling (Section 7), capability negotiation (Section 5.3), and
- mandatory/non-mandatory Attribute-Value Pairs (AVPs)
- (Section 4.1).
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 8]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Peer discovery and configuration
-
- RADIUS implementations typically require that the name or address
- of servers or clients be manually configured, along with the
- corresponding shared secrets. This results in a large
- administrative burden and creates the temptation to reuse the
- RADIUS shared secret, which can result in major security
- vulnerabilities if the Request Authenticator is not globally and
- temporally unique as required in [RFC2865]. Through DNS, Diameter
- enables dynamic discovery of peers (see Section 5.2). Derivation
- of dynamic session keys is enabled via transmission-level
- security.
-
- Over time, the capabilities of Network Access Server (NAS) devices
- have increased substantially. As a result, while Diameter is a
- considerably more sophisticated protocol than RADIUS, it remains
- feasible to implement it within embedded devices.
-</pre>
-
-&nada;
-
-<pre>
-
-1.1. Diameter Protocol
-
- The Diameter base protocol provides the following facilities:
-
- o Ability to exchange messages and deliver AVPs
-</pre>
-
-<p>
-There are two interfaces directly involved in message exchange when
-using diameter: the function &mod_call; for sending outgoing requests,
-and the application callback interface, documented in &man_app; for
-receiving incoming request and answers.</p>
-
-<pre>
-
- o Capabilities negotiation
-</pre>
-
-<p>
-Capabilities negotiation is the responsibility of diameter:
-a user configures a diameter service and/or transport with
-&capabilities; to provide AVP values for CER and CEA messages but it
-is diameter itself that sends these messages.
-A user receives notification of a successful capabilities exchange by
-way of &app_peer_up; callbacks.</p>
-
-<pre>
-
- o Error notification
-</pre>
-
-<p>
-A user can subscribe to &events;, using &mod_subscribe;, in order to
-receive notification of various failures.
-Errors in Diameter messaging are communicated via the application
-callbacks &app_handle_request;, &app_handle_answer; and
-&app_handle_error;.</p>
-
-
-<pre>
-
- o Extensibility, required in [RFC2989], through addition of new
- applications, commands, and AVPs
-</pre>
-
-<p>
-Support for applications, commands and AVP's is extensible using
-diameter's dictionary interface, as documented in &man_dict;.
-Dictionaries are compiled to Erlang encode/decode modules using
-&man_compile; or &man_make;.</p>
-
-<pre>
-
- o Basic services necessary for applications, such as the handling of
- user sessions or accounting
-</pre>
-
-<p>
-Compiled dictionaries are provided for the RFC 3588 and RFC 6733
-Diameter applications: common, base accounting and relay.
-Dictionaries for a number of standardized
-applications are provided in uncompiled form below the <c>examples</c>
-subdirectory of the diameter application directory.</p>
-
-<pre>
-
- All data delivered by the protocol is in the form of AVPs. Some of
- these AVP values are used by the Diameter protocol itself, while
- others deliver data associated with particular applications that
- employ Diameter. AVPs may be arbitrarily added to Diameter messages,
- the only restriction being that the Command Code Format (CCF)
- specification (Section 3.2) be satisfied. AVPs are used by the base
- Diameter protocol to support the following required features:
-
- o Transporting of user authentication information, for the purposes
- of enabling the Diameter server to authenticate the user
-
- o Transporting of service-specific authorization information,
- between client and servers, allowing the peers to decide whether a
- user's access request should be granted
-
-
-
-Fajardo, et al. Standards Track [Page 9]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o Exchanging resource usage information, which may be used for
- accounting purposes, capacity planning, etc.
-
- o Routing, relaying, proxying, and redirecting of Diameter messages
- through a server hierarchy
-
- The Diameter base protocol satisfies the minimum requirements for a
- AAA protocol, as specified by [RFC2989]. The base protocol may be
- used by itself for accounting purposes only, or it may be used with a
- Diameter application, such as Mobile IPv4 [RFC4004], or network
- access [RFC4005]. It is also possible for the base protocol to be
- extended for use in new applications, via the addition of new
- commands or AVPs. The initial focus of Diameter was network access
- and accounting applications. A truly generic AAA protocol used by
- many applications might provide functionality not provided by
- Diameter. Therefore, it is imperative that the designers of new
- applications understand their requirements before using Diameter.
- See Section 1.3.4 for more information on Diameter applications.
-
- Any node can initiate a request. In that sense, Diameter is a peer-
- to-peer protocol. In this document, a Diameter client is a device at
- the edge of the network that performs access control, such as a
- Network Access Server (NAS) or a Foreign Agent (FA). A Diameter
- client generates Diameter messages to request authentication,
- authorization, and accounting services for the user. A Diameter
- agent is a node that does not provide local user authentication or
- authorization services; agents include proxies, redirects, and relay
- agents. A Diameter server performs authentication and/or
- authorization of the user. A Diameter node may act as an agent for
- certain requests while acting as a server for others.
-
- The Diameter protocol also supports server-initiated messages, such
- as a request to abort service to a particular user.
-</pre>
-
-&nada;
-
-<pre>
-
-1.1.1. Description of the Document Set
-
- The Diameter specification consists of an updated version of the base
- protocol specification (this document) and the Transport Profile
- [RFC3539]. This document obsoletes both RFC 3588 and RFC 5719. A
- summary of the base protocol updates included in this document can be
- found in Section 1.1.3.
-
- This document defines the base protocol specification for AAA, which
- includes support for accounting. There are also a myriad of
- applications documents describing applications that use this base
- specification for Authentication, Authorization, and Accounting.
- These application documents specify how to use the Diameter protocol
- within the context of their application.
-
-
-
-Fajardo, et al. Standards Track [Page 10]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The Transport Profile document [RFC3539] discusses transport layer
- issues that arise with AAA protocols and recommendations on how to
- overcome these issues. This document also defines the Diameter
- failover algorithm and state machine.
-
- "Clarifications on the Routing of Diameter Request Based on the
- Username and the Realm" [RFC5729] defines specific behavior on how to
- route requests based on the content of the User-Name AVP (Attribute
- Value Pair).
-
-1.1.2. Conventions Used in This Document
-
- The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
- "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
- document are to be interpreted as described in [RFC2119].
-</pre>
-
-&nada;
-
-<pre>
-
-1.1.3. Changes from RFC 3588
-
- This document obsoletes RFC 3588 but is fully backward compatible
- with that document. The changes introduced in this document focus on
- fixing issues that have surfaced during the implementation of
- Diameter (RFC 3588). An overview of some the major changes are given
- below.
-</pre>
-
-<p>
-RFC 6733 is not fully backwards compatible with RFC 3588.
-(For example, in what values of Result-Code values are permissible with
-the E-bit.)
-The implications of incompatibilities for diameter are noted where
-appropriate.</p>
-
-<pre>
-
- o Deprecated the use of the Inband-Security AVP for negotiating
- Transport Layer Security (TLS) [RFC5246]. It has been generally
- considered that bootstrapping of TLS via Inband-Security AVP
- creates certain security risks because it does not completely
- protect the information carried in the CER/CEA (Capabilities-
- Exchange-Request/Capabilities-Exchange-Answer). This version of
- Diameter adopts the common approach of defining a well-known
- secured port that peers should use when communicating via TLS/TCP
- and DTLS/SCTP. This new approach augments the existing in-band
- security negotiation, but it does not completely replace it. The
- old method is kept for backward compatibility reasons.
-</pre>
-
-<p>
-&man_tcp; supports both methods of negotiating TLS:
-bootstrapping via Inband-Security and directly following connection
-establishment.</p>
-
-<pre>
-
- o Deprecated the exchange of CER/CEA messages in the open state.
- This feature was implied in the peer state machine table of RFC
- 3588, but it was not clearly defined anywhere else in that
- document. As work on this document progressed, it became clear
- that the multiplicity of meaning and use of Application-Id AVPs in
- the CER/CEA messages (and the messages themselves) is seen as an
- abuse of the Diameter extensibility rules and thus required
- simplification. Capabilities exchange in the open state has been
- re-introduced in a separate specification [RFC6737], which clearly
- defines new commands for this feature.
-</pre>
-
-<p>
-Capabilities exchange in the open state is not supported: an incoming
-CER in the open state will cause diameter to ask the relevant
-transport process to terminate, which implies the loss of the peer
-connection in the case of &man_tcp; and &man_sctp;.</p>
-
-<p>
-Capabilities update, as defined by RFC 6737, is not yet supported.
-Support will require diameter to handle CUR/CUA in the same way that
-it handles CER/CEA.</p>
-
-<pre>
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 11]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o Simplified security requirements. The use of a secured transport
- for exchanging Diameter messages remains mandatory. However, TLS/
- TCP and DTLS/SCTP have become the primary methods of securing
- Diameter with IPsec as a secondary alternative. See Section 13
- for details. The support for the End-to-End security framework
- (E2E-Sequence AVP and 'P'-bit in the AVP header) has also been
- deprecated.
-</pre>
-
-<p>
-The End-to-End security framework is not supported since it's use is
-largely unspecified: diameter will set the P-bit in outgoing AVP's as
-directed by the relevant dictionary and/or &app_prepare_request; or
-&app_handle_request; callbacks, but whether or not the P-bit is set on
-incoming AVP's has no consequence.</p>
-
-<p>
-As noted above, DTLS is not currently supported and whether or not
-IPsec is used is transparent to diameter.</p>
-
-<pre>
-
- o Changed Diameter extensibility. This includes fixes to the
- Diameter extensibility description (Section 1.3 and others) to
- better aid Diameter application designers; in addition, the new
- specification relaxes the policy with respect to the allocation of
- Command Codes for vendor-specific uses.
-
- o Clarified Application Id usage. Clarify the proper use of
- Application Id information, which can be found in multiple places
- within a Diameter message. This includes correlating Application
- Ids found in the message headers and AVPs. These changes also
- clearly specify the proper Application Id value to use for
- specific base protocol messages (ASR/ASA, STR/STA) as well as
- clarify the content and use of Vendor-Specific-Application-Id.
-
- o Clarified routing fixes. This document more clearly specifies
- what information (AVPs and Application Ids) can be used for making
- general routing decisions. A rule for the prioritization of
- redirect routing criteria when multiple route entries are found
- via redirects has also been added (see Section 6.13).
-
- o Simplified Diameter peer discovery. The Diameter discovery
- process now supports only widely used discovery schemes; the rest
- have been deprecated (see Section 5.2 for details).
-</pre>
-
-<p>
-Peer discover is not currently supported: peers to which a node should
-connect must be configured.
-Connection requests are accepted from arbitrary peers but a
-&mod_transport_opt; <c>capabilities_cb</c> can be used to reject a
-peer based on an incoming CER or CEA.</p>
-
-<pre>
-
- There are many other miscellaneous fixes that have been introduced in
- this document that may not be considered significant, but they have
- value nonetheless. Examples are removal of obsolete types, fixes to
- the state machine, clarification of the election process, message
- validation, fixes to Failed-AVP and Result-Code AVP values, etc. All
- of the errata filed against RFC 3588 prior to the publication of this
- document have been addressed. A comprehensive list of changes is not
- shown here for practical reasons.
-
-1.2. Terminology
-
- AAA
-
- Authentication, Authorization, and Accounting.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 12]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- ABNF
-
- Augmented Backus-Naur Form [RFC5234]. A metalanguage with its own
- formal syntax and rules. It is based on the Backus-Naur Form and
- is used to define message exchanges in a bi-directional
- communications protocol.
-
- Accounting
-
- The act of collecting information on resource usage for the
- purpose of capacity planning, auditing, billing, or cost
- allocation.
-
- Accounting Record
-
- An accounting record represents a summary of the resource
- consumption of a user over the entire session. Accounting servers
- creating the accounting record may do so by processing interim
- accounting events or accounting events from several devices
- serving the same user.
-
- Authentication
-
- The act of verifying the identity of an entity (subject).
-
- Authorization
-
- The act of determining whether a requesting entity (subject) will
- be allowed access to a resource (object).
-
- Attribute-Value Pair (AVP)
-
- The Diameter protocol consists of a header followed by one or more
- Attribute-Value-Pairs (AVPs). An AVP includes a header and is
- used to encapsulate protocol-specific data (e.g., routing
- information) as well as authentication, authorization, or
- accounting information.
-</pre>
-
-&nada;
-
-<pre>
-
- Command Code Format (CCF)
-
- A modified form of ABNF used to define Diameter commands (see
- Section 3.2).
-</pre>
-
-<p>
-The <c>@messages</c> section of the &man_dict; format has the CCF as
-content.</p>
-
-<pre>
-
- Diameter Agent
-
- A Diameter Agent is a Diameter node that provides relay, proxy,
- redirect, or translation services.
-
-
-
-
-Fajardo, et al. Standards Track [Page 13]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Diameter Client
-
- A Diameter client is a Diameter node that supports Diameter client
- applications as well as the base protocol. Diameter clients are
- often implemented in devices situated at the edge of a network and
- provide access control services for that network. Typical
- examples of Diameter clients include the Network Access Server
- (NAS) and the Mobile IP Foreign Agent (FA).
-
- Diameter Node
-
- A Diameter node is a host process that implements the Diameter
- protocol and acts as either a client, an agent, or a server.
-
- Diameter Peer
-
- Two Diameter nodes sharing a direct TCP or SCTP transport
- connection are called Diameter peers.
-
- Diameter Server
-
- A Diameter server is a Diameter node that handles authentication,
- authorization, and accounting requests for a particular realm. By
- its very nature, a Diameter server must support Diameter server
- applications in addition to the base protocol.
-</pre>
-
-<p>
-A Diameter Node is implemented by configuring a service
-using &mod_start_service; and one or more transports using
-&mod_add_transport;.
-The service typically represents a Diameter Node but since
-capabilities can be configured on individual transports it's more
-accurate to say that the node is a collection of transports
-advertising the same Origin-Host.</p>
-
-<p>
-The role of a node (agent, client or server) is not something that's
-configured explicitly.
-Transports are either connecting or listening, depending on whether
-diameter should establish a peer connection and send CER or accept
-connections and receive CER, but the role a node implements depends
-largely on dictionary configuration and &man_app; callback
-implementation.</p>
-
-<pre>
-
- Downstream
-
- Downstream is used to identify the direction of a particular
- Diameter message from the home server towards the Diameter client.
-
- Home Realm
-
- A Home Realm is the administrative domain with which the user
- maintains an account relationship.
-
- Home Server
-
- A Diameter server that serves the Home Realm.
-
- Interim Accounting
-
- An interim accounting message provides a snapshot of usage during
- a user's session. Typically, it is implemented in order to
- provide for partial accounting of a user's session in case a
- device reboot or other network problem prevents the delivery of a
- session summary message or session record.
-
-
-
-
-Fajardo, et al. Standards Track [Page 14]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Local Realm
-
- A local realm is the administrative domain providing services to a
- user. An administrative domain may act as a local realm for
- certain users while being a home realm for others.
-
- Multi-session
-
- A multi-session represents a logical linking of several sessions.
- Multi-sessions are tracked by using the Acct-Multi-Session-Id. An
- example of a multi-session would be a Multi-link PPP bundle. Each
- leg of the bundle would be a session while the entire bundle would
- be a multi-session.
-
- Network Access Identifier
-
- The Network Access Identifier, or NAI [RFC4282], is used in the
- Diameter protocol to extract a user's identity and realm. The
- identity is used to identify the user during authentication and/or
- authorization while the realm is used for message routing
- purposes.
-
- Proxy Agent or Proxy
-
- In addition to forwarding requests and responses, proxies make
- policy decisions relating to resource usage and provisioning.
- Typically, this is accomplished by tracking the state of NAS
- devices. While proxies usually do not respond to client requests
- prior to receiving a response from the server, they may originate
- Reject messages in cases where policies are violated. As a
- result, proxies need to understand the semantics of the messages
- passing through them, and they may not support all Diameter
- applications.
-
- Realm
-
- The string in the NAI that immediately follows the '@' character.
- NAI realm names are required to be unique and are piggybacked on
- the administration of the DNS namespace. Diameter makes use of
- the realm, also loosely referred to as domain, to determine
- whether messages can be satisfied locally or whether they must be
- routed or redirected. In RADIUS, realm names are not necessarily
- piggybacked on the DNS namespace but may be independent of it.
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 15]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Real-Time Accounting
-
- Real-time accounting involves the processing of information on
- resource usage within a defined time window. Typically, time
- constraints are imposed in order to limit financial risk. The
- Diameter Credit-Control Application [RFC4006] is an example of an
- application that defines real-time accounting functionality.
-
- Relay Agent or Relay
-
- Relays forward requests and responses based on routing-related
- AVPs and routing table entries. Since relays do not make policy
- decisions, they do not examine or alter non-routing AVPs. As a
- result, relays never originate messages, do not need to understand
- the semantics of messages or non-routing AVPs, and are capable of
- handling any Diameter application or message type. Since relays
- make decisions based on information in routing AVPs and realm
- forwarding tables, they do not keep state on NAS resource usage or
- sessions in progress.
-
- Redirect Agent
-
- Rather than forwarding requests and responses between clients and
- servers, redirect agents refer clients to servers and allow them
- to communicate directly. Since redirect agents do not sit in the
- forwarding path, they do not alter any AVPs transiting between
- client and server. Redirect agents do not originate messages and
- are capable of handling any message type, although they may be
- configured only to redirect messages of certain types, while
- acting as relay or proxy agents for other types. As with relay
- agents, redirect agents do not keep state with respect to sessions
- or NAS resources.
-</pre>
-
-&nada;
-
-<pre>
-
- Session
-
- A session is a related progression of events devoted to a
- particular activity. Diameter application documents provide
- guidelines as to when a session begins and ends. All Diameter
- packets with the same Session-Id are considered to be part of the
- same session.
-</pre>
-
-<p>
-Sessions are not something that diameter is aware of.
-The function &mod_session_id; can be used to construct appropriate
-values for Session-Id AVP's but logic connecting events in the same
-session is the responsibility of the diameter user.</p>
-
-<pre>
-
- Stateful Agent
-
- A stateful agent is one that maintains session state information,
- by keeping track of all authorized active sessions. Each
- authorized session is bound to a particular service, and its state
- is considered active either until it is notified otherwise or
- until expiration.
-
-
-
-Fajardo, et al. Standards Track [Page 16]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Sub-session
-
- A sub-session represents a distinct service (e.g., QoS or data
- characteristics) provided to a given session. These services may
- happen concurrently (e.g., simultaneous voice and data transfer
- during the same session) or serially. These changes in sessions
- are tracked with the Accounting-Sub-Session-Id.
-
- Transaction State
-
- The Diameter protocol requires that agents maintain transaction
- state, which is used for failover purposes. Transaction state
- implies that upon forwarding a request, the Hop-by-Hop Identifier
- is saved; the field is replaced with a locally unique identifier,
- which is restored to its original value when the corresponding
- answer is received. The request's state is released upon receipt
- of the answer. A stateless agent is one that only maintains
- transaction state.
-
- Translation Agent
-
- A translation agent (TLA in Figure 4) is a stateful Diameter node
- that performs protocol translation between Diameter and another
- AAA protocol, such as RADIUS.
-
- Upstream
-
- Upstream is used to identify the direction of a particular
- Diameter message from the Diameter client towards the home server.
-
- User
-
- The entity or device requesting or using some resource, in support
- of which a Diameter client has generated a request.
-</pre>
-
-&nada;
-
-<pre>
-
-1.3. Approach to Extensibility
-
- The Diameter protocol is designed to be extensible, using several
- mechanisms, including:
-
- o Defining new AVP values
-
- o Creating new AVPs
-
- o Creating new commands
-
- o Creating new applications
-
-
-
-
-Fajardo, et al. Standards Track [Page 17]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- From the point of view of extensibility, Diameter authentication,
- authorization, and accounting applications are treated in the same
- way.
-</pre>
-
-<p>
-Extensibility in diameter is by way of the dictionary interface
-documented in &man_dict;: a diameter user creates applications,
-commands and AVP's by implementing a new dictionary,
-compiling the dictionary to a codec module using &man_compile; or
-&man_make;, and configuring the resulting dictionary module on a
-service.
-The dictionary modules provided with diameter are all implemented in
-this manner.</p>
-
-<pre>
- Note: Protocol designers should try to reuse existing functionality,
- namely AVP values, AVPs, commands, and Diameter applications. Reuse
- simplifies standardization and implementation. To avoid potential
- interoperability issues, it is important to ensure that the semantics
- of the reused features are well understood. Given that Diameter can
- also carry RADIUS attributes as Diameter AVPs, such reuse
- considerations also apply to existing RADIUS attributes that may be
- useful in a Diameter application.
-</pre>
-
-<p>
-Reuse in dictionary files is achieved by way of the <c>@inherits</c>
-section.
-AVP's are inherited, commands are not.</p>
-
-<pre>
-
-1.3.1. Defining New AVP Values
-
- In order to allocate a new AVP value for AVPs defined in the Diameter
- base protocol, the IETF needs to approve a new RFC that describes the
- AVP value. IANA considerations for these AVP values are discussed in
- Section 11.3.
-
- The allocation of AVP values for other AVPs is guided by the IANA
- considerations of the document that defines those AVPs. Typically,
- allocation of new values for an AVP defined in an RFC would require
- IETF Review [RFC5226], whereas values for vendor-specific AVPs can be
- allocated by the vendor.
-
-1.3.2. Creating New AVPs
-
- A new AVP being defined MUST use one of the data types listed in
- Sections 4.2 or 4.3. If an appropriate derived data type is already
- defined, it SHOULD be used instead of a base data type to encourage
- reusability and good design practice.
-
- In the event that a logical grouping of AVPs is necessary, and
- multiple "groups" are possible in a given command, it is recommended
- that a Grouped AVP be used (see Section 4.4).
-
- The creation of new AVPs can happen in various ways. The recommended
- approach is to define a new general-purpose AVP in a Standards Track
- RFC approved by the IETF. However, as described in Section 11.1.1,
- there are other mechanisms.
-</pre>
-
-<p>
-Creating new AVP's is an issue for the dictionary designer, not
-diameter.</p>
-
-<pre>
-
-1.3.3. Creating New Commands
-
- A new Command Code MUST be allocated when required AVPs (those
- indicated as {AVP} in the CCF definition) are added to, deleted from,
- or redefined in (for example, by changing a required AVP into an
- optional one) an existing command.
-
-
-
-Fajardo, et al. Standards Track [Page 18]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Furthermore, if the transport characteristics of a command are
- changed (for example, with respect to the number of round trips
- required), a new Command Code MUST be registered.
-
- A change to the CCF of a command, such as described above, MUST
- result in the definition of a new Command Code. This subsequently
- leads to the need to define a new Diameter application for any
- application that will use that new command.
-
- The IANA considerations for Command Codes are discussed in
- Section 3.1.
-</pre>
-
-<p>
-Creating new commands is an issue for the dictionary designer, not
-diameter.</p>
-
-<pre>
-
-1.3.4. Creating New Diameter Applications
-
- Every Diameter application specification MUST have an IANA-assigned
- Application Id (see Section 2.4). The managed Application ID space
- is flat, and there is no relationship between different Diameter
- applications with respect to their Application Ids. As such, there
- is no versioning support provided by these Application Ids
- themselves; every Diameter application is a standalone application.
- If the application has a relationship with other Diameter
- applications, such a relationship is not known to Diameter.
-</pre>
-
-<p>
-Creating new applications is an issue for the dictionary designer,
-not diameter.</p>
-
-<p>
-An application's Application Id is specified in the <c>@id</c> section
-of a dictionary file.</p>
-
-<pre>
-
- Before describing the rules for creating new Diameter applications,
- it is important to discuss the semantics of the AVP occurrences as
- stated in the CCF and the M-bit flag (Section 4.1) for an AVP. There
- is no relationship imposed between the two; they are set
- independently.
-
- o The CCF indicates what AVPs are placed into a Diameter command by
- the sender of that command. Often, since there are multiple modes
- of protocol interactions, many of the AVPs are indicated as
- optional.
-
- o The M-bit allows the sender to indicate to the receiver whether or
- not understanding the semantics of an AVP and its content is
- mandatory. If the M-bit is set by the sender and the receiver
- does not understand the AVP or the values carried within that AVP,
- then a failure is generated (see Section 7).
-</pre>
-
-<p>
-The M-bit is set on outgoing AVP's as directed by the relevant
-dictionary.
-For incoming AVP's, an M-bit set on an AVP that isn't
-explicitly included in the definition of the command in question is
-interpreted as a 5001 error, DIAMETER_AVP_UNSUPPORTED, the
-consequences of which depend on the value of the &mod_application_opt;
-<c>answer_errors</c> or <c>request_errors</c>.</p>
-
-<pre>
-
- It is the decision of the protocol designer when to develop a new
- Diameter application rather than extending Diameter in other ways.
- However, a new Diameter application MUST be created when one or more
- of the following criteria are met:
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 19]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- M-bit Setting
-
- An AVP with the M-bit in the MUST column of the AVP flag table is
- added to an existing Command/Application. An AVP with the M-bit
- in the MAY column of the AVP flag table is added to an existing
- Command/Application.
-
- Note: The M-bit setting for a given AVP is relevant to an
- Application and each command within that application that includes
- the AVP. That is, if an AVP appears in two commands for
- application Foo and the M-bit settings are different in each
- command, then there should be two AVP flag tables describing when
- to set the M-bit.
-
- Commands
-
- A new command is used within the existing application because
- either an additional command is added, an existing command has
- been modified so that a new Command Code had to be registered, or
- a command has been deleted.
-
- AVP Flag bits
-
- If an existing application changes the meaning/semantics of its
- AVP Flags or adds new flag bits, then a new Diameter application
- MUST be created.
-
- If the CCF definition of a command allows it, an implementation may
- add arbitrary optional AVPs with the M-bit cleared (including vendor-
- specific AVPs) to that command without needing to define a new
- application. Please refer to Section 11.1.1 for details.
-</pre>
-
-&nada;
-
-<pre>
-
-2. Protocol Overview
-
- The base Diameter protocol concerns itself with establishing
- connections to peers, capabilities negotiation, how messages are sent
- and routed through peers, and how the connections are eventually torn
- down. The base protocol also defines certain rules that apply to all
- message exchanges between Diameter nodes.
-
- Communication between Diameter peers begins with one peer sending a
- message to another Diameter peer. The set of AVPs included in the
- message is determined by a particular Diameter application. One AVP
- that is included to reference a user's session is the Session-Id.
-
- The initial request for authentication and/or authorization of a user
- would include the Session-Id AVP. The Session-Id is then used in all
- subsequent messages to identify the user's session (see Section 8 for
-
-
-
-Fajardo, et al. Standards Track [Page 20]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- more information). The communicating party may accept the request or
- reject it by returning an answer message with the Result-Code AVP set
- to indicate that an error occurred. The specific behavior of the
- Diameter server or client receiving a request depends on the Diameter
- application employed.
-
- Session state (associated with a Session-Id) MUST be freed upon
- receipt of the Session-Termination-Request, Session-Termination-
- Answer, expiration of authorized service time in the Session-Timeout
- AVP, and according to rules established in a particular Diameter
- application.
-</pre>
-
-<p>
-Like Session-Id, session state is maintained by the diameter user:
-diameter has no session state of its own and does not interpret
-STR/STA in any way.</p>
-
-<pre>
-
- The base Diameter protocol may be used by itself for accounting
- applications. For authentication and authorization, it is always
- extended for a particular application.
-
- Diameter clients MUST support the base protocol, which includes
- accounting. In addition, they MUST fully support each Diameter
- application that is needed to implement the client's service, e.g.,
- Network Access Server Requirements (NASREQ) [RFC2881] and/or Mobile
- IPv4. A Diameter client MUST be referred to as "Diameter X Client"
- where X is the application that it supports and not a "Diameter
- Client".
-
- Diameter servers MUST support the base protocol, which includes
- accounting. In addition, they MUST fully support each Diameter
- application that is needed to implement the intended service, e.g.,
- NASREQ and/or Mobile IPv4. A Diameter server MUST be referred to as
- "Diameter X Server" where X is the application that it supports, and
- not a "Diameter Server".
-
- Diameter relays and redirect agents are transparent to the Diameter
- applications, but they MUST support the Diameter base protocol, which
- includes accounting, and all Diameter applications.
-
- Diameter proxies MUST support the base protocol, which includes
- accounting. In addition, they MUST fully support each Diameter
- application that is needed to implement proxied services, e.g.,
- NASREQ and/or Mobile IPv4. A Diameter proxy MUST be referred to as
- "Diameter X Proxy" where X is the application which it supports, and
- not a "Diameter Proxy".
-
-</pre>
-
-&nada;
-
-<pre>
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 21]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-2.1. Transport
-
- The Diameter Transport profile is defined in [RFC3539].
-
- The base Diameter protocol is run on port 3868 for both TCP [RFC0793]
- and SCTP [RFC4960]. For TLS [RFC5246] and Datagram Transport Layer
- Security (DTLS) [RFC6347], a Diameter node that initiates a
- connection prior to any message exchanges MUST run on port 5658. It
- is assumed that TLS is run on top of TCP when it is used, and DTLS is
- run on top of SCTP when it is used.
-</pre>
-
-<p>
-Which port a transport connects to or listens on is a matter of
-configuration.
-Both &man_tcp; and &man_sctp; will default to 3868 if no other value
-is specified.</p>
-
-<pre>
-
- If the Diameter peer does not support receiving TLS/TCP and DTLS/SCTP
- connections on port 5658 (i.e., the peer complies only with RFC
- 3588), then the initiator MAY revert to using TCP or SCTP on port
- 3868. Note that this scheme is kept only for the purpose of backward
- compatibility and that there are inherent security vulnerabilities
- when the initial CER/CEA messages are sent unprotected (see
- Section 5.6).
-
- Diameter clients MUST support either TCP or SCTP; agents and servers
- SHOULD support both.
-
- A Diameter node MAY initiate connections from a source port other
- than the one that it declares it accepts incoming connections on, and
- it MUST always be prepared to receive connections on port 3868 for
- TCP or SCTP and port 5658 for TLS/TCP and DTLS/SCTP connections.
- When DNS-based peer discovery (Section 5.2) is used, the port numbers
- received from SRV records take precedence over the default ports
- (3868 and 5658).
-
- A given Diameter instance of the peer state machine MUST NOT use more
- than one transport connection to communicate with a given peer,
- unless multiple instances exist on the peer, in which, case a
- separate connection per process is allowed.
-</pre>
-
-<p>
-The &mod_service_opt; <c>restrict_connection</c> controls to what
-extent a diameter service allows multiple connections to the same
-peer.
-(As identified by the value of Origin-Host received from it
-during capabilities exchange.)</p>
-
-<pre>
-
- When no transport connection exists with a peer, an attempt to
- connect SHOULD be made periodically. This behavior is handled via
- the Tc timer (see Section 12 for details), whose recommended value is
- 30 seconds. There are certain exceptions to this rule, such as when
- a peer has terminated the transport connection stating that it does
- not wish to communicate.
-
-</pre>
-
-<p>
-The frequency of reconnection attempts is configured with the
-&mod_transport_opt; <c>connect_timer</c> and
-<c>watchdog_timer</c>.</p>
-
-<pre>
-
- When connecting to a peer and either zero or more transports are
- specified, TLS SHOULD be tried first, followed by DTLS, then by TCP,
- and finally by SCTP. See Section 5.2 for more information on peer
- discovery.
-</pre>
-
-<p>
-The order in which different transports are attempted depends on the
-order of &mod_transport_opt; <c>transport_module</c> and
-<c>transport_config</c> tuples in transport configuration.</p>
-
-<pre>
-
-
-
-Fajardo, et al. Standards Track [Page 22]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Diameter implementations SHOULD be able to interpret ICMP protocol
- port unreachable messages as explicit indications that the server is
- not reachable, subject to security policy on trusting such messages.
- Further guidance regarding the treatment of ICMP errors can be found
- in [RFC5927] and [RFC5461]. Diameter implementations SHOULD also be
- able to interpret a reset from the transport and timed-out connection
- attempts. If Diameter receives data from the lower layer that cannot
- be parsed or identified as a Diameter error made by the peer, the
- stream is compromised and cannot be recovered. The transport
- connection MUST be closed using a RESET call (send a TCP RST bit) or
- an SCTP ABORT message (graceful closure is compromised).
-</pre>
-
-<p>
-ICMP messages and other transport-level errors aren't directly
-visible to diameter but transport implementations like &man_tcp; and
-&man_sctp; propagate these as terminating transport processes.</p>
-
-<pre>
-
-2.1.1. SCTP Guidelines
-
- Diameter messages SHOULD be mapped into SCTP streams in a way that
- avoids head-of-the-line (HOL) blocking. Among different ways of
- performing the mapping that fulfill this requirement it is
- RECOMMENDED that a Diameter node send every Diameter message (request
- or response) over stream zero with the unordered flag set. However,
- Diameter nodes MAY select and implement other design alternatives for
- avoiding HOL blocking such as using multiple streams with the
- unordered flag cleared (as originally instructed in RFC 3588). On
- the receiving side, a Diameter entity MUST be ready to receive
- Diameter messages over any stream, and it is free to return responses
- over a different stream. This way, both sides manage the available
- streams in the sending direction, independently of the streams chosen
- by the other side to send a particular Diameter message. These
- messages can be out-of-order and belong to different Diameter
- sessions.
-</pre>
-
-<p>
-&man_sctp; allows the sender to specify a stream number explicitly.
-The stream on which an incoming message is received it passed to
-&app_handle_request; and &app_handle_answer; callbacks as
-<c>transport_data</c> in a <c>#diameter_packet{}</c>.</p>
-
-<p>
-Ordered or unordered delivery can be configured per transport.</p>
-
-<pre>
-
- Out-of-order delivery has special concerns during a connection
- establishment and termination. When a connection is established, the
- responder side sends a CEA message and moves to R-Open state as
- specified in Section 5.6. If an application message is sent shortly
- after the CEA and delivered out-of-order, the initiator side, still
- in Wait-I-CEA state, will discard the application message and close
- the connection. In order to avoid this race condition, the receiver
- side SHOULD NOT use out-of-order delivery methods until the first
- message has been received from the initiator, proving that it has
- moved to I-Open state. To trigger such a message, the receiver side
- could send a DWR immediately after sending a CEA. Upon reception of
- the corresponding DWA, the receiver side should start using out-of-
- order delivery methods to counter the HOL blocking.
-</pre>
-
-<p>
-&man_sctp; does not currently allow the user to switch between ordered
-and unordered delivery, or to specify the manner of sending per
-message: one or the other must be configured, the defaults being
-ordered.</p>
-
-<pre>
-
- Another race condition may occur when DPR and DPA messages are used.
- Both DPR and DPA are small in size; thus, they may be delivered to
- the peer faster than application messages when an out-of-order
- delivery mechanism is used. Therefore, it is possible that a DPR/DPA
-
-
-
-Fajardo, et al. Standards Track [Page 23]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- exchange completes while application messages are still in transit,
- resulting in a loss of these messages. An implementation could
- mitigate this race condition, for example, using timers, and wait for
- a short period of time for pending application level messages to
- arrive before proceeding to disconnect the transport connection.
- Eventually, lost messages are handled by the retransmission mechanism
- described in Section 5.5.4.
-
- A Diameter agent SHOULD use dedicated payload protocol identifiers
- (PPIDs) for clear text and encrypted SCTP DATA chunks instead of only
- using the unspecified payload protocol identifier (value 0). For
- this purpose, two PPID values are allocated: the PPID value 46 is for
- Diameter messages in clear text SCTP DATA chunks, and the PPID value
- 47 is for Diameter messages in protected DTLS/SCTP DATA chunks.
-</pre>
-
-&nada;
-
-<pre>
-
-2.2. Securing Diameter Messages
-
- Connections between Diameter peers SHOULD be protected by TLS/TCP and
- DTLS/SCTP. All Diameter base protocol implementations MUST support
- the use of TLS/TCP and DTLS/SCTP. If desired, alternative security
- mechanisms that are independent of Diameter, such as IPsec [RFC4301],
- can be deployed to secure connections between peers. The Diameter
- protocol MUST NOT be used without one of TLS, DTLS, or IPsec.
-</pre>
-
-<p>
-As noted above, DTLS is not currently supported and IPsec usage is
-transparent to diameter.
-Security is not enforced by diameter.</p>
-
-<pre>
-
-2.3. Diameter Application Compliance
-
- Application Ids are advertised during the capabilities exchange phase
- (see Section 5.3). Advertising support of an application implies
- that the sender supports the functionality specified in the
- respective Diameter application specification.
-
- Implementations MAY add arbitrary optional AVPs with the M-bit
- cleared (including vendor-specific AVPs) to a command defined in an
- application, but only if the command's CCF syntax specification
- allows for it. Please refer to Section 11.1.1 for details.
-</pre>
-
-&nada;
-
-<pre>
-
-2.4. Application Identifiers
-
- Each Diameter application MUST have an IANA-assigned Application ID.
- The base protocol does not require an Application Id since its
- support is mandatory. During the capabilities exchange, Diameter
- nodes inform their peers of locally supported applications.
- Furthermore, all Diameter messages contain an Application Id, which
- is used in the message forwarding process.
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 24]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The following Application Id values are defined:
-
- Diameter common message 0
- Diameter base accounting 3
- Relay 0xffffffff
-</pre>
-
-<p>
-These applications are implemented in the dictionary modules
-<c>diameter_gen_base_rfc6733</c>, <c>diameter_gen_acct_rfc6733</c> and
-<c>diameter_relay</c> respectively.
-There are also RFC 3588 versions or the common and accounting
-dictionaries: <c>diameter_gen_base_rfc3588</c> and
-<c>diameter_base_accounting</c>.
-(The inconsistent naming is historical.)
-Dictionary modules are configured using the &mod_application_opt;
-<c>dictionary</c>.</p>
-
-<pre>
- Relay and redirect agents MUST advertise the Relay Application ID,
- while all other Diameter nodes MUST advertise locally supported
- applications. The receiver of a Capabilities Exchange message
- advertising relay service MUST assume that the sender supports all
- current and future applications.
-
- Diameter relay and proxy agents are responsible for finding an
- upstream server that supports the application of a particular
- message. If none can be found, an error message is returned with the
- Result-Code AVP set to DIAMETER_UNABLE_TO_DELIVER.
-</pre>
-
-&nada;
-
-<pre>
-
-2.5. Connections vs. Sessions
-
- This section attempts to provide the reader with an understanding of
- the difference between "connection" and "session", which are terms
- used extensively throughout this document.
-
- A connection refers to a transport-level connection between two peers
- that is used to send and receive Diameter messages. A session is a
- logical concept at the application layer that exists between the
- Diameter client and the Diameter server; it is identified via the
- Session-Id AVP.
-
- +--------+ +-------+ +--------+
- | Client | | Relay | | Server |
- +--------+ +-------+ +--------+
- &lt;----------> &lt;---------->
- peer connection A peer connection B
-
- &lt;----------------------------->
- User session x
-
- Figure 1: Diameter Connections and Sessions
-
- In the example provided in Figure 1, peer connection A is established
- between the client and the relay. Peer connection B is established
- between the relay and the server. User session X spans from the
- client via the relay to the server. Each "user" of a service causes
- an auth request to be sent, with a unique session identifier. Once
- accepted by the server, both the client and the server are aware of
- the session.
-
-
-
-
-Fajardo, et al. Standards Track [Page 25]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- It is important to note that there is no relationship between a
- connection and a session, and that Diameter messages for multiple
- sessions are all multiplexed through a single connection. Also, note
- that Diameter messages pertaining to the session, both application-
- specific and those that are defined in this document such as ASR/ASA,
- RAR/RAA, and STR/STA, MUST carry the Application Id of the
- application. Diameter messages pertaining to peer connection
- establishment and maintenance such as CER/CEA, DWR/DWA, and DPR/DPA
- MUST carry an Application Id of zero (0).
-</pre>
-
-<p>
-As noted above, diameter is not involved in session management.
-This is the responsibility of the diameter user.</p>
-
-<pre>
-
-2.6. Peer Table
-
- The Diameter peer table is used in message forwarding and is
- referenced by the routing table. A peer table entry contains the
- following fields:
-
- Host Identity
-
- Following the conventions described for the DiameterIdentity-
- derived AVP data format in Section 4.3.1, this field contains the
- contents of the Origin-Host (Section 6.3) AVP found in the CER or
- CEA message.
-
- StatusT
-
- This is the state of the peer entry, and it MUST match one of the
- values listed in Section 5.6.
-
- Static or Dynamic
-
- Specifies whether a peer entry was statically configured or
- dynamically discovered.
-
- Expiration Time
-
- Specifies the time at which dynamically discovered peer table
- entries are to be either refreshed or expired. If public key
- certificates are used for Diameter security (e.g., with TLS), this
- value MUST NOT be greater than the expiry times in the relevant
- certificates.
-
- TLS/TCP and DTLS/SCTP Enabled
-
- Specifies whether TLS/TCP and DTLS/SCTP is to be used when
- communicating with the peer.
-
- Additional security information, when needed (e.g., keys,
- certificates).
-</pre>
-
-<p>
-The Peer Table is not directly accessible to the diameter user.
-Information about connected peers can be retrieved using
-&mod_service_info;.</p>
-
-<pre>
-
-
-
-Fajardo, et al. Standards Track [Page 26]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-2.7. Routing Table
-
- All Realm-Based routing lookups are performed against what is
- commonly known as the routing table (see Section 12). Each routing
- table entry contains the following fields:
-
- Realm Name
-
- This is the field that MUST be used as a primary key in the
- routing table lookups. Note that some implementations perform
- their lookups based on longest-match-from-the-right on the realm
- rather than requiring an exact match.
-
- Application Identifier
-
- An application is identified by an Application Id. A route entry
- can have a different destination based on the Application Id in
- the message header. This field MUST be used as a secondary key
- field in routing table lookups.
-
- Local Action
-
- The Local Action field is used to identify how a message should be
- treated. The following actions are supported:
-
- 1. LOCAL - Diameter messages that can be satisfied locally and do
- not need to be routed to another Diameter entity.
-
- 2. RELAY - All Diameter messages that fall within this category
- MUST be routed to a next-hop Diameter entity that is indicated
- by the identifier described below. Routing is done without
- modifying any non-routing AVPs. See Section 6.1.9 for
- relaying guidelines.
-
- 3. PROXY - All Diameter messages that fall within this category
- MUST be routed to a next Diameter entity that is indicated by
- the identifier described below. The local server MAY apply
- its local policies to the message by including new AVPs to the
- message prior to routing. See Section 6.1.9 for proxying
- guidelines.
-
- 4. REDIRECT - Diameter messages that fall within this category
- MUST have the identity of the home Diameter server(s)
- appended, and returned to the sender of the message. See
- Section 6.1.8 for redirection guidelines.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 27]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Server Identifier
-
- The identity of one or more servers to which the message is to be
- routed. This identity MUST also be present in the Host Identity
- field of the peer table (Section 2.6). When the Local Action is
- set to RELAY or PROXY, this field contains the identity of the
- server(s) to which the message MUST be routed. When the Local
- Action field is set to REDIRECT, this field contains the identity
- of one or more servers to which the message MUST be redirected.
-
- Static or Dynamic
-
- Specifies whether a route entry was statically configured or
- dynamically discovered.
-
- Expiration Time
-
- Specifies the time at which a dynamically discovered route table
- entry expires. If public key certificates are used for Diameter
- security (e.g., with TLS), this value MUST NOT be greater than the
- expiry time in the relevant certificates.
-
- It is important to note that Diameter agents MUST support at least
- one of the LOCAL, RELAY, PROXY, or REDIRECT modes of operation.
- Agents do not need to support all modes of operation in order to
- conform with the protocol specification, but they MUST follow the
- protocol compliance guidelines in Section 2. Relay agents and
- proxies MUST NOT reorder AVPs.
-
- The routing table MAY include a default entry that MUST be used for
- any requests not matching any of the other entries. The routing
- table MAY consist of only such an entry.
-
- When a request is routed, the target server MUST have advertised the
- Application Id (see Section 2.4) for the given message or have
- advertised itself as a relay or proxy agent. Otherwise, an error is
- returned with the Result-Code AVP set to DIAMETER_UNABLE_TO_DELIVER.
-</pre>
-
-<p>
-Routing does not need specific support in diameter: a user can
-maintain their own routing table if desired and implement any desired
-routing in &man_app; callbacks.
-However, it may be convenient to add more specific routing support to
-diameter in the future.</p>
-
-<pre>
-
-2.8. Role of Diameter Agents
-
- In addition to clients and servers, the Diameter protocol introduces
- relay, proxy, redirect, and translation agents, each of which is
- defined in Section 1.2. Diameter agents are useful for several
- reasons:
-</pre>
-
-<p>
-An noted above, the role a node plays is largely a question of
-configuration and &man_app; callback implementation.</p>
-
-<pre>
-
- o They can distribute administration of systems to a configurable
- grouping, including the maintenance of security associations.
-
-
-
-
-Fajardo, et al. Standards Track [Page 28]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o They can be used for concentration of requests from a number of
- co-located or distributed NAS equipment sets to a set of like user
- groups.
-
- o They can do value-added processing to the requests or responses.
-
- o They can be used for load balancing.
-
- o A complex network will have multiple authentication sources, they
- can sort requests and forward towards the correct target.
-
- The Diameter protocol requires that agents maintain transaction
- state, which is used for failover purposes. Transaction state
- implies that upon forwarding a request, its Hop-by-Hop Identifier is
- saved; the field is replaced with a locally unique identifier, which
- is restored to its original value when the corresponding answer is
- received. The request's state is released upon receipt of the
- answer. A stateless agent is one that only maintains transaction
- state.
-
- The Proxy-Info AVP allows stateless agents to add local state to a
- Diameter request, with the guarantee that the same state will be
- present in the answer. However, the protocol's failover procedures
- require that agents maintain a copy of pending requests.
-
- A stateful agent is one that maintains session state information by
- keeping track of all authorized active sessions. Each authorized
- session is bound to a particular service, and its state is considered
- active until either the agent is notified otherwise or the session
- expires. Each authorized session has an expiration, which is
- communicated by Diameter servers via the Session-Timeout AVP.
-
- Maintaining session state may be useful in certain applications, such
- as:
-
- o Protocol translation (e.g., RADIUS &lt;-> Diameter)
-
- o Limiting resources authorized to a particular user
-
- o Per-user or per-transaction auditing
-
- A Diameter agent MAY act in a stateful manner for some requests and
- be stateless for others. A Diameter implementation MAY act as one
- type of agent for some requests and as another type of agent for
- others.
-</pre>
-
-&nada;
-
-<pre>
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 29]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-2.8.1. Relay Agents
-
- Relay agents are Diameter agents that accept requests and route
- messages to other Diameter nodes based on information found in the
- messages (e.g., the value of the Destination-Realm AVP Section 6.6).
- This routing decision is performed using a list of supported realms
- and known peers. This is known as the routing table, as is defined
- further in Section 2.7.
-
- Relays may, for example, be used to aggregate requests from multiple
- Network Access Servers (NASes) within a common geographical area
- (Point of Presence, POP). The use of relays is advantageous since it
- eliminates the need for NASes to be configured with the necessary
- security information they would otherwise require to communicate with
- Diameter servers in other realms. Likewise, this reduces the
- configuration load on Diameter servers that would otherwise be
- necessary when NASes are added, changed, or deleted.
-
- Relays modify Diameter messages by inserting and removing routing
- information, but they do not modify any other portion of a message.
- Relays SHOULD NOT maintain session state but MUST maintain
- transaction state.
-
- +------+ ---------> +------+ ---------> +------+
- | | 1. Request | | 2. Request | |
- | NAS | | DRL | | HMS |
- | | 4. Answer | | 3. Answer | |
- +------+ &lt;--------- +------+ &lt;--------- +------+
- example.net example.net example.com
-
- Figure 2: Relaying of Diameter messages
-
- The example provided in Figure 2 depicts a request issued from a NAS,
- which is an access device, for the user [email protected]. Prior to
- issuing the request, the NAS performs a Diameter route lookup, using
- "example.com" as the key, and determines that the message is to be
- relayed to a DRL, which is a Diameter relay. The DRL performs the
- same route lookup as the NAS, and relays the message to the HMS,
- which is example.com's home server. The HMS identifies that the
- request can be locally supported (via the realm), processes the
- authentication and/or authorization request, and replies with an
- answer, which is routed back to the NAS using saved transaction
- state.
-
- Since relays do not perform any application-level processing, they
- provide relaying services for all Diameter applications; therefore,
- they MUST advertise the Relay Application Id.
-</pre>
-
-<p>
-Requests are relayed by returning a <c>relay</c> tuple from a
-&app_handle_request; callback.</p>
-
-<pre>
-
-
-
-Fajardo, et al. Standards Track [Page 30]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-2.8.2. Proxy Agents
-
- Similar to relays, proxy agents route Diameter messages using the
- Diameter routing table. However, they differ since they modify
- messages to implement policy enforcement. This requires that proxies
- maintain the state of their downstream peers (e.g., access devices)
- to enforce resource usage, provide admission control, and provide
- provisioning.
-
- Proxies may, for example, be used in call control centers or access
- ISPs that provide outsourced connections; they can monitor the number
- and type of ports in use and make allocation and admission decisions
- according to their configuration.
-
- Since enforcing policies requires an understanding of the service
- being provided, proxies MUST only advertise the Diameter applications
- they support.
-</pre>
-
-&nada;
-
-<pre>
-
-2.8.3. Redirect Agents
-
- Redirect agents are useful in scenarios where the Diameter routing
- configuration needs to be centralized. An example is a redirect
- agent that provides services to all members of a consortium, but does
- not wish to be burdened with relaying all messages between realms.
- This scenario is advantageous since it does not require that the
- consortium provide routing updates to its members when changes are
- made to a member's infrastructure.
-
- Since redirect agents do not relay messages, and only return an
- answer with the information necessary for Diameter agents to
- communicate directly, they do not modify messages. Since redirect
- agents do not receive answer messages, they cannot maintain session
- state.
-
- The example provided in Figure 3 depicts a request issued from the
- access device, NAS, for the user [email protected]. The message is
- forwarded by the NAS to its relay, DRL, which does not have a routing
- entry in its Diameter routing table for example.com. The DRL has a
- default route configured to DRD, which is a redirect agent that
- returns a redirect notification to DRL, as well as the HMS' contact
- information. Upon receipt of the redirect notification, the DRL
- establishes a transport connection with the HMS, if one doesn't
- already exist, and forwards the request to it.
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 31]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- +------+
- | |
- | DRD |
- | |
- +------+
- ^ |
- 2. Request | | 3. Redirection
- | | Notification
- | v
- +------+ ---------> +------+ ---------> +------+
- | | 1. Request | | 4. Request | |
- | NAS | | DRL | | HMS |
- | | 6. Answer | | 5. Answer | |
- +------+ &lt;--------- +------+ &lt;--------- +------+
- example.net example.net example.com
-
- Figure 3: Redirecting a Diameter Message
-
- Since redirect agents do not perform any application-level
- processing, they provide relaying services for all Diameter
- applications; therefore, they MUST advertise the Relay Application
- ID.
-</pre>
-
-&nada;
-
-<pre>
-
-2.8.4. Translation Agents
-
- A translation agent is a device that provides translation between two
- protocols (e.g., RADIUS&lt;->Diameter, TACACS+&lt;->Diameter). Translation
- agents are likely to be used as aggregation servers to communicate
- with a Diameter infrastructure, while allowing for the embedded
- systems to be migrated at a slower pace.
-
- Given that the Diameter protocol introduces the concept of long-lived
- authorized sessions, translation agents MUST be session stateful and
- MUST maintain transaction state.
-
- Translation of messages can only occur if the agent recognizes the
- application of a particular request; therefore, translation agents
- MUST only advertise their locally supported applications.
-
- +------+ ---------> +------+ ---------> +------+
- | | RADIUS Request | | Diameter Request | |
- | NAS | | TLA | | HMS |
- | | RADIUS Answer | | Diameter Answer | |
- +------+ &lt;--------- +------+ &lt;--------- +------+
- example.net example.net example.com
-
- Figure 4: Translation of RADIUS to Diameter
-</pre>
-
-&nada;
-
-<pre>
-
-
-
-
-Fajardo, et al. Standards Track [Page 32]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-2.9. Diameter Path Authorization
-
- As noted in Section 2.2, Diameter provides transmission-level
- security for each connection using TLS/TCP and DTLS/SCTP. Therefore,
- each connection can be authenticated and can be replay and integrity
- protected.
-
- In addition to authenticating each connection, the entire session
- MUST also be authorized. Before initiating a connection, a Diameter
- peer MUST check that its peers are authorized to act in their roles.
- For example, a Diameter peer may be authentic, but that does not mean
- that it is authorized to act as a Diameter server advertising a set
- of Diameter applications.
-
- Prior to bringing up a connection, authorization checks are performed
- at each connection along the path. Diameter capabilities negotiation
- (CER/CEA) also MUST be carried out, in order to determine what
- Diameter applications are supported by each peer. Diameter sessions
- MUST be routed only through authorized nodes that have advertised
- support for the Diameter application required by the session.
-
- As noted in Section 6.1.9, a relay or proxy agent MUST append a
- Route-Record AVP to all requests forwarded. The AVP contains the
- identity of the peer from which the request was received.
-
- The home Diameter server, prior to authorizing a session, MUST check
- the Route-Record AVPs to make sure that the route traversed by the
- request is acceptable. For example, administrators within the home
- realm may not wish to honor requests that have been routed through an
- untrusted realm. By authorizing a request, the home Diameter server
- is implicitly indicating its willingness to engage in the business
- transaction as specified by any contractual relationship between the
- server and the previous hop. A DIAMETER_AUTHORIZATION_REJECTED error
- message (see Section 7.1.5) is sent if the route traversed by the
- request is unacceptable.
-
- A home realm may also wish to check that each accounting request
- message corresponds to a Diameter response authorizing the session.
- Accounting requests without corresponding authorization responses
- SHOULD be subjected to further scrutiny, as should accounting
- requests indicating a difference between the requested and provided
- service.
-
- Forwarding of an authorization response is considered evidence of a
- willingness to take on financial risk relative to the session. A
- local realm may wish to limit this exposure, for example, by
- establishing credit limits for intermediate realms and refusing to
- accept responses that would violate those limits. By issuing an
-
-
-
-Fajardo, et al. Standards Track [Page 33]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- accounting request corresponding to the authorization response, the
- local realm implicitly indicates its agreement to provide the service
- indicated in the authorization response. If the service cannot be
- provided by the local realm, then a DIAMETER_UNABLE_TO_COMPLY error
- message MUST be sent within the accounting request; a Diameter client
- receiving an authorization response for a service that it cannot
- perform MUST NOT substitute an alternate service and then send
- accounting requests for the alternate service instead.
-</pre>
-
-&nada;
-
-<pre>
-
-3. Diameter Header
-
- A summary of the Diameter header format is shown below. The fields
- are transmitted in network byte order.
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Version | Message Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Command Flags | Command Code |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Application-ID |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Hop-by-Hop Identifier |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | End-to-End Identifier |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | AVPs ...
- +-+-+-+-+-+-+-+-+-+-+-+-+-
-</pre>
-
-<p>
-The Diameter Header is represented by the <c>diameter_header</c>
-record defined in <c>diameter.hrl</c>.
-The <c>diameter_packet</c> record contains a <c>header</c> field whose
-value will be a decoded <c>#diameter_header{}</c> for incoming
-messages passed to &app_handle_request; and &app_handle_answer;
-callbacks.
-In the case of outgoing messages, diameter and the relevant
-dictionary populate the Diameter Header appropriately, although
-&app_prepare_request; and &app_handle_request; callbacks can modify
-header values.
-(Which can be useful in test.)</p>
-
-<pre>
-
- Version
-
- This Version field MUST be set to 1 to indicate Diameter Version
- 1.
-
- Message Length
-
- The Message Length field is three octets and indicates the length
- of the Diameter message including the header fields and the padded
- AVPs. Thus, the Message Length field is always a multiple of 4.
-
- Command Flags
-
- The Command Flags field is eight bits. The following bits are
- assigned:
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 34]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- 0 1 2 3 4 5 6 7
- +-+-+-+-+-+-+-+-+
- |R P E T r r r r|
- +-+-+-+-+-+-+-+-+
-
- R(equest)
-
- If set, the message is a request. If cleared, the message is
- an answer.
-
- P(roxiable)
-
- If set, the message MAY be proxied, relayed, or redirected. If
- cleared, the message MUST be locally processed.
-
- E(rror)
-
- If set, the message contains a protocol error, and the message
- will not conform to the CCF described for this command.
- Messages with the 'E' bit set are commonly referred to as error
- messages. This bit MUST NOT be set in request messages (see
- Section 7.2).
-
- T(Potentially retransmitted message)
-
- This flag is set after a link failover procedure, to aid the
- removal of duplicate requests. It is set when resending
- requests not yet acknowledged, as an indication of a possible
- duplicate due to a link failure. This bit MUST be cleared when
- sending a request for the first time; otherwise, the sender
- MUST set this flag. Diameter agents only need to be concerned
- about the number of requests they send based on a single
- received request; retransmissions by other entities need not be
- tracked. Diameter agents that receive a request with the T
- flag set, MUST keep the T flag set in the forwarded request.
- This flag MUST NOT be set if an error answer message (e.g., a
- protocol error) has been received for the earlier message. It
- can be set only in cases where no answer has been received from
- the server for a request, and the request has been sent again.
- This flag MUST NOT be set in answer messages.
-
- r(eserved)
-
- These flag bits are reserved for future use; they MUST be set
- to zero and ignored by the receiver.
-</pre>
-
-<p>
-Reserved bits are set to 0 in outgoing messages.</p>
-
-<pre>
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 35]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Command Code
-
- The Command Code field is three octets and is used in order to
- communicate the command associated with the message. The 24-bit
- address space is managed by IANA (see Section 3.1). Command Code
- values 16,777,214 and 16,777,215 (hexadecimal values FFFFFE-
- FFFFFF) are reserved for experimental use (see Section 11.2).
-
- Application-ID
-
- Application-ID is four octets and is used to identify for which
- application the message is applicable. The application can be an
- authentication application, an accounting application, or a
- vendor-specific application.
-
- The value of the Application-ID field in the header MUST be the
- same as any relevant Application-Id AVPs contained in the message.
-
- Hop-by-Hop Identifier
-
- The Hop-by-Hop Identifier is an unsigned 32-bit integer field (in
- network byte order) that aids in matching requests and replies.
- The sender MUST ensure that the Hop-by-Hop Identifier in a request
- is unique on a given connection at any given time, and it MAY
- attempt to ensure that the number is unique across reboots. The
- sender of an answer message MUST ensure that the Hop-by-Hop
- Identifier field contains the same value that was found in the
- corresponding request. The Hop-by-Hop Identifier is normally a
- monotonically increasing number, whose start value was randomly
- generated. An answer message that is received with an unknown
- Hop-by-Hop Identifier MUST be discarded.
-
- End-to-End Identifier
-
- The End-to-End Identifier is an unsigned 32-bit integer field (in
- network byte order) that is used to detect duplicate messages.
- Upon reboot, implementations MAY set the high order 12 bits to
- contain the low order 12 bits of current time, and the low order
- 20 bits to a random value. Senders of request messages MUST
- insert a unique identifier on each message. The identifier MUST
- remain locally unique for a period of at least 4 minutes, even
- across reboots. The originator of an answer message MUST ensure
- that the End-to-End Identifier field contains the same value that
- was found in the corresponding request. The End-to-End Identifier
- MUST NOT be modified by Diameter agents of any kind. The
- combination of the Origin-Host AVP (Section 6.3) and this field is
- used to detect duplicates. Duplicate requests SHOULD cause the
- same answer to be transmitted (modulo the Hop-by-Hop Identifier
-
-
-
-Fajardo, et al. Standards Track [Page 36]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- field and any routing AVPs that may be present), and they MUST NOT
- affect any state that was set when the original request was
- processed. Duplicate answer messages that are to be locally
- consumed (see Section 6.2) SHOULD be silently discarded.
-
- AVPs
-
- AVPs are a method of encapsulating information relevant to the
- Diameter message. See Section 4 for more information on AVPs.
-</pre>
-
-&nada;
-
-<pre>
-
-3.1. Command Codes
-
- Each command Request/Answer pair is assigned a Command Code, and the
- sub-type (i.e., request or answer) is identified via the 'R' bit in
- the Command Flags field of the Diameter header.
-
- Every Diameter message MUST contain a Command Code in its header's
- Command Code field, which is used to determine the action that is to
- be taken for a particular message. The following Command Codes are
- defined in the Diameter base protocol:
-
- Section
- Command Name Abbrev. Code Reference
- --------------------------------------------------------
- Abort-Session-Request ASR 274 8.5.1
- Abort-Session-Answer ASA 274 8.5.2
- Accounting-Request ACR 271 9.7.1
- Accounting-Answer ACA 271 9.7.2
- Capabilities-Exchange- CER 257 5.3.1
- Request
- Capabilities-Exchange- CEA 257 5.3.2
- Answer
- Device-Watchdog-Request DWR 280 5.5.1
- Device-Watchdog-Answer DWA 280 5.5.2
- Disconnect-Peer-Request DPR 282 5.4.1
- Disconnect-Peer-Answer DPA 282 5.4.2
- Re-Auth-Request RAR 258 8.3.1
- Re-Auth-Answer RAA 258 8.3.2
- Session-Termination- STR 275 8.4.1
- Request
- Session-Termination- STA 275 8.4.2
- Answer
-</pre>
-
-<p>
-These messages are all defined in diameter's implementation of the
-common dictionary in modules <c>diameter_gen_base_rfc6733</c> and
-<c>diameter_gen_base_rfc3588</c>.
-Corresponding record definitions are found in
-<c>diameter_gen_base_rfc6733.hrl</c> and
-<c>diameter_gen_base_rfc3588.hrl</c>.</p>
-
-<pre>
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 37]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-3.2. Command Code Format Specification
-
- Every Command Code defined MUST include a corresponding Command Code
- Format (CCF) specification, which is used to define the AVPs that
- MUST or MAY be present when sending the message. The following ABNF
- specifies the CCF used in the definition:
-</pre>
-
-<p>
-The CCF is what is specified in the <c>@messages</c> section of the
-&man_dict; format, except as noted below.</p>
-
-<pre>
-
- command-def = "&lt;" command-name ">" "::=" diameter-message
-</pre>
-
-<p>
-Angle brackets are currently not allowed here.
-This was a change between RFC 3588 and RFC 6733: the former disallowed
-them in the grammar but included them in its own command definitions.</p>
-
-<pre>
-
- command-name = diameter-name
-
- diameter-name = ALPHA *(ALPHA / DIGIT / "-")
-
- diameter-message = header *fixed *required *optional
-
- header = "&lt;Diameter-Header:" command-id
- [r-bit] [p-bit] [e-bit] [application-id]">"
-
- application-id = 1*DIGIT
-
- command-id = 1*DIGIT
- ; The Command Code assigned to the command.
-
- r-bit = ", REQ"
- ; If present, the 'R' bit in the Command
- ; Flags is set, indicating that the message
- ; is a request as opposed to an answer.
-
- p-bit = ", PXY"
- ; If present, the 'P' bit in the Command
- ; Flags is set, indicating that the message
- ; is proxiable.
-
- e-bit = ", ERR"
- ; If present, the 'E' bit in the Command
- ; Flags is set, indicating that the answer
- ; message contains a Result-Code AVP in
- ; the "protocol error" class.
-
- fixed = [qual] "&lt;" avp-spec ">"
- ; Defines the fixed position of an AVP.
-
- required = [qual] "{" avp-spec "}"
- ; The AVP MUST be present and can appear
- ; anywhere in the message.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 38]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- optional = [qual] "[" avp-name "]"
- ; The avp-name in the 'optional' rule cannot
- ; evaluate to any AVP Name that is included
- ; in a fixed or required rule. The AVP can
- ; appear anywhere in the message.
- ;
- ; NOTE: "[" and "]" have a slightly different
- ; meaning than in ABNF. These braces
- ; cannot be used to express optional fixed rules
- ; (such as an optional ICV at the end). To do
- ; this, the convention is '0*1fixed'.
-
- qual = [min] "*" [max]
- ; See ABNF conventions, RFC 5234, Section 4.
- ; The absence of any qualifier depends on
- ; whether it precedes a fixed, required, or
- ; optional rule. If a fixed or required rule has
- ; no qualifier, then exactly one such AVP MUST
- ; be present. If an optional rule has no
- ; qualifier, then 0 or 1 such AVP may be
- ; present. If an optional rule has a qualifier,
- ; then the value of min MUST be 0 if present.
-
- min = 1*DIGIT
- ; The minimum number of times the element may
- ; be present. If absent, the default value is 0
- ; for fixed and optional rules and 1 for
- ; required rules. The value MUST be at least 1
- ; for required rules.
-
- max = 1*DIGIT
- ; The maximum number of times the element may
- ; be present. If absent, the default value is
- ; infinity. A value of 0 implies the AVP MUST
- ; NOT be present.
-
- avp-spec = diameter-name
- ; The avp-spec has to be an AVP Name, defined
- ; in the base or extended Diameter
- ; specifications.
-
- avp-name = avp-spec / "AVP"
- ; The string "AVP" stands for *any* arbitrary AVP
- ; Name, not otherwise listed in that Command Code
- ; definition. The inclusion of this string
- ; is recommended for all CCFs to allow for
- ; extensibility.
-
-
-
-
-Fajardo, et al. Standards Track [Page 39]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The following is a definition of a fictitious Command Code:
-
- Example-Request ::= &lt; Diameter Header: 9999999, REQ, PXY >
- { User-Name }
- 1* { Origin-Host }
- * [ AVP ]
-</pre>
-
-&nada;
-
-<pre>
-
-3.3. Diameter Command Naming Conventions
-
- Diameter command names typically includes one or more English words
- followed by the verb "Request" or "Answer". Each English word is
- delimited by a hyphen. A three-letter acronym for both the request
- and answer is also normally provided.
-
- An example is a message set used to terminate a session. The command
- name is Session-Terminate-Request and Session-Terminate-Answer, while
- the acronyms are STR and STA, respectively.
-
- Both the request and the answer for a given command share the same
- Command Code. The request is identified by the R(equest) bit in the
- Diameter header set to one (1), to ask that a particular action be
- performed, such as authorizing a user or terminating a session. Once
- the receiver has completed the request, it issues the corresponding
- answer, which includes a result code that communicates one of the
- following:
-
- o The request was successful
-
- o The request failed
-
- o An additional request has to be sent to provide information the
- peer requires prior to returning a successful or failed answer.
-
- o The receiver could not process the request, but provides
- information about a Diameter peer that is able to satisfy the
- request, known as redirect.
-
- Additional information, encoded within AVPs, may also be included in
- answer messages.
-</pre>
-
-<p>
-The &man_dict; format places no requirement on the naming of commands.</p>
-
-<pre>
-
-4. Diameter AVPs
-
- Diameter AVPs carry specific authentication, accounting,
- authorization, and routing information as well as configuration
- details for the request and reply.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 40]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Each AVP of type OctetString MUST be padded to align on a 32-bit
- boundary, while other AVP types align naturally. A number of zero-
- valued bytes are added to the end of the AVP Data field until a word
- boundary is reached. The length of the padding is not reflected in
- the AVP Length field.
-
-4.1. AVP Header
-
- The fields in the AVP header MUST be sent in network byte order. The
- format of the header is:
-
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | AVP Code |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- |V M P r r r r r| AVP Length |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Vendor-ID (opt) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | Data ...
- +-+-+-+-+-+-+-+-+
-
- AVP Code
-
- The AVP Code, combined with the Vendor-Id field, identifies the
- attribute uniquely. AVP numbers 1 through 255 are reserved for
- reuse of RADIUS attributes, without setting the Vendor-Id field.
- AVP numbers 256 and above are used for Diameter, which are
- allocated by IANA (see Section 11.1.1).
-
- AVP Flags
-
- The AVP Flags field informs the receiver how each attribute must
- be handled. New Diameter applications SHOULD NOT define
- additional AVP Flag bits. However, note that new Diameter
- applications MAY define additional bits within the AVP header, and
- an unrecognized bit SHOULD be considered an error. The sender of
- the AVP MUST set 'R' (reserved) bits to 0 and the receiver SHOULD
- ignore all 'R' (reserved) bits. The 'P' bit has been reserved for
- future usage of end-to-end security. At the time of writing,
- there are no end-to-end security mechanisms specified; therefore,
- the 'P' bit SHOULD be set to 0.
-
- The 'M' bit, known as the Mandatory bit, indicates whether the
- receiver of the AVP MUST parse and understand the semantics of the
- AVP including its content. The receiving entity MUST return an
- appropriate error message if it receives an AVP that has the M-bit
-
-
-
-Fajardo, et al. Standards Track [Page 41]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- set but does not understand it. An exception applies when the AVP
- is embedded within a Grouped AVP. See Section 4.4 for details.
- Diameter relay and redirect agents MUST NOT reject messages with
- unrecognized AVPs.
-
- The 'M' bit MUST be set according to the rules defined in the
- application specification that introduces or reuses this AVP.
- Within a given application, the M-bit setting for an AVP is
- defined either for all command types or for each command type.
-
- AVPs with the 'M' bit cleared are informational only; a receiver
- that receives a message with such an AVP that is not supported, or
- whose value is not supported, MAY simply ignore the AVP.
-
- The 'V' bit, known as the Vendor-Specific bit, indicates whether
- the optional Vendor-ID field is present in the AVP header. When
- set, the AVP Code belongs to the specific vendor code address
- space.
-
- AVP Length
-
- The AVP Length field is three octets, and indicates the number of
- octets in this AVP including the AVP Code field, AVP Length field,
- AVP Flags field, Vendor-ID field (if present), and the AVP Data
- field. If a message is received with an invalid attribute length,
- the message MUST be rejected.
-
-4.1.1. Optional Header Elements
-
- The AVP header contains one optional field. This field is only
- present if the respective bit-flag is enabled.
-
- Vendor-ID
-
- The Vendor-ID field is present if the 'V' bit is set in the AVP
- Flags field. The optional four-octet Vendor-ID field contains the
- IANA-assigned "SMI Network Management Private Enterprise Codes"
- [ENTERPRISE] value, encoded in network byte order. Any vendors or
- standardization organizations that are also treated like vendors
- in the IANA-managed "SMI Network Management Private Enterprise
- Codes" space wishing to implement a vendor-specific Diameter AVP
- MUST use their own Vendor-ID along with their privately managed
- AVP address space, guaranteeing that they will not collide with
- any other vendor's vendor-specific AVP(s) or with future IETF
- AVPs.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 42]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- A Vendor-ID value of zero (0) corresponds to the IETF-adopted AVP
- values, as managed by IANA. Since the absence of the Vendor-ID
- field implies that the AVP in question is not vendor specific,
- implementations MUST NOT use the value of zero (0) for the
- Vendor-ID field.
-
-4.2. Basic AVP Data Formats
-
- The Data field is zero or more octets and contains information
- specific to the Attribute. The format and length of the Data field
- is determined by the AVP Code and AVP Length fields. The format of
- the Data field MUST be one of the following base data types or a data
- type derived from the base data types. In the event that a new Basic
- AVP Data Format is needed, a new version of this RFC MUST be created.
-
- OctetString
-
- The data contains arbitrary data of variable length. Unless
- otherwise noted, the AVP Length field MUST be set to at least 8
- (12 if the 'V' bit is enabled). AVP values of this type that are
- not a multiple of 4 octets in length are followed by the necessary
- padding so that the next AVP (if any) will start on a 32-bit
- boundary.
-
- Integer32
-
- 32-bit signed value, in network byte order. The AVP Length field
- MUST be set to 12 (16 if the 'V' bit is enabled).
-
- Integer64
-
- 64-bit signed value, in network byte order. The AVP Length field
- MUST be set to 16 (20 if the 'V' bit is enabled).
-
- Unsigned32
-
- 32-bit unsigned value, in network byte order. The AVP Length
- field MUST be set to 12 (16 if the 'V' bit is enabled).
-
- Unsigned64
-
- 64-bit unsigned value, in network byte order. The AVP Length
- field MUST be set to 16 (20 if the 'V' bit is enabled).
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 43]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Float32
-
- This represents floating point values of single precision as
- described by [FLOATPOINT]. The 32-bit value is transmitted in
- network byte order. The AVP Length field MUST be set to 12 (16 if
- the 'V' bit is enabled).
-
- Float64
-
- This represents floating point values of double precision as
- described by [FLOATPOINT]. The 64-bit value is transmitted in
- network byte order. The AVP Length field MUST be set to 16 (20 if
- the 'V' bit is enabled).
-
- Grouped
-
- The Data field is specified as a sequence of AVPs. These AVPs are
- concatenated -- including their headers and padding -- in the
- order in which they are specified and the result encapsulated in
- the Data field. The AVP Length field is set to 8 (12 if the 'V'
- bit is enabled) plus the total length of all included AVPs,
- including their headers and padding. Thus, the AVP Length field
- of an AVP of type Grouped is always a multiple of 4.
-
-4.3. Derived AVP Data Formats
-
- In addition to using the Basic AVP Data Formats, applications may
- define data formats derived from the Basic AVP Data Formats. An
- application that defines new Derived AVP Data Formats MUST include
- them in a section titled "Derived AVP Data Formats", using the same
- format as the definitions below. Each new definition MUST be either
- defined or listed with a reference to the RFC that defines the
- format.
-
-4.3.1. Common Derived AVP Data Formats
-
- The following are commonly used Derived AVP Data Formats.
-
- Address
-
- The Address format is derived from the OctetString Basic AVP
- Format. It is a discriminated union representing, for example, a
- 32-bit (IPv4) [RFC0791] or 128-bit (IPv6) [RFC4291] address, most
- significant octet first. The first two octets of the Address AVP
- represent the AddressType, which contains an Address Family,
- defined in [IANAADFAM]. The AddressType is used to discriminate
- the content and format of the remaining octets.
-
-
-
-
-Fajardo, et al. Standards Track [Page 44]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Time
-
- The Time format is derived from the OctetString Basic AVP Format.
- The string MUST contain four octets, in the same format as the
- first four bytes are in the NTP timestamp format. The NTP
- timestamp format is defined in Section 3 of [RFC5905].
-
- This represents the number of seconds since 0h on 1 January 1900
- with respect to the Coordinated Universal Time (UTC).
-
- On 6h 28m 16s UTC, 7 February 2036, the time value will overflow.
- Simple Network Time Protocol (SNTP) [RFC5905] describes a
- procedure to extend the time to 2104. This procedure MUST be
- supported by all Diameter nodes.
-
- UTF8String
-
- The UTF8String format is derived from the OctetString Basic AVP
- Format. This is a human-readable string represented using the
- ISO/IEC IS 10646-1 character set, encoded as an OctetString using
- the UTF-8 transformation format [RFC3629].
-
- Since additional code points are added by amendments to the 10646
- standard from time to time, implementations MUST be prepared to
- encounter any code point from 0x00000001 to 0x7fffffff. Byte
- sequences that do not correspond to the valid encoding of a code
- point into UTF-8 charset or are outside this range are prohibited.
-
- The use of control codes SHOULD be avoided. When it is necessary
- to represent a new line, the control code sequence CR LF SHOULD be
- used.
-
- The use of leading or trailing white space SHOULD be avoided.
-
- For code points not directly supported by user interface hardware
- or software, an alternative means of entry and display, such as
- hexadecimal, MAY be provided.
-
- For information encoded in 7-bit US-ASCII, the UTF-8 charset is
- identical to the US-ASCII charset.
-
- UTF-8 may require multiple bytes to represent a single character /
- code point; thus, the length of a UTF8String in octets may be
- different from the number of characters encoded.
-
- Note that the AVP Length field of an UTF8String is measured in
- octets not characters.
-
-
-
-
-Fajardo, et al. Standards Track [Page 45]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- DiameterIdentity
-
- The DiameterIdentity format is derived from the OctetString Basic
- AVP Format.
-
- DiameterIdentity = FQDN/Realm
-
- The DiameterIdentity value is used to uniquely identify either:
-
- * A Diameter node for purposes of duplicate connection and
- routing loop detection.
-
- * A Realm to determine whether messages can be satisfied locally
- or whether they must be routed or redirected.
-
- When a DiameterIdentity value is used to identify a Diameter node,
- the contents of the string MUST be the Fully Qualified Domain Name
- (FQDN) of the Diameter node. If multiple Diameter nodes run on
- the same host, each Diameter node MUST be assigned a unique
- DiameterIdentity. If a Diameter node can be identified by several
- FQDNs, a single FQDN should be picked at startup and used as the
- only DiameterIdentity for that node, whatever the connection on
- which it is sent. In this document, note that DiameterIdentity is
- in ASCII form in order to be compatible with existing DNS
- infrastructure. See Appendix D for interactions between the
- Diameter protocol and Internationalized Domain Names (IDNs).
-
- DiameterURI
-
- The DiameterURI MUST follow the Uniform Resource Identifiers (RFC
- 3986) syntax [RFC3986] rules specified below:
-
- "aaa://" FQDN [ port ] [ transport ] [ protocol ]
-
- ; No transport security
-
- "aaas://" FQDN [ port ] [ transport ] [ protocol ]
-
- ; Transport security used
-
- FQDN = &lt; Fully Qualified Domain Name >
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 46]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- port = ":" 1*DIGIT
-
- ; One of the ports used to listen for
- ; incoming connections.
- ; If absent, the default Diameter port
- ; (3868) is assumed if no transport
- ; security is used and port 5658 when
- ; transport security (TLS/TCP and DTLS/SCTP)
- ; is used.
-
- transport = ";transport=" transport-protocol
-
- ; One of the transports used to listen
- ; for incoming connections. If absent,
- ; the default protocol is assumed to be TCP.
- ; UDP MUST NOT be used when the aaa-protocol
- ; field is set to diameter.
-
- transport-protocol = ( "tcp" / "sctp" / "udp" )
-
- protocol = ";protocol=" aaa-protocol
-
- ; If absent, the default AAA protocol
- ; is Diameter.
-
- aaa-protocol = ( "diameter" / "radius" / "tacacs+" )
-
- The following are examples of valid Diameter host identities:
-
- aaa://host.example.com;transport=tcp
- aaa://host.example.com:6666;transport=tcp
- aaa://host.example.com;protocol=diameter
- aaa://host.example.com:6666;protocol=diameter
- aaa://host.example.com:6666;transport=tcp;protocol=diameter
- aaa://host.example.com:1813;transport=udp;protocol=radius
-
- Enumerated
-
- The Enumerated format is derived from the Integer32 Basic AVP
- Format. The definition contains a list of valid values and their
- interpretation and is described in the Diameter application
- introducing the AVP.
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 47]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- IPFilterRule
-
- The IPFilterRule format is derived from the OctetString Basic AVP
- Format and uses the ASCII charset. The rule syntax is a modified
- subset of ipfw(8) from FreeBSD. Packets may be filtered based on
- the following information that is associated with it:
-
- Direction (in or out)
- Source and destination IP address (possibly masked)
- Protocol
- Source and destination port (lists or ranges)
- TCP flags
- IP fragment flag
- IP options
- ICMP types
-
- Rules for the appropriate direction are evaluated in order, with the
- first matched rule terminating the evaluation. Each packet is
- evaluated once. If no rule matches, the packet is dropped if the
- last rule evaluated was a permit, and passed if the last rule was a
- deny.
-
- IPFilterRule filters MUST follow the format:
-
- action dir proto from src to dst [options]
-
- action permit - Allow packets that match the rule.
- deny - Drop packets that match the rule.
-
- dir "in" is from the terminal, "out" is to the
- terminal.
-
- proto An IP protocol specified by number. The "ip"
- keyword means any protocol will match.
-
- src and dst &lt;address/mask> [ports]
-
- The &lt;address/mask> may be specified as:
- ipno An IPv4 or IPv6 number in dotted-
- quad or canonical IPv6 form. Only
- this exact IP number will match the
- rule.
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 48]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- ipno/bits An IP number as above with a mask
- width of the form 192.0.2.10/24. In
- this case, all IP numbers from
- 192.0.2.0 to 192.0.2.255 will match.
- The bit width MUST be valid for the
- IP version, and the IP number MUST
- NOT have bits set beyond the mask.
- For a match to occur, the same IP
- version must be present in the
- packet that was used in describing
- the IP address. To test for a
- particular IP version, the bits part
- can be set to zero. The keyword
- "any" is 0.0.0.0/0 or the IPv6
- equivalent. The keyword "assigned"
- is the address or set of addresses
- assigned to the terminal. For IPv4,
- a typical first rule is often "deny
- in ip! assigned".
-
- The sense of the match can be inverted by
- preceding an address with the not modifier (!),
- causing all other addresses to be matched
- instead. This does not affect the selection of
- port numbers.
-
- With the TCP, UDP, and SCTP protocols, optional
- ports may be specified as:
-
- {port/port-port}[,ports[,...]]
-
- The '-' notation specifies a range of ports
- (including boundaries).
-
- Fragmented packets that have a non-zero offset
- (i.e., not the first fragment) will never match
- a rule that has one or more port
- specifications. See the frag option for
- details on matching fragmented packets.
-
- options:
- frag Match if the packet is a fragment and this is not
- the first fragment of the datagram. frag may not
- be used in conjunction with either tcpflags or
- TCP/UDP port specifications.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 49]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- ipoptions spec
- Match if the IP header contains the comma-separated
- list of options specified in spec. The
- supported IP options are:
-
- ssrr (strict source route), lsrr (loose source
- route), rr (record packet route), and ts
- (timestamp). The absence of a particular option
- may be denoted with a '!'.
-
- tcpoptions spec
- Match if the TCP header contains the comma-separated
- list of options specified in spec. The
- supported TCP options are:
-
- mss (maximum segment size), window (tcp window
- advertisement), sack (selective ack), ts (rfc1323
- timestamp), and cc (rfc1644 t/tcp connection
- count). The absence of a particular option may
- be denoted with a '!'.
-
- established
- TCP packets only. Match packets that have the RST
- or ACK bits set.
-
- setup TCP packets only. Match packets that have the SYN
- bit set but no ACK bit.
-
-
- tcpflags spec
- TCP packets only. Match if the TCP header
- contains the comma-separated list of flags
- specified in spec. The supported TCP flags are:
-
- fin, syn, rst, psh, ack, and urg. The absence of a
- particular flag may be denoted with a '!'. A rule
- that contains a tcpflags specification can never
- match a fragmented packet that has a non-zero
- offset. See the frag option for details on
- matching fragmented packets.
-
- icmptypes types
- ICMP packets only. Match if the ICMP type is in
- the list types. The list may be specified as any
- combination of ranges or individual types
- separated by commas. Both the numeric values and
- the symbolic values listed below can be used. The
- supported ICMP types are:
-
-
-
-Fajardo, et al. Standards Track [Page 50]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- echo reply (0), destination unreachable (3),
- source quench (4), redirect (5), echo request
- (8), router advertisement (9), router
- solicitation (10), time-to-live exceeded (11), IP
- header bad (12), timestamp request (13),
- timestamp reply (14), information request (15),
- information reply (16), address mask request (17),
- and address mask reply (18).
-
- There is one kind of packet that the access device MUST always
- discard, that is an IP fragment with a fragment offset of one. This
- is a valid packet, but it only has one use, to try to circumvent
- firewalls.
-
- An access device that is unable to interpret or apply a deny rule
- MUST terminate the session. An access device that is unable to
- interpret or apply a permit rule MAY apply a more restrictive rule.
- An access device MAY apply deny rules of its own before the supplied
- rules, for example to protect the access device owner's
- infrastructure.
-
-4.4. Grouped AVP Values
-
- The Diameter protocol allows AVP values of type 'Grouped'. This
- implies that the Data field is actually a sequence of AVPs. It is
- possible to include an AVP with a Grouped type within a Grouped type,
- that is, to nest them. AVPs within an AVP of type Grouped have the
- same padding requirements as non-Grouped AVPs, as defined in
- Section 4.4.
-
- The AVP Code numbering space of all AVPs included in a Grouped AVP is
- the same as for non-Grouped AVPs. Receivers of a Grouped AVP that
- does not have the 'M' (mandatory) bit set and one or more of the
- encapsulated AVPs within the group has the 'M' (mandatory) bit set
- MAY simply be ignored if the Grouped AVP itself is unrecognized. The
- rule applies even if the encapsulated AVP with its 'M' (mandatory)
- bit set is further encapsulated within other sub-groups, i.e., other
- Grouped AVPs embedded within the Grouped AVP.
-
- Every Grouped AVP definition MUST include a corresponding grammar,
- using ABNF [RFC5234] (with modifications), as defined below.
-
- grouped-avp-def = "&lt;" name ">" "::=" avp
-
- name-fmt = ALPHA *(ALPHA / DIGIT / "-")
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 51]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- name = name-fmt
- ; The name has to be the name of an AVP,
- ; defined in the base or extended Diameter
- ; specifications.
-
- avp = header *fixed *required *optional
-
- header = "&lt;" "AVP-Header:" avpcode [vendor] ">"
-
- avpcode = 1*DIGIT
- ; The AVP Code assigned to the Grouped AVP.
-
- vendor = 1*DIGIT
- ; The Vendor-ID assigned to the Grouped AVP.
- ; If absent, the default value of zero is
- ; used.
-
-4.4.1. Example AVP with a Grouped Data Type
-
- The Example-AVP (AVP Code 999999) is of type Grouped and is used to
- clarify how Grouped AVP values work. The Grouped Data field has the
- following CCF grammar:
-
- Example-AVP ::= &lt; AVP Header: 999999 >
- { Origin-Host }
- 1*{ Session-Id }
- *[ AVP ]
-
- An Example-AVP with Grouped Data follows.
-
- The Origin-Host AVP (Section 6.3) is required. In this case:
-
- Origin-Host = "example.com".
-
- One or more Session-Ids must follow. Here there are two:
-
- Session-Id =
- "grump.example.com:33041;23432;893;0AF3B81"
-
- Session-Id =
- "grump.example.com:33054;23561;2358;0AF3B82"
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 52]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- optional AVPs included are
-
- Recovery-Policy = &lt;binary>
- 2163bc1d0ad82371f6bc09484133c3f09ad74a0dd5346d54195a7cf0b35
- 2cabc881839a4fdcfbc1769e2677a4c1fb499284c5f70b48f58503a45c5
- c2d6943f82d5930f2b7c1da640f476f0e9c9572a50db8ea6e51e1c2c7bd
- f8bb43dc995144b8dbe297ac739493946803e1cee3e15d9b765008a1b2a
- cf4ac777c80041d72c01e691cf751dbf86e85f509f3988e5875dc905119
- 26841f00f0e29a6d1ddc1a842289d440268681e052b30fb638045f7779c
- 1d873c784f054f688f5001559ecff64865ef975f3e60d2fd7966b8c7f92
-
- Futuristic-Acct-Record = &lt;binary>
- fe19da5802acd98b07a5b86cb4d5d03f0314ab9ef1ad0b67111ff3b90a0
- 57fe29620bf3585fd2dd9fcc38ce62f6cc208c6163c008f4258d1bc88b8
- 17694a74ccad3ec69269461b14b2e7a4c111fb239e33714da207983f58c
- 41d018d56fe938f3cbf089aac12a912a2f0d1923a9390e5f789cb2e5067
- d3427475e49968f841
-
- The data for the optional AVPs is represented in hexadecimal form
- since the format of these AVPs is not known at the time of definition
- of the Example-AVP group nor (likely) at the time when the example
- instance of this AVP is interpreted -- except by Diameter
- implementations that support the same set of AVPs. The encoding
- example illustrates how padding is used and how length fields are
- calculated. Also, note that AVPs may be present in the Grouped AVP
- value that the receiver cannot interpret (here, the Recover-Policy
- and Futuristic-Acct-Record AVPs). The length of the Example-AVP is
- the sum of all the length of the member AVPs, including their
- padding, plus the Example-AVP header size.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 53]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- This AVP would be encoded as follows:
-
- 0 1 2 3 4 5 6 7
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 0 | Example AVP Header (AVP Code = 999999), Length = 496 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 8 | Origin-Host AVP Header (AVP Code = 264), Length = 19 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 16 | 'e' | 'x' | 'a' | 'm' | 'p' | 'l' | 'e' | '.' |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 24 | 'c' | 'o' | 'm' |Padding| Session-Id AVP Header |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 32 | (AVP Code = 263), Length = 49 | 'g' | 'r' | 'u' | 'm' |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- . . .
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 72 | 'F' | '3' | 'B' | '8' | '1' |Padding|Padding|Padding|
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 80 | Session-Id AVP Header (AVP Code = 263), Length = 50 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 88 | 'g' | 'r' | 'u' | 'm' | 'p' | '.' | 'e' | 'x' |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- . . .
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 120| '5' | '8' | ';' | '0' | 'A' | 'F' | '3' | 'B' |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 128| '8' | '2' |Padding|Padding| Recovery-Policy Header (AVP |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 136| Code = 8341), Length = 223 | 0x21 | 0x63 | 0xbc | 0x1d |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 144| 0x0a | 0xd8 | 0x23 | 0x71 | 0xf6 | 0xbc | 0x09 | 0x48 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- . . .
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 352| 0x8c | 0x7f | 0x92 |Padding| Futuristic-Acct-Record Header |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 328|(AVP Code = 15930),Length = 137| 0xfe | 0x19 | 0xda | 0x58 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 336| 0x02 | 0xac | 0xd9 | 0x8b | 0x07 | 0xa5 | 0xb8 | 0xc6 |
- +-------+-------+-------+-------+-------+-------+-------+-------+
- . . .
- +-------+-------+-------+-------+-------+-------+-------+-------+
- 488| 0xe4 | 0x99 | 0x68 | 0xf8 | 0x41 |Padding|Padding|Padding|
- +-------+-------+-------+-------+-------+-------+-------+-------+
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 54]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-4.5. Diameter Base Protocol AVPs
-
- The following table describes the Diameter AVPs defined in the base
- protocol, their AVP Code values, types, and possible flag values.
-
- Due to space constraints, the short form DiamIdent is used to
- represent DiameterIdentity.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 55]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- +----------+
- | AVP Flag |
- | rules |
- |----+-----|
- AVP Section | |MUST |
- Attribute Name Code Defined Data Type |MUST| NOT |
- -----------------------------------------|----+-----|
- Acct- 85 9.8.2 Unsigned32 | M | V |
- Interim-Interval | | |
- Accounting- 483 9.8.7 Enumerated | M | V |
- Realtime-Required | | |
- Acct- 50 9.8.5 UTF8String | M | V |
- Multi-Session-Id | | |
- Accounting- 485 9.8.3 Unsigned32 | M | V |
- Record-Number | | |
- Accounting- 480 9.8.1 Enumerated | M | V |
- Record-Type | | |
- Acct- 44 9.8.4 OctetString| M | V |
- Session-Id | | |
- Accounting- 287 9.8.6 Unsigned64 | M | V |
- Sub-Session-Id | | |
- Acct- 259 6.9 Unsigned32 | M | V |
- Application-Id | | |
- Auth- 258 6.8 Unsigned32 | M | V |
- Application-Id | | |
- Auth-Request- 274 8.7 Enumerated | M | V |
- Type | | |
- Authorization- 291 8.9 Unsigned32 | M | V |
- Lifetime | | |
- Auth-Grace- 276 8.10 Unsigned32 | M | V |
- Period | | |
- Auth-Session- 277 8.11 Enumerated | M | V |
- State | | |
- Re-Auth-Request- 285 8.12 Enumerated | M | V |
- Type | | |
- Class 25 8.20 OctetString| M | V |
- Destination-Host 293 6.5 DiamIdent | M | V |
- Destination- 283 6.6 DiamIdent | M | V |
- Realm | | |
- Disconnect-Cause 273 5.4.3 Enumerated | M | V |
- Error-Message 281 7.3 UTF8String | | V,M |
- Error-Reporting- 294 7.4 DiamIdent | | V,M |
- Host | | |
- Event-Timestamp 55 8.21 Time | M | V |
- Experimental- 297 7.6 Grouped | M | V |
- Result | | |
- -----------------------------------------|----+-----|
-
-
-
-
-Fajardo, et al. Standards Track [Page 56]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- +----------+
- | AVP Flag |
- | rules |
- |----+-----|
- AVP Section | |MUST |
- Attribute Name Code Defined Data Type |MUST| NOT |
- -----------------------------------------|----+-----|
- Experimental- 298 7.7 Unsigned32 | M | V |
- Result-Code | | |
- Failed-AVP 279 7.5 Grouped | M | V |
- Firmware- 267 5.3.4 Unsigned32 | | V,M |
- Revision | | |
- Host-IP-Address 257 5.3.5 Address | M | V |
- Inband-Security | M | V |
- -Id 299 6.10 Unsigned32 | | |
- Multi-Round- 272 8.19 Unsigned32 | M | V |
- Time-Out | | |
- Origin-Host 264 6.3 DiamIdent | M | V |
- Origin-Realm 296 6.4 DiamIdent | M | V |
- Origin-State-Id 278 8.16 Unsigned32 | M | V |
- Product-Name 269 5.3.7 UTF8String | | V,M |
- Proxy-Host 280 6.7.3 DiamIdent | M | V |
- Proxy-Info 284 6.7.2 Grouped | M | V |
- Proxy-State 33 6.7.4 OctetString| M | V |
- Redirect-Host 292 6.12 DiamURI | M | V |
- Redirect-Host- 261 6.13 Enumerated | M | V |
- Usage | | |
- Redirect-Max- 262 6.14 Unsigned32 | M | V |
- Cache-Time | | |
- Result-Code 268 7.1 Unsigned32 | M | V |
- Route-Record 282 6.7.1 DiamIdent | M | V |
- Session-Id 263 8.8 UTF8String | M | V |
- Session-Timeout 27 8.13 Unsigned32 | M | V |
- Session-Binding 270 8.17 Unsigned32 | M | V |
- Session-Server- 271 8.18 Enumerated | M | V |
- Failover | | |
- Supported- 265 5.3.6 Unsigned32 | M | V |
- Vendor-Id | | |
- Termination- 295 8.15 Enumerated | M | V |
- Cause | | |
- User-Name 1 8.14 UTF8String | M | V |
- Vendor-Id 266 5.3.3 Unsigned32 | M | V |
- Vendor-Specific- 260 6.11 Grouped | M | V |
- Application-Id | | |
- -----------------------------------------|----+-----|
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 57]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-5. Diameter Peers
-
- This section describes how Diameter nodes establish connections and
- communicate with peers.
-
-5.1. Peer Connections
-
- Connections between diameter peers are established using their valid
- DiameterIdentity. A Diameter node initiating a connection to a peer
- MUST know the peer's DiameterIdentity. Methods for discovering a
- Diameter peer can be found in Section 5.2.
-
- Although a Diameter node may have many possible peers with which it
- is able to communicate, it may not be economical to have an
- established connection to all of them. At a minimum, a Diameter node
- SHOULD have an established connection with two peers per realm, known
- as the primary and secondary peers. Of course, a node MAY have
- additional connections, if it is deemed necessary. Typically, all
- messages for a realm are sent to the primary peer but, in the event
- that failover procedures are invoked, any pending requests are sent
- to the secondary peer. However, implementations are free to load
- balance requests between a set of peers.
-
- Note that a given peer MAY act as a primary for a given realm while
- acting as a secondary for another realm.
-
- When a peer is deemed suspect, which could occur for various reasons,
- including not receiving a DWA within an allotted time frame, no new
- requests should be forwarded to the peer, but failover procedures are
- invoked. When an active peer is moved to this mode, additional
- connections SHOULD be established to ensure that the necessary number
- of active connections exists.
-
- There are two ways that a peer is removed from the suspect peer list:
-
- 1. The peer is no longer reachable, causing the transport connection
- to be shut down. The peer is moved to the closed state.
-
- 2. Three watchdog messages are exchanged with accepted round-trip
- times, and the connection to the peer is considered stabilized.
-
- In the event the peer being removed is either the primary or
- secondary, an alternate peer SHOULD replace the deleted peer and
- assume the role of either primary or secondary.
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 58]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-5.2. Diameter Peer Discovery
-
- Allowing for dynamic Diameter agent discovery makes possible simpler
- and more robust deployment of Diameter services. In order to promote
- interoperable implementations of Diameter peer discovery, the
- following mechanisms (manual configuration and DNS) are described.
- These are based on existing IETF standards. Both mechanisms MUST be
- supported by all Diameter implementations; either MAY be used.
-
- There are two cases where Diameter peer discovery may be performed.
- The first is when a Diameter client needs to discover a first-hop
- Diameter agent. The second case is when a Diameter agent needs to
- discover another agent for further handling of a Diameter operation.
- In both cases, the following 'search order' is recommended:
-
- 1. The Diameter implementation consults its list of statically
- (manually) configured Diameter agent locations. These will be
- used if they exist and respond.
-
- 2. The Diameter implementation performs a NAPTR query for a server
- in a particular realm. The Diameter implementation has to know,
- in advance, in which realm to look for a Diameter agent. This
- could be deduced, for example, from the 'realm' in an NAI on
- which a Diameter implementation needed to perform a Diameter
- operation.
-
- The NAPTR usage in Diameter follows the S-NAPTR DDDS application
- [RFC3958] in which the SERVICE field includes tags for the
- desired application and supported application protocol. The
- application service tag for a Diameter application is 'aaa' and
- the supported application protocol tags are 'diameter.tcp',
- 'diameter.sctp', 'diameter.dtls', or 'diameter.tls.tcp'
- [RFC6408].
-
- The client can follow the resolution process defined by the
- S-NAPTR DDDS [RFC3958] application to find a matching SRV, A, or
- AAAA record of a suitable peer. The domain suffixes in the NAPTR
- replacement field SHOULD match the domain of the original query.
- An example can be found in Appendix B.
-
- 3. If no NAPTR records are found, the requester directly queries for
- one of the following SRV records: for Diameter over TCP, use
- "_diameter._tcp.realm"; for Diameter over TLS, use
- "_diameters._tcp.realm"; for Diameter over SCTP, use
- "_diameter._sctp.realm"; for Diameter over DTLS, use
- "_diameters._sctp.realm". If SRV records are found, then the
- requester can perform address record query (A RR's and/or AAAA
-
-
-
-
-Fajardo, et al. Standards Track [Page 59]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- RR's) for the target hostname specified in the SRV records
- following the rules given in [RFC2782]. If no SRV records are
- found, the requester gives up.
-
- If the server is using a site certificate, the domain name in the
- NAPTR query and the domain name in the replacement field MUST both be
- valid based on the site certificate handed out by the server in the
- TLS/TCP and DTLS/SCTP or Internet Key Exchange Protocol (IKE)
- exchange. Similarly, the domain name in the SRV query and the domain
- name in the target in the SRV record MUST both be valid based on the
- same site certificate. Otherwise, an attacker could modify the DNS
- records to contain replacement values in a different domain, and the
- client could not validate whether this was the desired behavior or
- the result of an attack.
-
- Also, the Diameter peer MUST check to make sure that the discovered
- peers are authorized to act in its role. Authentication via IKE or
- TLS/TCP and DTLS/SCTP, or validation of DNS RRs via DNSSEC is not
- sufficient to conclude this. For example, a web server may have
- obtained a valid TLS/TCP and DTLS/SCTP certificate, and secured RRs
- may be included in the DNS, but this does not imply that it is
- authorized to act as a Diameter server.
-
- Authorization can be achieved, for example, by the configuration of a
- Diameter server Certification Authority (CA). The server CA issues a
- certificate to the Diameter server, which includes an Object
- Identifier (OID) to indicate the subject is a Diameter server in the
- Extended Key Usage extension [RFC5280]. This certificate is then
- used during TLS/TCP, DTLS/SCTP, or IKE security negotiation.
- However, note that, at the time of writing, no Diameter server
- Certification Authorities exist.
-
- A dynamically discovered peer causes an entry in the peer table (see
- Section 2.6) to be created. Note that entries created via DNS MUST
- expire (or be refreshed) within the DNS Time to Live (TTL). If a
- peer is discovered outside of the local realm, a routing table entry
- (see Section 2.7) for the peer's realm is created. The routing table
- entry's expiration MUST match the peer's expiration value.
-
-5.3. Capabilities Exchange
-
- When two Diameter peers establish a transport connection, they MUST
- exchange the Capabilities Exchange messages, as specified in the peer
- state machine (see Section 5.6). This message allows the discovery
- of a peer's identity and its capabilities (protocol version number,
- the identifiers of supported Diameter applications, security
- mechanisms, etc.).
-
-
-
-
-Fajardo, et al. Standards Track [Page 60]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The receiver only issues commands to its peers that have advertised
- support for the Diameter application that defines the command. A
- Diameter node MUST cache the supported Application Ids in order to
- ensure that unrecognized commands and/or AVPs are not unnecessarily
- sent to a peer.
-
- A receiver of a Capabilities-Exchange-Request (CER) message that does
- not have any applications in common with the sender MUST return a
- Capabilities-Exchange-Answer (CEA) with the Result-Code AVP set to
- DIAMETER_NO_COMMON_APPLICATION and SHOULD disconnect the transport
- layer connection. Note that receiving a CER or CEA from a peer
- advertising itself as a relay (see Section 2.4) MUST be interpreted
- as having common applications with the peer.
-
- The receiver of the Capabilities-Exchange-Request (CER) MUST
- determine common applications by computing the intersection of its
- own set of supported Application Ids against all of the
- Application-Id AVPs (Auth-Application-Id, Acct-Application-Id, and
- Vendor-Specific-Application-Id) present in the CER. The value of the
- Vendor-Id AVP in the Vendor-Specific-Application-Id MUST NOT be used
- during computation. The sender of the Capabilities-Exchange-Answer
- (CEA) SHOULD include all of its supported applications as a hint to
- the receiver regarding all of its application capabilities.
-
- Diameter implementations SHOULD first attempt to establish a TLS/TCP
- and DTLS/SCTP connection prior to the CER/CEA exchange. This
- protects the capabilities information of both peers. To support
- older Diameter implementations that do not fully conform to this
- document, the transport security MAY still be negotiated via an
- Inband-Security AVP. In this case, the receiver of a Capabilities-
- Exchange-Request (CER) message that does not have any security
- mechanisms in common with the sender MUST return a Capabilities-
- Exchange-Answer (CEA) with the Result-Code AVP set to
- DIAMETER_NO_COMMON_SECURITY and SHOULD disconnect the transport layer
- connection.
-
- CERs received from unknown peers MAY be silently discarded, or a CEA
- MAY be issued with the Result-Code AVP set to DIAMETER_UNKNOWN_PEER.
- In both cases, the transport connection is closed. If the local
- policy permits receiving CERs from unknown hosts, a successful CEA
- MAY be returned. If a CER from an unknown peer is answered with a
- successful CEA, the lifetime of the peer entry is equal to the
- lifetime of the transport connection. In case of a transport
- failure, all the pending transactions destined to the unknown peer
- can be discarded.
-
- The CER and CEA messages MUST NOT be proxied, redirected, or relayed.
-
-
-
-
-Fajardo, et al. Standards Track [Page 61]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Since the CER/CEA messages cannot be proxied, it is still possible
- that an upstream agent will receive a message for which it has no
- available peers to handle the application that corresponds to the
- Command Code. In such instances, the 'E' bit is set in the answer
- message (Section 7) with the Result-Code AVP set to
- DIAMETER_UNABLE_TO_DELIVER to inform the downstream agent to take
- action (e.g., re-routing request to an alternate peer).
-
- With the exception of the Capabilities-Exchange-Request message, a
- message of type Request that includes the Auth-Application-Id or
- Acct-Application-Id AVPs, or a message with an application-specific
- Command Code MAY only be forwarded to a host that has explicitly
- advertised support for the application (or has advertised the Relay
- Application Id).
-
-5.3.1. Capabilities-Exchange-Request
-
- The Capabilities-Exchange-Request (CER), indicated by the Command
- Code set to 257 and the Command Flags' 'R' bit set, is sent to
- exchange local capabilities. Upon detection of a transport failure,
- this message MUST NOT be sent to an alternate peer.
-
- When Diameter is run over SCTP [RFC4960] or DTLS/SCTP [RFC6083],
- which allow for connections to span multiple interfaces and multiple
- IP addresses, the Capabilities-Exchange-Request message MUST contain
- one Host-IP-Address AVP for each potential IP address that MAY be
- locally used when transmitting Diameter messages.
-
- Message Format
-
- &lt;CER> ::= &lt; Diameter Header: 257, REQ >
- { Origin-Host }
- { Origin-Realm }
- 1* { Host-IP-Address }
- { Vendor-Id }
- { Product-Name }
- [ Origin-State-Id ]
- * [ Supported-Vendor-Id ]
- * [ Auth-Application-Id ]
- * [ Inband-Security-Id ]
- * [ Acct-Application-Id ]
- * [ Vendor-Specific-Application-Id ]
- [ Firmware-Revision ]
- * [ AVP ]
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 62]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-5.3.2. Capabilities-Exchange-Answer
-
- The Capabilities-Exchange-Answer (CEA), indicated by the Command Code
- set to 257 and the Command Flags' 'R' bit cleared, is sent in
- response to a CER message.
-
- When Diameter is run over SCTP [RFC4960] or DTLS/SCTP [RFC6083],
- which allow connections to span multiple interfaces, hence, multiple
- IP addresses, the Capabilities-Exchange-Answer message MUST contain
- one Host-IP-Address AVP for each potential IP address that MAY be
- locally used when transmitting Diameter messages.
-
- Message Format
-
- &lt;CEA> ::= &lt; Diameter Header: 257 >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- 1* { Host-IP-Address }
- { Vendor-Id }
- { Product-Name }
- [ Origin-State-Id ]
- [ Error-Message ]
- [ Failed-AVP ]
- * [ Supported-Vendor-Id ]
- * [ Auth-Application-Id ]
- * [ Inband-Security-Id ]
- * [ Acct-Application-Id ]
- * [ Vendor-Specific-Application-Id ]
- [ Firmware-Revision ]
- * [ AVP ]
-
-5.3.3. Vendor-Id AVP
-
- The Vendor-Id AVP (AVP Code 266) is of type Unsigned32 and contains
- the IANA "SMI Network Management Private Enterprise Codes"
- [ENTERPRISE] value assigned to the Diameter Software vendor. It is
- envisioned that the combination of the Vendor-Id, Product-Name
- (Section 5.3.7), and Firmware-Revision (Section 5.3.4) AVPs may
- provide useful debugging information.
-
- A Vendor-Id value of zero in the CER or CEA message is reserved and
- indicates that this field is ignored.
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 63]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-5.3.4. Firmware-Revision AVP
-
- The Firmware-Revision AVP (AVP Code 267) is of type Unsigned32 and is
- used to inform a Diameter peer of the firmware revision of the
- issuing device.
-
- For devices that do not have a firmware revision (general-purpose
- computers running Diameter software modules, for instance), the
- revision of the Diameter software module may be reported instead.
-
-5.3.5. Host-IP-Address AVP
-
- The Host-IP-Address AVP (AVP Code 257) is of type Address and is used
- to inform a Diameter peer of the sender's IP address. All source
- addresses that a Diameter node expects to use with SCTP [RFC4960] or
- DTLS/SCTP [RFC6083] MUST be advertised in the CER and CEA messages by
- including a Host-IP-Address AVP for each address.
-
-5.3.6. Supported-Vendor-Id AVP
-
- The Supported-Vendor-Id AVP (AVP Code 265) is of type Unsigned32 and
- contains the IANA "SMI Network Management Private Enterprise Codes"
- [ENTERPRISE] value assigned to a vendor other than the device vendor
- but including the application vendor. This is used in the CER and
- CEA messages in order to inform the peer that the sender supports (a
- subset of) the Vendor-Specific AVPs defined by the vendor identified
- in this AVP. The value of this AVP MUST NOT be set to zero.
- Multiple instances of this AVP containing the same value SHOULD NOT
- be sent.
-
-5.3.7. Product-Name AVP
-
- The Product-Name AVP (AVP Code 269) is of type UTF8String and
- contains the vendor-assigned name for the product. The Product-Name
- AVP SHOULD remain constant across firmware revisions for the same
- product.
-
-5.4. Disconnecting Peer Connections
-
- When a Diameter node disconnects one of its transport connections,
- its peer cannot know the reason for the disconnect and will most
- likely assume that a connectivity problem occurred or that the peer
- has rebooted. In these cases, the peer may periodically attempt to
- reconnect, as stated in Section 2.1. In the event that the
- disconnect was a result of either a shortage of internal resources or
- simply that the node in question has no intentions of forwarding any
- Diameter messages to the peer in the foreseeable future, a periodic
-
-
-
-
-Fajardo, et al. Standards Track [Page 64]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- connection request would not be welcomed. The Disconnection-Reason
- AVP contains the reason the Diameter node issued the Disconnect-Peer-
- Request message.
-
- The Disconnect-Peer-Request message is used by a Diameter node to
- inform its peer of its intent to disconnect the transport layer and
- that the peer shouldn't reconnect unless it has a valid reason to do
- so (e.g., message to be forwarded). Upon receipt of the message, the
- Disconnect-Peer-Answer message is returned, which SHOULD contain an
- error if messages have recently been forwarded, and are likely in
- flight, which would otherwise cause a race condition.
-
- The receiver of the Disconnect-Peer-Answer message initiates the
- transport disconnect. The sender of the Disconnect-Peer-Answer
- message should be able to detect the transport closure and clean up
- the connection.
-
-5.4.1. Disconnect-Peer-Request
-
- The Disconnect-Peer-Request (DPR), indicated by the Command Code set
- to 282 and the Command Flags' 'R' bit set, is sent to a peer to
- inform it of its intentions to shut down the transport connection.
- Upon detection of a transport failure, this message MUST NOT be sent
- to an alternate peer.
-
- Message Format
-
- &lt;DPR> ::= &lt; Diameter Header: 282, REQ >
- { Origin-Host }
- { Origin-Realm }
- { Disconnect-Cause }
- * [ AVP ]
-
-5.4.2. Disconnect-Peer-Answer
-
- The Disconnect-Peer-Answer (DPA), indicated by the Command Code set
- to 282 and the Command Flags' 'R' bit cleared, is sent as a response
- to the Disconnect-Peer-Request message. Upon receipt of this
- message, the transport connection is shut down.
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 65]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Message Format
-
- &lt;DPA> ::= &lt; Diameter Header: 282 >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- [ Error-Message ]
- [ Failed-AVP ]
- * [ AVP ]
-
-
-5.4.3. Disconnect-Cause AVP
-
- The Disconnect-Cause AVP (AVP Code 273) is of type Enumerated. A
- Diameter node MUST include this AVP in the Disconnect-Peer-Request
- message to inform the peer of the reason for its intention to shut
- down the transport connection. The following values are supported:
-
- REBOOTING 0
- A scheduled reboot is imminent. A receiver of a DPR with
- above result code MAY attempt reconnection.
-
- BUSY 1
- The peer's internal resources are constrained, and it has
- determined that the transport connection needs to be closed.
- A receiver of a DPR with above result code SHOULD NOT attempt
- reconnection.
-
- DO_NOT_WANT_TO_TALK_TO_YOU 2
- The peer has determined that it does not see a need for the
- transport connection to exist, since it does not expect any
- messages to be exchanged in the near future. A receiver of a
- DPR with above result code SHOULD NOT attempt reconnection.
-
-5.5. Transport Failure Detection
-
- Given the nature of the Diameter protocol, it is recommended that
- transport failures be detected as soon as possible. Detecting such
- failures will minimize the occurrence of messages sent to unavailable
- agents, resulting in unnecessary delays, and will provide better
- failover performance. The Device-Watchdog-Request and Device-
- Watchdog-Answer messages, defined in this section, are used to pro-
- actively detect transport failures.
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 66]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-5.5.1. Device-Watchdog-Request
-
- The Device-Watchdog-Request (DWR), indicated by the Command Code set
- to 280 and the Command Flags' 'R' bit set, is sent to a peer when no
- traffic has been exchanged between two peers (see Section 5.5.3).
- Upon detection of a transport failure, this message MUST NOT be sent
- to an alternate peer.
-
- Message Format
-
- &lt;DWR> ::= &lt; Diameter Header: 280, REQ >
- { Origin-Host }
- { Origin-Realm }
- [ Origin-State-Id ]
- * [ AVP ]
-
-5.5.2. Device-Watchdog-Answer
-
- The Device-Watchdog-Answer (DWA), indicated by the Command Code set
- to 280 and the Command Flags' 'R' bit cleared, is sent as a response
- to the Device-Watchdog-Request message.
-
- Message Format
-
- &lt;DWA> ::= &lt; Diameter Header: 280 >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- [ Error-Message ]
- [ Failed-AVP ]
- [ Origin-State-Id ]
- * [ AVP ]
-
-5.5.3. Transport Failure Algorithm
-
- The transport failure algorithm is defined in [RFC3539]. All
- Diameter implementations MUST support the algorithm defined in that
- specification in order to be compliant to the Diameter base protocol.
-
-5.5.4. Failover and Failback Procedures
-
- In the event that a transport failure is detected with a peer, it is
- necessary for all pending request messages to be forwarded to an
- alternate agent, if possible. This is commonly referred to as
- "failover".
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 67]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- In order for a Diameter node to perform failover procedures, it is
- necessary for the node to maintain a pending message queue for a
- given peer. When an answer message is received, the corresponding
- request is removed from the queue. The Hop-by-Hop Identifier field
- is used to match the answer with the queued request.
-
- When a transport failure is detected, if possible, all messages in
- the queue are sent to an alternate agent with the T flag set. On
- booting a Diameter client or agent, the T flag is also set on any
- remaining records in non-volatile storage that are still waiting to
- be transmitted. An example of a case where it is not possible to
- forward the message to an alternate server is when the message has a
- fixed destination, and the unavailable peer is the message's final
- destination (see Destination-Host AVP). Such an error requires that
- the agent return an answer message with the 'E' bit set and the
- Result-Code AVP set to DIAMETER_UNABLE_TO_DELIVER.
-
- It is important to note that multiple identical requests or answers
- MAY be received as a result of a failover. The End-to-End Identifier
- field in the Diameter header along with the Origin-Host AVP MUST be
- used to identify duplicate messages.
-
- As described in Section 2.1, a connection request should be
- periodically attempted with the failed peer in order to re-establish
- the transport connection. Once a connection has been successfully
- established, messages can once again be forwarded to the peer. This
- is commonly referred to as "failback".
-
-5.6. Peer State Machine
-
- This section contains a finite state machine that MUST be observed by
- all Diameter implementations. Each Diameter node MUST follow the
- state machine described below when communicating with each peer.
- Multiple actions are separated by commas, and may continue on
- succeeding lines, as space requires. Similarly, state and next state
- may also span multiple lines, as space requires.
-
- This state machine is closely coupled with the state machine
- described in [RFC3539], which is used to open, close, failover,
- probe, and reopen transport connections. In particular, note that
- [RFC3539] requires the use of watchdog messages to probe connections.
- For Diameter, DWR and DWA messages are to be used.
-
- The I- prefix is used to represent the initiator (connecting)
- connection, while the R- prefix is used to represent the responder
- (listening) connection. The lack of a prefix indicates that the
- event or action is the same regardless of the connection on which the
- event occurred.
-
-
-
-Fajardo, et al. Standards Track [Page 68]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The stable states that a state machine may be in are Closed, I-Open,
- and R-Open; all other states are intermediate. Note that I-Open and
- R-Open are equivalent except for whether the initiator or responder
- transport connection is used for communication.
-
- A CER message is always sent on the initiating connection immediately
- after the connection request is successfully completed. In the case
- of an election, one of the two connections will shut down. The
- responder connection will survive if the Origin-Host of the local
- Diameter entity is higher than that of the peer; the initiator
- connection will survive if the peer's Origin-Host is higher. All
- subsequent messages are sent on the surviving connection. Note that
- the results of an election on one peer are guaranteed to be the
- inverse of the results on the other.
-
- For TLS/TCP and DTLS/SCTP usage, a TLS/TCP and DTLS/SCTP handshake
- SHOULD begin when both ends are in the closed state prior to any
- Diameter message exchanges. The TLS/TCP and DTLS/SCTP connection
- SHOULD be established before sending any CER or CEA message to secure
- and protect the capabilities information of both peers. The TLS/TCP
- and DTLS/SCTP connection SHOULD be disconnected when the state
- machine moves to the closed state. When connecting to responders
- that do not conform to this document (i.e., older Diameter
- implementations that are not prepared to received TLS/TCP and DTLS/
- SCTP connections in the closed state), the initial TLS/TCP and DTLS/
- SCTP connection attempt will fail. The initiator MAY then attempt to
- connect via TCP or SCTP and initiate the TLS/TCP and DTLS/SCTP
- handshake when both ends are in the open state. If the handshake is
- successful, all further messages will be sent via TLS/TCP and DTLS/
- SCTP. If the handshake fails, both ends move to the closed state.
-
- The state machine constrains only the behavior of a Diameter
- implementation as seen by Diameter peers through events on the wire.
-
- Any implementation that produces equivalent results is considered
- compliant.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 69]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- state event action next state
- -----------------------------------------------------------------
- Closed Start I-Snd-Conn-Req Wait-Conn-Ack
- R-Conn-CER R-Accept, R-Open
- Process-CER,
- R-Snd-CEA
-
- Wait-Conn-Ack I-Rcv-Conn-Ack I-Snd-CER Wait-I-CEA
- I-Rcv-Conn-Nack Cleanup Closed
- R-Conn-CER R-Accept, Wait-Conn-Ack/
- Process-CER Elect
- Timeout Error Closed
-
- Wait-I-CEA I-Rcv-CEA Process-CEA I-Open
- R-Conn-CER R-Accept, Wait-Returns
- Process-CER,
- Elect
- I-Peer-Disc I-Disc Closed
- I-Rcv-Non-CEA Error Closed
- Timeout Error Closed
-
- Wait-Conn-Ack/ I-Rcv-Conn-Ack I-Snd-CER,Elect Wait-Returns
- Elect I-Rcv-Conn-Nack R-Snd-CEA R-Open
- R-Peer-Disc R-Disc Wait-Conn-Ack
- R-Conn-CER R-Reject Wait-Conn-Ack/
- Elect
- Timeout Error Closed
-
- Wait-Returns Win-Election I-Disc,R-Snd-CEA R-Open
- I-Peer-Disc I-Disc, R-Open
- R-Snd-CEA
- I-Rcv-CEA R-Disc I-Open
- R-Peer-Disc R-Disc Wait-I-CEA
- R-Conn-CER R-Reject Wait-Returns
- Timeout Error Closed
-
- R-Open Send-Message R-Snd-Message R-Open
- R-Rcv-Message Process R-Open
- R-Rcv-DWR Process-DWR, R-Open
- R-Snd-DWA
- R-Rcv-DWA Process-DWA R-Open
- R-Conn-CER R-Reject R-Open
- Stop R-Snd-DPR Closing
- R-Rcv-DPR R-Snd-DPA Closing
- R-Peer-Disc R-Disc Closed
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 70]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- I-Open Send-Message I-Snd-Message I-Open
- I-Rcv-Message Process I-Open
- I-Rcv-DWR Process-DWR, I-Open
- I-Snd-DWA
- I-Rcv-DWA Process-DWA I-Open
- R-Conn-CER R-Reject I-Open
- Stop I-Snd-DPR Closing
- I-Rcv-DPR I-Snd-DPA Closing
- I-Peer-Disc I-Disc Closed
-
- Closing I-Rcv-DPA I-Disc Closed
- R-Rcv-DPA R-Disc Closed
- Timeout Error Closed
- I-Peer-Disc I-Disc Closed
- R-Peer-Disc R-Disc Closed
-
-5.6.1. Incoming Connections
-
- When a connection request is received from a Diameter peer, it is
- not, in the general case, possible to know the identity of that peer
- until a CER is received from it. This is because host and port
- determine the identity of a Diameter peer; the source port of an
- incoming connection is arbitrary. Upon receipt of a CER, the
- identity of the connecting peer can be uniquely determined from the
- Origin-Host.
-
- For this reason, a Diameter peer must employ logic separate from the
- state machine to receive connection requests, accept them, and await
- the CER. Once the CER arrives on a new connection, the Origin-Host
- that identifies the peer is used to locate the state machine
- associated with that peer, and the new connection and CER are passed
- to the state machine as an R-Conn-CER event.
-
- The logic that handles incoming connections SHOULD close and discard
- the connection if any message other than a CER arrives or if an
- implementation-defined timeout occurs prior to receipt of CER.
-
- Because handling of incoming connections up to and including receipt
- of a CER requires logic, separate from that of any individual state
- machine associated with a particular peer, it is described separately
- in this section rather than in the state machine above.
-
-5.6.2. Events
-
- Transitions and actions in the automaton are caused by events. In
- this section, we will ignore the I- and R- prefixes, since the actual
- event would be identical, but it would occur on one of two possible
- connections.
-
-
-
-Fajardo, et al. Standards Track [Page 71]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Start The Diameter application has signaled that a
- connection should be initiated with the peer.
-
- R-Conn-CER An acknowledgement is received stating that the
- transport connection has been established, and the
- associated CER has arrived.
-
- Rcv-Conn-Ack A positive acknowledgement is received confirming that
- the transport connection is established.
-
- Rcv-Conn-Nack A negative acknowledgement was received stating that
- the transport connection was not established.
-
- Timeout An application-defined timer has expired while waiting
- for some event.
-
- Rcv-CER A CER message from the peer was received.
-
- Rcv-CEA A CEA message from the peer was received.
-
- Rcv-Non-CEA A message, other than a CEA, from the peer was
- received.
-
- Peer-Disc A disconnection indication from the peer was received.
-
- Rcv-DPR A DPR message from the peer was received.
-
- Rcv-DPA A DPA message from the peer was received.
-
- Win-Election An election was held, and the local node was the
- winner.
-
- Send-Message A message is to be sent.
-
- Rcv-Message A message other than CER, CEA, DPR, DPA, DWR, or DWA
- was received.
-
- Stop The Diameter application has signaled that a
- connection should be terminated (e.g., on system
- shutdown).
-
-5.6.3. Actions
-
- Actions in the automaton are caused by events and typically indicate
- the transmission of packets and/or an action to be taken on the
- connection. In this section, we will ignore the I- and R- prefixes,
- since the actual action would be identical, but it would occur on one
- of two possible connections.
-
-
-
-Fajardo, et al. Standards Track [Page 72]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Snd-Conn-Req A transport connection is initiated with the peer.
-
- Accept The incoming connection associated with the R-Conn-CER
- is accepted as the responder connection.
-
- Reject The incoming connection associated with the R-Conn-CER
- is disconnected.
-
- Process-CER The CER associated with the R-Conn-CER is processed.
-
- Snd-CER A CER message is sent to the peer.
-
- Snd-CEA A CEA message is sent to the peer.
-
- Cleanup If necessary, the connection is shut down, and any
- local resources are freed.
-
- Error The transport layer connection is disconnected,
- either politely or abortively, in response to
- an error condition. Local resources are freed.
-
- Process-CEA A received CEA is processed.
-
- Snd-DPR A DPR message is sent to the peer.
-
- Snd-DPA A DPA message is sent to the peer.
-
- Disc The transport layer connection is disconnected,
- and local resources are freed.
-
- Elect An election occurs (see Section 5.6.4 for more
- information).
-
- Snd-Message A message is sent.
-
- Snd-DWR A DWR message is sent.
-
- Snd-DWA A DWA message is sent.
-
- Process-DWR The DWR message is serviced.
-
- Process-DWA The DWA message is serviced.
-
- Process A message is serviced.
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 73]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-5.6.4. The Election Process
-
- The election is performed on the responder. The responder compares
- the Origin-Host received in the CER with its own Origin-Host as two
- streams of octets. If the local Origin-Host lexicographically
- succeeds the received Origin-Host, a Win-Election event is issued
- locally. Diameter identities are in ASCII form; therefore, the
- lexical comparison is consistent with DNS case insensitivity, where
- octets that fall in the ASCII range 'a' through 'z' MUST compare
- equally to their uppercase counterparts between 'A' and 'Z'. See
- Appendix D for interactions between the Diameter protocol and
- Internationalized Domain Name (IDNs).
-
- The winner of the election MUST close the connection it initiated.
- Historically, maintaining the responder side of a connection was more
- efficient than maintaining the initiator side. However, current
- practices makes this distinction irrelevant.
-
-6. Diameter Message Processing
-
- This section describes how Diameter requests and answers are created
- and processed.
-
-6.1. Diameter Request Routing Overview
-
- A request is sent towards its final destination using one of the
- following three combinations of the Destination-Realm and
- Destination-Host AVPs:
-
- o A request that is not able to be proxied (such as a CER) MUST NOT
- contain either Destination-Realm or Destination-Host AVPs.
-
- o A request that needs to be sent to a home server serving a
- specific realm, but not to a specific server (such as the first
- request of a series of round trips), MUST contain a Destination-
- Realm AVP but MUST NOT contain a Destination-Host AVP. For
- Diameter clients, the value of the Destination-Realm AVP MAY be
- extracted from the User-Name AVP, or other methods.
-
- o Otherwise, a request that needs to be sent to a specific home
- server among those serving a given realm MUST contain both the
- Destination-Realm and Destination-Host AVPs.
-
- The Destination-Host AVP is used as described above when the
- destination of the request is fixed, which includes:
-
- o Authentication requests that span multiple round trips.
-
-
-
-
-Fajardo, et al. Standards Track [Page 74]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o A Diameter message that uses a security mechanism that makes use
- of a pre-established session key shared between the source and the
- final destination of the message.
-
- o Server-initiated messages that MUST be received by a specific
- Diameter client (e.g., access device), such as the Abort-Session-
- Request message, which is used to request that a particular user's
- session be terminated.
-
- Note that an agent can only forward a request to a host described in
- the Destination-Host AVP if the host in question is included in its
- peer table (see Section 2.6). Otherwise, the request is routed based
- on the Destination-Realm only (see Section 6.1.6).
-
- When a message is received, the message is processed in the following
- order:
-
- o If the message is destined for the local host, the procedures
- listed in Section 6.1.4 are followed.
-
- o If the message is intended for a Diameter peer with whom the local
- host is able to directly communicate, the procedures listed in
- Section 6.1.5 are followed. This is known as "Request
- Forwarding".
-
- o The procedure listed in Section 6.1.6 is followed, which is known
- as "Request Routing".
-
- o If none of the above are successful, an answer is returned with
- the Result-Code set to DIAMETER_UNABLE_TO_DELIVER, with the 'E'
- bit set.
-
- For routing of Diameter messages to work within an administrative
- domain, all Diameter nodes within the realm MUST be peers.
-
- The overview contained in this section (6.1) is intended to provide
- general guidelines to Diameter developers. Implementations are free
- to use different methods than the ones described here as long as they
- conform to the requirements specified in Sections 6.1.1 through
- 6.1.9. See Section 7 for more details on error handling.
-
-6.1.1. Originating a Request
-
- When creating a request, in addition to any other procedures
- described in the application definition for that specific request,
- the following procedures MUST be followed:
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 75]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o the Command Code is set to the appropriate value;
-
- o the 'R' bit is set;
-
- o the End-to-End Identifier is set to a locally unique value;
-
- o the Origin-Host and Origin-Realm AVPs MUST be set to the
- appropriate values, used to identify the source of the message;
- and
-
- o the Destination-Host and Destination-Realm AVPs MUST be set to the
- appropriate values, as described in Section 6.1.
-
-6.1.2. Sending a Request
-
- When sending a request, originated either locally or as the result of
- a forwarding or routing operation, the following procedures SHOULD be
- followed:
-
- o The Hop-by-Hop Identifier SHOULD be set to a locally unique value.
-
- o The message SHOULD be saved in the list of pending requests.
-
- Other actions to perform on the message based on the particular role
- the agent is playing are described in the following sections.
-
-6.1.3. Receiving Requests
-
- A relay or proxy agent MUST check for forwarding loops when receiving
- requests. A loop is detected if the server finds its own identity in
- a Route-Record AVP. When such an event occurs, the agent MUST answer
- with the Result-Code AVP set to DIAMETER_LOOP_DETECTED.
-
-6.1.4. Processing Local Requests
-
- A request is known to be for local consumption when one of the
- following conditions occurs:
-
- o The Destination-Host AVP contains the local host's identity;
-
- o The Destination-Host AVP is not present, the Destination-Realm AVP
- contains a realm the server is configured to process locally, and
- the Diameter application is locally supported; or
-
- o Both the Destination-Host and the Destination-Realm are not
- present.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 76]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- When a request is locally processed, the rules in Section 6.2 should
- be used to generate the corresponding answer.
-
-6.1.5. Request Forwarding
-
- Request forwarding is done using the Diameter peer table. The
- Diameter peer table contains all of the peers with which the local
- node is able to directly communicate.
-
- When a request is received, and the host encoded in the Destination-
- Host AVP is one that is present in the peer table, the message SHOULD
- be forwarded to the peer.
-
-6.1.6. Request Routing
-
- Diameter request message routing is done via realms and Application
- Ids. A Diameter message that may be forwarded by Diameter agents
- (proxies, redirect agents, or relay agents) MUST include the target
- realm in the Destination-Realm AVP. Request routing SHOULD rely on
- the Destination-Realm AVP and the Application Id present in the
- request message header to aid in the routing decision. The realm MAY
- be retrieved from the User-Name AVP, which is in the form of a
- Network Access Identifier (NAI). The realm portion of the NAI is
- inserted in the Destination-Realm AVP.
-
- Diameter agents MAY have a list of locally supported realms and
- applications, and they MAY have a list of externally supported realms
- and applications. When a request is received that includes a realm
- and/or application that is not locally supported, the message is
- routed to the peer configured in the routing table (see Section 2.7).
-
- Realm names and Application Ids are the minimum supported routing
- criteria, additional information may be needed to support redirect
- semantics.
-
-6.1.7. Predictive Loop Avoidance
-
- Before forwarding or routing a request, Diameter agents, in addition
- to performing the processing described in Section 6.1.3, SHOULD check
- for the presence of a candidate route's peer identity in any of the
- Route-Record AVPs. In the event of the agent detecting the presence
- of a candidate route's peer identity in a Route-Record AVP, the agent
- MUST ignore such a route for the Diameter request message and attempt
- alternate routes if any exist. In case all the candidate routes are
- eliminated by the above criteria, the agent SHOULD return a
- DIAMETER_UNABLE_TO_DELIVER message.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 77]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-6.1.8. Redirecting Requests
-
- When a redirect agent receives a request whose routing entry is set
- to REDIRECT, it MUST reply with an answer message with the 'E' bit
- set, while maintaining the Hop-by-Hop Identifier in the header, and
- include the Result-Code AVP to DIAMETER_REDIRECT_INDICATION. Each of
- the servers associated with the routing entry are added in a separate
- Redirect-Host AVP.
-
- +------------------+
- | Diameter |
- | Redirect Agent |
- +------------------+
- ^ | 2. command + 'E' bit
- 1. Request | | Result-Code =
- [email protected] | | DIAMETER_REDIRECT_INDICATION +
- | | Redirect-Host AVP(s)
- | v
- +-------------+ 3. Request +-------------+
- | example.com |------------->| example.net |
- | Relay | | Diameter |
- | Agent |&lt;-------------| Server |
- +-------------+ 4. Answer +-------------+
-
- Figure 5: Diameter Redirect Agent
-
- The receiver of an answer message with the 'E' bit set and the
- Result-Code AVP set to DIAMETER_REDIRECT_INDICATION uses the Hop-by-
- Hop Identifier in the Diameter header to identify the request in the
- pending message queue (see Section 5.5.4) that is to be redirected.
- If no transport connection exists with the new peer, one is created,
- and the request is sent directly to it.
-
- Multiple Redirect-Host AVPs are allowed. The receiver of the answer
- message with the 'E' bit set selects exactly one of these hosts as
- the destination of the redirected message.
-
- When the Redirect-Host-Usage AVP included in the answer message has a
- non-zero value, a route entry for the redirect indications is created
- and cached by the receiver. The redirect usage for such a route
- entry is set by the value of Redirect-Host-Usage AVP and the lifetime
- of the cached route entry is set by Redirect-Max-Cache-Time AVP
- value.
-
- It is possible that multiple redirect indications can create multiple
- cached route entries differing only in their redirect usage and the
- peer to forward messages to. As an example, two(2) route entries
- that are created by two(2) redirect indications results in two(2)
-
-
-
-Fajardo, et al. Standards Track [Page 78]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- cached routes for the same realm and Application Id. However, one
- has a redirect usage of ALL_SESSION, where matching requests will be
- forwarded to one peer; the other has a redirect usage of ALL_REALM,
- where request are forwarded to another peer. Therefore, an incoming
- request that matches the realm and Application Id of both routes will
- need additional resolution. In such a case, a routing precedence
- rule MUST be used against the redirect usage value to resolve the
- contention. The precedence rule can be found in Section 6.13.
-
-6.1.9. Relaying and Proxying Requests
-
- A relay or proxy agent MUST append a Route-Record AVP to all requests
- forwarded. The AVP contains the identity of the peer from which the
- request was received.
-
- The Hop-by-Hop Identifier in the request is saved and replaced with a
- locally unique value. The source of the request is also saved, which
- includes the IP address, port, and protocol.
-
- A relay or proxy agent MAY include the Proxy-Info AVP in requests if
- it requires access to any local state information when the
- corresponding response is received. The Proxy-Info AVP has security
- implications as state information is distributed to other entities.
- As such, it is RECOMMENDED that the content of the Proxy-Info AVP be
- protected with cryptographic mechanisms, for example, by using a
- keyed message digest such as HMAC-SHA1 [RFC2104]. Such a mechanism,
- however, requires the management of keys, although only locally at
- the Diameter server. Still, a full description of the management of
- the keys used to protect the Proxy-Info AVP is beyond the scope of
- this document. Below is a list of common recommendations:
-
- o The keys should be generated securely following the randomness
- recommendations in [RFC4086].
-
- o The keys and cryptographic protection algorithms should be at
- least 128 bits in strength.
-
- o The keys should not be used for any other purpose than generating
- and verifying instances of the Proxy-Info AVP.
-
- o The keys should be changed regularly.
-
- o The keys should be changed if the AVP format or cryptographic
- protection algorithms change.
-
- The message is then forwarded to the next hop, as identified in the
- routing table.
-
-
-
-
-Fajardo, et al. Standards Track [Page 79]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Figure 6 provides an example of message routing using the procedures
- listed in these sections.
-
- (Origin-Host=nas.example.net) (Origin-Host=nas.example.net)
- (Origin-Realm=example.net) (Origin-Realm=example.net)
- (Destination-Realm=example.com) (Destination-Realm=example.com)
- (Route-Record=nas.example.net)
- +------+ ------> +------+ ------> +------+
- | | (Request) | | (Request) | |
- | NAS +-------------------+ DRL +-------------------+ HMS |
- | | | | | |
- +------+ &lt;------ +------+ &lt;------ +------+
- example.net (Answer) example.net (Answer) example.com
- (Origin-Host=hms.example.com) (Origin-Host=hms.example.com)
- (Origin-Realm=example.com) (Origin-Realm=example.com)
-
- Figure 6: Routing of Diameter messages
-
- Relay and proxy agents are not required to perform full inspection of
- incoming messages. At a minimum, validation of the message header
- and relevant routing AVPs has to be done when relaying messages.
- Proxy agents may optionally perform more in-depth message validation
- for applications in which it is interested.
-
-6.2. Diameter Answer Processing
-
- When a request is locally processed, the following procedures MUST be
- applied to create the associated answer, in addition to any
- additional procedures that MAY be discussed in the Diameter
- application defining the command:
-
- o The same Hop-by-Hop Identifier in the request is used in the
- answer.
-
- o The local host's identity is encoded in the Origin-Host AVP.
-
- o The Destination-Host and Destination-Realm AVPs MUST NOT be
- present in the answer message.
-
- o The Result-Code AVP is added with its value indicating success or
- failure.
-
- o If the Session-Id is present in the request, it MUST be included
- in the answer.
-
- o Any Proxy-Info AVPs in the request MUST be added to the answer
- message, in the same order they were present in the request.
-
-
-
-
-Fajardo, et al. Standards Track [Page 80]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o The 'P' bit is set to the same value as the one in the request.
-
- o The same End-to-End identifier in the request is used in the
- answer.
-
- Note that the error messages (see Section 7) are also subjected to
- the above processing rules.
-
-6.2.1. Processing Received Answers
-
- A Diameter client or proxy MUST match the Hop-by-Hop Identifier in an
- answer received against the list of pending requests. The
- corresponding message should be removed from the list of pending
- requests. It SHOULD ignore answers received that do not match a
- known Hop-by-Hop Identifier.
-
-6.2.2. Relaying and Proxying Answers
-
- If the answer is for a request that was proxied or relayed, the agent
- MUST restore the original value of the Diameter header's Hop-by-Hop
- Identifier field.
-
- If the last Proxy-Info AVP in the message is targeted to the local
- Diameter server, the AVP MUST be removed before the answer is
- forwarded.
-
- If a relay or proxy agent receives an answer with a Result-Code AVP
- indicating a failure, it MUST NOT modify the contents of the AVP.
- Any additional local errors detected SHOULD be logged but not
- reflected in the Result-Code AVP. If the agent receives an answer
- message with a Result-Code AVP indicating success, and it wishes to
- modify the AVP to indicate an error, it MUST modify the Result-Code
- AVP to contain the appropriate error in the message destined towards
- the access device as well as include the Error-Reporting-Host AVP; it
- MUST also issue an STR on behalf of the access device towards the
- Diameter server.
-
- The agent MUST then send the answer to the host that it received the
- original request from.
-
-6.3. Origin-Host AVP
-
- The Origin-Host AVP (AVP Code 264) is of type DiameterIdentity, and
- it MUST be present in all Diameter messages. This AVP identifies the
- endpoint that originated the Diameter message. Relay agents MUST NOT
- modify this AVP.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 81]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The value of the Origin-Host AVP is guaranteed to be unique within a
- single host.
-
- Note that the Origin-Host AVP may resolve to more than one address as
- the Diameter peer may support more than one address.
-
- This AVP SHOULD be placed as close to the Diameter header as
- possible.
-
-6.4. Origin-Realm AVP
-
- The Origin-Realm AVP (AVP Code 296) is of type DiameterIdentity.
- This AVP contains the Realm of the originator of any Diameter message
- and MUST be present in all messages.
-
- This AVP SHOULD be placed as close to the Diameter header as
- possible.
-
-6.5. Destination-Host AVP
-
- The Destination-Host AVP (AVP Code 293) is of type DiameterIdentity.
- This AVP MUST be present in all unsolicited agent initiated messages,
- MAY be present in request messages, and MUST NOT be present in answer
- messages.
-
- The absence of the Destination-Host AVP will cause a message to be
- sent to any Diameter server supporting the application within the
- realm specified in Destination-Realm AVP.
-
- This AVP SHOULD be placed as close to the Diameter header as
- possible.
-
-6.6. Destination-Realm AVP
-
- The Destination-Realm AVP (AVP Code 283) is of type DiameterIdentity
- and contains the realm to which the message is to be routed. The
- Destination-Realm AVP MUST NOT be present in answer messages.
- Diameter clients insert the realm portion of the User-Name AVP.
- Diameter servers initiating a request message use the value of the
- Origin-Realm AVP from a previous message received from the intended
- target host (unless it is known a priori). When present, the
- Destination-Realm AVP is used to perform message routing decisions.
-
- The CCF for a request message that includes the Destination-Realm AVP
- SHOULD list the Destination-Realm AVP as a required AVP (an AVP
- indicated as {AVP}); otherwise, the message is inherently a non-
- routable message.
-
-
-
-
-Fajardo, et al. Standards Track [Page 82]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- This AVP SHOULD be placed as close to the Diameter header as
- possible.
-
-6.7. Routing AVPs
-
- The AVPs defined in this section are Diameter AVPs used for routing
- purposes. These AVPs change as Diameter messages are processed by
- agents.
-
-6.7.1. Route-Record AVP
-
- The Route-Record AVP (AVP Code 282) is of type DiameterIdentity. The
- identity added in this AVP MUST be the same as the one received in
- the Origin-Host of the Capabilities Exchange message.
-
-6.7.2. Proxy-Info AVP
-
- The Proxy-Info AVP (AVP Code 284) is of type Grouped. This AVP
- contains the identity and local state information of the Diameter
- node that creates and adds it to a message. The Grouped Data field
- has the following CCF grammar:
-
- Proxy-Info ::= &lt; AVP Header: 284 >
- { Proxy-Host }
- { Proxy-State }
- * [ AVP ]
-
-6.7.3. Proxy-Host AVP
-
- The Proxy-Host AVP (AVP Code 280) is of type DiameterIdentity. This
- AVP contains the identity of the host that added the Proxy-Info AVP.
-
-6.7.4. Proxy-State AVP
-
- The Proxy-State AVP (AVP Code 33) is of type OctetString. It
- contains state information that would otherwise be stored at the
- Diameter entity that created it. As such, this AVP MUST be treated
- as opaque data by other Diameter entities.
-
-6.8. Auth-Application-Id AVP
-
- The Auth-Application-Id AVP (AVP Code 258) is of type Unsigned32 and
- is used in order to advertise support of the Authentication and
- Authorization portion of an application (see Section 2.4). If
- present in a message other than CER and CEA, the value of the Auth-
- Application-Id AVP MUST match the Application Id present in the
- Diameter message header.
-
-
-
-
-Fajardo, et al. Standards Track [Page 83]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-6.9. Acct-Application-Id AVP
-
- The Acct-Application-Id AVP (AVP Code 259) is of type Unsigned32 and
- is used in order to advertise support of the accounting portion of an
- application (see Section 2.4). If present in a message other than
- CER and CEA, the value of the Acct-Application-Id AVP MUST match the
- Application Id present in the Diameter message header.
-
-6.10. Inband-Security-Id AVP
-
- The Inband-Security-Id AVP (AVP Code 299) is of type Unsigned32 and
- is used in order to advertise support of the security portion of the
- application. The use of this AVP in CER and CEA messages is NOT
- RECOMMENDED. Instead, discovery of a Diameter entity's security
- capabilities can be done either through static configuration or via
- Diameter Peer Discovery as described in Section 5.2.
-
- The following values are supported:
-
-
- NO_INBAND_SECURITY 0
-
- This peer does not support TLS/TCP and DTLS/SCTP. This is the
- default value, if the AVP is omitted.
-
- TLS 1
-
- This node supports TLS/TCP [RFC5246] and DTLS/SCTP [RFC6083]
- security.
-
-6.11. Vendor-Specific-Application-Id AVP
-
- The Vendor-Specific-Application-Id AVP (AVP Code 260) is of type
- Grouped and is used to advertise support of a vendor-specific
- Diameter application. Exactly one instance of either Auth-
- Application-Id or Acct-Application-Id AVP MUST be present. The
- Application Id carried by either Auth-Application-Id or Acct-
- Application-Id AVP MUST comply with vendor-specific Application Id
- assignment described in Section 11.3. It MUST also match the
- Application Id present in the Diameter header except when used in a
- CER or CEA message.
-
- The Vendor-Id AVP is an informational AVP pertaining to the vendor
- who may have authorship of the vendor-specific Diameter application.
- It MUST NOT be used as a means of defining a completely separate
- vendor-specific Application Id space.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 84]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The Vendor-Specific-Application-Id AVP SHOULD be placed as close to
- the Diameter header as possible.
-
- AVP Format
-
- &lt;Vendor-Specific-Application-Id> ::= &lt; AVP Header: 260 >
- { Vendor-Id }
- [ Auth-Application-Id ]
- [ Acct-Application-Id ]
-
- A Vendor-Specific-Application-Id AVP MUST contain exactly one of
- either Auth-Application-Id or Acct-Application-Id. If a Vendor-
- Specific-Application-Id is received without one of these two AVPs,
- then the recipient SHOULD issue an answer with a Result-Code set to
- DIAMETER_MISSING_AVP. The answer SHOULD also include a Failed-AVP,
- which MUST contain an example of an Auth-Application-Id AVP and an
- Acct-Application-Id AVP.
-
- If a Vendor-Specific-Application-Id is received that contains both
- Auth-Application-Id and Acct-Application-Id, then the recipient MUST
- issue an answer with Result-Code set to
- DIAMETER_AVP_OCCURS_TOO_MANY_TIMES. The answer MUST also include a
- Failed-AVP, which MUST contain the received Auth-Application-Id AVP
- and Acct-Application-Id AVP.
-
-6.12. Redirect-Host AVP
-
- The Redirect-Host AVP (AVP Code 292) is of type DiameterURI. One or
- more instances of this AVP MUST be present if the answer message's
- 'E' bit is set and the Result-Code AVP is set to
- DIAMETER_REDIRECT_INDICATION.
-
- Upon receiving the above, the receiving Diameter node SHOULD forward
- the request directly to one of the hosts identified in these AVPs.
- The server contained in the selected Redirect-Host AVP SHOULD be used
- for all messages matching the criteria set by the Redirect-Host-Usage
- AVP.
-
-6.13. Redirect-Host-Usage AVP
-
- The Redirect-Host-Usage AVP (AVP Code 261) is of type Enumerated.
- This AVP MAY be present in answer messages whose 'E' bit is set and
- the Result-Code AVP is set to DIAMETER_REDIRECT_INDICATION.
-
- When present, this AVP provides hints about how the routing entry
- resulting from the Redirect-Host is to be used. The following values
- are supported:
-
-
-
-
-Fajardo, et al. Standards Track [Page 85]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- DONT_CACHE 0
-
- The host specified in the Redirect-Host AVP SHOULD NOT be cached.
- This is the default value.
-
- ALL_SESSION 1
-
- All messages within the same session, as defined by the same value
- of the Session-ID AVP SHOULD be sent to the host specified in the
- Redirect-Host AVP.
-
- ALL_REALM 2
-
- All messages destined for the realm requested SHOULD be sent to
- the host specified in the Redirect-Host AVP.
-
- REALM_AND_APPLICATION 3
-
- All messages for the application requested to the realm specified
- SHOULD be sent to the host specified in the Redirect-Host AVP.
-
- ALL_APPLICATION 4
-
- All messages for the application requested SHOULD be sent to the
- host specified in the Redirect-Host AVP.
-
- ALL_HOST 5
-
- All messages that would be sent to the host that generated the
- Redirect-Host SHOULD be sent to the host specified in the
- Redirect-Host AVP.
-
- ALL_USER 6
-
- All messages for the user requested SHOULD be sent to the host
- specified in the Redirect-Host AVP.
-
- When multiple cached routes are created by redirect indications and
- they differ only in redirect usage and peers to forward requests to
- (see Section 6.1.8), a precedence rule MUST be applied to the
- redirect usage values of the cached routes during normal routing to
- resolve contentions that may occur. The precedence rule is the order
- that dictate which redirect usage should be considered before any
- other as they appear. The order is as follows:
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 86]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- 1. ALL_SESSION
-
- 2. ALL_USER
-
- 3. REALM_AND_APPLICATION
-
- 4. ALL_REALM
-
- 5. ALL_APPLICATION
-
- 6. ALL_HOST
-
-6.14. Redirect-Max-Cache-Time AVP
-
- The Redirect-Max-Cache-Time AVP (AVP Code 262) is of type Unsigned32.
- This AVP MUST be present in answer messages whose 'E' bit is set,
- whose Result-Code AVP is set to DIAMETER_REDIRECT_INDICATION, and
- whose Redirect-Host-Usage AVP set to a non-zero value.
-
- This AVP contains the maximum number of seconds the peer and route
- table entries, created as a result of the Redirect-Host, SHOULD be
- cached. Note that once a host is no longer reachable, any associated
- cache, peer, and routing table entries MUST be deleted.
-
-7. Error Handling
-
- There are two different types of errors in Diameter; protocol errors
- and application errors. A protocol error is one that occurs at the
- base protocol level and MAY require per-hop attention (e.g., a
- message routing error). Application errors, on the other hand,
- generally occur due to a problem with a function specified in a
- Diameter application (e.g., user authentication, missing AVP).
-
- Result-Code AVP values that are used to report protocol errors MUST
- only be present in answer messages whose 'E' bit is set. When a
- request message is received that causes a protocol error, an answer
- message is returned with the 'E' bit set, and the Result-Code AVP is
- set to the appropriate protocol error value. As the answer is sent
- back towards the originator of the request, each proxy or relay agent
- MAY take action on the message.
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 87]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- 1. Request +---------+ Link Broken
- +-------------------------->|Diameter |----///----+
- | +---------------------| | v
- +------+--+ | 2. answer + 'E' set | Relay 2 | +--------+
- |Diameter |&lt;-+ (Unable to Forward) +---------+ |Diameter|
- | | | Home |
- | Relay 1 |--+ +---------+ | Server |
- +---------+ | 3. Request |Diameter | +--------+
- +-------------------->| | ^
- | Relay 3 |-----------+
- +---------+
-
- Figure 7: Example of Protocol Error Causing Answer Message
-
- Figure 7 provides an example of a message forwarded upstream by a
- Diameter relay. When the message is received by Relay 2, and it
- detects that it cannot forward the request to the home server, an
- answer message is returned with the 'E' bit set and the Result-Code
- AVP set to DIAMETER_UNABLE_TO_DELIVER. Given that this error falls
- within the protocol error category, Relay 1 would take special
- action, and given the error, attempt to route the message through its
- alternate Relay 3.
-
- +---------+ 1. Request +---------+ 2. Request +---------+
- | Access |------------>|Diameter |------------>|Diameter |
- | | | | | Home |
- | Device |&lt;------------| Relay |&lt;------------| Server |
- +---------+ 4. Answer +---------+ 3. Answer +---------+
- (Missing AVP) (Missing AVP)
-
- Figure 8: Example of Application Error Answer Message
-
- Figure 8 provides an example of a Diameter message that caused an
- application error. When application errors occur, the Diameter
- entity reporting the error clears the 'R' bit in the Command Flags
- and adds the Result-Code AVP with the proper value. Application
- errors do not require any proxy or relay agent involvement;
- therefore, the message would be forwarded back to the originator of
- the request.
-
- In the case where the answer message itself contains errors, any
- related session SHOULD be terminated by sending an STR or ASR
- message. The Termination-Cause AVP in the STR MAY be filled with the
- appropriate value to indicate the cause of the error. An application
- MAY also send an application-specific request instead of an STR or
- ASR message to signal the error in the case where no state is
- maintained or to allow for some form of error recovery with the
- corresponding Diameter entity.
-
-
-
-Fajardo, et al. Standards Track [Page 88]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- There are certain Result-Code AVP application errors that require
- additional AVPs to be present in the answer. In these cases, the
- Diameter node that sets the Result-Code AVP to indicate the error
- MUST add the AVPs. Examples are as follows:
-
- o A request with an unrecognized AVP is received with the 'M' bit
- (Mandatory bit) set causes an answer to be sent with the Result-
- Code AVP set to DIAMETER_AVP_UNSUPPORTED and the Failed-AVP AVP
- containing the offending AVP.
-
- o A request with an AVP that is received with an unrecognized value
- causes an answer to be returned with the Result-Code AVP set to
- DIAMETER_INVALID_AVP_VALUE, with the Failed-AVP AVP containing the
- AVP causing the error.
-
- o A received command that is missing AVPs that are defined as
- required in the commands CCF; examples are AVPs indicated as
- {AVP}. The receiver issues an answer with the Result-Code set to
- DIAMETER_MISSING_AVP and creates an AVP with the AVP Code and
- other fields set as expected in the missing AVP. The created AVP
- is then added to the Failed-AVP AVP.
-
- The Result-Code AVP describes the error that the Diameter node
- encountered in its processing. In case there are multiple errors,
- the Diameter node MUST report only the first error it encountered
- (detected possibly in some implementation-dependent order). The
- specific errors that can be described by this AVP are described in
- the following section.
-
-7.1. Result-Code AVP
-
- The Result-Code AVP (AVP Code 268) is of type Unsigned32 and
- indicates whether a particular request was completed successfully or
- an error occurred. All Diameter answer messages in IETF-defined
- Diameter application specifications MUST include one Result-Code AVP.
- A non-successful Result-Code AVP (one containing a non-2xxx value
- other than DIAMETER_REDIRECT_INDICATION) MUST include the Error-
- Reporting-Host AVP if the host setting the Result-Code AVP is
- different from the identity encoded in the Origin-Host AVP.
-
- The Result-Code data field contains an IANA-managed 32-bit address
- space representing errors (see Section 11.3.2). Diameter provides
- the following classes of errors, all identified by the thousands
- digit in the decimal notation:
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 89]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o 1xxx (Informational)
-
- o 2xxx (Success)
-
- o 3xxx (Protocol Errors)
-
- o 4xxx (Transient Failures)
-
- o 5xxx (Permanent Failure)
-
- An unrecognized class (one whose first digit is not defined in this
- section) MUST be handled as a permanent failure.
-
-7.1.1. Informational
-
- Errors that fall within this category are used to inform the
- requester that a request could not be satisfied, and additional
- action is required on its part before access is granted.
-
- DIAMETER_MULTI_ROUND_AUTH 1001
-
- This informational error is returned by a Diameter server to
- inform the access device that the authentication mechanism being
- used requires multiple round trips, and a subsequent request needs
- to be issued in order for access to be granted.
-
-7.1.2. Success
-
- Errors that fall within the Success category are used to inform a
- peer that a request has been successfully completed.
-
- DIAMETER_SUCCESS 2001
-
- The request was successfully completed.
-
- DIAMETER_LIMITED_SUCCESS 2002
-
- When returned, the request was successfully completed, but
- additional processing is required by the application in order to
- provide service to the user.
-
-7.1.3. Protocol Errors
-
- Errors that fall within the Protocol Error category SHOULD be treated
- on a per-hop basis, and Diameter proxies MAY attempt to correct the
- error, if it is possible. Note that these errors MUST only be used
- in answer messages whose 'E' bit is set.
-
-
-
-
-Fajardo, et al. Standards Track [Page 90]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- DIAMETER_COMMAND_UNSUPPORTED 3001
-
- This error code is used when a Diameter entity receives a message
- with a Command Code that it does not support.
-
- DIAMETER_UNABLE_TO_DELIVER 3002
-
- This error is given when Diameter cannot deliver the message to
- the destination, either because no host within the realm
- supporting the required application was available to process the
- request or because the Destination-Host AVP was given without the
- associated Destination-Realm AVP.
-
- DIAMETER_REALM_NOT_SERVED 3003
-
- The intended realm of the request is not recognized.
-
- DIAMETER_TOO_BUSY 3004
-
- When returned, a Diameter node SHOULD attempt to send the message
- to an alternate peer. This error MUST only be used when a
- specific server is requested, and it cannot provide the requested
- service.
-
- DIAMETER_LOOP_DETECTED 3005
-
- An agent detected a loop while trying to get the message to the
- intended recipient. The message MAY be sent to an alternate peer,
- if one is available, but the peer reporting the error has
- identified a configuration problem.
-
- DIAMETER_REDIRECT_INDICATION 3006
-
- A redirect agent has determined that the request could not be
- satisfied locally, and the initiator of the request SHOULD direct
- the request directly to the server, whose contact information has
- been added to the response. When set, the Redirect-Host AVP MUST
- be present.
-
- DIAMETER_APPLICATION_UNSUPPORTED 3007
-
- A request was sent for an application that is not supported.
-
- DIAMETER_INVALID_HDR_BITS 3008
-
- A request was received whose bits in the Diameter header were set
- either to an invalid combination or to a value that is
- inconsistent with the Command Code's definition.
-
-
-
-Fajardo, et al. Standards Track [Page 91]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- DIAMETER_INVALID_AVP_BITS 3009
-
- A request was received that included an AVP whose flag bits are
- set to an unrecognized value or that is inconsistent with the
- AVP's definition.
-
- DIAMETER_UNKNOWN_PEER 3010
-
- A CER was received from an unknown peer.
-
-7.1.4. Transient Failures
-
- Errors that fall within the transient failures category are used to
- inform a peer that the request could not be satisfied at the time it
- was received but MAY be able to satisfy the request in the future.
- Note that these errors MUST be used in answer messages whose 'E' bit
- is not set.
-
- DIAMETER_AUTHENTICATION_REJECTED 4001
-
- The authentication process for the user failed, most likely due to
- an invalid password used by the user. Further attempts MUST only
- be tried after prompting the user for a new password.
-
- DIAMETER_OUT_OF_SPACE 4002
-
- A Diameter node received the accounting request but was unable to
- commit it to stable storage due to a temporary lack of space.
-
- ELECTION_LOST 4003
-
- The peer has determined that it has lost the election process and
- has therefore disconnected the transport connection.
-
-7.1.5. Permanent Failures
-
- Errors that fall within the permanent failures category are used to
- inform the peer that the request failed and should not be attempted
- again. Note that these errors SHOULD be used in answer messages
- whose 'E' bit is not set. In error conditions where it is not
- possible or efficient to compose application-specific answer grammar,
- answer messages with the 'E' bit set and which comply to the grammar
- described in Section 7.2 MAY also be used for permanent errors.
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 92]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- DIAMETER_AVP_UNSUPPORTED 5001
-
- The peer received a message that contained an AVP that is not
- recognized or supported and was marked with the 'M' (Mandatory)
- bit. A Diameter message with this error MUST contain one or more
- Failed-AVP AVPs containing the AVPs that caused the failure.
-
- DIAMETER_UNKNOWN_SESSION_ID 5002
-
- The request contained an unknown Session-Id.
-
- DIAMETER_AUTHORIZATION_REJECTED 5003
-
- A request was received for which the user could not be authorized.
- This error could occur if the service requested is not permitted
- to the user.
-
- DIAMETER_INVALID_AVP_VALUE 5004
-
- The request contained an AVP with an invalid value in its data
- portion. A Diameter message indicating this error MUST include
- the offending AVPs within a Failed-AVP AVP.
-
- DIAMETER_MISSING_AVP 5005
-
- The request did not contain an AVP that is required by the Command
- Code definition. If this value is sent in the Result-Code AVP, a
- Failed-AVP AVP SHOULD be included in the message. The Failed-AVP
- AVP MUST contain an example of the missing AVP complete with the
- Vendor-Id if applicable. The value field of the missing AVP
- should be of correct minimum length and contain zeroes.
-
- DIAMETER_RESOURCES_EXCEEDED 5006
-
- A request was received that cannot be authorized because the user
- has already expended allowed resources. An example of this error
- condition is when a user that is restricted to one dial-up PPP
- port attempts to establish a second PPP connection.
-
- DIAMETER_CONTRADICTING_AVPS 5007
-
- The Home Diameter server has detected AVPs in the request that
- contradicted each other, and it is not willing to provide service
- to the user. The Failed-AVP AVP MUST be present, which contain
- the AVPs that contradicted each other.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 93]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- DIAMETER_AVP_NOT_ALLOWED 5008
-
- A message was received with an AVP that MUST NOT be present. The
- Failed-AVP AVP MUST be included and contain a copy of the
- offending AVP.
-
- DIAMETER_AVP_OCCURS_TOO_MANY_TIMES 5009
-
- A message was received that included an AVP that appeared more
- often than permitted in the message definition. The Failed-AVP
- AVP MUST be included and contain a copy of the first instance of
- the offending AVP that exceeded the maximum number of occurrences.
-
- DIAMETER_NO_COMMON_APPLICATION 5010
-
- This error is returned by a Diameter node that receives a CER
- whereby no applications are common between the CER sending peer
- and the CER receiving peer.
-
- DIAMETER_UNSUPPORTED_VERSION 5011
-
- This error is returned when a request was received, whose version
- number is unsupported.
-
- DIAMETER_UNABLE_TO_COMPLY 5012
-
- This error is returned when a request is rejected for unspecified
- reasons.
-
- DIAMETER_INVALID_BIT_IN_HEADER 5013
-
- This error is returned when a reserved bit in the Diameter header
- is set to one (1) or the bits in the Diameter header are set
- incorrectly.
-
- DIAMETER_INVALID_AVP_LENGTH 5014
-
- The request contained an AVP with an invalid length. A Diameter
- message indicating this error MUST include the offending AVPs
- within a Failed-AVP AVP. In cases where the erroneous AVP length
- value exceeds the message length or is less than the minimum AVP
- header length, it is sufficient to include the offending AVP
- header and a zero filled payload of the minimum required length
- for the payloads data type. If the AVP is a Grouped AVP, the
- Grouped AVP header with an empty payload would be sufficient to
- indicate the offending AVP. In the case where the offending AVP
- header cannot be fully decoded when the AVP length is less than
-
-
-
-
-Fajardo, et al. Standards Track [Page 94]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- the minimum AVP header length, it is sufficient to include an
- offending AVP header that is formulated by padding the incomplete
- AVP header with zero up to the minimum AVP header length.
-
- DIAMETER_INVALID_MESSAGE_LENGTH 5015
-
- This error is returned when a request is received with an invalid
- message length.
-
- DIAMETER_INVALID_AVP_BIT_COMBO 5016
-
- The request contained an AVP with which is not allowed to have the
- given value in the AVP Flags field. A Diameter message indicating
- this error MUST include the offending AVPs within a Failed-AVP
- AVP.
-
- DIAMETER_NO_COMMON_SECURITY 5017
-
- This error is returned when a CER message is received, and there
- are no common security mechanisms supported between the peers. A
- Capabilities-Exchange-Answer (CEA) message MUST be returned with
- the Result-Code AVP set to DIAMETER_NO_COMMON_SECURITY.
-
-7.2. Error Bit
-
- The 'E' (Error Bit) in the Diameter header is set when the request
- caused a protocol-related error (see Section 7.1.3). A message with
- the 'E' bit MUST NOT be sent as a response to an answer message.
- Note that a message with the 'E' bit set is still subjected to the
- processing rules defined in Section 6.2. When set, the answer
- message will not conform to the CCF specification for the command;
- instead, it and will conform to the following CCF:
-
- Message Format
-
- &lt;answer-message> ::= &lt; Diameter Header: code, ERR [, PXY] >
- 0*1&lt; Session-Id >
- { Origin-Host }
- { Origin-Realm }
- { Result-Code }
- [ Origin-State-Id ]
- [ Error-Message ]
- [ Error-Reporting-Host ]
- [ Failed-AVP ]
- [ Experimental-Result ]
- * [ Proxy-Info ]
- * [ AVP ]
-
-
-
-
-Fajardo, et al. Standards Track [Page 95]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Note that the code used in the header is the same than the one found
- in the request message, but with the 'R' bit cleared and the 'E' bit
- set. The 'P' bit in the header is set to the same value as the one
- found in the request message.
-
-7.3. Error-Message AVP
-
- The Error-Message AVP (AVP Code 281) is of type UTF8String. It MAY
- accompany a Result-Code AVP as a human-readable error message. The
- Error-Message AVP is not intended to be useful in an environment
- where error messages are processed automatically. It SHOULD NOT be
- expected that the content of this AVP be parsed by network entities.
-
-7.4. Error-Reporting-Host AVP
-
- The Error-Reporting-Host AVP (AVP Code 294) is of type
- DiameterIdentity. This AVP contains the identity of the Diameter
- host that sent the Result-Code AVP to a value other than 2001
- (Success), only if the host setting the Result-Code is different from
- the one encoded in the Origin-Host AVP. This AVP is intended to be
- used for troubleshooting purposes, and it MUST be set when the
- Result-Code AVP indicates a failure.
-
-7.5. Failed-AVP AVP
-
- The Failed-AVP AVP (AVP Code 279) is of type Grouped and provides
- debugging information in cases where a request is rejected or not
- fully processed due to erroneous information in a specific AVP. The
- value of the Result-Code AVP will provide information on the reason
- for the Failed-AVP AVP. A Diameter answer message SHOULD contain an
- instance of the Failed-AVP AVP that corresponds to the error
- indicated by the Result-Code AVP. For practical purposes, this
- Failed-AVP would typically refer to the first AVP processing error
- that a Diameter node encounters.
-
- The possible reasons for this AVP are the presence of an improperly
- constructed AVP, an unsupported or unrecognized AVP, an invalid AVP
- value, the omission of a required AVP, the presence of an explicitly
- excluded AVP (see tables in Section 10) or the presence of two or
- more occurrences of an AVP that is restricted to 0, 1, or 0-1
- occurrences.
-
- A Diameter message SHOULD contain one Failed-AVP AVP, containing the
- entire AVP that could not be processed successfully. If the failure
- reason is omission of a required AVP, an AVP with the missing AVP
- code, the missing Vendor-Id, and a zero-filled payload of the minimum
- required length for the omitted AVP will be added. If the failure
- reason is an invalid AVP length where the reported length is less
-
-
-
-Fajardo, et al. Standards Track [Page 96]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- than the minimum AVP header length or greater than the reported
- message length, a copy of the offending AVP header and a zero-filled
- payload of the minimum required length SHOULD be added.
-
- In the case where the offending AVP is embedded within a Grouped AVP,
- the Failed-AVP MAY contain the grouped AVP, which in turn contains
- the single offending AVP. The same method MAY be employed if the
- grouped AVP itself is embedded in yet another grouped AVP and so on.
- In this case, the Failed-AVP MAY contain the grouped AVP hierarchy up
- to the single offending AVP. This enables the recipient to detect
- the location of the offending AVP when embedded in a group.
-
- AVP Format
-
- &lt;Failed-AVP> ::= &lt; AVP Header: 279 >
- 1* {AVP}
-
-7.6. Experimental-Result AVP
-
- The Experimental-Result AVP (AVP Code 297) is of type Grouped, and
- indicates whether a particular vendor-specific request was completed
- successfully or whether an error occurred. This AVP has the
- following structure:
-
- AVP Format
-
- Experimental-Result ::= &lt; AVP Header: 297 >
- { Vendor-Id }
- { Experimental-Result-Code }
-
- The Vendor-Id AVP (see Section 5.3.3) in this grouped AVP identifies
- the vendor responsible for the assignment of the result code that
- follows. All Diameter answer messages defined in vendor-specific
- applications MUST include either one Result-Code AVP or one
- Experimental-Result AVP.
-
-7.7. Experimental-Result-Code AVP
-
- The Experimental-Result-Code AVP (AVP Code 298) is of type Unsigned32
- and contains a vendor-assigned value representing the result of
- processing the request.
-
- It is recommended that vendor-specific result codes follow the same
- conventions given for the Result-Code AVP regarding the different
- types of result codes and the handling of errors (for non-2xxx
- values).
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 97]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-8. Diameter User Sessions
-
- In general, Diameter can provide two different types of services to
- applications. The first involves authentication and authorization,
- and it can optionally make use of accounting. The second only makes
- use of accounting.
-
- When a service makes use of the authentication and/or authorization
- portion of an application, and a user requests access to the network,
- the Diameter client issues an auth request to its local server. The
- auth request is defined in a service-specific Diameter application
- (e.g., NASREQ). The request contains a Session-Id AVP, which is used
- in subsequent messages (e.g., subsequent authorization, accounting,
- etc.) relating to the user's session. The Session-Id AVP is a means
- for the client and servers to correlate a Diameter message with a
- user session.
-
- When a Diameter server authorizes a user to implement network
- resources for a finite amount of time, and it is willing to extend
- the authorization via a future request, it MUST add the
- Authorization- Lifetime AVP to the answer message. The
- Authorization-Lifetime AVP defines the maximum number of seconds a
- user MAY make use of the resources before another authorization
- request is expected by the server. The Auth-Grace-Period AVP
- contains the number of seconds following the expiration of the
- Authorization-Lifetime, after which the server will release all state
- information related to the user's session. Note that if payment for
- services is expected by the serving realm from the user's home realm,
- the Authorization-Lifetime AVP, combined with the Auth-Grace-Period
- AVP, implies the maximum length of the session for which the home
- realm is willing to be fiscally responsible. Services provided past
- the expiration of the Authorization-Lifetime and Auth-Grace-Period
- AVPs are the responsibility of the access device. Of course, the
- actual cost of services rendered is clearly outside the scope of the
- protocol.
-
- An access device that does not expect to send a re-authorization or a
- session termination request to the server MAY include the Auth-
- Session-State AVP with the value set to NO_STATE_MAINTAINED as a hint
- to the server. If the server accepts the hint, it agrees that since
- no session termination message will be received once service to the
- user is terminated, it cannot maintain state for the session. If the
- answer message from the server contains a different value in the
- Auth-Session-State AVP (or the default value if the AVP is absent),
- the access device MUST follow the server's directives. Note that the
- value NO_STATE_MAINTAINED MUST NOT be set in subsequent re-
- authorization requests and answers.
-
-
-
-
-Fajardo, et al. Standards Track [Page 98]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The base protocol does not include any authorization request
- messages, since these are largely application-specific and are
- defined in a Diameter application document. However, the base
- protocol does define a set of messages that are used to terminate
- user sessions. These are used to allow servers that maintain state
- information to free resources.
-
- When a service only makes use of the accounting portion of the
- Diameter protocol, even in combination with an application, the
- Session-Id is still used to identify user sessions. However, the
- session termination messages are not used, since a session is
- signaled as being terminated by issuing an accounting stop message.
-
- Diameter may also be used for services that cannot be easily
- categorized as authentication, authorization, or accounting (e.g.,
- certain Third Generation Partnership Project Internet Multimedia
- System (3GPP IMS) interfaces). In such cases, the finite state
- machine defined in subsequent sections may not be applicable.
- Therefore, the application itself MAY need to define its own finite
- state machine. However, such application-specific state machines
- SHOULD follow the general state machine framework outlined in this
- document such as the use of Session-Id AVPs and the use of STR/STA,
- ASR/ASA messages for stateful sessions.
-
-8.1. Authorization Session State Machine
-
- This section contains a set of finite state machines, which represent
- the life cycle of Diameter sessions and which MUST be observed by all
- Diameter implementations that make use of the authentication and/or
- authorization portion of a Diameter application. The term "Service-
- Specific" below refers to a message defined in a Diameter application
- (e.g., Mobile IPv4, NASREQ).
-
- There are four different authorization session state machines
- supported in the Diameter base protocol. The first two describe a
- session in which the server is maintaining session state, indicated
- by the value of the Auth-Session-State AVP (or its absence). One
- describes the session from a client perspective, the other from a
- server perspective. The second two state machines are used when the
- server does not maintain session state. Here again, one describes
- the session from a client perspective, the other from a server
- perspective.
-
- When a session is moved to the Idle state, any resources that were
- allocated for the particular session must be released. Any event not
- listed in the state machines MUST be considered an error condition,
- and an answer, if applicable, MUST be returned to the originator of
- the message.
-
-
-
-Fajardo, et al. Standards Track [Page 99]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- In the case that an application does not support re-auth, the state
- transitions related to server-initiated re-auth, when both client and
- server sessions maintain state (e.g., Send RAR, Pending, Receive
- RAA), MAY be ignored.
-
- In the state table, the event "Failure to send X" means that the
- Diameter agent is unable to send command X to the desired
- destination. This could be due to the peer being down or due to the
- peer sending back a transient failure or temporary protocol error
- notification DIAMETER_TOO_BUSY or DIAMETER_LOOP_DETECTED in the
- Result-Code AVP of the corresponding Answer command. The event 'X
- successfully sent' is the complement of 'Failure to send X'.
-
- The following state machine is observed by a client when state is
- maintained on the server:
-
- CLIENT, STATEFUL
- State Event Action New State
- ---------------------------------------------------------------
- Idle Client or device requests Send Pending
- access service-
- specific
- auth req
-
- Idle ASR Received Send ASA Idle
- for unknown session with
- Result-Code =
- UNKNOWN_
- SESSION_ID
-
- Idle RAR Received Send RAA Idle
- for unknown session with
- Result-Code =
- UNKNOWN_
- SESSION_ID
-
- Pending Successful service-specific Grant Open
- authorization answer Access
- received with default
- Auth-Session-State value
-
- Pending Successful service-specific Sent STR Discon
- authorization answer received,
- but service not provided
-
- Pending Error processing successful Sent STR Discon
- service-specific authorization
- answer
-
-
-
-Fajardo, et al. Standards Track [Page 100]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Pending Failed service-specific Clean up Idle
- authorization answer received
-
- Open User or client device Send Open
- requests access to service service-
- specific
- auth req
-
- Open Successful service-specific Provide Open
- authorization answer received service
-
- Open Failed service-specific Discon. Idle
- authorization answer user/device
- received.
-
- Open RAR received and client will Send RAA Open
- perform subsequent re-auth with
- Result-Code =
- SUCCESS
-
- Open RAR received and client will Send RAA Idle
- not perform subsequent with
- re-auth Result-Code !=
- SUCCESS,
- Discon.
- user/device
-
- Open Session-Timeout expires on Send STR Discon
- access device
-
- Open ASR received, Send ASA Discon
- client will comply with
- with request to end the Result-Code =
- session = SUCCESS,
- Send STR.
-
- Open ASR Received, Send ASA Open
- client will not comply with
- with request to end the Result-Code !=
- session != SUCCESS
-
- Open Authorization-Lifetime + Send STR Discon
- Auth-Grace-Period expires on
- access device
-
- Discon ASR received Send ASA Discon
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 101]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Discon STA received Discon. Idle
- user/device
-
- The following state machine is observed by a server when it is
- maintaining state for the session:
-
- SERVER, STATEFUL
- State Event Action New State
- ---------------------------------------------------------------
- Idle Service-specific authorization Send Open
- request received, and successful
- user is authorized service-
- specific
- answer
-
- Idle Service-specific authorization Send Idle
- request received, and failed
- user is not authorized service-
- specific
- answer
-
- Open Service-specific authorization Send Open
- request received, and user successful
- is authorized service-
- specific
- answer
-
- Open Service-specific authorization Send Idle
- request received, and user failed
- is not authorized service-
- specific
- answer,
- Clean up
-
- Open Home server wants to confirm Send RAR Pending
- authentication and/or
- authorization of the user
-
- Pending Received RAA with a failed Clean up Idle
- Result-Code
-
- Pending Received RAA with Result-Code Update Open
- = SUCCESS session
-
- Open Home server wants to Send ASR Discon
- terminate the service
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 102]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Open Authorization-Lifetime (and Clean up Idle
- Auth-Grace-Period) expires
- on home server
-
- Open Session-Timeout expires on Clean up Idle
- home server
-
- Discon Failure to send ASR Wait, Discon
- resend ASR
-
- Discon ASR successfully sent and Clean up Idle
- ASA Received with Result-Code
-
- Not ASA Received None No Change
- Discon
-
- Any STR Received Send STA, Idle
- Clean up
-
- The following state machine is observed by a client when state is not
- maintained on the server:
-
- CLIENT, STATELESS
- State Event Action New State
- ---------------------------------------------------------------
- Idle Client or device requests Send Pending
- access service-
- specific
- auth req
-
- Pending Successful service-specific Grant Open
- authorization answer access
- received with Auth-Session-
- State set to
- NO_STATE_MAINTAINED
-
- Pending Failed service-specific Clean up Idle
- authorization answer
- received
-
- Open Session-Timeout expires on Discon. Idle
- access device user/device
-
- Open Service to user is terminated Discon. Idle
- user/device
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 103]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The following state machine is observed by a server when it is not
- maintaining state for the session:
-
- SERVER, STATELESS
- State Event Action New State
- ---------------------------------------------------------------
- Idle Service-specific authorization Send Idle
- request received, and service-
- successfully processed specific
- answer
-
-8.2. Accounting Session State Machine
-
- The following state machines MUST be supported for applications that
- have an accounting portion or that require only accounting services.
- The first state machine is to be observed by clients.
-
- See Section 9.7 for Accounting Command Codes and Section 9.8 for
- Accounting AVPs.
-
- The server side in the accounting state machine depends in some cases
- on the particular application. The Diameter base protocol defines a
- default state machine that MUST be followed by all applications that
- have not specified other state machines. This is the second state
- machine in this section described below.
-
- The default server side state machine requires the reception of
- accounting records in any order and at any time, and it does not
- place any standards requirement on the processing of these records.
- Implementations of Diameter may perform checking, ordering,
- correlation, fraud detection, and other tasks based on these records.
- AVPs may need to be inspected as a part of these tasks. The tasks
- can happen either immediately after record reception or in a post-
- processing phase. However, as these tasks are typically application
- or even policy dependent, they are not standardized by the Diameter
- specifications. Applications MAY define requirements on when to
- accept accounting records based on the used value of Accounting-
- Realtime-Required AVP, credit-limit checks, and so on.
-
- However, the Diameter base protocol defines one optional server side
- state machine that MAY be followed by applications that require
- keeping track of the session state at the accounting server. Note
- that such tracking is incompatible with the ability to sustain long
- duration connectivity problems. Therefore, the use of this state
- machine is recommended only in applications where the value of the
- Accounting-Realtime-Required AVP is DELIVER_AND_GRANT; hence,
- accounting connectivity problems are required to cause the serviced
- user to be disconnected. Otherwise, records produced by the client
-
-
-
-Fajardo, et al. Standards Track [Page 104]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- may be lost by the server, which no longer accepts them after the
- connectivity is re-established. This state machine is the third
- state machine in this section. The state machine is supervised by a
- supervision session timer Ts, whose value should be reasonably higher
- than the Acct_Interim_Interval value. Ts MAY be set to two times the
- value of the Acct_Interim_Interval so as to avoid the accounting
- session in the Diameter server to change to Idle state in case of
- short transient network failure.
-
- Any event not listed in the state machines MUST be considered as an
- error condition, and a corresponding answer, if applicable, MUST be
- returned to the originator of the message.
-
- In the state table, the event "Failure to send" means that the
- Diameter client is unable to communicate with the desired
- destination. This could be due to the peer being down, or due to the
- peer sending back a transient failure or temporary protocol error
- notification DIAMETER_OUT_OF_SPACE, DIAMETER_TOO_BUSY, or
- DIAMETER_LOOP_DETECTED in the Result-Code AVP of the Accounting
- Answer command.
-
- The event "Failed answer" means that the Diameter client received a
- non-transient failure notification in the Accounting Answer command.
-
- Note that the action "Disconnect user/dev" MUST also have an effect
- on the authorization session state table, e.g., cause the STR message
- to be sent, if the given application has both authentication/
- authorization and accounting portions.
-
- The states PendingS, PendingI, PendingL, PendingE, and PendingB stand
- for pending states to wait for an answer to an accounting request
- related to a Start, Interim, Stop, Event, or buffered record,
- respectively.
-
- CLIENT, ACCOUNTING
- State Event Action New State
- ---------------------------------------------------------------
- Idle Client or device requests Send PendingS
- access accounting
- start req.
-
- Idle Client or device requests Send PendingE
- a one-time service accounting
- event req
-
- Idle Records in storage Send PendingB
- record
-
-
-
-
-Fajardo, et al. Standards Track [Page 105]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- PendingS Successful accounting Open
- start answer received
-
- PendingS Failure to send and buffer Store Open
- space available and real time Start
- not equal to DELIVER_AND_GRANT Record
-
- PendingS Failure to send and no buffer Open
- space available and real time
- equal to GRANT_AND_LOSE
-
- PendingS Failure to send and no Disconnect Idle
- buffer space available and user/dev
- real time not equal to
- GRANT_AND_LOSE
-
- PendingS Failed accounting start answer Open
- received and real time equal
- to GRANT_AND_LOSE
-
- PendingS Failed accounting start answer Disconnect Idle
- received and real time not user/dev
- equal to GRANT_AND_LOSE
-
- PendingS User service terminated Store PendingS
- stop
- record
-
- Open Interim interval elapses Send PendingI
- accounting
- interim
- record
-
- Open User service terminated Send PendingL
- accounting
- stop req.
-
- PendingI Successful accounting interim Open
- answer received
-
- PendingI Failure to send and (buffer Store Open
- space available or old interim
- record can be overwritten) record
- and real time not equal to
- DELIVER_AND_GRANT
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 106]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- PendingI Failure to send and no buffer Open
- space available and real time
- equal to GRANT_AND_LOSE
-
- PendingI Failure to send and no Disconnect Idle
- buffer space available and user/dev
- real time not equal to
- GRANT_AND_LOSE
-
- PendingI Failed accounting interim Open
- answer received and real time
- equal to GRANT_AND_LOSE
-
- PendingI Failed accounting interim Disconnect Idle
- answer received and user/dev
- real time not equal to
- GRANT_AND_LOSE
-
- PendingI User service terminated Store PendingI
- stop
- record
- PendingE Successful accounting Idle
- event answer received
-
- PendingE Failure to send and buffer Store Idle
- space available event
- record
-
- PendingE Failure to send and no buffer Idle
- space available
-
- PendingE Failed accounting event answer Idle
- received
-
- PendingB Successful accounting answer Delete Idle
- received record
-
- PendingB Failure to send Idle
-
- PendingB Failed accounting answer Delete Idle
- received record
-
- PendingL Successful accounting Idle
- stop answer received
-
- PendingL Failure to send and buffer Store Idle
- space available stop
- record
-
-
-
-Fajardo, et al. Standards Track [Page 107]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- PendingL Failure to send and no buffer Idle
- space available
-
- PendingL Failed accounting stop answer Idle
- received
-
-
- SERVER, STATELESS ACCOUNTING
- State Event Action New State
- ---------------------------------------------------------------
-
- Idle Accounting start request Send Idle
- received and successfully accounting
- processed. start
- answer
-
- Idle Accounting event request Send Idle
- received and successfully accounting
- processed. event
- answer
-
- Idle Interim record received Send Idle
- and successfully processed. accounting
- interim
- answer
-
- Idle Accounting stop request Send Idle
- received and successfully accounting
- processed stop answer
-
- Idle Accounting request received; Send Idle
- no space left to store accounting
- records answer;
- Result-Code =
- OUT_OF_
- SPACE
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 108]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- SERVER, STATEFUL ACCOUNTING
- State Event Action New State
- ---------------------------------------------------------------
-
- Idle Accounting start request Send Open
- received and successfully accounting
- processed. start
- answer;
- Start Ts
-
- Idle Accounting event request Send Idle
- received and successfully accounting
- processed. event
- answer
- Idle Accounting request received; Send Idle
- no space left to store accounting
- records answer;
- Result-Code =
- OUT_OF_
- SPACE
-
- Open Interim record received Send Open
- and successfully processed. accounting
- interim
- answer;
- Restart Ts
-
- Open Accounting stop request Send Idle
- received and successfully accounting
- processed stop answer;
- Stop Ts
-
- Open Accounting request received; Send Idle
- no space left to store accounting
- records answer;
- Result-Code =
- OUT_OF_
- SPACE;
- Stop Ts
-
- Open Session supervision timer Ts Stop Ts Idle
- expired
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 109]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-8.3. Server-Initiated Re-Auth
-
- A Diameter server may initiate a re-authentication and/or re-
- authorization service for a particular session by issuing a Re-Auth-
- Request (RAR).
-
- For example, for prepaid services, the Diameter server that
- originally authorized a session may need some confirmation that the
- user is still using the services.
-
- An access device that receives an RAR message with the Session-Id
- equal to a currently active session MUST initiate a re-auth towards
- the user, if the service supports this particular feature. Each
- Diameter application MUST state whether server-initiated re-auth is
- supported, since some applications do not allow access devices to
- prompt the user for re-auth.
-
-8.3.1. Re-Auth-Request
-
- The Re-Auth-Request (RAR), indicated by the Command Code set to 258
- and the message flags' 'R' bit set, may be sent by any server to the
- access device that is providing session service, to request that the
- user be re-authenticated and/or re-authorized.
-
-
- Message Format
-
- &lt;RAR> ::= &lt; Diameter Header: 258, REQ, PXY >
- &lt; Session-Id >
- { Origin-Host }
- { Origin-Realm }
- { Destination-Realm }
- { Destination-Host }
- { Auth-Application-Id }
- { Re-Auth-Request-Type }
- [ User-Name ]
- [ Origin-State-Id ]
- * [ Proxy-Info ]
- * [ Route-Record ]
- * [ AVP ]
-
-8.3.2. Re-Auth-Answer
-
- The Re-Auth-Answer (RAA), indicated by the Command Code set to 258
- and the message flags' 'R' bit clear, is sent in response to the RAR.
- The Result-Code AVP MUST be present, and it indicates the disposition
- of the request.
-
-
-
-
-Fajardo, et al. Standards Track [Page 110]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- A successful RAA message MUST be followed by an application-specific
- authentication and/or authorization message.
-
- Message Format
-
- &lt;RAA> ::= &lt; Diameter Header: 258, PXY >
- &lt; Session-Id >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- [ User-Name ]
- [ Origin-State-Id ]
- [ Error-Message ]
- [ Error-Reporting-Host ]
- [ Failed-AVP ]
- * [ Redirect-Host ]
- [ Redirect-Host-Usage ]
- [ Redirect-Max-Cache-Time ]
- * [ Proxy-Info ]
- * [ AVP ]
-
-8.4. Session Termination
-
- It is necessary for a Diameter server that authorized a session, for
- which it is maintaining state, to be notified when that session is no
- longer active, both for tracking purposes as well as to allow
- stateful agents to release any resources that they may have provided
- for the user's session. For sessions whose state is not being
- maintained, this section is not used.
-
- When a user session that required Diameter authorization terminates,
- the access device that provided the service MUST issue a Session-
- Termination-Request (STR) message to the Diameter server that
- authorized the service, to notify it that the session is no longer
- active. An STR MUST be issued when a user session terminates for any
- reason, including user logoff, expiration of Session-Timeout,
- administrative action, termination upon receipt of an Abort-Session-
- Request (see below), orderly shutdown of the access device, etc.
-
- The access device also MUST issue an STR for a session that was
- authorized but never actually started. This could occur, for
- example, due to a sudden resource shortage in the access device, or
- because the access device is unwilling to provide the type of service
- requested in the authorization, or because the access device does not
- support a mandatory AVP returned in the authorization, etc.
-
- It is also possible that a session that was authorized is never
- actually started due to action of a proxy. For example, a proxy may
-
-
-
-Fajardo, et al. Standards Track [Page 111]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- modify an authorization answer, converting the result from success to
- failure, prior to forwarding the message to the access device. If
- the answer did not contain an Auth-Session-State AVP with the value
- NO_STATE_MAINTAINED, a proxy that causes an authorized session not to
- be started MUST issue an STR to the Diameter server that authorized
- the session, since the access device has no way of knowing that the
- session had been authorized.
-
- A Diameter server that receives an STR message MUST clean up
- resources (e.g., session state) associated with the Session-Id
- specified in the STR and return a Session-Termination-Answer.
-
- A Diameter server also MUST clean up resources when the Session-
- Timeout expires, or when the Authorization-Lifetime and the Auth-
- Grace-Period AVPs expire without receipt of a re-authorization
- request, regardless of whether an STR for that session is received.
- The access device is not expected to provide service beyond the
- expiration of these timers; thus, expiration of either of these
- timers implies that the access device may have unexpectedly shut
- down.
-
-8.4.1. Session-Termination-Request
-
- The Session-Termination-Request (STR), indicated by the Command Code
- set to 275 and the Command Flags' 'R' bit set, is sent by a Diameter
- client or by a Diameter proxy to inform the Diameter server that an
- authenticated and/or authorized session is being terminated.
-
- Message Format
-
- &lt;STR> ::= &lt; Diameter Header: 275, REQ, PXY >
- &lt; Session-Id >
- { Origin-Host }
- { Origin-Realm }
- { Destination-Realm }
- { Auth-Application-Id }
- { Termination-Cause }
- [ User-Name ]
- [ Destination-Host ]
- * [ Class ]
- [ Origin-State-Id ]
- * [ Proxy-Info ]
- * [ Route-Record ]
- * [ AVP ]
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 112]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-8.4.2. Session-Termination-Answer
-
- The Session-Termination-Answer (STA), indicated by the Command Code
- set to 275 and the message flags' 'R' bit clear, is sent by the
- Diameter server to acknowledge the notification that the session has
- been terminated. The Result-Code AVP MUST be present, and it MAY
- contain an indication that an error occurred while servicing the STR.
-
- Upon sending or receipt of the STA, the Diameter server MUST release
- all resources for the session indicated by the Session-Id AVP. Any
- intermediate server in the Proxy-Chain MAY also release any
- resources, if necessary.
-
- Message Format
-
- &lt;STA> ::= &lt; Diameter Header: 275, PXY >
- &lt; Session-Id >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- [ User-Name ]
- * [ Class ]
- [ Error-Message ]
- [ Error-Reporting-Host ]
- [ Failed-AVP ]
- [ Origin-State-Id ]
- * [ Redirect-Host ]
- [ Redirect-Host-Usage ]
- [ Redirect-Max-Cache-Time ]
- * [ Proxy-Info ]
- * [ AVP ]
-
-8.5. Aborting a Session
-
- A Diameter server may request that the access device stop providing
- service for a particular session by issuing an Abort-Session-Request
- (ASR).
-
- For example, the Diameter server that originally authorized the
- session may be required to cause that session to be stopped for lack
- of credit or other reasons that were not anticipated when the session
- was first authorized.
-
- An access device that receives an ASR with Session-ID equal to a
- currently active session MAY stop the session. Whether the access
- device stops the session or not is implementation and/or
- configuration dependent. For example, an access device may honor
- ASRs from certain agents only. In any case, the access device MUST
-
-
-
-Fajardo, et al. Standards Track [Page 113]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- respond with an Abort-Session-Answer, including a Result-Code AVP to
- indicate what action it took.
-
-8.5.1. Abort-Session-Request
-
- The Abort-Session-Request (ASR), indicated by the Command Code set to
- 274 and the message flags' 'R' bit set, may be sent by any Diameter
- server or any Diameter proxy to the access device that is providing
- session service, to request that the session identified by the
- Session-Id be stopped.
-
- Message Format
-
- &lt;ASR> ::= &lt; Diameter Header: 274, REQ, PXY >
- &lt; Session-Id >
- { Origin-Host }
- { Origin-Realm }
- { Destination-Realm }
- { Destination-Host }
- { Auth-Application-Id }
- [ User-Name ]
- [ Origin-State-Id ]
- * [ Proxy-Info ]
- * [ Route-Record ]
- * [ AVP ]
-
-8.5.2. Abort-Session-Answer
-
- The Abort-Session-Answer (ASA), indicated by the Command Code set to
- 274 and the message flags' 'R' bit clear, is sent in response to the
- ASR. The Result-Code AVP MUST be present and indicates the
- disposition of the request.
-
- If the session identified by Session-Id in the ASR was successfully
- terminated, the Result-Code is set to DIAMETER_SUCCESS. If the
- session is not currently active, the Result-Code is set to
- DIAMETER_UNKNOWN_SESSION_ID. If the access device does not stop the
- session for any other reason, the Result-Code is set to
- DIAMETER_UNABLE_TO_COMPLY.
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 114]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Message Format
-
- &lt;ASA> ::= &lt; Diameter Header: 274, PXY >
- &lt; Session-Id >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- [ User-Name ]
- [ Origin-State-Id ]
- [ Error-Message ]
- [ Error-Reporting-Host ]
- [ Failed-AVP ]
- * [ Redirect-Host ]
- [ Redirect-Host-Usage ]
- [ Redirect-Max-Cache-Time ]
- * [ Proxy-Info ]
- * [ AVP ]
-
-8.6. Inferring Session Termination from Origin-State-Id
-
- The Origin-State-Id is used to allow detection of terminated sessions
- for which no STR would have been issued, due to unanticipated
- shutdown of an access device.
-
- A Diameter client or access device increments the value of the
- Origin-State-Id every time it is started or powered up. The new
- Origin-State-Id is then sent in the CER/CEA message immediately upon
- connection to the server. The Diameter server receiving the new
- Origin-State-Id can determine whether the sending Diameter client had
- abruptly shut down by comparing the old value of the Origin-State-Id
- it has kept for that specific client is less than the new value and
- whether it has un-terminated sessions originating from that client.
-
- An access device can also include the Origin-State-Id in request
- messages other than the CER if there are relays or proxies in between
- the access device and the server. In this case, however, the server
- cannot discover that the access device has been restarted unless and
- until it receives a new request from it. Therefore, this mechanism
- is more opportunistic across proxies and relays.
-
- The Diameter server may assume that all sessions that were active
- prior to detection of a client restart have been terminated. The
- Diameter server MAY clean up all session state associated with such
- lost sessions, and it MAY also issue STRs for all such lost sessions
- that were authorized on upstream servers, to allow session state to
- be cleaned up globally.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 115]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-8.7. Auth-Request-Type AVP
-
- The Auth-Request-Type AVP (AVP Code 274) is of type Enumerated and is
- included in application-specific auth requests to inform the peers
- whether a user is to be authenticated only, authorized only, or both.
- Note any value other than both MAY cause RADIUS interoperability
- issues. The following values are defined:
-
- AUTHENTICATE_ONLY 1
-
- The request being sent is for authentication only, and it MUST
- contain the relevant application-specific authentication AVPs that
- are needed by the Diameter server to authenticate the user.
-
- AUTHORIZE_ONLY 2
-
- The request being sent is for authorization only, and it MUST
- contain the application-specific authorization AVPs that are
- necessary to identify the service being requested/offered.
-
- AUTHORIZE_AUTHENTICATE 3
-
- The request contains a request for both authentication and
- authorization. The request MUST include both the relevant
- application-specific authentication information and authorization
- information necessary to identify the service being requested/
- offered.
-
-8.8. Session-Id AVP
-
- The Session-Id AVP (AVP Code 263) is of type UTF8String and is used
- to identify a specific session (see Section 8). All messages
- pertaining to a specific session MUST include only one Session-Id
- AVP, and the same value MUST be used throughout the life of a
- session. When present, the Session-Id SHOULD appear immediately
- following the Diameter header (see Section 3).
-
- The Session-Id MUST be globally and eternally unique, as it is meant
- to uniquely identify a user session without reference to any other
- information, and it may be needed to correlate historical
- authentication information with accounting information. The
- Session-Id includes a mandatory portion and an implementation-defined
- portion; a recommended format for the implementation-defined portion
- is outlined below.
-
- The Session-Id MUST begin with the sender's identity encoded in the
- DiameterIdentity type (see Section 4.3.1). The remainder of the
- Session-Id is delimited by a ";" character, and it MAY be any
-
-
-
-Fajardo, et al. Standards Track [Page 116]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- sequence that the client can guarantee to be eternally unique;
- however, the following format is recommended, (square brackets []
- indicate an optional element):
-
- &lt;DiameterIdentity>;&lt;high 32 bits>;&lt;low 32 bits>[;&lt;optional value>]
-
- &lt;high 32 bits> and &lt;low 32 bits> are decimal representations of the
- high and low 32 bits of a monotonically increasing 64-bit value. The
- 64-bit value is rendered in two part to simplify formatting by 32-bit
- processors. At startup, the high 32 bits of the 64-bit value MAY be
- initialized to the time in NTP format [RFC5905], and the low 32 bits
- MAY be initialized to zero. This will for practical purposes
- eliminate the possibility of overlapping Session-Ids after a reboot,
- assuming the reboot process takes longer than a second.
- Alternatively, an implementation MAY keep track of the increasing
- value in non-volatile memory.
-
-
- &lt;optional value> is implementation specific, but it may include a
- modem's device Id, a Layer 2 address, timestamp, etc.
-
- Example, in which there is no optional value:
-
- accesspoint7.example.com;1876543210;523
-
- Example, in which there is an optional value:
-
- accesspoint7.example.com;1876543210;523;[email protected]
-
- The Session-Id is created by the Diameter application initiating the
- session, which, in most cases, is done by the client. Note that a
- Session-Id MAY be used for both the authentication, authorization,
- and accounting commands of a given application.
-
-8.9. Authorization-Lifetime AVP
-
- The Authorization-Lifetime AVP (AVP Code 291) is of type Unsigned32
- and contains the maximum number of seconds of service to be provided
- to the user before the user is to be re-authenticated and/or re-
- authorized. Care should be taken when the Authorization-Lifetime
- value is determined, since a low, non-zero value could create
- significant Diameter traffic, which could congest both the network
- and the agents.
-
- A value of zero (0) means that immediate re-auth is necessary by the
- access device. The absence of this AVP, or a value of all ones
- (meaning all bits in the 32-bit field are set to one) means no re-
- auth is expected.
-
-
-
-Fajardo, et al. Standards Track [Page 117]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- If both this AVP and the Session-Timeout AVP are present in a
- message, the value of the latter MUST NOT be smaller than the
- Authorization-Lifetime AVP.
-
- An Authorization-Lifetime AVP MAY be present in re-authorization
- messages, and it contains the number of seconds the user is
- authorized to receive service from the time the re-auth answer
- message is received by the access device.
-
- This AVP MAY be provided by the client as a hint of the maximum
- lifetime that it is willing to accept. The server MUST return a
- value that is equal to, or smaller than, the one provided by the
- client.
-
-8.10. Auth-Grace-Period AVP
-
- The Auth-Grace-Period AVP (AVP Code 276) is of type Unsigned32 and
- contains the number of seconds the Diameter server will wait
- following the expiration of the Authorization-Lifetime AVP before
- cleaning up resources for the session.
-
-8.11. Auth-Session-State AVP
-
- The Auth-Session-State AVP (AVP Code 277) is of type Enumerated and
- specifies whether state is maintained for a particular session. The
- client MAY include this AVP in requests as a hint to the server, but
- the value in the server's answer message is binding. The following
- values are supported:
-
- STATE_MAINTAINED 0
-
- This value is used to specify that session state is being
- maintained, and the access device MUST issue a session termination
- message when service to the user is terminated. This is the
- default value.
-
- NO_STATE_MAINTAINED 1
-
- This value is used to specify that no session termination messages
- will be sent by the access device upon expiration of the
- Authorization-Lifetime.
-
-8.12. Re-Auth-Request-Type AVP
-
- The Re-Auth-Request-Type AVP (AVP Code 285) is of type Enumerated and
- is included in application-specific auth answers to inform the client
- of the action expected upon expiration of the Authorization-Lifetime.
-
-
-
-
-Fajardo, et al. Standards Track [Page 118]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- If the answer message contains an Authorization-Lifetime AVP with a
- positive value, the Re-Auth-Request-Type AVP MUST be present in an
- answer message. The following values are defined:
-
- AUTHORIZE_ONLY 0
-
- An authorization only re-auth is expected upon expiration of the
- Authorization-Lifetime. This is the default value if the AVP is
- not present in answer messages that include the Authorization-
- Lifetime.
-
- AUTHORIZE_AUTHENTICATE 1
-
- An authentication and authorization re-auth is expected upon
- expiration of the Authorization-Lifetime.
-
-8.13. Session-Timeout AVP
-
- The Session-Timeout AVP (AVP Code 27) [RFC2865] is of type Unsigned32
- and contains the maximum number of seconds of service to be provided
- to the user before termination of the session. When both the
- Session-Timeout and the Authorization-Lifetime AVPs are present in an
- answer message, the former MUST be equal to or greater than the value
- of the latter.
-
- A session that terminates on an access device due to the expiration
- of the Session-Timeout MUST cause an STR to be issued, unless both
- the access device and the home server had previously agreed that no
- session termination messages would be sent (see Section 8).
-
- A Session-Timeout AVP MAY be present in a re-authorization answer
- message, and it contains the remaining number of seconds from the
- beginning of the re-auth.
-
- A value of zero, or the absence of this AVP, means that this session
- has an unlimited number of seconds before termination.
-
- This AVP MAY be provided by the client as a hint of the maximum
- timeout that it is willing to accept. However, the server MAY return
- a value that is equal to, or smaller than, the one provided by the
- client.
-
-8.14. User-Name AVP
-
- The User-Name AVP (AVP Code 1) [RFC2865] is of type UTF8String, which
- contains the User-Name, in a format consistent with the NAI
- specification [RFC4282].
-
-
-
-
-Fajardo, et al. Standards Track [Page 119]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-8.15. Termination-Cause AVP
-
- The Termination-Cause AVP (AVP Code 295) is of type Enumerated, and
- is used to indicate the reason why a session was terminated on the
- access device. The currently assigned values for this AVP can be
- found in the IANA registry for Termination-Cause AVP Values
- [IANATCV].
-
-8.16. Origin-State-Id AVP
-
- The Origin-State-Id AVP (AVP Code 278), of type Unsigned32, is a
- monotonically increasing value that is advanced whenever a Diameter
- entity restarts with loss of previous state, for example, upon
- reboot. Origin-State-Id MAY be included in any Diameter message,
- including CER.
-
- A Diameter entity issuing this AVP MUST create a higher value for
- this AVP each time its state is reset. A Diameter entity MAY set
- Origin-State-Id to the time of startup, or it MAY use an incrementing
- counter retained in non-volatile memory across restarts.
-
- The Origin-State-Id, if present, MUST reflect the state of the entity
- indicated by Origin-Host. If a proxy modifies Origin-Host, it MUST
- either remove Origin-State-Id or modify it appropriately as well.
- Typically, Origin-State-Id is used by an access device that always
- starts up with no active sessions; that is, any session active prior
- to restart will have been lost. By including Origin-State-Id in a
- message, it allows other Diameter entities to infer that sessions
- associated with a lower Origin-State-Id are no longer active. If an
- access device does not intend for such inferences to be made, it MUST
- either not include Origin-State-Id in any message or set its value to
- 0.
-
-8.17. Session-Binding AVP
-
- The Session-Binding AVP (AVP Code 270) is of type Unsigned32, and it
- MAY be present in application-specific authorization answer messages.
- If present, this AVP MAY inform the Diameter client that all future
- application-specific re-auth and Session-Termination-Request messages
- for this session MUST be sent to the same authorization server.
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 120]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- This field is a bit mask, and the following bits have been defined:
-
- RE_AUTH 1
-
- When set, future re-auth messages for this session MUST NOT
- include the Destination-Host AVP. When cleared, the default
- value, the Destination-Host AVP MUST be present in all re-auth
- messages for this session.
-
- STR 2
-
- When set, the STR message for this session MUST NOT include the
- Destination-Host AVP. When cleared, the default value, the
- Destination-Host AVP MUST be present in the STR message for this
- session.
-
- ACCOUNTING 4
-
- When set, all accounting messages for this session MUST NOT
- include the Destination-Host AVP. When cleared, the default
- value, the Destination-Host AVP, if known, MUST be present in all
- accounting messages for this session.
-
-8.18. Session-Server-Failover AVP
-
- The Session-Server-Failover AVP (AVP Code 271) is of type Enumerated
- and MAY be present in application-specific authorization answer
- messages that either do not include the Session-Binding AVP or
- include the Session-Binding AVP with any of the bits set to a zero
- value. If present, this AVP MAY inform the Diameter client that if a
- re-auth or STR message fails due to a delivery problem, the Diameter
- client SHOULD issue a subsequent message without the Destination-Host
- AVP. When absent, the default value is REFUSE_SERVICE.
-
- The following values are supported:
-
- REFUSE_SERVICE 0
-
- If either the re-auth or the STR message delivery fails, terminate
- service with the user and do not attempt any subsequent attempts.
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 121]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- TRY_AGAIN 1
-
- If either the re-auth or the STR message delivery fails, resend
- the failed message without the Destination-Host AVP present.
-
- ALLOW_SERVICE 2
-
- If re-auth message delivery fails, assume that re-authorization
- succeeded. If STR message delivery fails, terminate the session.
-
- TRY_AGAIN_ALLOW_SERVICE 3
-
- If either the re-auth or the STR message delivery fails, resend
- the failed message without the Destination-Host AVP present. If
- the second delivery fails for re-auth, assume re-authorization
- succeeded. If the second delivery fails for STR, terminate the
- session.
-
-8.19. Multi-Round-Time-Out AVP
-
- The Multi-Round-Time-Out AVP (AVP Code 272) is of type Unsigned32 and
- SHOULD be present in application-specific authorization answer
- messages whose Result-Code AVP is set to DIAMETER_MULTI_ROUND_AUTH.
- This AVP contains the maximum number of seconds that the access
- device MUST provide the user in responding to an authentication
- request.
-
-8.20. Class AVP
-
- The Class AVP (AVP Code 25) is of type OctetString and is used by
- Diameter servers to return state information to the access device.
- When one or more Class AVPs are present in application-specific
- authorization answer messages, they MUST be present in subsequent re-
- authorization, session termination and accounting messages. Class
- AVPs found in a re-authorization answer message override the ones
- found in any previous authorization answer message. Diameter server
- implementations SHOULD NOT return Class AVPs that require more than
- 4096 bytes of storage on the Diameter client. A Diameter client that
- receives Class AVPs whose size exceeds local available storage MUST
- terminate the session.
-
-8.21. Event-Timestamp AVP
-
- The Event-Timestamp (AVP Code 55) is of type Time and MAY be included
- in an Accounting-Request and Accounting-Answer messages to record the
- time that the reported event occurred, in seconds since January 1,
- 1900 00:00 UTC.
-
-
-
-
-Fajardo, et al. Standards Track [Page 122]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-9. Accounting
-
- This accounting protocol is based on a server directed model with
- capabilities for real-time delivery of accounting information.
- Several fault resilience methods [RFC2975] have been built into the
- protocol in order minimize loss of accounting data in various fault
- situations and under different assumptions about the capabilities of
- the used devices.
-
-9.1. Server Directed Model
-
- The server directed model means that the device generating the
- accounting data gets information from either the authorization server
- (if contacted) or the accounting server regarding the way accounting
- data shall be forwarded. This information includes accounting record
- timeliness requirements.
-
- As discussed in [RFC2975], real-time transfer of accounting records
- is a requirement, such as the need to perform credit-limit checks and
- fraud detection. Note that batch accounting is not a requirement,
- and is therefore not supported by Diameter. Should batched
- accounting be required in the future, a new Diameter application will
- need to be created, or it could be handled using another protocol.
- Note, however, that even if at the Diameter layer, accounting
- requests are processed one by one; transport protocols used under
- Diameter typically batch several requests in the same packet under
- heavy traffic conditions. This may be sufficient for many
- applications.
-
- The authorization server (chain) directs the selection of proper
- transfer strategy, based on its knowledge of the user and
- relationships of roaming partnerships. The server (or agents) uses
- the Acct-Interim-Interval and Accounting-Realtime-Required AVPs to
- control the operation of the Diameter peer operating as a client.
- The Acct-Interim-Interval AVP, when present, instructs the Diameter
- node acting as a client to produce accounting records continuously
- even during a session. Accounting-Realtime-Required AVP is used to
- control the behavior of the client when the transfer of accounting
- records from the Diameter client is delayed or unsuccessful.
-
- The Diameter accounting server MAY override the interim interval or
- the real-time requirements by including the Acct-Interim-Interval or
- Accounting-Realtime-Required AVP in the Accounting-Answer message.
- When one of these AVPs is present, the latest value received SHOULD
- be used in further accounting activities for the same session.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 123]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-9.2. Protocol Messages
-
- A Diameter node that receives a successful authentication and/or
- authorization message from the Diameter server SHOULD collect
- accounting information for the session. The Accounting-Request
- message is used to transmit the accounting information to the
- Diameter server, which MUST reply with the Accounting-Answer message
- to confirm reception. The Accounting-Answer message includes the
- Result-Code AVP, which MAY indicate that an error was present in the
- accounting message. The value of the Accounting-Realtime-Required
- AVP received earlier for the session in question may indicate that
- the user's session has to be terminated when a rejected Accounting-
- Request message was received.
-
-9.3. Accounting Application Extension and Requirements
-
- Each Diameter application (e.g., NASREQ, Mobile IP) SHOULD define its
- service-specific AVPs that MUST be present in the Accounting-Request
- message in a section titled "Accounting AVPs". The application MUST
- assume that the AVPs described in this document will be present in
- all Accounting messages, so only their respective service-specific
- AVPs need to be defined in that section.
-
- Applications have the option of using one or both of the following
- accounting application extension models:
-
- Split Accounting Service
-
- The accounting message will carry the Application Id of the
- Diameter base accounting application (see Section 2.4).
- Accounting messages may be routed to Diameter nodes other than the
- corresponding Diameter application. These nodes might be
- centralized accounting servers that provide accounting service for
- multiple different Diameter applications. These nodes MUST
- advertise the Diameter base accounting Application Id during
- capabilities exchange.
-
- Coupled Accounting Service
-
- The accounting message will carry the Application Id of the
- application that is using it. The application itself will process
- the received accounting records or forward them to an accounting
- server. There is no accounting application advertisement required
- during capabilities exchange, and the accounting messages will be
- routed the same way as any of the other application messages.
-
- In cases where an application does not define its own accounting
- service, it is preferred that the split accounting model be used.
-
-
-
-Fajardo, et al. Standards Track [Page 124]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-9.4. Fault Resilience
-
- Diameter base protocol mechanisms are used to overcome small message
- loss and network faults of a temporary nature.
-
- Diameter peers acting as clients MUST implement the use of failover
- to guard against server failures and certain network failures.
- Diameter peers acting as agents or related off-line processing
- systems MUST detect duplicate accounting records caused by the
- sending of the same record to several servers and duplication of
- messages in transit. This detection MUST be based on the inspection
- of the Session-Id and Accounting-Record-Number AVP pairs. Appendix C
- discusses duplicate detection needs and implementation issues.
-
- Diameter clients MAY have non-volatile memory for the safe storage of
- accounting records over reboots or extended network failures, network
- partitions, and server failures. If such memory is available, the
- client SHOULD store new accounting records there as soon as the
- records are created and until a positive acknowledgement of their
- reception from the Diameter server has been received. Upon a reboot,
- the client MUST start sending the records in the non-volatile memory
- to the accounting server with the appropriate modifications in
- termination cause, session length, and other relevant information in
- the records.
-
- A further application of this protocol may include AVPs to control
- the maximum number of accounting records that may be stored in the
- Diameter client without committing them to the non-volatile memory or
- transferring them to the Diameter server.
-
- The client SHOULD NOT remove the accounting data from any of its
- memory areas before the correct Accounting-Answer has been received.
- The client MAY remove the oldest, undelivered, or as yet
- unacknowledged accounting data if it runs out of resources such as
- memory. It is an implementation-dependent matter for the client to
- accept new sessions under this condition.
-
-9.5. Accounting Records
-
- In all accounting records, the Session-Id AVP MUST be present; the
- User-Name AVP MUST be present if it is available to the Diameter
- client.
-
- Different types of accounting records are sent depending on the
- actual type of accounted service and the authorization server's
- directions for interim accounting. If the accounted service is a
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 125]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- one-time event, meaning that the start and stop of the event are
- simultaneous, then the Accounting-Record-Type AVP MUST be present and
- set to the value EVENT_RECORD.
-
- If the accounted service is of a measurable length, then the AVP MUST
- use the values START_RECORD, STOP_RECORD, and possibly,
- INTERIM_RECORD. If the authorization server has not directed interim
- accounting to be enabled for the session, two accounting records MUST
- be generated for each service of type session. When the initial
- Accounting-Request for a given session is sent, the Accounting-
- Record-Type AVP MUST be set to the value START_RECORD. When the last
- Accounting-Request is sent, the value MUST be STOP_RECORD.
-
- If the authorization server has directed interim accounting to be
- enabled, the Diameter client MUST produce additional records between
- the START_RECORD and STOP_RECORD, marked INTERIM_RECORD. The
- production of these records is directed by Acct-Interim-Interval as
- well as any re-authentication or re-authorization of the session.
- The Diameter client MUST overwrite any previous interim accounting
- records that are locally stored for delivery, if a new record is
- being generated for the same session. This ensures that only one
- pending interim record can exist on an access device for any given
- session.
-
- A particular value of Accounting-Sub-Session-Id MUST appear only in
- one sequence of accounting records from a Diameter client, except for
- the purposes of retransmission. The one sequence that is sent MUST
- be either one record with Accounting-Record-Type AVP set to the value
- EVENT_RECORD or several records starting with one having the value
- START_RECORD, followed by zero or more INTERIM_RECORDs and a single
- STOP_RECORD. A particular Diameter application specification MUST
- define the type of sequences that MUST be used.
-
-9.6. Correlation of Accounting Records
-
- If an application uses accounting messages, it can correlate
- accounting records with a specific application session by using the
- Session-Id of the particular application session in the accounting
- messages. Accounting messages MAY also use a different Session-Id
- from that of the application sessions, in which case, other session-
- related information is needed to perform correlation.
-
- In cases where an application requires multiple accounting sub-
- sessions, an Accounting-Sub-Session-Id AVP is used to differentiate
- each sub-session. The Session-Id would remain constant for all sub-
- sessions and is used to correlate all the sub-sessions to a
- particular application session. Note that receiving a STOP_RECORD
-
-
-
-
-Fajardo, et al. Standards Track [Page 126]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- with no Accounting-Sub-Session-Id AVP when sub-sessions were
- originally used in the START_RECORD messages implies that all sub-
- sessions are terminated.
-
- There are also cases where an application needs to correlate multiple
- application sessions into a single accounting record; the accounting
- record may span multiple different Diameter applications and sessions
- used by the same user at a given time. In such cases, the Acct-
- Multi-Session-Id AVP is used. The Acct-Multi-Session-Id AVP SHOULD
- be signaled by the server to the access device (typically, during
- authorization) when it determines that a request belongs to an
- existing session. The access device MUST then include the Acct-
- Multi-Session-Id AVP in all subsequent accounting messages.
-
- The Acct-Multi-Session-Id AVP MAY include the value of the original
- Session-Id. Its contents are implementation specific, but the MUST
- be globally unique across other Acct-Multi-Session-Ids and MUST NOT
- change during the life of a session.
-
- A Diameter application document MUST define the exact concept of a
- session that is being accounted, and it MAY define the concept of a
- multi-session. For instance, the NASREQ DIAMETER application treats
- a single PPP connection to a Network Access Server as one session and
- a set of Multilink PPP sessions as one multi-session.
-
-9.7. Accounting Command Codes
-
- This section defines Command Code values that MUST be supported by
- all Diameter implementations that provide accounting services.
-
-9.7.1. Accounting-Request
-
- The Accounting-Request (ACR) command, indicated by the Command Code
- field set to 271 and the Command Flags' 'R' bit set, is sent by a
- Diameter node, acting as a client, in order to exchange accounting
- information with a peer.
-
- In addition to the AVPs listed below, Accounting-Request messages
- SHOULD include service-specific accounting AVPs.
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 127]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Message Format
-
- &lt;ACR> ::= &lt; Diameter Header: 271, REQ, PXY >
- &lt; Session-Id >
- { Origin-Host }
- { Origin-Realm }
- { Destination-Realm }
- { Accounting-Record-Type }
- { Accounting-Record-Number }
- [ Acct-Application-Id ]
- [ Vendor-Specific-Application-Id ]
- [ User-Name ]
- [ Destination-Host ]
- [ Accounting-Sub-Session-Id ]
- [ Acct-Session-Id ]
- [ Acct-Multi-Session-Id ]
- [ Acct-Interim-Interval ]
- [ Accounting-Realtime-Required ]
- [ Origin-State-Id ]
- [ Event-Timestamp ]
- * [ Proxy-Info ]
- * [ Route-Record ]
- * [ AVP ]
-
-9.7.2. Accounting-Answer
-
- The Accounting-Answer (ACA) command, indicated by the Command Code
- field set to 271 and the Command Flags' 'R' bit cleared, is used to
- acknowledge an Accounting-Request command. The Accounting-Answer
- command contains the same Session-Id as the corresponding request.
-
- Only the target Diameter server, known as the home Diameter server,
- SHOULD respond with the Accounting-Answer command.
-
- In addition to the AVPs listed below, Accounting-Answer messages
- SHOULD include service-specific accounting AVPs.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 128]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Message Format
-
- &lt;ACA> ::= &lt; Diameter Header: 271, PXY >
- &lt; Session-Id >
- { Result-Code }
- { Origin-Host }
- { Origin-Realm }
- { Accounting-Record-Type }
- { Accounting-Record-Number }
- [ Acct-Application-Id ]
- [ Vendor-Specific-Application-Id ]
- [ User-Name ]
- [ Accounting-Sub-Session-Id ]
- [ Acct-Session-Id ]
- [ Acct-Multi-Session-Id ]
- [ Error-Message ]
- [ Error-Reporting-Host ]
- [ Failed-AVP ]
- [ Acct-Interim-Interval ]
- [ Accounting-Realtime-Required ]
- [ Origin-State-Id ]
- [ Event-Timestamp ]
- * [ Proxy-Info ]
- * [ AVP ]
-
-9.8. Accounting AVPs
-
- This section contains AVPs that describe accounting usage information
- related to a specific session.
-
-9.8.1. Accounting-Record-Type AVP
-
- The Accounting-Record-Type AVP (AVP Code 480) is of type Enumerated
- and contains the type of accounting record being sent. The following
- values are currently defined for the Accounting-Record-Type AVP:
-
- EVENT_RECORD 1
-
- An Accounting Event Record is used to indicate that a one-time
- event has occurred (meaning that the start and end of the event
- are simultaneous). This record contains all information relevant
- to the service, and it is the only record of the service.
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 129]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- START_RECORD 2
-
- Accounting Start, Interim, and Stop Records are used to indicate
- that a service of a measurable length has been given. An
- Accounting Start Record is used to initiate an accounting session
- and contains accounting information that is relevant to the
- initiation of the session.
-
- INTERIM_RECORD 3
-
- An Interim Accounting Record contains cumulative accounting
- information for an existing accounting session. Interim
- Accounting Records SHOULD be sent every time a re-authentication
- or re-authorization occurs. Further, additional interim record
- triggers MAY be defined by application-specific Diameter
- applications. The selection of whether to use INTERIM_RECORD
- records is done by the Acct-Interim-Interval AVP.
-
- STOP_RECORD 4
-
- An Accounting Stop Record is sent to terminate an accounting
- session and contains cumulative accounting information relevant to
- the existing session.
-
-9.8.2. Acct-Interim-Interval AVP
-
- The Acct-Interim-Interval AVP (AVP Code 85) is of type Unsigned32 and
- is sent from the Diameter home authorization server to the Diameter
- client. The client uses information in this AVP to decide how and
- when to produce accounting records. With different values in this
- AVP, service sessions can result in one, two, or two+N accounting
- records, based on the needs of the home organization. The following
- accounting record production behavior is directed by the inclusion of
- this AVP:
-
- 1. The omission of the Acct-Interim-Interval AVP or its inclusion
- with Value field set to 0 means that EVENT_RECORD, START_RECORD,
- and STOP_RECORD are produced, as appropriate for the service.
-
- 2. The inclusion of the AVP with Value field set to a non-zero value
- means that INTERIM_RECORD records MUST be produced between the
- START_RECORD and STOP_RECORD records. The Value field of this
- AVP is the nominal interval between these records in seconds.
- The Diameter node that originates the accounting information,
- known as the client, MUST produce the first INTERIM_RECORD record
- roughly at the time when this nominal interval has elapsed from
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 130]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- the START_RECORD, the next one again as the interval has elapsed
- once more, and so on until the session ends and a STOP_RECORD
- record is produced.
-
- The client MUST ensure that the interim record production times
- are randomized so that large accounting message storms are not
- created either among records or around a common service start
- time.
-
-9.8.3. Accounting-Record-Number AVP
-
- The Accounting-Record-Number AVP (AVP Code 485) is of type Unsigned32
- and identifies this record within one session. As Session-Id AVPs
- are globally unique, the combination of Session-Id and Accounting-
- Record-Number AVPs is also globally unique and can be used in
- matching accounting records with confirmations. An easy way to
- produce unique numbers is to set the value to 0 for records of type
- EVENT_RECORD and START_RECORD and set the value to 1 for the first
- INTERIM_RECORD, 2 for the second, and so on until the value for
- STOP_RECORD is one more than for the last INTERIM_RECORD.
-
-9.8.4. Acct-Session-Id AVP
-
- The Acct-Session-Id AVP (AVP Code 44) is of type OctetString is only
- used when RADIUS/Diameter translation occurs. This AVP contains the
- contents of the RADIUS Acct-Session-Id attribute.
-
-9.8.5. Acct-Multi-Session-Id AVP
-
- The Acct-Multi-Session-Id AVP (AVP Code 50) is of type UTF8String,
- following the format specified in Section 8.8. The Acct-Multi-
- Session-Id AVP is used to link multiple related accounting sessions,
- where each session would have a unique Session-Id but the same Acct-
- Multi-Session-Id AVP. This AVP MAY be returned by the Diameter
- server in an authorization answer, and it MUST be used in all
- accounting messages for the given session.
-
-9.8.6. Accounting-Sub-Session-Id AVP
-
- The Accounting-Sub-Session-Id AVP (AVP Code 287) is of type
- Unsigned64 and contains the accounting sub-session identifier. The
- combination of the Session-Id and this AVP MUST be unique per sub-
- session, and the value of this AVP MUST be monotonically increased by
- one for all new sub-sessions. The absence of this AVP implies no
- sub-sessions are in use, with the exception of an Accounting-Request
- whose Accounting-Record-Type is set to STOP_RECORD. A STOP_RECORD
- message with no Accounting-Sub-Session-Id AVP present will signal the
- termination of all sub-sessions for a given Session-Id.
-
-
-
-Fajardo, et al. Standards Track [Page 131]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-9.8.7. Accounting-Realtime-Required AVP
-
- The Accounting-Realtime-Required AVP (AVP Code 483) is of type
- Enumerated and is sent from the Diameter home authorization server to
- the Diameter client or in the Accounting-Answer from the accounting
- server. The client uses information in this AVP to decide what to do
- if the sending of accounting records to the accounting server has
- been temporarily prevented due to, for instance, a network problem.
-
- DELIVER_AND_GRANT 1
-
- The AVP with Value field set to DELIVER_AND_GRANT means that the
- service MUST only be granted as long as there is a connection to
- an accounting server. Note that the set of alternative accounting
- servers are treated as one server in this sense. Having to move
- the accounting record stream to a backup server is not a reason to
- discontinue the service to the user.
-
- GRANT_AND_STORE 2
-
- The AVP with Value field set to GRANT_AND_STORE means that service
- SHOULD be granted if there is a connection, or as long as records
- can still be stored as described in Section 9.4.
-
- This is the default behavior if the AVP isn't included in the
- reply from the authorization server.
-
- GRANT_AND_LOSE 3
-
- The AVP with Value field set to GRANT_AND_LOSE means that service
- SHOULD be granted even if the records cannot be delivered or
- stored.
-
-10. AVP Occurrence Tables
-
- The following tables present the AVPs defined in this document and
- specify in which Diameter messages they MAY or MAY NOT be present.
- AVPs that occur only inside a Grouped AVP are not shown in these
- tables.
-
- The tables use the following symbols:
-
- 0 The AVP MUST NOT be present in the message.
-
- 0+ Zero or more instances of the AVP MAY be present in the
- message.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 132]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- 0-1 Zero or one instance of the AVP MAY be present in the message.
- It is considered an error if there are more than one instance
- of the AVP.
-
- 1 One instance of the AVP MUST be present in the message.
-
- 1+ At least one instance of the AVP MUST be present in the
- message.
-
-10.1. Base Protocol Command AVP Table
-
- The table in this section is limited to the non-Accounting Command
- Codes defined in this specification.
-
- +-----------------------------------------------+
- | Command Code |
- +---+---+---+---+---+---+---+---+---+---+---+---+
- Attribute Name |CER|CEA|DPR|DPA|DWR|DWA|RAR|RAA|ASR|ASA|STR|STA|
- --------------------+---+---+---+---+---+---+---+---+---+---+---+---+
- Acct-Interim- |0 |0 |0 |0 |0 |0 |0-1|0 |0 |0 |0 |0 |
- Interval | | | | | | | | | | | | |
- Accounting-Realtime-|0 |0 |0 |0 |0 |0 |0-1|0 |0 |0 |0 |0 |
- Required | | | | | | | | | | | | |
- Acct-Application-Id |0+ |0+ |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Auth-Application-Id |0+ |0+ |0 |0 |0 |0 |1 |0 |1 |0 |1 |0 |
- Auth-Grace-Period |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Auth-Request-Type |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Auth-Session-State |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Authorization- |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Lifetime | | | | | | | | | | | | |
- Class |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0+ |0+ |
- Destination-Host |0 |0 |0 |0 |0 |0 |1 |0 |1 |0 |0-1|0 |
- Destination-Realm |0 |0 |0 |0 |0 |0 |1 |0 |1 |0 |1 |0 |
- Disconnect-Cause |0 |0 |1 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Error-Message |0 |0-1|0 |0-1|0 |0-1|0 |0-1|0 |0-1|0 |0-1|
- Error-Reporting-Host|0 |0 |0 |0 |0 |0 |0 |0-1|0 |0-1|0 |0-1|
- Failed-AVP |0 |0-1|0 |0-1|0 |0-1|0 |0-1|0 |0-1|0 |0-1|
- Firmware-Revision |0-1|0-1|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Host-IP-Address |1+ |1+ |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Inband-Security-Id |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Multi-Round-Time-Out|0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 133]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Origin-Host |1 |1 |1 |1 |1 |1 |1 |1 |1 |1 |1 |1 |
- Origin-Realm |1 |1 |1 |1 |1 |1 |1 |1 |1 |1 |1 |1 |
- Origin-State-Id |0-1|0-1|0 |0 |0-1|0-1|0-1|0-1|0-1|0-1|0-1|0-1|
- Product-Name |1 |1 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Proxy-Info |0 |0 |0 |0 |0 |0 |0+ |0+ |0+ |0+ |0+ |0+ |
- Redirect-Host |0 |0 |0 |0 |0 |0 |0 |0+ |0 |0+ |0 |0+ |
- Redirect-Host-Usage |0 |0 |0 |0 |0 |0 |0 |0-1|0 |0-1|0 |0-1|
- Redirect-Max-Cache- |0 |0 |0 |0 |0 |0 |0 |0-1|0 |0-1|0 |0-1|
- Time | | | | | | | | | | | | |
- Result-Code |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |0 |1 |
- Re-Auth-Request-Type|0 |0 |0 |0 |0 |0 |1 |0 |0 |0 |0 |0 |
- Route-Record |0 |0 |0 |0 |0 |0 |0+ |0 |0+ |0 |0+ |0 |
- Session-Binding |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Session-Id |0 |0 |0 |0 |0 |0 |1 |1 |1 |1 |1 |1 |
- Session-Server- |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Failover | | | | | | | | | | | | |
- Session-Timeout |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Supported-Vendor-Id |0+ |0+ |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Termination-Cause |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |1 |0 |
- User-Name |0 |0 |0 |0 |0 |0 |0-1|0-1|0-1|0-1|0-1|0-1|
- Vendor-Id |1 |1 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Vendor-Specific- |0+ |0+ |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |
- Application-Id | | | | | | | | | | | | |
- --------------------+---+---+---+---+---+---+---+---+---+---+---+---+
-
-10.2. Accounting AVP Table
-
- The table in this section is used to represent which AVPs defined in
- this document are to be present in the Accounting messages. These
- AVP occurrence requirements are guidelines, which may be expanded,
- and/or overridden by application-specific requirements in the
- Diameter applications documents.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 134]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- +-----------+
- | Command |
- | Code |
- +-----+-----+
- Attribute Name | ACR | ACA |
- ------------------------------+-----+-----+
- Acct-Interim-Interval | 0-1 | 0-1 |
- Acct-Multi-Session-Id | 0-1 | 0-1 |
- Accounting-Record-Number | 1 | 1 |
- Accounting-Record-Type | 1 | 1 |
- Acct-Session-Id | 0-1 | 0-1 |
- Accounting-Sub-Session-Id | 0-1 | 0-1 |
- Accounting-Realtime-Required | 0-1 | 0-1 |
- Acct-Application-Id | 0-1 | 0-1 |
- Auth-Application-Id | 0 | 0 |
- Class | 0+ | 0+ |
- Destination-Host | 0-1 | 0 |
- Destination-Realm | 1 | 0 |
- Error-Reporting-Host | 0 | 0+ |
- Event-Timestamp | 0-1 | 0-1 |
- Failed-AVP | 0 | 0-1 |
- Origin-Host | 1 | 1 |
- Origin-Realm | 1 | 1 |
- Proxy-Info | 0+ | 0+ |
- Route-Record | 0+ | 0 |
- Result-Code | 0 | 1 |
- Session-Id | 1 | 1 |
- Termination-Cause | 0 | 0 |
- User-Name | 0-1 | 0-1 |
- Vendor-Specific-Application-Id| 0-1 | 0-1 |
- ------------------------------+-----+-----+
-
-11. IANA Considerations
-
- This section provides guidance to the Internet Assigned Numbers
- Authority (IANA) regarding registration of values related to the
- Diameter protocol, in accordance with [RFC5226]. Existing IANA
- registries and assignments put in place by RFC 3588 remain the same
- unless explicitly updated or deprecated in this section.
-
-11.1. AVP Header
-
- As defined in Section 4, the AVP header contains three fields that
- require IANA namespace management: the AVP Code, Vendor-ID, and Flags
- fields.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 135]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-11.1.1. AVP Codes
-
- There are multiple namespaces. Vendors can have their own AVP Codes
- namespace that will be identified by their Vendor-ID (also known as
- Enterprise-Number), and they control the assignments of their vendor-
- specific AVP Codes within their own namespace. The absence of a
- Vendor-ID or a Vendor-ID value of zero (0) identifies the IETF AVP
- Codes namespace, which is under IANA control. The AVP Codes and
- sometimes possible values in an AVP are controlled and maintained by
- IANA. AVP Code 0 is not used. AVP Codes 1-255 are managed
- separately as RADIUS Attribute Types. Where a Vendor-Specific AVP is
- implemented by more than one vendor, allocation of global AVPs should
- be encouraged instead.
-
- AVPs may be allocated following Expert Review (by a Designated
- Expert) with Specification Required [RFC5226]. A block allocation
- (release of more than three AVPs at a time for a given purpose)
- requires IETF Review [RFC5226].
-
-11.1.2. AVP Flags
-
- Section 4.1 describes the existing AVP Flags. The remaining bits can
- only be assigned via a Standards Action [RFC5226].
-
-11.2. Diameter Header
-
-11.2.1. Command Codes
-
- For the Diameter header, the Command Code namespace allocation has
- changed. The new allocation rules are as follows:
-
- The Command Code values 256 - 8,388,607 (0x100 to 0x7fffff) are
- for permanent, standard commands, allocated by IETF Review
- [RFC5226].
-
- The values 8,388,608 - 16,777,213 (0x800000 - 0xfffffd) are
- reserved for vendor-specific Command Codes, to be allocated on a
- First Come, First Served basis by IANA [RFC5226]. The request to
- IANA for a Vendor-Specific Command Code SHOULD include a reference
- to a publicly available specification that documents the command
- in sufficient detail to aid in interoperability between
- independent implementations. If the specification cannot be made
- publicly available, the request for a vendor-specific Command Code
- MUST include the contact information of persons and/or entities
- responsible for authoring and maintaining the command.
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 136]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- The values 16,777,214 and 16,777,215 (hexadecimal values 0xfffffe
- - 0xffffff) are reserved for experimental commands. As these
- codes are only for experimental and testing purposes, no guarantee
- is made for interoperability between Diameter peers using
- experimental commands.
-
-11.2.2. Command Flags
-
- Section 3 describes the existing Command Flags field. The remaining
- bits can only be assigned via a Standards Action [RFC5226].
-
-11.3. AVP Values
-
- For AVP values, the Experimental-Result-Code AVP value allocation has
- been added; see Section 11.3.1. The old AVP value allocation rule,
- IETF Consensus, has been updated to IETF Review as per [RFC5226], and
- affected AVPs are listed as reminders.
-
-11.3.1. Experimental-Result-Code AVP
-
- Values for this AVP are purely local to the indicated vendor, and no
- IANA registry is maintained for them.
-
-11.3.2. Result-Code AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.3. Accounting-Record-Type AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.4. Termination-Cause AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.5. Redirect-Host-Usage AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.6. Session-Server-Failover AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.7. Session-Binding AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 137]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-11.3.8. Disconnect-Cause AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.9. Auth-Request-Type AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.10. Auth-Session-State AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.11. Re-Auth-Request-Type AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.12. Accounting-Realtime-Required AVP Values
-
- New values are available for assignment via IETF Review [RFC5226].
-
-11.3.13. Inband-Security-Id AVP (code 299)
-
- The use of this AVP has been deprecated.
-
-11.4. _diameters Service Name and Port Number Registration
-
- IANA has registered the "_diameters" service name and assigned port
- numbers for TLS/TCP and DTLS/SCTP according to the guidelines given
- in [RFC6335].
-
- Service Name: _diameters
-
- Transport Protocols: TCP, SCTP
-
- Assignee: IESG &lt;[email protected]>
-
- Contact: IETF Chair &lt;[email protected]>
-
- Description: Diameter over TLS/TCP and DTLS/SCTP
-
- Reference: RFC 6733
-
- Port Number: 5868, from the User Range
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 138]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-11.5. SCTP Payload Protocol Identifiers
-
- Two SCTP payload protocol identifiers have been registered in the
- SCTP Payload Protocol Identifiers registry:
-
-
- Value | SCTP Payload Protocol Identifier
- -------|-----------------------------------
- 46 | Diameter in a SCTP DATA chunk
- 47 | Diameter in a DTLS/SCTP DATA chunk
-
-
-11.6. S-NAPTR Parameters
-
- The following tag has been registered in the S-NAPTR Application
- Protocol Tags registry:
-
- Tag | Protocol
- -------------------|---------
- diameter.dtls.sctp | DTLS/SCTP
-
-12. Diameter Protocol-Related Configurable Parameters
-
- This section contains the configurable parameters that are found
- throughout this document:
-
- Diameter Peer
-
- A Diameter entity MAY communicate with peers that are statically
- configured. A statically configured Diameter peer would require
- that either the IP address or the fully qualified domain name
- (FQDN) be supplied, which would then be used to resolve through
- DNS.
-
- Routing Table
-
- A Diameter proxy server routes messages based on the realm portion
- of a Network Access Identifier (NAI). The server MUST have a
- table of Realm Names, and the address of the peer to which the
- message must be forwarded. The routing table MAY also include a
- "default route", which is typically used for all messages that
- cannot be locally processed.
-
- Tc timer
-
- The Tc timer controls the frequency that transport connection
- attempts are done to a peer with whom no active transport
- connection exists. The recommended value is 30 seconds.
-
-
-
-Fajardo, et al. Standards Track [Page 139]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-13. Security Considerations
-
- The Diameter base protocol messages SHOULD be secured by using TLS
- [RFC5246] or DTLS/SCTP [RFC6083]. Additional security mechanisms
- such as IPsec [RFC4301] MAY also be deployed to secure connections
- between peers. However, all Diameter base protocol implementations
- MUST support the use of TLS/TCP and DTLS/SCTP, and the Diameter
- protocol MUST NOT be used without one of TLS, DTLS, or IPsec.
-
- If a Diameter connection is to be protected via TLS/TCP and DTLS/SCTP
- or IPsec, then TLS/TCP and DTLS/SCTP or IPsec/IKE SHOULD begin prior
- to any Diameter message exchange. All security parameters for TLS/
- TCP and DTLS/SCTP or IPsec are configured independent of the Diameter
- protocol. All Diameter messages will be sent through the TLS/TCP and
- DTLS/SCTP or IPsec connection after a successful setup.
-
- For TLS/TCP and DTLS/SCTP connections to be established in the open
- state, the CER/CEA exchange MUST include an Inband-Security-ID AVP
- with a value of TLS/TCP and DTLS/SCTP. The TLS/TCP and DTLS/SCTP
- handshake will begin when both ends successfully reach the open
- state, after completion of the CER/CEA exchange. If the TLS/TCP and
- DTLS/SCTP handshake is successful, all further messages will be sent
- via TLS/TCP and DTLS/SCTP. If the handshake fails, both ends MUST
- move to the closed state. See Section 13.1 for more details.
-
-13.1. TLS/TCP and DTLS/SCTP Usage
-
- Diameter nodes using TLS/TCP and DTLS/SCTP for security MUST mutually
- authenticate as part of TLS/TCP and DTLS/SCTP session establishment.
- In order to ensure mutual authentication, the Diameter node acting as
- the TLS/TCP and DTLS/SCTP server MUST request a certificate from the
- Diameter node acting as TLS/TCP and DTLS/SCTP client, and the
- Diameter node acting as the TLS/TCP and DTLS/SCTP client MUST be
- prepared to supply a certificate on request.
-
- Diameter nodes MUST be able to negotiate the following TLS/TCP and
- DTLS/SCTP cipher suites:
-
- TLS_RSA_WITH_RC4_128_MD5
- TLS_RSA_WITH_RC4_128_SHA
- TLS_RSA_WITH_3DES_EDE_CBC_SHA
-
- Diameter nodes SHOULD be able to negotiate the following TLS/TCP and
- DTLS/SCTP cipher suite:
-
- TLS_RSA_WITH_AES_128_CBC_SHA
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 140]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- Note that it is quite possible that support for the
- TLS_RSA_WITH_AES_128_CBC_SHA cipher suite will be REQUIRED at some
- future date. Diameter nodes MAY negotiate other TLS/TCP and DTLS/
- SCTP cipher suites.
-
- If public key certificates are used for Diameter security (for
- example, with TLS), the value of the expiration times in the routing
- and peer tables MUST NOT be greater than the expiry time in the
- relevant certificates.
-
-13.2. Peer-to-Peer Considerations
-
- As with any peer-to-peer protocol, proper configuration of the trust
- model within a Diameter peer is essential to security. When
- certificates are used, it is necessary to configure the root
- certificate authorities trusted by the Diameter peer. These root CAs
- are likely to be unique to Diameter usage and distinct from the root
- CAs that might be trusted for other purposes such as Web browsing.
- In general, it is expected that those root CAs will be configured so
- as to reflect the business relationships between the organization
- hosting the Diameter peer and other organizations. As a result, a
- Diameter peer will typically not be configured to allow connectivity
- with any arbitrary peer. With certificate authentication, Diameter
- peers may not be known beforehand and therefore peer discovery may be
- required.
-
-13.3. AVP Considerations
-
- Diameter AVPs often contain security-sensitive data; for example,
- user passwords and location data, network addresses and cryptographic
- keys. The following AVPs defined in this document are considered to
- be security-sensitive:
-
- o Acct-Interim-Interval
-
- o Accounting-Realtime-Required
-
- o Acct-Multi-Session-Id
-
- o Accounting-Record-Number
-
- o Accounting-Record-Type
-
- o Accounting-Session-Id
-
- o Accounting-Sub-Session-Id
-
- o Class
-
-
-
-Fajardo, et al. Standards Track [Page 141]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- o Session-Id
-
- o Session-Binding
-
- o Session-Server-Failover
-
- o User-Name
-
- Diameter messages containing these or any other AVPs considered to be
- security-sensitive MUST only be sent protected via mutually
- authenticated TLS or IPsec. In addition, those messages MUST NOT be
- sent via intermediate nodes unless there is end-to-end security
- between the originator and recipient or the originator has locally
- trusted configuration that indicates that end-to-end security is not
- needed. For example, end-to-end security may not be required in the
- case where an intermediary node is known to be operated as part of
- the same administrative domain as the endpoints so that an ability to
- successfully compromise the intermediary would imply a high
- probability of being able to compromise the endpoints as well. Note
- that no end-to-end security mechanism is specified in this document.
-
-14. References
-
-14.1. Normative References
-
- [FLOATPOINT]
- Institute of Electrical and Electronics Engineers, "IEEE
- Standard for Binary Floating-Point Arithmetic, ANSI/IEEE
- Standard 754-1985", August 1985.
-
- [IANAADFAM]
- IANA, "Address Family Numbers",
- &lt;http://www.iana.org/assignments/address-family-numbers>.
-
- [RFC0791] Postel, J., "Internet Protocol", STD 5, RFC 791,
- September 1981.
-
- [RFC0793] Postel, J., "Transmission Control Protocol", STD 7,
- RFC 793, September 1981.
-
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
- Requirement Levels", BCP 14, RFC 2119, March 1997.
-
- [RFC3492] Costello, A., "Punycode: A Bootstring encoding of Unicode
- for Internationalized Domain Names in Applications
- (IDNA)", RFC 3492, March 2003.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 142]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- [RFC3539] Aboba, B. and J. Wood, "Authentication, Authorization and
- Accounting (AAA) Transport Profile", RFC 3539, June 2003.
-
- [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO
- 10646", STD 63, RFC 3629, November 2003.
-
- [RFC3958] Daigle, L. and A. Newton, "Domain-Based Application
- Service Location Using SRV RRs and the Dynamic Delegation
- Discovery Service (DDDS)", RFC 3958, January 2005.
-
- [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
- Resource Identifier (URI): Generic Syntax", STD 66,
- RFC 3986, January 2005.
-
- [RFC4004] Calhoun, P., Johansson, T., Perkins, C., Hiller, T., and
- P. McCann, "Diameter Mobile IPv4 Application", RFC 4004,
- August 2005.
-
- [RFC4005] Calhoun, P., Zorn, G., Spence, D., and D. Mitton,
- "Diameter Network Access Server Application", RFC 4005,
- August 2005.
-
- [RFC4006] Hakala, H., Mattila, L., Koskinen, J-P., Stura, M., and J.
- Loughney, "Diameter Credit-Control Application", RFC 4006,
- August 2005.
-
- [RFC4086] Eastlake, D., Schiller, J., and S. Crocker, "Randomness
- Requirements for Security", BCP 106, RFC 4086, June 2005.
-
- [RFC4282] Aboba, B., Beadles, M., Arkko, J., and P. Eronen, "The
- Network Access Identifier", RFC 4282, December 2005.
-
- [RFC4291] Hinden, R. and S. Deering, "IP Version 6 Addressing
- Architecture", RFC 4291, February 2006.
-
- [RFC4960] Stewart, R., "Stream Control Transmission Protocol",
- RFC 4960, September 2007.
-
- [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an
- IANA Considerations Section in RFCs", BCP 26, RFC 5226,
- May 2008.
-
- [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
- Specifications: ABNF", STD 68, RFC 5234, January 2008.
-
- [RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
- (TLS) Protocol Version 1.2", RFC 5246, August 2008.
-
-
-
-
-Fajardo, et al. Standards Track [Page 143]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- [RFC5280] Cooper, D., Santesson, S., Farrell, S., Boeyen, S.,
- Housley, R., and W. Polk, "Internet X.509 Public Key
- Infrastructure Certificate and Certificate Revocation List
- (CRL) Profile", RFC 5280, May 2008.
-
- [RFC5729] Korhonen, J., Jones, M., Morand, L., and T. Tsou,
- "Clarifications on the Routing of Diameter Requests Based
- on the Username and the Realm", RFC 5729, December 2009.
-
- [RFC5890] Klensin, J., "Internationalized Domain Names for
- Applications (IDNA): Definitions and Document Framework",
- RFC 5890, August 2010.
-
- [RFC5891] Klensin, J., "Internationalized Domain Names in
- Applications (IDNA): Protocol", RFC 5891, August 2010.
-
- [RFC6083] Tuexen, M., Seggelmann, R., and E. Rescorla, "Datagram
- Transport Layer Security (DTLS) for Stream Control
- Transmission Protocol (SCTP)", RFC 6083, January 2011.
-
- [RFC6347] Rescorla, E. and N. Modadugu, "Datagram Transport Layer
- Security Version 1.2", RFC 6347, January 2012.
-
- [RFC6408] Jones, M., Korhonen, J., and L. Morand, "Diameter
- Straightforward-Naming Authority Pointer (S-NAPTR) Usage",
- RFC 6408, November 2011.
-
-14.2. Informative References
-
- [ENTERPRISE] IANA, "SMI Network Management Private Enterprise
- Codes",
- &lt;http://www.iana.org/assignments/enterprise-numbers>.
-
- [IANATCV] IANA, "Termination-Cause AVP Values (code 295)",
- &lt;http://www.iana.org/assignments/aaa-parameters/
- aaa-parameters.xml#aaa-parameters-16>.
-
- [RFC1492] Finseth, C., "An Access Control Protocol, Sometimes
- Called TACACS", RFC 1492, July 1993.
-
- [RFC1661] Simpson, W., "The Point-to-Point Protocol (PPP)",
- STD 51, RFC 1661, July 1994.
-
- [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC:
- Keyed-Hashing for Message Authentication", RFC 2104,
- February 1997.
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 144]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- [RFC2782] Gulbrandsen, A., Vixie, P., and L. Esibov, "A DNS RR
- for specifying the location of services (DNS SRV)",
- RFC 2782, February 2000.
-
- [RFC2865] Rigney, C., Willens, S., Rubens, A., and W. Simpson,
- "Remote Authentication Dial In User Service (RADIUS)",
- RFC 2865, June 2000.
-
- [RFC2866] Rigney, C., "RADIUS Accounting", RFC 2866, June 2000.
-
- [RFC2869] Rigney, C., Willats, W., and P. Calhoun, "RADIUS
- Extensions", RFC 2869, June 2000.
-
- [RFC2881] Mitton, D. and M. Beadles, "Network Access Server
- Requirements Next Generation (NASREQNG) NAS Model",
- RFC 2881, July 2000.
-
- [RFC2975] Aboba, B., Arkko, J., and D. Harrington, "Introduction
- to Accounting Management", RFC 2975, October 2000.
-
- [RFC2989] Aboba, B., Calhoun, P., Glass, S., Hiller, T., McCann,
- P., Shiino, H., Walsh, P., Zorn, G., Dommety, G.,
- Perkins, C., Patil, B., Mitton, D., Manning, S.,
- Beadles, M., Chen, X., Sivalingham, S., Hameed, A.,
- Munson, M., Jacobs, S., Lim, B., Hirschman, B., Hsu,
- R., Koo, H., Lipford, M., Campbell, E., Xu, Y., Baba,
- S., and E. Jaques, "Criteria for Evaluating AAA
- Protocols for Network Access", RFC 2989, November 2000.
-
- [RFC3162] Aboba, B., Zorn, G., and D. Mitton, "RADIUS and IPv6",
- RFC 3162, August 2001.
-
- [RFC3748] Aboba, B., Blunk, L., Vollbrecht, J., Carlson, J., and
- H. Levkowetz, "Extensible Authentication Protocol
- (EAP)", RFC 3748, June 2004.
-
- [RFC4301] Kent, S. and K. Seo, "Security Architecture for the
- Internet Protocol", RFC 4301, December 2005.
-
- [RFC4690] Klensin, J., Faltstrom, P., Karp, C., and IAB, "Review
- and Recommendations for Internationalized Domain Names
- (IDNs)", RFC 4690, September 2006.
-
- [RFC5176] Chiba, M., Dommety, G., Eklund, M., Mitton, D., and B.
- Aboba, "Dynamic Authorization Extensions to Remote
- Authentication Dial In User Service (RADIUS)",
- RFC 5176, January 2008.
-
-
-
-
-Fajardo, et al. Standards Track [Page 145]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- [RFC5461] Gont, F., "TCP's Reaction to Soft Errors", RFC 5461,
- February 2009.
-
- [RFC5905] Mills, D., Martin, J., Burbank, J., and W. Kasch,
- "Network Time Protocol Version 4: Protocol and
- Algorithms Specification", RFC 5905, June 2010.
-
- [RFC5927] Gont, F., "ICMP Attacks against TCP", RFC 5927,
- July 2010.
-
- [RFC6335] Cotton, M., Eggert, L., Touch, J., Westerlund, M., and
- S. Cheshire, "Internet Assigned Numbers Authority
- (IANA) Procedures for the Management of the Service
- Name and Transport Protocol Port Number Registry",
- BCP 165, RFC 6335, August 2011.
-
- [RFC6737] Kang, J. and G. Zorn, "The Diameter Capabilities Update
- Application", RFC 6737, October 2012.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Fajardo, et al. Standards Track [Page 146]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
-Appendix A. Acknowledgements
-
-A.1. This Document
-
- The authors would like to thank the following people that have
- provided proposals and contributions to this document:
-
- To Vishnu Ram and Satendra Gera for their contributions on
- capabilities updates, predictive loop avoidance, as well as many
- other technical proposals. To Tolga Asveren for his insights and
- contributions on almost all of the proposed solutions incorporated
- into this document. To Timothy Smith for helping on the capabilities
- Update and other topics. To Tony Zhang for providing fixes to
- loopholes on composing Failed-AVPs as well as many other issues and
- topics. To Jan Nordqvist for clearly stating the usage of
- Application Ids. To Anders Kristensen for providing needed technical
- opinions. To David Frascone for providing invaluable review of the
- document. To Mark Jones for providing clarifying text on vendor
- command codes and other vendor-specific indicators. To Victor
- Pascual and Sebastien Decugis for new text and recommendations on
- SCTP/DTLS. To Jouni Korhonen for taking over the editing task and
- resolving last bits from versions 27 through 29.
-
- Special thanks to the Diameter extensibility design team, which
- helped resolve the tricky question of mandatory AVPs and ABNF
- semantics. The members of this team are as follows:
-
- Avi Lior, Jari Arkko, Glen Zorn, Lionel Morand, Mark Jones, Tolga
- Asveren, Jouni Korhonen, and Glenn McGregor.
-
- Special thanks also to people who have provided invaluable comments
- and inputs especially in resolving controversial issues:
-
- Glen Zorn, Yoshihiro Ohba, Marco Stura, Stephen Farrel, Pete Resnick,
- Peter Saint-Andre, Robert Sparks, Krishna Prasad, Sean Turner, Barry
- Leiba, and Pasi Eronen.
-
- Finally, we would like to thank the original authors of this
- document:
-
- Pat Calhoun, John Loughney, Jari Arkko, Erik Guttman, and Glen Zorn.
-
- Their invaluable knowledge and experience has given us a robust and
- flexible AAA protocol that many people have seen great value in
- adopting. We greatly appreciate their support and stewardship for
- the continued improvements of Diameter as a protocol. We would also
- like to extend our gratitude to folks aside from the authors who have
-
-
-
-
-Fajardo, et al. Standards Track [Page 147]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- assisted and contributed to the original version of this document.
- Their efforts significantly contributed to the success of Diameter.
-
-A.2. RFC 3588
-
- The authors would like to thank Nenad Trifunovic, Tony Johansson and
- Pankaj Patel for their participation in the pre-IETF Document Reading
- Party. Allison Mankin, Jonathan Wood, and Bernard Aboba provided
- invaluable assistance in working out transport issues and this was
- also the case with Steven Bellovin in the security area.
-
- Paul Funk and David Mitton were instrumental in getting the Peer
- State Machine correct, and our deep thanks go to them for their time.
-
- Text in this document was also provided by Paul Funk, Mark Eklund,
- Mark Jones, and Dave Spence. Jacques Caron provided many great
- comments as a result of a thorough review of the spec.
-
- The authors would also like to acknowledge the following people for
- their contribution in the development of the Diameter protocol:
-
- Allan C. Rubens, Haseeb Akhtar, William Bulley, Stephen Farrell,
- David Frascone, Daniel C. Fox, Lol Grant, Ignacio Goyret, Nancy
- Greene, Peter Heitman, Fredrik Johansson, Mark Jones, Martin Julien,
- Bob Kopacz, Paul Krumviede, Fergal Ladley, Ryan Moats, Victor Muslin,
- Kenneth Peirce, John Schnizlein, Sumit Vakil, John R. Vollbrecht, and
- Jeff Weisberg.
-
- Finally, Pat Calhoun would like to thank Sun Microsystems since most
- of the effort put into this document was done while he was in their
- employ.
-
-Appendix B. S-NAPTR Example
-
- As an example, consider a client that wishes to resolve aaa:
- ex1.example.com. The client performs a NAPTR query for that domain,
- and the following NAPTR records are returned:
-
- ;; order pref flags service regexp replacement
- IN NAPTR 50 50 "s" "aaa:diameter.tls.tcp" ""
- _diameter._tls.ex1.example.com
- IN NAPTR 100 50 "s" "aaa:diameter.tcp" ""
- _aaa._tcp.ex1.example.com
- IN NAPTR 150 50 "s" "aaa:diameter.sctp" ""
- _diameter._sctp.ex1.example.com
-
- This indicates that the server supports TLS, TCP, and SCTP in that
- order. If the client supports TLS, TLS will be used, targeted to a
-
-
-
-Fajardo, et al. Standards Track [Page 148]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- host determined by an SRV lookup of _diameter._tls.ex1.example.com.
- That lookup would return:
-
- ;; Priority Weight Port Target
- IN SRV 0 1 5060 server1.ex1.example.com
- IN SRV 0 2 5060 server2.ex1.example.com
-
- As an alternative example, a client that wishes to resolve aaa:
- ex2.example.com. The client performs a NAPTR query for that domain,
- and the following NAPTR records are returned:
-
- ;; order pref flags service regexp replacement
- IN NAPTR 150 50 "a" "aaa:diameter.tls.tcp" ""
- server1.ex2.example.com
- IN NAPTR 150 50 "a" "aaa:diameter.tls.tcp" ""
- server2.ex2.example.com
-
- This indicates that the server supports TCP available at the returned
- host names.
-
-Appendix C. Duplicate Detection
-
- As described in Section 9.4, accounting record duplicate detection is
- based on session identifiers. Duplicates can appear for various
- reasons:
-
- o Failover to an alternate server. Where close to real-time
- performance is required, failover thresholds need to be kept low.
- This may lead to an increased likelihood of duplicates. Failover
- can occur at the client or within Diameter agents.
-
- o Failure of a client or agent after sending a record from non-
- volatile memory, but prior to receipt of an application-layer ACK
- and deletion of the record to be sent. This will result in
- retransmission of the record soon after the client or agent has
- rebooted.
-
- o Duplicates received from RADIUS gateways. Since the
- retransmission behavior of RADIUS is not defined within [RFC2865],
- the likelihood of duplication will vary according to the
- implementation.
-
- o Implementation problems and misconfiguration.
-
- The T flag is used as an indication of an application-layer
- retransmission event, e.g., due to failover to an alternate server.
- It is defined only for request messages sent by Diameter clients or
- agents. For instance, after a reboot, a client may not know whether
-
-
-
-Fajardo, et al. Standards Track [Page 149]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- it has already tried to send the accounting records in its non-
- volatile memory before the reboot occurred. Diameter servers MAY use
- the T flag as an aid when processing requests and detecting duplicate
- messages. However, servers that do this MUST ensure that duplicates
- are found even when the first transmitted request arrives at the
- server after the retransmitted request. It can be used only in cases
- where no answer has been received from the server for a request and
- the request is sent again, (e.g., due to a failover to an alternate
- peer, due to a recovered primary peer or due to a client re-sending a
- stored record from non-volatile memory such as after reboot of a
- client or agent).
-
- In some cases, the Diameter accounting server can delay the duplicate
- detection and accounting record processing until a post-processing
- phase takes place. At that time records are likely to be sorted
- according to the included User-Name and duplicate elimination is easy
- in this case. In other situations, it may be necessary to perform
- real-time duplicate detection, such as when credit limits are imposed
- or real-time fraud detection is desired.
-
- In general, only generation of duplicates due to failover or re-
- sending of records in non-volatile storage can be reliably detected
- by Diameter clients or agents. In such cases, the Diameter client or
- agents can mark the message as a possible duplicate by setting the T
- flag. Since the Diameter server is responsible for duplicate
- detection, it can choose whether or not to make use of the T flag, in
- order to optimize duplicate detection. Since the T flag does not
- affect interoperability, and it may not be needed by some servers,
- generation of the T flag is REQUIRED for Diameter clients and agents,
- but it MAY be implemented by Diameter servers.
-
- As an example, it can be usually be assumed that duplicates appear
- within a time window of longest recorded network partition or device
- fault, perhaps a day. So only records within this time window need
- to be looked at in the backward direction. Secondly, hashing
- techniques or other schemes, such as the use of the T flag in the
- received messages, may be used to eliminate the need to do a full
- search even in this set except for rare cases.
-
- The following is an example of how the T flag may be used by the
- server to detect duplicate requests.
-
- A Diameter server MAY check the T flag of the received message to
- determine if the record is a possible duplicate. If the T flag is
- set in the request message, the server searches for a duplicate
- within a configurable duplication time window backward and
- forward. This limits database searching to those records where
- the T flag is set. In a well-run network, network partitions and
-
-
-
-Fajardo, et al. Standards Track [Page 150]
-
-RFC 6733 Diameter Base Protocol October 2012
-
-
- device faults will presumably be rare events, so this approach
- represents a substantial optimization of the duplicate detection
- process. During failover, it is possible for the original record
- to be received after the T-flag-marked record, due to differences
- in network delays experienced along the path by the original and
- duplicate transmissions. The likelihood of this occurring
- increases as the failover interval is decreased. In order to be
- able to detect duplicates that are out of order, the Diameter
- server should use backward and forward time windows when
- performing duplicate checking for the T-flag-marked request. For
- example, in order to allow time for the original record to exit
- the network and be recorded by the accounting server, the Diameter
- server can delay processing records with the T flag set until a
- time period TIME_WAIT + RECORD_PROCESSING_TIME has elapsed after
- the closing of the original transport connection. After this time
- period, it may check the T-flag-marked records against the
- database with relative assurance that the original records, if
- sent, have been received and recorded.
-
-Appendix D. Internationalized Domain Names
-
- To be compatible with the existing DNS infrastructure and simplify
- host and domain name comparison, Diameter identities (FQDNs) are
- represented in ASCII form. This allows the Diameter protocol to fall
- in-line with the DNS strategy of being transparent from the effects
- of Internationalized Domain Names (IDNs) by following the
- recommendations in [RFC4690] and [RFC5890]. Applications that
- provide support for IDNs outside of the Diameter protocol but
- interacting with it SHOULD use the representation and conversion
- framework described in [RFC5890], [RFC5891], and [RFC3492].
-</pre>
-
-</section>
diff --git a/lib/diameter/doc/src/diameter_tcp.xml b/lib/diameter/doc/src/diameter_tcp.xml
index 1d65d14257..9f84eeb9fd 100644
--- a/lib/diameter/doc/src/diameter_tcp.xml
+++ b/lib/diameter/doc/src/diameter_tcp.xml
@@ -27,7 +27,8 @@
<erlref>
<header>
<copyright>
-<year>2011</year><year>2016</year>
+<year>2011</year>
+<year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -99,7 +100,9 @@ before configuring TLS capability on diameter transports.</p>
| {rport, integer()}
| {accept, Match}
| {port, integer()}
- | {fragment_timer, infinity | 0..16#FFFFFFFF}</v>
+ | {fragment_timer, infinity | 0..16#FFFFFFFF}
+ | {message_cb, &mod_eval;}
+ | {sender, boolean()}</v>
<v>SslOpt = {ssl_options, true | list()}</v>
<v>TcpOpt = term()</v>
<v>Match = &ip_address; | string() | [Match]</v>
@@ -140,6 +143,44 @@ such a message is received over the transport interface after
two successive timeouts without the reception of additional bytes.
Defaults to 1000.</p>
+<marker id="sender"/>
+<p>
+Option <c>sender</c> specifies whether or not to use a dedicated
+process for sending outgoing messages, which avoids the possibility of
+send blocking reception.
+Defaults to <c>false</c>.
+If set to <c>true</c> then a <c>message_cb</c> that avoids the
+possibility of messages being queued in the sender process without
+bound should be configured.</p>
+
+<p>
+Option <c>message_cb</c> specifies a callback that is invoked on
+incoming and outgoing messages, that can be used to implement
+flow control.
+It is applied to two arguments: an atom indicating the
+reason for the callback (<c>send</c>, <c>recv</c>, or <c>ack</c> after
+a completed send), and the message in question (binary() on
+<c>recv</c>, binary() or diameter_packet record on <c>send</c> or
+<c>ack</c>, or <c>false</c> on <c>ack</c> when an incoming request has
+been discarded).
+It should return a list of actions and a new callback as
+tail; eg. <c>[fun cb/3, State]</c>.
+Valid actions are the atoms <c>send</c> or <c>recv</c>, to
+cause a following message-valued action to be sent/received,
+a message to send/receive (binary() or
+diameter_packet record), or a boolean() to enable/disable reading on
+the socket.
+More than one <c>send</c>/<c>recv</c>/message sequence can be
+returned from the same callback, and an initial
+<c>send</c>/<c>recv</c> can be omitted if the same as the value passed
+as the callback's first argument.
+Reading is initially enabled, and returning <c>false</c> does not
+imply there cannot be subsequent <c>recv</c> callbacks since
+messages may already have been read.
+An empty tail is equivalent to the prevailing callback.
+Defaults to a callback equivalent to <c>fun(ack, _) -> []; (_, Msg) ->
+[Msg] end</c>.</p>
+
<p>
Remaining options are any accepted by &ssl_connect3; or
&gen_tcp_connect3; for
diff --git a/lib/diameter/doc/src/files.mk b/lib/diameter/doc/src/files.mk
index cb4f88a375..4c1297f6cc 100644
--- a/lib/diameter/doc/src/files.mk
+++ b/lib/diameter/doc/src/files.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2010-2016. All Rights Reserved.
+# Copyright Ericsson AB 2010-2017. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -40,8 +40,7 @@ XML_PART_FILES = \
user_man.xml
XML_EXTRA_FILES = \
- seealso.ent \
- diameter_soc_rfc6733.xml
+ seealso.ent
XML_CHAPTER_FILES = \
diameter_intro.xml \
diff --git a/lib/erl_docgen/src/erl_docgen.app.src b/lib/erl_docgen/src/erl_docgen.app.src
index d63d880d89..171c697585 100644
--- a/lib/erl_docgen/src/erl_docgen.app.src
+++ b/lib/erl_docgen/src/erl_docgen.app.src
@@ -9,6 +9,6 @@
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["xmerl-1.3.7","stdlib-2.5","edoc-0.7.13","erts-6.0"]}
+ {runtime_dependencies, ["xmerl-1.3.7","stdlib-3.4","edoc-0.7.13","erts-9.0"]}
]
}.
diff --git a/lib/et/src/et.app.src b/lib/et/src/et.app.src
index 7a5928d6ab..f4e32f734d 100644
--- a/lib/et/src/et.app.src
+++ b/lib/et/src/et.app.src
@@ -33,6 +33,6 @@
{registered, [et_collector]},
{applications, [stdlib, kernel]},
{env, []},
- {runtime_dependencies, ["wx-1.2","stdlib-2.0","runtime_tools-1.10",
- "kernel-3.0","erts-8.0"]}
+ {runtime_dependencies, ["wx-1.2","stdlib-3.4","runtime_tools-1.10",
+ "kernel-5.3","erts-9.0"]}
]}.
diff --git a/lib/eunit/src/eunit.app.src b/lib/eunit/src/eunit.app.src
index b4ff6c9242..cc75a0f790 100644
--- a/lib/eunit/src/eunit.app.src
+++ b/lib/eunit/src/eunit.app.src
@@ -19,4 +19,4 @@
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["stdlib-2.5","kernel-3.0","erts-6.0"]}]}.
+ {runtime_dependencies, ["stdlib-3.4","kernel-5.3","erts-9.0"]}]}.
diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src
index 3c3a1004f1..5b2280594f 100644
--- a/lib/hipe/main/hipe.app.src
+++ b/lib/hipe/main/hipe.app.src
@@ -235,5 +235,5 @@
{registered,[]},
{applications, [kernel,stdlib]},
{env, []},
- {runtime_dependencies, ["syntax_tools-1.6.14","stdlib-2.5","kernel-3.0",
+ {runtime_dependencies, ["syntax_tools-1.6.14","stdlib-3.4","kernel-5.3",
"erts-9.0","compiler-5.0"]}]}.
diff --git a/lib/kernel/src/erts_debug.erl b/lib/kernel/src/erts_debug.erl
index 480db6814e..2887014c1c 100644
--- a/lib/kernel/src/erts_debug.erl
+++ b/lib/kernel/src/erts_debug.erl
@@ -378,16 +378,11 @@ df(Mod, Func, Arity) when is_atom(Mod), is_atom(Func) ->
catch _:_ -> {undef,Mod}
end.
-dff(File, Fs) when is_pid(File), is_list(Fs) ->
- lists:foreach(fun(Mfa) ->
- disassemble_function(File, Mfa),
- io:nl(File)
- end, Fs);
-dff(Name, Fs) when is_list(Name) ->
- case file:open(Name, [write]) of
+dff(Name, Fs) ->
+ case file:open(Name, [write,raw,delayed_write]) of
{ok,F} ->
try
- dff(F, Fs)
+ dff_1(F, Fs)
after
_ = file:close(F)
end;
@@ -395,12 +390,18 @@ dff(Name, Fs) when is_list(Name) ->
{error,{badopen,Reason}}
end.
+dff_1(File, Fs) ->
+ lists:foreach(fun(Mfa) ->
+ disassemble_function(File, Mfa),
+ file:write(File, "\n")
+ end, Fs).
+
disassemble_function(File, {_,_,_}=MFA) ->
cont_dis(File, erts_debug:disassemble(MFA), MFA).
cont_dis(_, false, _) -> ok;
cont_dis(File, {Addr,Str,MFA}, MFA) ->
- io:put_chars(File, binary_to_list(Str)),
+ ok = file:write(File, Str),
cont_dis(File, erts_debug:disassemble(Addr), MFA);
cont_dis(_, {_,_,_}, _) -> ok.
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 90e49ddfdf..49aa5f8bda 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.erl
@@ -859,15 +859,17 @@ query_ns(S0, Id, Buffer, IP, Port, Timer, Retry, I,
{ok,S} ->
Timeout =
inet:timeout( (Tm * (1 bsl I)) div Retry, Timer),
- {S,
case query_udp(
S, Id, Buffer, IP, Port, Timeout, Verbose) of
{ok,#dns_rec{header=H}} when H#dns_header.tc ->
TcpTimeout = inet:timeout(Tm*5, Timer),
- query_tcp(
- TcpTimeout, Id, Buffer, IP, Port, Verbose);
- Reply -> Reply
- end};
+ {S, query_tcp(
+ TcpTimeout, Id, Buffer, IP, Port, Verbose)};
+ {error, econnrefused} = Err ->
+ ok = udp_close(S),
+ {#sock{}, Err};
+ Reply -> {S, Reply}
+ end;
Error ->
{S0,Error}
end
diff --git a/lib/kernel/src/kernel.app.src b/lib/kernel/src/kernel.app.src
index 2a11b04310..2a88cc7e26 100644
--- a/lib/kernel/src/kernel.app.src
+++ b/lib/kernel/src/kernel.app.src
@@ -120,6 +120,6 @@
{applications, []},
{env, [{error_logger, tty}]},
{mod, {kernel, []}},
- {runtime_dependencies, ["erts-9.1", "stdlib-3.0", "sasl-3.0"]}
+ {runtime_dependencies, ["erts-9.1", "stdlib-3.4", "sasl-3.0"]}
]
}.
diff --git a/lib/mnesia/src/mnesia.app.src b/lib/mnesia/src/mnesia.app.src
index 6b49fc6c88..c755b4d4b9 100644
--- a/lib/mnesia/src/mnesia.app.src
+++ b/lib/mnesia/src/mnesia.app.src
@@ -49,4 +49,4 @@
]},
{applications, [kernel, stdlib]},
{mod, {mnesia_app, []}},
- {runtime_dependencies, ["stdlib-2.0","kernel-3.0","erts-7.0"]}]}.
+ {runtime_dependencies, ["stdlib-3.4","kernel-5.3","erts-9.0"]}]}.
diff --git a/lib/observer/priv/bin/cdv b/lib/observer/priv/bin/cdv
index d14fd47e41..2a509c16af 100755
--- a/lib/observer/priv/bin/cdv
+++ b/lib/observer/priv/bin/cdv
@@ -1,4 +1,4 @@
#!/bin/sh
-erl -noinput -s crashdump_viewer script_start $@
+erl -env ERL_CRASH_DUMP_SECONDS 0 -noinput -s crashdump_viewer script_start $@
diff --git a/lib/observer/priv/bin/cdv.bat b/lib/observer/priv/bin/cdv.bat
index 18136a30d6..fa87c08adf 100644
--- a/lib/observer/priv/bin/cdv.bat
+++ b/lib/observer/priv/bin/cdv.bat
@@ -1,2 +1,2 @@
@ECHO OFF
-CALL werl -s crashdump_viewer script_start %*
+CALL werl -env ERL_CRASH_DUMP_SECONDS 0 -s crashdump_viewer script_start %*
diff --git a/lib/observer/src/cdv_detail_wx.erl b/lib/observer/src/cdv_detail_wx.erl
index 4c26e447a6..f6d282638a 100644
--- a/lib/observer/src/cdv_detail_wx.erl
+++ b/lib/observer/src/cdv_detail_wx.erl
@@ -20,7 +20,7 @@
-behaviour(wx_object).
--export([start_link/4]).
+-export([start_link/5]).
-export([init/1, handle_event/2, handle_cast/2, terminate/2, code_change/3,
handle_call/3, handle_info/2]).
@@ -39,27 +39,42 @@
-define(ID_NOTEBOOK, 604).
%% Detail view
-start_link(Id, Data, ParentFrame, Callback) ->
- wx_object:start_link(?MODULE, [Id, Data, ParentFrame, Callback, self()], []).
+start_link(Id, Data, ParentFrame, Callback, App) ->
+ wx_object:start_link(?MODULE,[Id,Data,ParentFrame,Callback,App,self()],[]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-init([Id, Data, ParentFrame, Callback, Parent]) ->
+init([Id, Data, ParentFrame, Callback, App, Parent]) ->
+ display_progress(ParentFrame,App),
case Callback:get_details(Id, Data) of
{ok,Details} ->
- init(Id,ParentFrame,Callback,Parent,Details);
+ init(Id,ParentFrame,Callback,App,Parent,Details);
{yes_no, Info, Fun} ->
+ destroy_progress(App),
case observer_lib:display_yes_no_dialog(Info) of
?wxID_YES -> Fun();
?wxID_NO -> ok
end,
{stop,normal};
{info,Info} ->
+ destroy_progress(App),
observer_lib:display_info_dialog(ParentFrame,Info),
{stop,normal}
end.
-init(Id,ParentFrame,Callback,Parent,{Title,Info,TW}) ->
+%% Display progress bar only if the calling app is crashdump_viewer
+display_progress(ParentFrame,cdv) ->
+ observer_lib:display_progress_dialog(ParentFrame,
+ "Crashdump Viewer",
+ "Reading data");
+display_progress(_,_) ->
+ ok.
+destroy_progress(cdv) ->
+ observer_lib:destroy_progress_dialog();
+destroy_progress(_) ->
+ ok.
+
+init(Id,ParentFrame,Callback,App,Parent,{Title,Info,TW}) ->
Frame=wxFrame:new(ParentFrame, ?wxID_ANY, [Title],
[{style, ?wxDEFAULT_FRAME_STYLE}, {size, {850,600}}]),
MenuBar = wxMenuBar:new(),
@@ -88,6 +103,7 @@ init(Id,ParentFrame,Callback,Parent,{Title,Info,TW}) ->
wxFrame:connect(Frame, close_window),
wxMenu:connect(Frame, command_menu_selected),
wxFrame:show(Frame),
+ destroy_progress(App),
{Frame, #state{parent=Parent,
id=Id,
frame=Frame,
diff --git a/lib/observer/src/cdv_html_wx.erl b/lib/observer/src/cdv_html_wx.erl
index 5158e95a65..4b43b6a840 100644
--- a/lib/observer/src/cdv_html_wx.erl
+++ b/lib/observer/src/cdv_html_wx.erl
@@ -52,8 +52,12 @@ init([ParentWin, HtmlText]) ->
init(ParentWin, HtmlText, undefined, cdv).
init(ParentWin, HtmlText, Tab, App) ->
+ %% If progress dialog is shown, remove it now - and sett cursor busy instead
+ observer_lib:destroy_progress_dialog(),
+ wx_misc:beginBusyCursor(),
HtmlWin = observer_lib:html_window(ParentWin),
wxHtmlWindow:setPage(HtmlWin,HtmlText),
+ wx_misc:endBusyCursor(),
{HtmlWin, #state{panel=HtmlWin,expand_table=Tab,app=App}}.
%%%%%%%%%%%%%%%%%%%%%%% Callbacks %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -123,11 +127,12 @@ handle_event(Event, State) ->
%%%-----------------------------------------------------------------
%%% Internal
-expand(Id,Callback,#state{expand_wins=Opened0}=State) ->
+expand(Id,Callback,#state{expand_wins=Opened0, app=App}=State) ->
Opened =
case lists:keyfind(Id,1,Opened0) of
false ->
- EW = cdv_detail_wx:start_link(Id,[],State#state.panel,Callback),
+ EW = cdv_detail_wx:start_link(Id,[],State#state.panel,
+ Callback,App),
wx_object:get_pid(EW) ! active,
[{Id,EW}|Opened0];
{_,EW} ->
diff --git a/lib/observer/src/cdv_term_cb.erl b/lib/observer/src/cdv_term_cb.erl
index f206d7e4c9..bdcb13f22d 100644
--- a/lib/observer/src/cdv_term_cb.erl
+++ b/lib/observer/src/cdv_term_cb.erl
@@ -30,23 +30,31 @@ detail_pages() ->
[{"Term", fun init_term_page/2}].
init_term_page(ParentWin, {Type, [Term, Tab]}) ->
+ observer_lib:report_progress({ok,"Expanding term"}),
+ observer_lib:report_progress({ok,start_pulse}),
Expanded = expand(Term, true),
BinSaved = expand(Term, Tab),
+ observer_lib:report_progress({ok,stop_pulse}),
cdv_multi_wx:start_link(
ParentWin,
[{"Format \~p",cdv_html_wx,{Type, format_term_fun("~p",BinSaved,Tab)}},
{"Format \~tp",cdv_html_wx,{Type,format_term_fun("~tp",BinSaved,Tab)}},
{"Format \~w",cdv_html_wx,{Type,format_term_fun("~w",BinSaved,Tab)}},
+ {"Format \~tw",cdv_html_wx,{Type,format_term_fun("~tw",BinSaved,Tab)}},
{"Format \~s",cdv_html_wx,{Type,format_term_fun("~s",Expanded,Tab)}},
{"Format \~ts",cdv_html_wx,{Type,format_term_fun("~ts",Expanded,Tab)}}]).
format_term_fun(Format,Term,Tab) ->
fun() ->
+ observer_lib:report_progress({ok,"Formatting term"}),
+ observer_lib:report_progress({ok,start_pulse}),
try io_lib:format(Format,[Term]) of
Str -> {expand, plain_html(Str), Tab}
catch error:badarg ->
Warning = "This term can not be formatted with " ++ Format,
observer_html_lib:warning(Warning)
+ after
+ observer_lib:report_progress({ok,stop_pulse})
end
end.
diff --git a/lib/observer/src/cdv_virtual_list_wx.erl b/lib/observer/src/cdv_virtual_list_wx.erl
index f3daae8e4d..33c0c880b1 100644
--- a/lib/observer/src/cdv_virtual_list_wx.erl
+++ b/lib/observer/src/cdv_virtual_list_wx.erl
@@ -174,7 +174,7 @@ do_start_detail_win(Id, #state{panel=Panel,detail_wins=Opened,
case lists:keyfind(Id, 1, Opened) of
false ->
Data = call(Holder, {get_data, self(), Id}),
- case cdv_detail_wx:start_link(Id, Data, Panel, Callback) of
+ case cdv_detail_wx:start_link(Id, Data, Panel, Callback, cdv) of
{error, _} -> Opened;
IW -> [{Id, IW} | Opened]
end;
diff --git a/lib/observer/src/cdv_wx.erl b/lib/observer/src/cdv_wx.erl
index 8cc135d174..0e33c9e618 100644
--- a/lib/observer/src/cdv_wx.erl
+++ b/lib/observer/src/cdv_wx.erl
@@ -413,7 +413,16 @@ load_dump(Frame,undefined) ->
error
end;
load_dump(Frame,FileName) ->
- ok = observer_lib:display_progress_dialog("Crashdump Viewer",
+ case maybe_warn_filename(FileName) of
+ continue ->
+ do_load_dump(Frame,FileName);
+ stop ->
+ error
+ end.
+
+do_load_dump(Frame,FileName) ->
+ ok = observer_lib:display_progress_dialog(wx:null(),
+ "Crashdump Viewer",
"Loading crashdump"),
crashdump_viewer:read_file(FileName),
case observer_lib:wait_for_progress() of
@@ -433,6 +442,33 @@ load_dump(Frame,FileName) ->
error
end.
+maybe_warn_filename(FileName) ->
+ case os:getenv("ERL_CRASH_DUMP_SECONDS")=="0" orelse
+ os:getenv("ERL_CRASH_DUMP_BYTES")=="0" of
+ true ->
+ continue;
+ false ->
+ DumpName = case os:getenv("ERL_CRASH_DUMP") of
+ false -> filename:absname("erl_crash.dump");
+ Name -> filename:absname(Name)
+ end,
+ case filename:absname(FileName) of
+ DumpName ->
+ Warning =
+ "WARNING: the current crashdump might be overwritten "
+ "if the crashdump_viewer node crashes.\n\n"
+ "Renaming the file before inspecting it will "
+ "remove the problem.\n\n"
+ "Do you want to continue?",
+ case observer_lib:display_yes_no_dialog(Warning) of
+ ?wxID_YES -> continue;
+ ?wxID_NO -> stop
+ end;
+ _ ->
+ continue
+ end
+ end.
+
%%%-----------------------------------------------------------------
%%% Find help document (HTML files)
get_help_doc(HelpId) ->
diff --git a/lib/observer/src/crashdump_viewer.erl b/lib/observer/src/crashdump_viewer.erl
index 31258cdf20..51ff69fd69 100644
--- a/lib/observer/src/crashdump_viewer.erl
+++ b/lib/observer/src/crashdump_viewer.erl
@@ -36,7 +36,6 @@
%% file: The name of the crashdump currently viewed.
%% dump_vsn: The version number of the crashdump
%% wordsize: 4 | 8, the number of bytes in a word.
-%% binaries: a gb_tree containing binaries or links to binaries in the dump
%%
%% User API
@@ -87,6 +86,7 @@
-define(max_line_size,100). % max number of bytes (i.e. characters) the
% line_head/1 function can return
-define(not_available,"N/A").
+-define(binary_size_progress_limit,10000).
%% All possible tags - use macros in order to avoid misspelling in the code
@@ -106,6 +106,8 @@
-define(internal_ets,internal_ets).
-define(loaded_modules,loaded_modules).
-define(memory,memory).
+-define(memory_map,memory_map).
+-define(memory_status,memory_status).
-define(mod,mod).
-define(no_distribution,no_distribution).
-define(node,node).
@@ -122,7 +124,7 @@
-define(visible_node,visible_node).
--record(state,{file,dump_vsn,wordsize=4,num_atoms="unknown",binaries}).
+-record(state,{file,dump_vsn,wordsize=4,num_atoms="unknown"}).
%%%-----------------------------------------------------------------
%%% Debugging
@@ -203,7 +205,8 @@ do_script_start(StartFun) ->
io:format("\ncdv crash: ~tp\n",[Reason])
end;
_ ->
- io:format("\ncdv crash: ~p\n",[unknown_reason])
+ %io:format("\ncdv crash: ~p\n",[unknown_reason])
+ ok
end;
Error ->
io:format("\ncdv start failed: ~tp\n",[Error])
@@ -305,6 +308,8 @@ expand_binary(Pos) ->
init([]) ->
ets:new(cdv_dump_index_table,[ordered_set,named_table,public]),
ets:new(cdv_reg_proc_table,[ordered_set,named_table,public]),
+ ets:new(cdv_binary_index_table,[ordered_set,named_table,public]),
+ ets:new(cdv_heap_file_chars,[ordered_set,named_table,public]),
{ok, #state{}}.
%%--------------------------------------------------------------------
@@ -348,9 +353,9 @@ handle_call(procs_summary,_From,State=#state{file=File,wordsize=WS}) ->
Procs = procs_summary(File,WS),
{reply,{ok,Procs,TW},State};
handle_call({proc_details,Pid},_From,
- State=#state{file=File,wordsize=WS,dump_vsn=DumpVsn,binaries=B})->
+ State=#state{file=File,wordsize=WS,dump_vsn=DumpVsn})->
Reply =
- case get_proc_details(File,Pid,WS,DumpVsn,B) of
+ case get_proc_details(File,Pid,WS,DumpVsn) of
{ok,Proc,TW} ->
{ok,Proc,TW};
Other ->
@@ -462,9 +467,9 @@ handle_call(schedulers,_From,State=#state{file=File}) ->
%%--------------------------------------------------------------------
handle_cast({read_file,File}, _State) ->
case do_read_file(File) of
- {ok,Binaries,DumpVsn} ->
+ {ok,DumpVsn} ->
observer_lib:report_progress({ok,done}),
- {noreply, #state{file=File,binaries=Binaries,dump_vsn=DumpVsn}};
+ {noreply, #state{file=File,dump_vsn=DumpVsn}};
Error ->
end_progress(Error),
{noreply, #state{}}
@@ -746,32 +751,6 @@ get_rest_of_line_1(Fd, <<>>, Acc) ->
eof -> {eof,lists:reverse(Acc)}
end.
-get_lines_to_empty(Fd) ->
- case get_chunk(Fd) of
- {ok,Bin} ->
- get_lines_to_empty(Fd,Bin,[],[]);
- eof ->
- []
- end.
-get_lines_to_empty(Fd,<<$\n:8,Bin/binary>>,[],Lines) ->
- put_chunk(Fd,Bin),
- lists:reverse(Lines);
-get_lines_to_empty(Fd,<<$\n:8,Bin/binary>>,Acc,Lines) ->
- get_lines_to_empty(Fd,Bin,[],[byte_list_to_string(lists:reverse(Acc))|Lines]);
-get_lines_to_empty(Fd,<<$\r:8,Bin/binary>>,Acc,Lines) ->
- get_lines_to_empty(Fd,Bin,Acc,Lines);
-get_lines_to_empty(Fd,<<$\s:8,Bin/binary>>,[],Lines) ->
- get_lines_to_empty(Fd,Bin,[],Lines);
-get_lines_to_empty(Fd,<<Char:8,Bin/binary>>,Acc,Lines) ->
- get_lines_to_empty(Fd,Bin,[Char|Acc],Lines);
-get_lines_to_empty(Fd,<<>>,Acc,Lines) ->
- case get_chunk(Fd) of
- {ok,Bin} ->
- get_lines_to_empty(Fd,Bin,Acc,Lines);
- eof ->
- lists:reverse(Lines,[byte_list_to_string(lists:reverse(Acc))])
- end.
-
split(Str) ->
split($ ,Str,[]).
split(Char,Str) ->
@@ -817,18 +796,17 @@ do_read_file(File) ->
{Tag,Id,Rest,N1} = tag(Fd,TagAndRest,1),
case Tag of
?erl_crash_dump ->
- reset_index_table(),
+ reset_tables(),
insert_index(Tag,Id,N1+1),
put_last_tag(Tag,""),
- indexify(Fd,Rest,N1),
+ DumpVsn = [list_to_integer(L) ||
+ L<-string:lexemes(Id,".")],
+ AddrAdj = get_bin_addr_adj(DumpVsn),
+ indexify(Fd,AddrAdj,Rest,N1),
end_progress(),
check_if_truncated(),
- [{DumpVsn0,_}] = lookup_index(?erl_crash_dump),
- DumpVsn = [list_to_integer(L) ||
- L<-string:lexemes(DumpVsn0,".")],
- Binaries = read_binaries(Fd,DumpVsn),
close(Fd),
- {ok,Binaries,DumpVsn};
+ {ok,DumpVsn};
_Other ->
R = io_lib:format(
"~ts is not an Erlang crash dump~n",
@@ -856,15 +834,31 @@ do_read_file(File) ->
{error,R}
end.
-indexify(Fd,Bin,N) ->
+indexify(Fd,AddrAdj,Bin,N) ->
case binary:match(Bin,<<"\n=">>) of
{Start,Len} ->
Pos = Start+Len,
<<_:Pos/binary,TagAndRest/binary>> = Bin,
{Tag,Id,Rest,N1} = tag(Fd,TagAndRest,N+Pos),
- insert_index(Tag,Id,N1+1), % +1 to get past newline
- put_last_tag(Tag,Id),
- indexify(Fd,Rest,N1);
+ NewPos = N1+1, % +1 to get past newline
+ case Tag of
+ ?binary ->
+ %% Binaries are stored in a separate table in
+ %% order to minimize lookup time. Key is the
+ %% translated address.
+ {HexAddr,_} = get_hex(Id),
+ Addr = HexAddr bor AddrAdj,
+ insert_binary_index(Addr,NewPos);
+ _ ->
+ insert_index(Tag,Id,NewPos)
+ end,
+ case put_last_tag(Tag,Id) of
+ {?proc_heap,LastId} ->
+ [{_,LastPos}] = lookup_index(?proc_heap,LastId),
+ ets:insert(cdv_heap_file_chars,{LastId,N+Start+1-LastPos});
+ _ -> ok
+ end,
+ indexify(Fd,AddrAdj,Rest,N1);
nomatch ->
case progress_read(Fd) of
{ok,Chunk0} when is_binary(Chunk0) ->
@@ -875,7 +869,7 @@ indexify(Fd,Bin,N) ->
_ ->
{Chunk0,N+byte_size(Bin)}
end,
- indexify(Fd,Chunk,N1);
+ indexify(Fd,AddrAdj,Chunk,N1);
eof ->
eof
end
@@ -911,7 +905,11 @@ check_if_truncated() ->
find_truncated_proc(TruncatedTag)
end.
-find_truncated_proc({?atoms,_Id}) ->
+find_truncated_proc({Tag,_Id}) when Tag==?atoms;
+ Tag==?binary;
+ Tag==?instr_data;
+ Tag==?memory_status;
+ Tag==?memory_map ->
put(truncated_proc,false);
find_truncated_proc({Tag,Pid}) ->
case is_proc_tag(Tag) of
@@ -1060,14 +1058,14 @@ procs_summary(File,WS) ->
%%-----------------------------------------------------------------
%% Page with one process
-get_proc_details(File,Pid,WS,DumpVsn,Binaries) ->
+get_proc_details(File,Pid,WS,DumpVsn) ->
case lookup_index(?proc,Pid) of
[{_,Start}] ->
Fd = open(File),
{{Stack,MsgQ,Dict},TW} =
case truncated_warning([{?proc,Pid}]) of
[] ->
- {expand_memory(Fd,Pid,DumpVsn,Binaries),[]};
+ {expand_memory(Fd,Pid,DumpVsn),[]};
TW0 ->
{{[],[],[]},TW0}
end,
@@ -1176,7 +1174,7 @@ all_procinfo(Fd,Fun,Proc,WS,LineHead) ->
get_procinfo(Fd,Fun,Proc#proc{old_heap_end=bytes(Fd)},WS);
%% - END - moved from get_procinfo -
"Last calls" ->
- get_procinfo(Fd,Fun,Proc#proc{last_calls=get_lines_to_empty(Fd)},WS);
+ get_procinfo(Fd,Fun,Proc#proc{last_calls=get_last_calls(Fd)},WS);
"Link list" ->
{Links,Monitors,MonitoredBy} = parse_link_list(bytes(Fd),[],[],[]),
get_procinfo(Fd,Fun,Proc#proc{links=Links,
@@ -1200,6 +1198,66 @@ all_procinfo(Fd,Fun,Proc,WS,LineHead) ->
get_procinfo(Fd,Fun,Proc,WS)
end.
+%% The end of the 'Last calls' section is meant to be an empty line,
+%% but in some cases this is not the case, so we also need to look for
+%% the next heading which currently (OTP-20.1) can be "Link list: ",
+%% "Dictionary: " or "Reductions: ". We do this by looking for ": "
+%% and when found, pushing the heading back into the saved chunk.
+%%
+%% Note that the 'Last calls' section is only present if the
+%% 'save_calls' process flag is set.
+get_last_calls(Fd) ->
+ case get_chunk(Fd) of
+ {ok,Bin} ->
+ get_last_calls(Fd,Bin,[],[]);
+ eof ->
+ []
+ end.
+get_last_calls(Fd,<<$\n:8,Bin/binary>>,[],Lines) ->
+ %% Empty line - we're done
+ put_chunk(Fd,Bin),
+ lists:reverse(Lines);
+get_last_calls(Fd,<<$::8>>,Acc,Lines) ->
+ case get_chunk(Fd) of
+ {ok,Bin} ->
+ %% Could be a colon followed by a space - see next function clause
+ get_last_calls(Fd,<<$::8,Bin/binary>>,Acc,Lines);
+ eof ->
+ %% Truncated here - either we've got the next heading, or
+ %% it was truncated in a last call function, in which case
+ %% we note that it was truncated
+ case byte_list_to_string(lists:reverse(Acc)) of
+ NextHeading when NextHeading=="Link list";
+ NextHeading=="Dictionary";
+ NextHeading=="Reductions" ->
+ put_chunk(Fd,list_to_binary(NextHeading++":")),
+ lists:reverse(Lines);
+ LastCallFunction->
+ lists:reverse(Lines,[LastCallFunction++":...(truncated)"])
+ end
+ end;
+get_last_calls(Fd,<<$\::8,$\s:8,Bin/binary>>,Acc,Lines) ->
+ %% ": " - means we have the next heading in Acc - save it back
+ %% into the chunk and return the lines we've found
+ HeadingBin = list_to_binary(lists:reverse(Acc,[$:])),
+ put_chunk(Fd,<<HeadingBin/binary,Bin/binary>>),
+ lists:reverse(Lines);
+get_last_calls(Fd,<<$\n:8,Bin/binary>>,Acc,Lines) ->
+ get_last_calls(Fd,Bin,[],[byte_list_to_string(lists:reverse(Acc))|Lines]);
+get_last_calls(Fd,<<$\r:8,Bin/binary>>,Acc,Lines) ->
+ get_last_calls(Fd,Bin,Acc,Lines);
+get_last_calls(Fd,<<$\s:8,Bin/binary>>,[],Lines) ->
+ get_last_calls(Fd,Bin,[],Lines);
+get_last_calls(Fd,<<Char:8,Bin/binary>>,Acc,Lines) ->
+ get_last_calls(Fd,Bin,[Char|Acc],Lines);
+get_last_calls(Fd,<<>>,Acc,Lines) ->
+ case get_chunk(Fd) of
+ {ok,Bin} ->
+ get_last_calls(Fd,Bin,Acc,Lines);
+ eof ->
+ lists:reverse(Lines,[byte_list_to_string(lists:reverse(Acc))])
+ end.
+
parse_link_list([SB|Str],Links,Monitors,MonitoredBy) when SB==$[; SB==$] ->
parse_link_list(Str,Links,Monitors,MonitoredBy);
parse_link_list("#Port"++_=Str,Links,Monitors,MonitoredBy) ->
@@ -1325,10 +1383,10 @@ maybe_other_node2(Channel) ->
end.
-expand_memory(Fd,Pid,DumpVsn,Binaries) ->
+expand_memory(Fd,Pid,DumpVsn) ->
BinAddrAdj = get_bin_addr_adj(DumpVsn),
put(fd,Fd),
- Dict = read_heap(Fd,Pid,BinAddrAdj,Binaries),
+ Dict = read_heap(Fd,Pid,BinAddrAdj,gb_trees:empty()),
Expanded = {read_stack_dump(Fd,Pid,BinAddrAdj,Dict),
read_messages(Fd,Pid,BinAddrAdj,Dict),
read_dictionary(Fd,Pid,BinAddrAdj,Dict)},
@@ -1346,25 +1404,6 @@ get_bin_addr_adj(_) ->
0.
%%%
-%%% Read binaries.
-%%%
-read_binaries(Fd,DumpVsn) ->
- AllBinaries = lookup_index(?binary),
- AddrAdj = get_bin_addr_adj(DumpVsn),
- Fun = fun({Addr0,Pos},Dict0) ->
- pos_bof(Fd,Pos),
- {HexAddr,_} = get_hex(Addr0),
- Addr = HexAddr bor AddrAdj,
- Bin =
- case line_head(Fd) of
- {eof,_} -> '#CDVTruncatedBinary';
- _Size -> {'#CDVBin',Pos}
- end,
- gb_trees:enter(Addr,Bin,Dict0)
- end,
- progress_foldl("Processing binaries",Fun,gb_trees:empty(),AllBinaries).
-
-%%%
%%% Read top level section.
%%%
@@ -1454,6 +1493,8 @@ parse_dictionary(Line0, BinAddrAdj, D) ->
read_heap(Fd,Pid,BinAddrAdj,Dict0) ->
case lookup_index(?proc_heap,Pid) of
[{_,Pos}] ->
+ [{_,Chars}] = ets:lookup(cdv_heap_file_chars,Pid),
+ init_progress("Reading process heap",Chars),
pos_bof(Fd,Pos),
read_heap(BinAddrAdj,Dict0);
[] ->
@@ -1464,13 +1505,16 @@ read_heap(BinAddrAdj,Dict0) ->
%% This function is never called if the dump is truncated in {?proc_heap,Pid}
case get(fd) of
end_of_heap ->
+ end_progress(),
Dict0;
Fd ->
case bytes(Fd) of
"=" ++ _next_tag ->
+ end_progress(),
put(fd, end_of_heap),
Dict0;
Line ->
+ update_progress(length(Line)+1),
Dict = parse(Line,BinAddrAdj,Dict0),
read_heap(BinAddrAdj,Dict)
end
@@ -2526,9 +2570,9 @@ parse_heap_term("Yc"++Line0, Addr, BinAddrAdj, D0) -> %Reference-counted binary.
{Offset,":"++Line2} = get_hex(Line1),
{Sz,Line} = get_hex(Line2),
Binp = Binp0 bor BinAddrAdj,
- Term = case gb_trees:lookup(Binp, D0) of
- {value,Bin} -> cdvbin(Offset,Sz,Bin);
- none -> '#CDVNonexistingBinary'
+ Term = case lookup_binary_index(Binp) of
+ [{_,Start}] -> cdvbin(Offset,Sz,{'#CDVBin',Start});
+ [] -> '#CDVNonexistingBinary'
end,
D = gb_trees:insert(Addr, Term, D0),
{Term,Line,D};
@@ -2537,15 +2581,14 @@ parse_heap_term("Ys"++Line0, Addr, BinAddrAdj, D0) -> %Sub binary.
{Offset,":"++Line2} = get_hex(Line1),
{Sz,Line} = get_hex(Line2),
Binp = Binp0 bor BinAddrAdj,
- Term = case gb_trees:lookup(Binp, D0) of
- {value,Bin} -> cdvbin(Offset,Sz,Bin);
- none when Binp0=/=Binp ->
+ Term = case lookup_binary_index(Binp) of
+ [{_,Start}] -> cdvbin(Offset,Sz,{'#CDVBin',Start});
+ [] ->
%% Might it be on the heap?
- case gb_trees:lookup(Binp0, D0) of
+ case gb_trees:lookup(Binp, D0) of
{value,Bin} -> cdvbin(Offset,Sz,Bin);
none -> '#CDVNonexistingBinary'
- end;
- none -> '#CDVNonexistingBinary'
+ end
end,
D = gb_trees:insert(Addr, Term, D0),
{Term,Line,D}.
@@ -2636,6 +2679,7 @@ deref_ptr(Ptr, Line, BinAddrAdj, D0) ->
put(fd, end_of_heap),
deref_ptr(Ptr, Line, BinAddrAdj, D0);
L ->
+ update_progress(length(L)+1),
D = parse(L, BinAddrAdj, D0),
deref_ptr(Ptr, Line, BinAddrAdj, D)
end
@@ -2701,19 +2745,33 @@ get_label([H|T], Acc) ->
get_label(T, [H|Acc]).
get_binary(Line0) ->
- {N,":"++Line} = get_hex(Line0),
- do_get_binary(N, Line, []).
+ case get_hex(Line0) of
+ {N,":"++Line} ->
+ do_get_binary(N, Line, [], false);
+ _ ->
+ {'#CDVTruncatedBinary',[]}
+ end.
get_binary(Offset,Size,Line0) ->
- {_N,":"++Line} = get_hex(Line0),
- do_get_binary(Size, lists:sublist(Line,(Offset*2)+1,Size*2), []).
-
-do_get_binary(0, Line, Acc) ->
+ case get_hex(Line0) of
+ {_N,":"++Line} ->
+ Progress = Size>?binary_size_progress_limit,
+ Progress andalso init_progress("Reading binary",Size),
+ do_get_binary(Size, lists:sublist(Line,(Offset*2)+1,Size*2), [],
+ Progress);
+ _ ->
+ {'#CDVTruncatedBinary',[]}
+ end.
+
+do_get_binary(0, Line, Acc, Progress) ->
+ Progress andalso end_progress(),
{list_to_binary(lists:reverse(Acc)),Line};
-do_get_binary(N, [A,B|Line], Acc) ->
+do_get_binary(N, [A,B|Line], Acc, Progress) ->
Byte = (get_hex_digit(A) bsl 4) bor get_hex_digit(B),
- do_get_binary(N-1, Line, [Byte|Acc]);
-do_get_binary(_N, [], _Acc) ->
+ Progress andalso update_progress(),
+ do_get_binary(N-1, Line, [Byte|Acc], Progress);
+do_get_binary(_N, [], _Acc, Progress) ->
+ Progress andalso end_progress(),
{'#CDVTruncatedBinary',[]}.
cdvbin(Offset,Size,{'#CDVBin',Pos}) ->
@@ -2721,12 +2779,17 @@ cdvbin(Offset,Size,{'#CDVBin',Pos}) ->
cdvbin(Offset,Size,['#CDVBin',_,_,Pos]) ->
['#CDVBin',Offset,Size,Pos];
cdvbin(_,_,'#CDVTruncatedBinary') ->
- '#CDVTruncatedBinary'.
+ '#CDVTruncatedBinary';
+cdvbin(_,_,'#CDVNonexistingBinary') ->
+ '#CDVNonexistingBinary'.
%%-----------------------------------------------------------------
-%% Functions for accessing the cdv_dump_index_table
-reset_index_table() ->
- ets:delete_all_objects(cdv_dump_index_table).
+%% Functions for accessing tables
+reset_tables() ->
+ ets:delete_all_objects(cdv_dump_index_table),
+ ets:delete_all_objects(cdv_reg_proc_table),
+ ets:delete_all_objects(cdv_binary_index_table),
+ ets:delete_all_objects(cdv_heap_file_chars).
insert_index(Tag,Id,Pos) ->
ets:insert(cdv_dump_index_table,{{Tag,Pos},Id}).
@@ -2741,6 +2804,11 @@ lookup_index(Tag,Id) ->
count_index(Tag) ->
ets:select_count(cdv_dump_index_table,[{{{Tag,'_'},'_'},[],[true]}]).
+insert_binary_index(Addr,Pos) ->
+ ets:insert(cdv_binary_index_table,{Addr,Pos}).
+
+lookup_binary_index(Addr) ->
+ ets:lookup(cdv_binary_index_table,Addr).
%%-----------------------------------------------------------------
%% Convert tags read from crashdump to atoms used as first part of key
@@ -2811,23 +2879,6 @@ to_value_list(Record) ->
Values.
%%%-----------------------------------------------------------------
-%%% Fold over List and report progress in percent.
-%%% Report is the text to be presented in the progress dialog.
-%%% Acc0 is the initial accumulator and will be passed to Fun as the
-%%% second arguement, i.e. Fun = fun(Item,Acc) -> NewAcc end.
-progress_foldl(Report,Fun,Acc0,List) ->
- init_progress(Report, length(List)),
- progress_foldl1(Fun,Acc0,List).
-
-progress_foldl1(Fun,Acc,[H|T]) ->
- update_progress(),
- progress_foldl1(Fun,Fun(H,Acc),T);
-progress_foldl1(_Fun,Acc,[]) ->
- end_progress(),
- Acc.
-
-
-%%%-----------------------------------------------------------------
%%% Map over List and report progress in percent.
%%% Report is the text to be presented in the progress dialog.
%%% Distribute the load over a number of processes, and File is opened
diff --git a/lib/observer/src/observer.app.src b/lib/observer/src/observer.app.src
index 3a5bd172e7..f682e3dc7b 100644
--- a/lib/observer/src/observer.app.src
+++ b/lib/observer/src/observer.app.src
@@ -65,7 +65,7 @@
{registered, []},
{applications, [kernel, stdlib]},
{env, []},
- {runtime_dependencies, ["wx-1.2","stdlib-2.0","runtime_tools-1.8.14",
+ {runtime_dependencies, ["wx-1.2","stdlib-3.4","runtime_tools-1.8.14",
"kernel-3.0","inets-5.10","et-1.5",
"erts-7.0"]}]}.
diff --git a/lib/observer/src/observer_html_lib.erl b/lib/observer/src/observer_html_lib.erl
index 92fc7cec92..68381bcc7b 100644
--- a/lib/observer/src/observer_html_lib.erl
+++ b/lib/observer/src/observer_html_lib.erl
@@ -337,17 +337,24 @@ href_proc_bin(From, T, Acc, LTB) ->
Size = list_to_integer(SizeStr),
PreviewSize = min(Size,10),
Id = {list_to_integer(Offset),PreviewSize,list_to_integer(Pos)},
- {ok,PreviewBin} = crashdump_viewer:expand_binary(Id),
- PreviewStr = preview_string(Size, PreviewBin),
- if LTB ->
- href("TARGET=\"expanded\"",
- ["#Binary?offset="++Offset++
- "&size="++SizeStr++
- "&pos="++Pos],
- PreviewStr);
- true ->
- PreviewStr
- end;
+ case crashdump_viewer:expand_binary(Id) of
+ {ok, '#CDVTruncatedBinary'} ->
+ lists:flatten(
+ "<FONT COLOR=\"#FF0000\">"
+ "&lt;&lt;...(Truncated Binary)&gt;&gt;"
+ "</FONT>");
+ {ok, PreviewBin} ->
+ PreviewStr = preview_string(Size, PreviewBin),
+ if LTB ->
+ href("TARGET=\"expanded\"",
+ ["#Binary?offset="++Offset++
+ "&size="++SizeStr++
+ "&pos="++Pos],
+ PreviewStr);
+ true ->
+ PreviewStr
+ end
+ end;
[PreviewIntStr,SizeStr,Md5] when From =:= obs ->
Size = list_to_integer(SizeStr),
PreviewInt = list_to_integer(PreviewIntStr),
diff --git a/lib/observer/src/observer_lib.erl b/lib/observer/src/observer_lib.erl
index 658adf1c4a..e5ffe61d25 100644
--- a/lib/observer/src/observer_lib.erl
+++ b/lib/observer/src/observer_lib.erl
@@ -21,7 +21,7 @@
-export([get_wx_parent/1,
display_info_dialog/2, display_yes_no_dialog/1,
- display_progress_dialog/2, destroy_progress_dialog/0,
+ display_progress_dialog/3, destroy_progress_dialog/0,
wait_for_progress/0, report_progress/1,
user_term/3, user_term_multiline/3,
interval_dialog/4, start_timer/1, start_timer/2, stop_timer/1, timer_config/1,
@@ -40,6 +40,7 @@
-define(SINGLE_LINE_STYLE, ?wxBORDER_NONE bor ?wxTE_READONLY bor ?wxTE_RICH2).
-define(MULTI_LINE_STYLE, ?SINGLE_LINE_STYLE bor ?wxTE_MULTILINE).
+-define(pulse_timeout,50).
get_wx_parent(Window) ->
Parent = wxWindow:getParent(Window),
@@ -688,11 +689,11 @@ create_status_bar(Panel) ->
%%%-----------------------------------------------------------------
%%% Progress dialog
-define(progress_handler,cdv_progress_handler).
-display_progress_dialog(Title,Str) ->
+display_progress_dialog(Parent,Title,Str) ->
Caller = self(),
Env = wx:get_env(),
spawn_link(fun() ->
- progress_handler(Caller,Env,Title,Str)
+ progress_handler(Caller,Env,Parent,Title,Str)
end),
ok.
@@ -716,31 +717,38 @@ report_progress(Progress) ->
ok
end.
-progress_handler(Caller,Env,Title,Str) ->
+progress_handler(Caller,Env,Parent,Title,Str) ->
register(?progress_handler,self()),
wx:set_env(Env),
- PD = progress_dialog(Env,Title,Str),
- try progress_loop(Title,PD,Caller)
+ PD = progress_dialog(Env,Parent,Title,Str),
+ try progress_loop(Title,PD,Caller,infinity)
catch closed -> normal end.
-progress_loop(Title,PD,Caller) ->
+progress_loop(Title,PD,Caller,Pulse) ->
receive
{progress,{ok,done}} -> % to make wait_for_progress/0 return
Caller ! continue,
- progress_loop(Title,PD,Caller);
+ progress_loop(Title,PD,Caller,Pulse);
+ {progress,{ok,start_pulse}} ->
+ update_progress_pulse(PD),
+ progress_loop(Title,PD,Caller,?pulse_timeout);
+ {progress,{ok,stop_pulse}} ->
+ progress_loop(Title,PD,Caller,infinity);
{progress,{ok,Percent}} when is_integer(Percent) ->
update_progress(PD,Percent),
- progress_loop(Title,PD,Caller);
+ progress_loop(Title,PD,Caller,Pulse);
{progress,{ok,Msg}} ->
update_progress_text(PD,Msg),
- progress_loop(Title,PD,Caller);
+ progress_loop(Title,PD,Caller,Pulse);
{progress,{error, Reason}} ->
+ {Dialog,_,_} = PD,
+ Parent = wxWindow:getParent(Dialog),
finish_progress(PD),
FailMsg =
if is_list(Reason) -> Reason;
true -> file:format_error(Reason)
end,
- display_info_dialog(PD,"Crashdump Viewer Error",FailMsg),
+ display_info_dialog(Parent,"Crashdump Viewer Error",FailMsg),
Caller ! error,
unregister(?progress_handler),
unlink(Caller);
@@ -748,28 +756,57 @@ progress_loop(Title,PD,Caller) ->
finish_progress(PD),
unregister(?progress_handler),
unlink(Caller)
+ after Pulse ->
+ update_progress_pulse(PD),
+ progress_loop(Title,PD,Caller,?pulse_timeout)
end.
-progress_dialog(_Env,Title,Str) ->
- PD = wxProgressDialog:new(Title,Str,
- [{maximum,101},
- {style,
- ?wxPD_APP_MODAL bor
- ?wxPD_SMOOTH bor
- ?wxPD_AUTO_HIDE}]),
- wxProgressDialog:setMinSize(PD,{200,-1}),
- PD.
+progress_dialog(_Env,Parent,Title,Str) ->
+ progress_dialog_new(Parent,Title,Str).
update_progress(PD,Value) ->
- try wxProgressDialog:update(PD,Value)
+ try progress_dialog_update(PD,Value)
catch _:_ -> throw(closed) %% Port or window have died
end.
update_progress_text(PD,Text) ->
- try wxProgressDialog:update(PD,0,[{newmsg,Text}])
+ try progress_dialog_update(PD,Text)
+ catch _:_ -> throw(closed) %% Port or window have died
+ end.
+update_progress_pulse(PD) ->
+ try progress_dialog_pulse(PD)
catch _:_ -> throw(closed) %% Port or window have died
end.
finish_progress(PD) ->
- wxProgressDialog:destroy(PD).
+ try progress_dialog_update(PD,100)
+ catch _:_ -> ok
+ after progress_dialog_destroy(PD)
+ end.
+
+progress_dialog_new(Parent,Title,Str) ->
+ Dialog = wxDialog:new(Parent, ?wxID_ANY, Title,
+ [{style,?wxDEFAULT_DIALOG_STYLE}]),
+ Panel = wxPanel:new(Dialog),
+ Sizer = wxBoxSizer:new(?wxVERTICAL),
+ Message = wxStaticText:new(Panel, 1, Str),
+ Gauge = wxGauge:new(Panel, 2, 100, [{size, {170, -1}},
+ {style, ?wxGA_HORIZONTAL}]),
+ SizerFlags = ?wxEXPAND bor ?wxLEFT bor ?wxRIGHT bor ?wxTOP,
+ wxSizer:add(Sizer, Message, [{flag,SizerFlags},{border,15}]),
+ wxSizer:add(Sizer, Gauge, [{flag, SizerFlags bor ?wxBOTTOM},{border,15}]),
+ wxPanel:setSizer(Panel, Sizer),
+ wxSizer:setSizeHints(Sizer, Dialog),
+ wxDialog:show(Dialog),
+ {Dialog,Message,Gauge}.
+
+progress_dialog_update({_,_,Gauge},Value) when is_integer(Value) ->
+ wxGauge:setValue(Gauge,Value);
+progress_dialog_update({_,Message,Gauge},Text) when is_list(Text) ->
+ wxGauge:setValue(Gauge,0),
+ wxStaticText:setLabel(Message,Text).
+progress_dialog_pulse({_,_,Gauge}) ->
+ wxGauge:pulse(Gauge).
+progress_dialog_destroy({Dialog,_,_}) ->
+ wxDialog:destroy(Dialog).
make_obsbin(Bin,Tab) ->
Size = byte_size(Bin),
diff --git a/lib/observer/src/observer_procinfo.erl b/lib/observer/src/observer_procinfo.erl
index d1665cec06..4ce38e439d 100644
--- a/lib/observer/src/observer_procinfo.erl
+++ b/lib/observer/src/observer_procinfo.erl
@@ -151,7 +151,7 @@ handle_event(#wx{event=#wxHtmlLink{linkInfo=#wxHtmlLinkInfo{href=Href}}},
Opened =
case lists:keyfind(Id,1,Opened0) of
false ->
- Win = cdv_detail_wx:start_link(Id,[],Frame,Callback),
+ Win = cdv_detail_wx:start_link(Id,[],Frame,Callback,obs),
[{Id,Win}|Opened0];
{_,Win} ->
wxFrame:raise(Win),
diff --git a/lib/observer/test/Makefile b/lib/observer/test/Makefile
index fcb1b73911..a44e54fc52 100644
--- a/lib/observer/test/Makefile
+++ b/lib/observer/test/Makefile
@@ -47,7 +47,7 @@ RELSYSDIR = $(RELEASE_PATH)/observer_test
# FLAGS
# ----------------------------------------------------
ERL_MAKE_FLAGS +=
-ERL_COMPILE_FLAGS += +nowarn_export_all
+ERL_COMPILE_FLAGS += +warnings_as_errors +nowarn_export_all
EBIN = .
diff --git a/lib/observer/test/crashdump_viewer_SUITE.erl b/lib/observer/test/crashdump_viewer_SUITE.erl
index 77cf086d4b..f9ac884743 100644
--- a/lib/observer/test/crashdump_viewer_SUITE.erl
+++ b/lib/observer/test/crashdump_viewer_SUITE.erl
@@ -76,7 +76,7 @@ end_per_testcase(Case, Config) ->
end,
ok.
-suite() -> [{ct_hooks,[ts_install_cth]}].
+suite() -> [].
all() ->
[start_stop,
@@ -364,6 +364,9 @@ special(File,Procs) ->
crashdump_viewer:expand_binary({SOffset,SSize,SPos}),
io:format(" expand binary ok",[]),
+ #proc{last_calls=LastCalls} = ProcDetails,
+ true = length(LastCalls) =< 4,
+
['#CDVPid',X1,Y1,Z1] = proplists:get_value(ext_pid,Dict),
ChannelStr1 = integer_to_list(X1),
ExtPid =
@@ -413,19 +416,90 @@ special(File,Procs) ->
old_attrib=undefined,
old_comp_info=undefined}=Mod2,
ok;
- %% ".strangemodname" ->
- %% {ok,Mods,[]} = crashdump_viewer:loaded_modules(),
- %% lookat_all_mods(Mods),
- %% ok;
- %% ".sort" ->
- %% %% sort ports, atoms and modules ????
- %% ok;
- %% ".trunc" ->
- %% %% ????
- %% ok;
- ".trunc.bytes" ->
+ ".trunc_bin1" ->
+ %% This is 'full_dist' truncated after the first
+ %% "=binary:"
+ %% i.e. no binary exist in the dump
+ [#proc{pid=Pid0}|_Rest] = lists:keysort(#proc.name,Procs),
+ Pid = pid_to_list(Pid0),
+ {ok,ProcDetails=#proc{},[]} = crashdump_viewer:proc_details(Pid),
+ io:format(" process details ok",[]),
+
+ #proc{dict=Dict} = ProcDetails,
+
+ '#CDVNonexistingBinary' = proplists:get_value(bin,Dict),
+ '#CDVNonexistingBinary' = proplists:get_value(sub_bin,Dict),
+
+ io:format(" nonexisting binaries ok",[]),
+ ok;
+ ".trunc_bin2" ->
+ %% This is 'full_dist' truncated after the first
+ %% "=binary:Addr\n
+ %% Size"
+ %% i.e. binaries are truncated
+ [#proc{pid=Pid0}|_Rest] = lists:keysort(#proc.name,Procs),
+ Pid = pid_to_list(Pid0),
+ {ok,ProcDetails=#proc{},[]} = crashdump_viewer:proc_details(Pid),
+ io:format(" process details ok",[]),
+
+ #proc{dict=Dict} = ProcDetails,
+
+ ['#CDVBin',Offset,Size,Pos] = proplists:get_value(bin,Dict),
+ {ok,'#CDVTruncatedBinary'} =
+ crashdump_viewer:expand_binary({Offset,Size,Pos}),
+ ['#CDVBin',SOffset,SSize,SPos] = proplists:get_value(sub_bin,Dict),
+ {ok,'#CDVTruncatedBinary'} =
+ crashdump_viewer:expand_binary({SOffset,SSize,SPos}),
+
+ io:format(" expand truncated binary ok",[]),
+ ok;
+ ".trunc_bin3" ->
+ %% This is 'full_dist' truncated after the first
+ %% "=binary:Addr\n
+ %% Size:"
+ %% i.e. same as 'trunc_bin2', except the colon exists also
+ [#proc{pid=Pid0}|_Rest] = lists:keysort(#proc.name,Procs),
+ Pid = pid_to_list(Pid0),
+ {ok,ProcDetails=#proc{},[]} = crashdump_viewer:proc_details(Pid),
+ io:format(" process details ok",[]),
+
+ #proc{dict=Dict} = ProcDetails,
+
+ ['#CDVBin',Offset,Size,Pos] = proplists:get_value(bin,Dict),
+ {ok,'#CDVTruncatedBinary'} =
+ crashdump_viewer:expand_binary({Offset,Size,Pos}),
+ ['#CDVBin',SOffset,SSize,SPos] = proplists:get_value(sub_bin,Dict),
+ {ok,'#CDVTruncatedBinary'} =
+ crashdump_viewer:expand_binary({SOffset,SSize,SPos}),
+
+ io:format(" expand truncated binary ok",[]),
+ ok;
+ ".trunc_bin4" ->
+ %% This is 'full_dist' truncated after the first
+ %% "=binary:Addr\n
+ %% Size:BinaryMissinOneByte"
+ %% i.e. the full binary is truncated, but the sub binary is complete
+ [#proc{pid=Pid0}|_Rest] = lists:keysort(#proc.name,Procs),
+ Pid = pid_to_list(Pid0),
+ {ok,ProcDetails=#proc{},[]} = crashdump_viewer:proc_details(Pid),
+ io:format(" process details ok",[]),
+
+ #proc{dict=Dict} = ProcDetails,
+
+ ['#CDVBin',Offset,Size,Pos] = proplists:get_value(bin,Dict),
+ {ok,'#CDVTruncatedBinary'} =
+ crashdump_viewer:expand_binary({Offset,Size,Pos}),
+ io:format(" expand truncated binary ok",[]),
+ ['#CDVBin',SOffset,SSize,SPos] = proplists:get_value(sub_bin,Dict),
+ {ok,<<_:SSize/binary>>} =
+ crashdump_viewer:expand_binary({SOffset,SSize,SPos}),
+ io:format(" expand complete sub binary ok",[]),
+
+ ok;
+ ".trunc_bytes" ->
{ok,_,[TW]} = crashdump_viewer:general_info(),
{match,_} = re:run(TW,"CRASH DUMP SIZE LIMIT REACHED"),
+ io:format(" size limit information ok",[]),
ok;
".unicode" ->
#proc{pid=Pid0} =
@@ -500,16 +574,45 @@ do_create_dumps(DataDir,Rel) ->
current ->
CD3 = dump_with_args(DataDir,Rel,"instr","+Mim true"),
CD4 = dump_with_strange_module_name(DataDir,Rel,"strangemodname"),
- Bytes = rand:uniform(300000) + 100,
- CD5 = dump_with_args(DataDir,Rel,"trunc.bytes",
+ Tmp = dump_with_args(DataDir,Rel,"trunc_bytes",""),
+ {ok,#file_info{size=Max}} = file:read_file_info(Tmp),
+ ok = file:delete(Tmp),
+ Bytes = max(15,rand:uniform(Max)),
+ CD5 = dump_with_args(DataDir,Rel,"trunc_bytes",
"-env ERL_CRASH_DUMP_BYTES " ++
integer_to_list(Bytes)),
CD6 = dump_with_unicode_atoms(DataDir,Rel,"unicode"),
- {[CD1,CD2,CD3,CD4,CD5,CD6], DosDump};
+ TruncatedDumps = truncate_dump(CD1),
+ {[CD1,CD2,CD3,CD4,CD5,CD6|TruncatedDumps], DosDump};
_ ->
{[CD1,CD2], DosDump}
end.
+truncate_dump(File) ->
+ {ok,Bin} = file:read_file(File),
+ BinTag = <<"\n=binary:">>,
+ Colon = <<":">>,
+ NewLine = case os:type() of
+ {win32,_} -> <<"\r\n">>;
+ _ -> <<"\n">>
+ end,
+ [StartBin,AfterTag] = binary:split(Bin,BinTag),
+ [AddrAndSize,BinaryAndRest] = binary:split(AfterTag,Colon),
+ [Binary,_Rest] = binary:split(BinaryAndRest,NewLine),
+ TruncSize = byte_size(Binary) - 2,
+ <<TruncBinary:TruncSize/binary,_/binary>> = Binary,
+ TruncName = filename:rootname(File) ++ ".trunc_bin",
+ write_trunc_files(TruncName,StartBin,
+ [BinTag,AddrAndSize,Colon,TruncBinary],1).
+
+write_trunc_files(TruncName0,Bin,[Part|Parts],N) ->
+ TruncName = TruncName0++integer_to_list(N),
+ Bin1 = <<Bin/binary,Part/binary>>,
+ ok = file:write_file(TruncName,Bin1),
+ [TruncName|write_trunc_files(TruncName0,Bin1,Parts,N+1)];
+write_trunc_files(_,_,[],_) ->
+ [].
+
%% Create a dump which has three visible nodes, one hidden and one
%% not connected node, and with monitors and links between nodes.
diff --git a/lib/observer/test/observer_SUITE.erl b/lib/observer/test/observer_SUITE.erl
index 41726b1521..0db2c1ea77 100644
--- a/lib/observer/test/observer_SUITE.erl
+++ b/lib/observer/test/observer_SUITE.erl
@@ -115,6 +115,7 @@ basic(doc) -> [""];
basic(Config) when is_list(Config) ->
timer:send_after(100, "foobar"), %% Otherwise the timer server gets added to procs
ProcsBefore = processes(),
+ ProcInfoBefore = [{P,process_info(P)} || P <- ProcsBefore],
NumProcsBefore = length(ProcsBefore),
ok = observer:start(),
@@ -145,8 +146,10 @@ basic(Config) when is_list(Config) ->
ProcsAfter = processes(),
NumProcsAfter = length(ProcsAfter),
if NumProcsAfter=/=NumProcsBefore ->
+ BeforeNotAfter = ProcsBefore -- ProcsAfter,
ct:log("Before but not after:~n~p~n",
- [[{P,process_info(P)} || P <- ProcsBefore -- ProcsAfter]]),
+ [[{P,I} || {P,I} <- ProcInfoBefore,
+ lists:member(P,BeforeNotAfter)]]),
ct:log("After but not before:~n~p~n",
[[{P,process_info(P)} || P <- ProcsAfter -- ProcsBefore]]),
ct:fail("leaking processes");
@@ -304,10 +307,10 @@ table_win(Config) when is_list(Config) ->
%% Test PR-1296/OTP-14151
%% Clicking a link to a port before the port tab has been activated the
%% first time crashes observer.
-port_win_when_tab_not_initiated(Config) ->
+port_win_when_tab_not_initiated(_Config) ->
{ok,Port} = gen_tcp:listen(0,[]),
ok = observer:start(),
- Notebook = setup_whitebox_testing(),
+ _Notebook = setup_whitebox_testing(),
observer ! {open_link,erlang:port_to_list(Port)},
timer:sleep(1000),
observer:stop(),
diff --git a/lib/observer/test/ttb_SUITE.erl b/lib/observer/test/ttb_SUITE.erl
index 6d7e574856..ed62efbb58 100644
--- a/lib/observer/test/ttb_SUITE.erl
+++ b/lib/observer/test/ttb_SUITE.erl
@@ -778,37 +778,37 @@ otp_4967_2(suite) ->
otp_4967_2(doc) ->
["OTP-4967: Trace message sent to {Name, Node}"];
otp_4967_2(Config) when is_list(Config) ->
- io:format("1: ~p",[now()]),
+ io:format("1: ~p",[erlang:timestamp()]),
?line Privdir = priv_dir(Config),
- io:format("2: ~p",[now()]),
+ io:format("2: ~p",[erlang:timestamp()]),
?line File = filename:join(Privdir,"otp_4967"),
- io:format("3: ~p",[now()]),
+ io:format("3: ~p",[erlang:timestamp()]),
?line S = self(),
- io:format("4: ~p",[now()]),
+ io:format("4: ~p",[erlang:timestamp()]),
?line {ok,[Node]} =
ttb:tracer(node(),[{file, File},
{handler,{fun myhandler/4, S}}]),
- io:format("5: ~p",[now()]),
+ io:format("5: ~p",[erlang:timestamp()]),
%% Test that delayed registration of a process works.
receive after 200 -> ok end,
?line register(otp_4967,self()),
- io:format("6: ~p",[now()]),
+ io:format("6: ~p",[erlang:timestamp()]),
?line {ok,[{S,[{matched,Node,1}]}]} = ttb:p(self(),s),
- io:format("7: ~p",[now()]),
+ io:format("7: ~p",[erlang:timestamp()]),
?line {otp_4967,node()} ! heihopp,
- io:format("8: ~p",[now()]),
+ io:format("8: ~p",[erlang:timestamp()]),
?line stopped = ttb:stop([format]),
- io:format("9: ~p",[now()]),
+ io:format("9: ~p",[erlang:timestamp()]),
?line Msgs = flush(),
- io:format("10: ~p",[now()]),
+ io:format("10: ~p",[erlang:timestamp()]),
?line io:format("Messages received: \n~p\n",[Msgs]),
- io:format("11: ~p",[now()]),
+ io:format("11: ~p",[erlang:timestamp()]),
?line true = lists:member(heihopp,Msgs), % the heihopp message itself
- io:format("13: ~p",[now()]),
+ io:format("13: ~p",[erlang:timestamp()]),
?line {value,{trace_ts,_,send,heihopp,{_,otp_4967,Node},{_,_,_}}} =
lists:keysearch(heihopp,4,Msgs), % trace trace of the heihopp message
- io:format("14: ~p",[now()]),
+ io:format("14: ~p",[erlang:timestamp()]),
?line end_of_trace = lists:last(Msgs), % end of the trace
ok.
diff --git a/lib/public_key/doc/src/public_key.xml b/lib/public_key/doc/src/public_key.xml
index 942203bd12..fcf37a7a4d 100644
--- a/lib/public_key/doc/src/public_key.xml
+++ b/lib/public_key/doc/src/public_key.xml
@@ -119,6 +119,10 @@
<tag><c>ec_private_key() =</c></tag>
<item><p><c>#'ECPrivateKey'{}</c></p></item>
+ <tag><c>key_params() =</c></tag>
+ <item><p> #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}
+ | {rsa, Size::integer(), PubExp::integer()} </p></item>
+
<tag><c>public_crypt_options() =</c></tag>
<item><p><c>[{rsa_pad, rsa_padding()}]</c></p></item>
@@ -347,8 +351,7 @@
<name>generate_key(Params) -> {Public::binary(), Private::binary()} | #'ECPrivateKey'{} | #'RSAPrivateKey'{}</name>
<fsummary>Generates a new keypair.</fsummary>
<type>
- <v>Params = #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{}
- | {rsa, Size::integer(), PubExp::integer} </v>
+ <v>Params = key_params()</v>
</type>
<desc>
<p>Generates a new keypair. Note that except for Diffie-Hellman
@@ -769,6 +772,85 @@ fun(#'DistributionPoint'{}, #'CertificateList'{},
</desc>
</func>
+ <func>
+ <name>pkix_test_data(Options) -> Config </name>
+ <fsummary>Creates certificate test data.</fsummary>
+ <type>
+ <v>Options = #{chain_type() := chain_opts()} </v>
+ <d>Options for ROOT, Intermediate and Peer certs</d>
+
+ <v>chain_type() = server_chain | client_chain </v>
+
+ <v>chain_opts() = #{chain_end() := [cert_opt()],
+ intermediates => [[cert_opt()]]}</v>
+ <d>A valid chain must have at least a ROOT and a peer cert</d>
+
+ <v>chain_end() = root | peer </v>
+
+ <v>cert_opt() = {Key, Value}</v>
+ <d>For available options see <seealso marker="#cert_opt"> cert_opt()</seealso> below.</d>
+
+ <v>Config = #{server_config := [conf_opt()],
+ client_config := [conf_opt()]}</v>
+
+ <v>conf_opt() = {cert, der_encoded()} | {key, der_encoded()} |{cacerts, [der_encoded()]}</v>
+ <d>This is a subset of the type <seealso marker="ssl:ssl#type-ssloption"> ssl:ssl_option()</seealso> </d>
+ </type>
+
+ <desc>
+ <p>Creates certificate test data to facilitate automated testing
+ of applications using X509-certificates often through
+ SSL/TLS. The test data can be used when you have control
+ over both the client and the server in a test scenario.
+ </p>
+
+ <p> The <marker id="cert_opt"/> cert_opt() type consists of the following options: </p>
+ <taglist>
+ <tag> {digest, digest_type()}</tag>
+ <item><p>Hash algorithm to be used for
+ signing the certificate together with the key option. Defaults to sha that is sha1.
+ </p></item>
+ <tag> {key, key_params() | private_key()}</tag>
+ <item><p>Parameters to be used to call public_key:generate_key/1, to generate a key, or an existing
+ key. Defaults to generating an ECDSA key. Note this could fail if Erlang/OTP is compiled with a very old
+ cryptolib.</p></item>
+ <tag> {validity, {From::erlang:timestamp(), To::erlang:timestamp()}} </tag>
+ <item><p>The validity period of the certificate.</p></item>
+ <tag> {extensions, [#'Extension'{}]}</tag>
+ <item><p> Extensions to include in the certificate.</p>
+
+ <p>Default extensions included in CA certificates if not
+ otherwise specified are: </p>
+ <code>[#'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = [keyCertSign, cRLSign],
+ critical = false},
+#'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA = true},
+ critical = true}]
+ </code>
+
+ <p>Default extensions included in the server peer cert if not
+ otherwise specified are: </p>
+ <code>[#'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = [digitalSignature, keyAgreement],
+ critical = false},
+#'Extension'{extnID = ?'id-ce-subjectAltName',
+ extnValue = [{dNSName, Hostname}],
+ critical = false}]
+ </code>
+ <p>Hostname is the result of calling net_adm:localhost() in the Erlang node
+ where this funcion is called.
+ </p></item>
+
+ </taglist>
+
+ <note><p>
+ Note that the generated certificates and keys does not provide a formally correct PKIX-trust-chain
+ and they can not be used to achieve real security. This function is provided for testing purposes only.
+</p></note>
+ </desc>
+ </func>
+
<func>
<name>pkix_verify(Cert, Key) -> boolean()</name>
<fsummary>Verifies PKIX x.509 certificate signature.</fsummary>
diff --git a/lib/public_key/doc/src/public_key_records.xml b/lib/public_key/doc/src/public_key_records.xml
index d34f3ed9a3..739310c88b 100644
--- a/lib/public_key/doc/src/public_key_records.xml
+++ b/lib/public_key/doc/src/public_key_records.xml
@@ -171,9 +171,9 @@
#'ECPrivateKey'{
version, % integer()
privateKey, % binary()
- parameters, % der_encoded() - {'EcpkParameters', #'ECParameters'{}} |
- {'EcpkParameters', {namedCurve, oid()}} |
- {'EcpkParameters', 'NULL'} % Inherited by CA
+ parameters, % {ecParameters, #'ECParameters'{}} |
+ % {namedCurve, Oid::tuple()} |
+ % {implicitlyCA, 'NULL'}
publicKey % bitstring()
}.
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index f45f2c2e9a..13833830a7 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -32,12 +32,25 @@
is_issuer/2, issuer_id/2, distribution_points/1,
is_fixed_dh_cert/1, verify_data/1, verify_fun/4,
select_extension/2, match_name/3,
- extensions_list/1, cert_auth_key_id/1, time_str_2_gregorian_sec/1]).
+ extensions_list/1, cert_auth_key_id/1, time_str_2_gregorian_sec/1,
+ gen_test_certs/1]).
-define(NULL, 0).
-
+
+-export_type([chain_opts/0, test_config/0]).
+
+-type cert_opt() :: {digest, public_key:digest_type()} |
+ {key, public_key:key_params() | public_key:private_key()} |
+ {validity, {From::erlang:timestamp(), To::erlang:timestamp()}} |
+ {extensions, [#'Extension'{}]}.
+-type chain_end() :: root | peer.
+-type chain_opts() :: #{chain_end() := [cert_opt()], intermediates => [[cert_opt()]]}.
+-type conf_opt() :: {cert, public_key:der_encoded()} |
+ {key, public_key:der_encoded()} |
+ {cacerts, [public_key:der_encoded()]}.
+-type test_config() :: #{server_config := [conf_opt()], client_config := [conf_opt()]}.
%%====================================================================
-%% Internal application API
+%% Internal application APIu
%%====================================================================
%%--------------------------------------------------------------------
@@ -417,6 +430,31 @@ match_name(Fun, Name, PermittedName, [Head | Tail]) ->
false ->
match_name(Fun, Name, Head, Tail)
end.
+%%%
+-spec gen_test_certs(#{server_chain:= chain_opts(), client_chain:= chain_opts()}) -> test_config().
+
+%% Generates server and and client configuration for testing
+%% purposes. All certificate options have default values
+gen_test_certs(#{client_chain := #{root := ClientRootConf,
+ intermediates := ClientCAs,
+ peer := ClientPeer},
+ server_chain :=
+ #{root := ServerRootConf,
+ intermediates := ServerCAs,
+ peer := ServerPeer}}) ->
+ SRootKey = gen_key(proplists:get_value(key, ServerRootConf, default_key_gen())),
+ CRootKey = gen_key(proplists:get_value(key, ClientRootConf, default_key_gen())),
+ ServerRoot = root_cert("server", SRootKey, ClientRootConf),
+ ClientRoot = root_cert("client", CRootKey, ServerRootConf),
+
+ [{ServerDERCert, ServerDERKey} | ServerCAsKeys] = config(server, ServerRoot,
+ SRootKey, lists:reverse([ServerPeer | lists:reverse(ServerCAs)])),
+ [{ClientDERCert, ClientDERKey} | ClientCAsKeys] = config(client, ClientRoot,
+ CRootKey, lists:reverse([ClientPeer | lists:reverse(ClientCAs)])),
+ ServerDERCA = ca_config(ClientRoot, ServerCAsKeys),
+ ClientDERCA = ca_config(ServerRoot, ClientCAsKeys),
+ #{server_config => [{cert, ServerDERCert}, {key, ServerDERKey}, {cacerts, ServerDERCA}],
+ client_config => [{cert, ClientDERCert}, {key, ClientDERKey}, {cacerts, ClientDERCA}]}.
%%--------------------------------------------------------------------
%%% Internal functions
@@ -1064,3 +1102,212 @@ missing_basic_constraints(OtpCert, SelfSigned, ValidationState, VerifyFun, UserS
Len - 1},
UserState}
end.
+
+ gen_key(KeyGen) ->
+ case is_key(KeyGen) of
+ true ->
+ KeyGen;
+ false ->
+ public_key:generate_key(KeyGen)
+ end.
+
+is_key(#'DSAPrivateKey'{}) ->
+ true;
+is_key(#'RSAPrivateKey'{}) ->
+ true;
+is_key(#'ECPrivateKey'{}) ->
+ true;
+is_key(_) ->
+ false.
+
+root_cert(Role, PrivKey, Opts) ->
+ TBS = cert_template(),
+ Issuer = issuer("root", Role, " ROOT CA"),
+ OTPTBS = TBS#'OTPTBSCertificate'{
+ signature = sign_algorithm(PrivKey, Opts),
+ issuer = Issuer,
+ validity = validity(Opts),
+ subject = Issuer,
+ subjectPublicKeyInfo = public_key(PrivKey),
+ extensions = extensions(Role, ca, Opts)
+ },
+ public_key:pkix_sign(OTPTBS, PrivKey).
+
+cert_template() ->
+ #'OTPTBSCertificate'{
+ version = v3,
+ serialNumber = trunc(rand:uniform()*100000000)*10000 + 1,
+ issuerUniqueID = asn1_NOVALUE,
+ subjectUniqueID = asn1_NOVALUE
+ }.
+issuer(Contact, Role, Name) ->
+ subject(Contact, Role ++ Name).
+
+subject(Contact, Name) ->
+ Opts = [{email, Contact ++ "@erlang.org"},
+ {name, Name},
+ {city, "Stockholm"},
+ {country, "SE"},
+ {org, "erlang"},
+ {org_unit, "automated testing"}],
+ subject(Opts).
+
+subject(SubjectOpts) when is_list(SubjectOpts) ->
+ Encode = fun(Opt) ->
+ {Type,Value} = subject_enc(Opt),
+ [#'AttributeTypeAndValue'{type=Type, value=Value}]
+ end,
+ {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}.
+
+subject_enc({name, Name}) ->
+ {?'id-at-commonName', {printableString, Name}};
+subject_enc({email, Email}) ->
+ {?'id-emailAddress', Email};
+subject_enc({city, City}) ->
+ {?'id-at-localityName', {printableString, City}};
+subject_enc({org, Org}) ->
+ {?'id-at-organizationName', {printableString, Org}};
+subject_enc({org_unit, OrgUnit}) ->
+ {?'id-at-organizationalUnitName', {printableString, OrgUnit}};
+subject_enc({country, Country}) ->
+ {?'id-at-countryName', Country}.
+
+validity(Opts) ->
+ DefFrom0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())-1),
+ DefTo0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+7),
+ {DefFrom, DefTo} = proplists:get_value(validity, Opts, {DefFrom0, DefTo0}),
+ Format = fun({Y,M,D}) ->
+ lists:flatten(io_lib:format("~w~2..0w~2..0w000000Z",[Y,M,D]))
+ end,
+ #'Validity'{notBefore={generalTime, Format(DefFrom)},
+ notAfter ={generalTime, Format(DefTo)}}.
+
+sign_algorithm(#'RSAPrivateKey'{}, Opts) ->
+ Type = rsa_digest_oid(proplists:get_value(digest, Opts, sha1)),
+ #'SignatureAlgorithm'{algorithm = Type,
+ parameters = 'NULL'};
+sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) ->
+ #'SignatureAlgorithm'{algorithm = ?'id-dsa-with-sha1',
+ parameters = {params,#'Dss-Parms'{p=P, q=Q, g=G}}};
+sign_algorithm(#'ECPrivateKey'{parameters = Parms}, Opts) ->
+ Type = ecdsa_digest_oid(proplists:get_value(digest, Opts, sha1)),
+ #'SignatureAlgorithm'{algorithm = Type,
+ parameters = Parms}.
+rsa_digest_oid(sha1) ->
+ ?'sha1WithRSAEncryption';
+rsa_digest_oid(sha512) ->
+ ?'sha512WithRSAEncryption';
+rsa_digest_oid(sha384) ->
+ ?'sha384WithRSAEncryption';
+rsa_digest_oid(sha256) ->
+ ?'sha256WithRSAEncryption';
+rsa_digest_oid(md5) ->
+ ?'md5WithRSAEncryption'.
+
+ecdsa_digest_oid(sha1) ->
+ ?'ecdsa-with-SHA1';
+ecdsa_digest_oid(sha512) ->
+ ?'ecdsa-with-SHA512';
+ecdsa_digest_oid(sha384) ->
+ ?'ecdsa-with-SHA384';
+ecdsa_digest_oid(sha256) ->
+ ?'ecdsa-with-SHA256'.
+
+config(Role, Root, Key, Opts) ->
+ cert_chain(Role, Root, Key, Opts).
+
+cert_chain(Role, Root, RootKey, Opts) ->
+ cert_chain(Role, Root, RootKey, Opts, 0, []).
+
+cert_chain(Role, IssuerCert, IssuerKey, [PeerOpts], _, Acc) ->
+ Key = gen_key(proplists:get_value(key, PeerOpts, default_key_gen())),
+ Cert = cert(Role, public_key:pkix_decode_cert(IssuerCert, otp),
+ IssuerKey, Key, "admin", " Peer cert", PeerOpts, peer),
+ [{Cert, Key}, {IssuerCert, IssuerKey} | Acc];
+cert_chain(Role, IssuerCert, IssuerKey, [CAOpts | Rest], N, Acc) ->
+ Key = gen_key(proplists:get_value(key, CAOpts, default_key_gen())),
+ Cert = cert(Role, public_key:pkix_decode_cert(IssuerCert, otp), IssuerKey, Key, "webadmin",
+ " Intermidiate CA " ++ integer_to_list(N), CAOpts, ca),
+ cert_chain(Role, Cert, Key, Rest, N+1, [{IssuerCert, IssuerKey} | Acc]).
+
+cert(Role, #'OTPCertificate'{tbsCertificate = #'OTPTBSCertificate'{subject = Issuer}},
+ PrivKey, Key, Contact, Name, Opts, Type) ->
+ TBS = cert_template(),
+ OTPTBS = TBS#'OTPTBSCertificate'{
+ signature = sign_algorithm(PrivKey, Opts),
+ issuer = Issuer,
+ validity = validity(Opts),
+ subject = subject(Contact, atom_to_list(Role) ++ Name),
+ subjectPublicKeyInfo = public_key(Key),
+ extensions = extensions(Role, Type, Opts)
+
+ },
+ public_key:pkix_sign(OTPTBS, PrivKey).
+
+ca_config(Root, CAsKeys) ->
+ [Root | [CA || {CA, _} <- CAsKeys]].
+
+default_key_gen() ->
+ case crypto:ec_curves() of
+ [] ->
+ {rsa, 2048, 17};
+ [Curve |_] ->
+ Oid = pubkey_cert_records:namedCurves(Curve),
+ {namedCurve, Oid}
+ end.
+
+public_key(#'RSAPrivateKey'{modulus=N, publicExponent=E}) ->
+ Public = #'RSAPublicKey'{modulus=N, publicExponent=E},
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
+ subjectPublicKey = Public};
+public_key(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) ->
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa',
+ parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y};
+public_key(#'ECPrivateKey'{version = _Version,
+ privateKey = _PrivKey,
+ parameters = Params,
+ publicKey = PubKey}) ->
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-ecPublicKey', parameters=Params},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
+ subjectPublicKey = #'ECPoint'{point = PubKey}}.
+
+extensions(Role, Type, Opts) ->
+ Exts = proplists:get_value(extensions, Opts, []),
+ add_default_extensions(Role, Type, Exts).
+
+add_default_extensions(_, ca, Exts) ->
+ Default = [#'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = [keyCertSign, cRLSign],
+ critical = false},
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA = true},
+ critical = true}],
+ add_default_extensions(Default, Exts);
+
+add_default_extensions(server, peer, Exts) ->
+ Hostname = net_adm:localhost(),
+ Default = [#'Extension'{extnID = ?'id-ce-keyUsage',
+ extnValue = [digitalSignature, keyAgreement],
+ critical = false},
+ #'Extension'{extnID = ?'id-ce-subjectAltName',
+ extnValue = [{dNSName, Hostname}],
+ critical = false}
+ ],
+ add_default_extensions(Default, Exts);
+
+add_default_extensions(_, peer, Exts) ->
+ Exts.
+
+add_default_extensions(Defaults0, Exts) ->
+ Defaults = lists:filtermap(fun(#'Extension'{extnID = ID} = Ext) ->
+ case lists:keymember(ID, 2, Exts) of
+ true ->
+ false;
+ false ->
+ {true, Ext}
+ end
+ end, Defaults0),
+ Exts ++ Defaults.
+
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index c2060c144c..cc01b61433 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -58,11 +58,13 @@
pkix_match_dist_point/2,
pkix_crl_verify/2,
pkix_crl_issuer/1,
- short_name_hash/1
+ short_name_hash/1,
+ pkix_test_data/1
]).
-export_type([public_key/0, private_key/0, pem_entry/0,
- pki_asn1_type/0, asn1_type/0, ssh_file/0, der_encoded/0]).
+ pki_asn1_type/0, asn1_type/0, ssh_file/0, der_encoded/0,
+ key_params/0, digest_type/0]).
-type public_key() :: rsa_public_key() | dsa_public_key() | ec_public_key().
-type private_key() :: rsa_private_key() | dsa_private_key() | ec_private_key().
@@ -71,8 +73,12 @@
-type rsa_private_key() :: #'RSAPrivateKey'{}.
-type dsa_private_key() :: #'DSAPrivateKey'{}.
-type dsa_public_key() :: {integer(), #'Dss-Parms'{}}.
--type ec_public_key() :: {#'ECPoint'{},{namedCurve, Oid::tuple()} | #'ECParameters'{}}.
+-type ecpk_parameters() :: {ecParameters, #'ECParameters'{}} | {namedCurve, Oid::tuple()}.
+-type ecpk_parameters_api() :: ecpk_parameters() | #'ECParameters'{} | {namedCurve, Name::atom()}.
+-type ec_public_key() :: {#'ECPoint'{}, ecpk_parameters_api()}.
-type ec_private_key() :: #'ECPrivateKey'{}.
+-type key_params() :: #'DHParameter'{} | {namedCurve, oid()} | #'ECParameters'{} |
+ {rsa, Size::integer(), PubExp::integer()}.
-type der_encoded() :: binary().
-type pki_asn1_type() :: 'Certificate' | 'RSAPrivateKey' | 'RSAPublicKey'
| 'DSAPrivateKey' | 'DSAPublicKey' | 'DHParameter'
@@ -100,6 +106,7 @@
-type crl_reason() :: unspecified | keyCompromise | cACompromise | affiliationChanged | superseded
| cessationOfOperation | certificateHold | privilegeWithdrawn | aACompromise.
-type oid() :: tuple().
+-type chain_type() :: server_chain | client_chain.
-define(UINT32(X), X:32/unsigned-big-integer).
-define(DER_NULL, <<5, 0>>).
@@ -399,9 +406,7 @@ dh_gex_group(Min, N, Max, Groups) ->
%%--------------------------------------------------------------------
-spec generate_key(#'DHParameter'{}) ->
{Public::binary(), Private::binary()};
- ({namedCurve, Name ::oid()}) ->
- #'ECPrivateKey'{};
- (#'ECParameters'{}) ->
+ (ecpk_parameters_api()) ->
#'ECPrivateKey'{};
({rsa, Size::pos_integer(), PubExp::pos_integer()}) ->
#'RSAPrivateKey'{}.
@@ -412,6 +417,8 @@ generate_key(#'DHParameter'{prime = P, base = G}) ->
crypto:generate_key(dh, [P, G]);
generate_key({namedCurve, _} = Params) ->
ec_generate_key(Params);
+generate_key({ecParameters, _} = Params) ->
+ ec_generate_key(Params);
generate_key(#'ECParameters'{} = Params) ->
ec_generate_key(Params);
generate_key({rsa, ModulusSize, PublicExponent}) ->
@@ -1025,6 +1032,22 @@ short_name_hash({rdnSequence, _Attributes} = Name) ->
<<HashValue:32/little, _/binary>> = crypto:hash(sha, HashThis),
string:to_lower(string:right(integer_to_list(HashValue, 16), 8, $0)).
+
+%%--------------------------------------------------------------------
+-spec pkix_test_data(#{chain_type() := pubkey_cert:chain_opts()}) ->
+ pubkey_cert:test_config().
+
+%% Description: Generates OpenSSL-style hash of a name.
+%%--------------------------------------------------------------------
+
+pkix_test_data(#{client_chain := ClientChain0,
+ server_chain := ServerChain0}) ->
+ Default = #{intermediates => []},
+ ClientChain = maps:merge(Default, ClientChain0),
+ ServerChain = maps:merge(Default, ServerChain0),
+ pubkey_cert:gen_test_certs(#{client_chain => ClientChain,
+ server_chain => ServerChain}).
+
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
@@ -1286,22 +1309,34 @@ format_rsa_private_key(#'RSAPrivateKey'{modulus = N, publicExponent = E,
is_integer(D) ->
[E, N, D].
+-spec ec_generate_key(ecpk_parameters_api()) -> #'ECPrivateKey'{}.
ec_generate_key(Params) ->
Curve = ec_curve_spec(Params),
Term = crypto:generate_key(ecdh, Curve),
- ec_key(Term, Params).
+ NormParams = ec_normalize_params(Params),
+ ec_key(Term, NormParams).
+-spec ec_normalize_params(ecpk_parameters_api()) -> ecpk_parameters().
+ec_normalize_params({namedCurve, Name}) when is_atom(Name) ->
+ {namedCurve, pubkey_cert_records:namedCurves(Name)};
+ec_normalize_params(#'ECParameters'{} = ECParams) ->
+ {ecParameters, ECParams};
+ec_normalize_params(Other) -> Other.
+
+-spec ec_curve_spec(ecpk_parameters_api()) -> term().
ec_curve_spec( #'ECParameters'{fieldID = FieldId, curve = PCurve, base = Base, order = Order, cofactor = CoFactor }) ->
Field = {pubkey_cert_records:supportedCurvesTypes(FieldId#'FieldID'.fieldType),
FieldId#'FieldID'.parameters},
Curve = {PCurve#'Curve'.a, PCurve#'Curve'.b, none},
{Field, Curve, Base, Order, CoFactor};
+ec_curve_spec({ecParameters, ECParams}) ->
+ ec_curve_spec(ECParams);
ec_curve_spec({namedCurve, OID}) when is_tuple(OID), is_integer(element(1,OID)) ->
ec_curve_spec({namedCurve, pubkey_cert_records:namedCurves(OID)});
ec_curve_spec({namedCurve, Name}) when is_atom(Name) ->
crypto:ec_curve(Name).
-
+-spec ec_key({PubKey::term(), PrivateKey::term()}, Params::ecpk_parameters()) -> #'ECPrivateKey'{}.
ec_key({PubKey, PrivateKey}, Params) ->
#'ECPrivateKey'{version = 1,
privateKey = PrivateKey,
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 80895ce97c..374fb20375 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -48,6 +48,8 @@ all() ->
pkix_verify_hostname_cn,
pkix_verify_hostname_subjAltName,
pkix_verify_hostname_options,
+ pkix_test_data_all_default,
+ pkix_test_data,
short_cert_issuer_hash, short_crl_issuer_hash,
ssh_hostkey_fingerprint_md5_implicit,
ssh_hostkey_fingerprint_md5,
@@ -60,7 +62,8 @@ all() ->
groups() ->
[{pem_decode_encode, [], [dsa_pem, rsa_pem, ec_pem, encrypted_pem,
- dh_pem, cert_pem, pkcs7_pem, pkcs10_pem]},
+ dh_pem, cert_pem, pkcs7_pem, pkcs10_pem, ec_pem2,
+ ec_pem_encode_generated]},
{ssh_public_key_decode_encode, [],
[ssh_rsa_public_key, ssh_dsa_public_key, ssh_ecdsa_public_key,
ssh_rfc4716_rsa_comment, ssh_rfc4716_dsa_comment,
@@ -92,6 +95,14 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
%%-------------------------------------------------------------------
+
+init_per_testcase(pkix_test_data_all_default, Config) ->
+ case crypto:ec_curves() of
+ [] ->
+ {skip, missing_ecc_support};
+ _ ->
+ init_common_per_testcase(Config)
+ end;
init_per_testcase(TestCase, Config) ->
case TestCase of
ssh_hostkey_fingerprint_md5_implicit -> init_fingerprint_testcase([md5], Config);
@@ -101,6 +112,7 @@ init_per_testcase(TestCase, Config) ->
ssh_hostkey_fingerprint_sha384 -> init_fingerprint_testcase([sha384], Config);
ssh_hostkey_fingerprint_sha512 -> init_fingerprint_testcase([sha512], Config);
ssh_hostkey_fingerprint_list -> init_fingerprint_testcase([sha,md5], Config);
+ ec_pem_encode_generated -> init_ec_pem_encode_generated(Config);
_ -> init_common_per_testcase(Config)
end.
@@ -217,9 +229,47 @@ ec_pem(Config) when is_list(Config) ->
true = check_entry_type(ECParams, 'EcpkParameters'),
ECPrivKey = public_key:pem_entry_decode(Entry2),
true = check_entry_type(ECPrivKey, 'ECPrivateKey'),
+ true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'),
ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem),
ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([Entry1, Entry2])).
+ec_pem2() ->
+ [{doc, "EC key w/explicit params PEM-file decode/encode"}].
+ec_pem2(Config) when is_list(Config) ->
+ Datadir = proplists:get_value(data_dir, Config),
+
+ %% Load key with explicit curve parameters. Generated with...
+ %% openssl ecparam -name secp521r1 -genkey -param_enc explicit -out ec_key2.pem
+ {ok, ECPrivPem} = file:read_file(filename:join(Datadir, "ec_key2.pem")),
+ [{'EcpkParameters', _, not_encrypted} = Entry1,
+ {'ECPrivateKey', _, not_encrypted} = Entry2] = public_key:pem_decode(ECPrivPem),
+
+ ECParams = public_key:pem_entry_decode(Entry1),
+ true = check_entry_type(ECParams, 'EcpkParameters'),
+ ECPrivKey = public_key:pem_entry_decode(Entry2),
+ true = check_entry_type(ECPrivKey, 'ECPrivateKey'),
+ true = check_entry_type(ECPrivKey#'ECPrivateKey'.parameters, 'EcpkParameters'),
+ ECPemNoEndNewLines = strip_superfluous_newlines(ECPrivPem),
+ ECPemNoEndNewLines = strip_superfluous_newlines(public_key:pem_encode([Entry1, Entry2])).
+
+
+init_ec_pem_encode_generated(Config) ->
+ case catch true = lists:member('secp384r1', crypto:ec_curves()) of
+ {'EXIT', _} -> {skip, {'secp384r1', not_supported}};
+ _ -> init_common_per_testcase(Config)
+ end.
+
+ec_pem_encode_generated() ->
+ [{doc, "PEM-encode generated EC key"}].
+ec_pem_encode_generated(Config) ->
+
+ Key1 = public_key:generate_key({namedCurve, 'secp384r1'}),
+ public_key:pem_entry_encode('ECPrivateKey', Key1),
+
+ Key2 = public_key:generate_key({namedCurve, ?'secp384r1'}),
+ public_key:pem_entry_encode('ECPrivateKey', Key2).
+
+
%%--------------------------------------------------------------------
encrypted_pem() ->
@@ -1007,6 +1057,84 @@ general_name(Config) when is_list(Config) ->
authorityCertSerialNumber =
1}).
%%--------------------------------------------------------------------
+
+pkix_test_data_all_default() ->
+ [{doc, "Test API function pkix_test_data/1"}].
+
+pkix_test_data_all_default(Config) when is_list(Config) ->
+ #{server_config := ServerConf0,
+ client_config := ClientConf0} = public_key:pkix_test_data(#{server_chain =>
+ #{root => [],
+ intermediates => [[]],
+ peer => []},
+ client_chain =>
+ #{root => [],
+ intermediates => [[]],
+ peer => []}}),
+ check_conf_member(ServerConf0, [key, cert, cacerts]),
+ check_conf_member(ClientConf0, [key, cert, cacerts]),
+
+ 3 = length(proplists:get_value(cacerts, ServerConf0)),
+ 3 = length(proplists:get_value(cacerts, ServerConf0)),
+
+ #{server_config := ServerConf1,
+ client_config := ClientConf1} = public_key:pkix_test_data(#{server_chain =>
+ #{root => [],
+ peer => []},
+ client_chain =>
+ #{root => [],
+ peer => []}}),
+ 2 = length(proplists:get_value(cacerts, ServerConf1)),
+ 2 = length(proplists:get_value(cacerts, ServerConf1)),
+
+ check_conf_member(ServerConf1, [key, cert, cacerts]),
+ check_conf_member(ClientConf1, [key, cert, cacerts]).
+
+
+pkix_test_data() ->
+ [{doc, "Test API function pkix_test_data/1"}].
+
+pkix_test_data(Config) when is_list(Config) ->
+ {Year, Month, Day} = date(),
+ Keygen =
+ case crypto:ec_curves() of
+ [] ->
+ {rsa, 2048, 17};
+ [Curve |_] ->
+ Oid = pubkey_cert_records:namedCurves(Curve),
+ {namedCurve, Oid}
+ end,
+ #{server_config := ServerConf0,
+ client_config := ClientConf0} =
+ public_key:pkix_test_data(#{server_chain =>
+ #{root => [],
+ intermediates => [],
+ peer => [{key, hardcode_rsa_key()}]},
+ client_chain =>
+ #{root => [{validity, {{Year-2, Month, Day},
+ {Year-1, Month, Day}}}],
+ intermediates =>
+ [[{extensions, [#'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA=true,
+ pathLenConstraint = 1},
+ critical = true}]}]],
+ peer => [{key, Keygen}, {digest, sha1}]}}),
+ check_conf_member(ServerConf0, [key, cert, cacerts]),
+ check_conf_member(ClientConf0, [key, cert, cacerts]).
+
+
+
+check_conf_member(_, []) ->
+ true;
+check_conf_member(Conf, [Member | Rest]) ->
+ case lists:keymember(Member, 1, Conf) of
+ true ->
+ check_conf_member(Conf, Rest);
+ false ->
+ ct:fail({misssing_conf, Member})
+ end.
+
+%%--------------------------------------------------------------------
short_cert_issuer_hash() ->
[{doc, "Test OpenSSL-style hash for certificate issuer"}].
@@ -1095,7 +1223,7 @@ check_entry_type(#'ECPrivateKey'{}, 'ECPrivateKey') ->
true;
check_entry_type({namedCurve, _}, 'EcpkParameters') ->
true;
-check_entry_type(#'ECParameters'{}, 'EcpkParameters') ->
+check_entry_type({ecParameters, #'ECParameters'{}}, 'EcpkParameters') ->
true;
check_entry_type(_,_) ->
false.
@@ -1128,3 +1256,15 @@ ssh_hostkey(rsa) ->
public_key),
PKdecoded.
+hardcode_rsa_key() ->
+ #'RSAPrivateKey'{
+ version = 'two-prime',
+ modulus = 23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669,
+ publicExponent = 17,
+ privateExponent = 11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657,
+ prime1 = 169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197,
+ prime2 = 141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577,
+ exponent1 = 119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609,
+ exponent2 = 41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993,
+ coefficient = 76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441,
+ otherPrimeInfos = asn1_NOVALUE}.
diff --git a/lib/public_key/test/public_key_SUITE_data/ec_key2.pem b/lib/public_key/test/public_key_SUITE_data/ec_key2.pem
new file mode 100644
index 0000000000..56b8169e86
--- /dev/null
+++ b/lib/public_key/test/public_key_SUITE_data/ec_key2.pem
@@ -0,0 +1,29 @@
+-----BEGIN EC PARAMETERS-----
+MIIBwgIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////
+//////////////////////////////////////////////////8wgZ4EQgH/////
+////////////////////////////////////////////////////////////////
+/////////////////ARBUZU+uWGOHJofkpohoLaFQO6i2nJbmbMV87i0iZGO8Qnh
+Vhk5Uex+k3sWUsC9O7G/BzVz34g9LDTx70Uf1GtQPwADFQDQnogAKRy4U5bMZxc5
+MoSqoNpkugSBhQQAxoWOBrcEBOnNnj7LZiOVtEKcZIE5BT+1Ifgor2BrTT26oUte
+d+/nWSj+HcEnov+o3jNIs8GFakKb+X5+McLlvWYBGDkpaniaO8AEXIpftCx9G9mY
+9URJV5tEaBevvRcnPmYsl+5ymV70JkDFULkBP60HYTU8cIaicsJAiL6Udp/RZlAC
+QgH///////////////////////////////////////////pRhoeDvy+Wa3/MAUj3
+CaXQO7XJuImcR667b7cekThkCQIBAQ==
+-----END EC PARAMETERS-----
+-----BEGIN EC PRIVATE KEY-----
+MIICnQIBAQRCAVE6lUKRj5AE8Cw21A+iPWhXSg+XNuerrTyeFERY6AtOrRJ9mTQ3
+Av3xjiM3zhZy2KWnm62hvkvlGbZ7iDKcqg2GoIIBxjCCAcICAQEwTQYHKoZIzj0B
+AQJCAf//////////////////////////////////////////////////////////
+////////////////////////////MIGeBEIB////////////////////////////
+//////////////////////////////////////////////////////////wEQVGV
+PrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ4VYZOVHsfpN7FlLAvTuxvwc1
+c9+IPSw08e9FH9RrUD8AAxUA0J6IACkcuFOWzGcXOTKEqqDaZLoEgYUEAMaFjga3
+BATpzZ4+y2YjlbRCnGSBOQU/tSH4KK9ga009uqFLXnfv51ko/h3BJ6L/qN4zSLPB
+hWpCm/l+fjHC5b1mARg5KWp4mjvABFyKX7QsfRvZmPVESVebRGgXr70XJz5mLJfu
+cple9CZAxVC5AT+tB2E1PHCGonLCQIi+lHaf0WZQAkIB////////////////////
+///////////////////////6UYaHg78vlmt/zAFI9wml0Du1ybiJnEeuu2+3HpE4
+ZAkCAQGhgYkDgYYABAFLBJzBphlIJmSPuXzTDTnZpL7A0fnyqit9V3TBvaOcL6Iw
+6m2TpXvNakxi8Flj0Ok4hdRt+YhawFs0bmzZCT8kfAFs7p55BPHk7FaMZaba77R8
+4V6MhUJSKLc0I/XQBtvoOgVlPJ0MPOndnIxPspCPll886yxG5kOMUAx3HjFg16RT
+eA==
+-----END EC PRIVATE KEY-----
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index 83a77d2a28..bb96c2237d 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1 +1 @@
-PUBLIC_KEY_VSN = 1.4.1
+PUBLIC_KEY_VSN = 1.5
diff --git a/lib/reltool/src/reltool.app.src b/lib/reltool/src/reltool.app.src
index 90f93d2901..dc21c1cfce 100644
--- a/lib/reltool/src/reltool.app.src
+++ b/lib/reltool/src/reltool.app.src
@@ -36,6 +36,6 @@
{registered, []},
{applications, [stdlib, kernel]},
{env, []},
- {runtime_dependencies, ["wx-1.2","tools-2.6.14","stdlib-2.0","sasl-2.4",
+ {runtime_dependencies, ["wx-1.2","tools-2.6.14","stdlib-3.4","sasl-2.4",
"kernel-3.0","erts-7.0"]}
]}.
diff --git a/lib/sasl/src/sasl.app.src b/lib/sasl/src/sasl.app.src
index d75543a91b..1e8e58a978 100644
--- a/lib/sasl/src/sasl.app.src
+++ b/lib/sasl/src/sasl.app.src
@@ -43,6 +43,6 @@
{env, [{sasl_error_logger, tty},
{errlog_type, all}]},
{mod, {sasl, []}},
- {runtime_dependencies, ["tools-2.6.14","stdlib-3.0","kernel-5.0",
- "erts-8.1"]}]}.
+ {runtime_dependencies, ["tools-2.6.14","stdlib-3.4","kernel-5.3",
+ "erts-9.0"]}]}.
diff --git a/lib/ssl/src/ssl.app.src b/lib/ssl/src/ssl.app.src
index 064dcd6892..51407ef3b9 100644
--- a/lib/ssl/src/ssl.app.src
+++ b/lib/ssl/src/ssl.app.src
@@ -63,7 +63,7 @@
{applications, [crypto, public_key, kernel, stdlib]},
{env, []},
{mod, {ssl_app, []}},
- {runtime_dependencies, ["stdlib-3.2","public_key-1.2","kernel-3.0",
+ {runtime_dependencies, ["stdlib-3.2","public_key-1.5","kernel-3.0",
"erts-7.0","crypto-3.3", "inets-5.10.7"]}]}.
diff --git a/lib/ssl/test/ssl_ECC_SUITE.erl b/lib/ssl/test/ssl_ECC_SUITE.erl
index 64e8042b25..f38c0a7416 100644
--- a/lib/ssl/test/ssl_ECC_SUITE.erl
+++ b/lib/ssl/test/ssl_ECC_SUITE.erl
@@ -232,103 +232,150 @@ end_per_testcase(_TestCase, Config) ->
%% ECDH_RSA
client_ecdh_rsa_server_ecdh_rsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
ecdh_rsa, ecdh_rsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdh_rsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_rsa_server_ecdh_rsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_rsa, ecdh_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_rsa, ecdh_rsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdh_rsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_ecdsa_server_ecdh_rsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdh_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdh_rsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdh_rsa} | proplists:delete(check_keyex, Config)]).
%% ECDHE_RSA
client_ecdh_rsa_server_ecdhe_rsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdh_rsa, ecdhe_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdh_rsa, ecdhe_rsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdhe_rsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_rsa_server_ecdhe_rsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_rsa, ecdhe_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_rsa, ecdhe_rsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdhe_rsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_ecdsa_server_ecdhe_rsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdh_ecdsa, ecdhe_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdh_ecdsa, ecdhe_rsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdhe_rsa} | proplists:delete(check_keyex, Config)]).
-
+
%% ECDH_ECDSA
client_ecdh_ecdsa_server_ecdh_ecdsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
- [{extensions, [{key_usage, [keyEncipherment]
- }]}]}],
+ Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain,
+ [[], [], [{extensions, Ext}]]},
+ {client_chain,
+ ssl_test_lib:default_cert_chain_conf()}],
ecdh_ecdsa, ecdh_ecdsa, Config),
basic_test(COpts, SOpts,
[{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_rsa_server_ecdh_ecdsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
- [{extensions, [{key_usage, [keyEncipherment]
- }]}]}],
- ecdhe_rsa, ecdh_ecdsa, Config),
- basic_test(COpts, SOpts, [{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
+ Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain,
+ [[], [], [{extensions, Ext}]]},
+ {client_chain,
+ ssl_test_lib:default_cert_chain_conf()}],
+ ecdhe_rsa, ecdh_ecdsa, Config),
+ basic_test(COpts, SOpts, [{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_ecdsa_server_ecdh_ecdsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
- [{extensions, [{key_usage, [keyEncipherment]
- }]}]}],
- ecdhe_ecdsa, ecdh_ecdsa, Config),
+ Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain,
+ [[], [], [{extensions, Ext}]]},
+ {client_chain,
+ ssl_test_lib:default_cert_chain_conf()}],
+ ecdhe_ecdsa, ecdh_ecdsa, Config),
basic_test(COpts, SOpts,
[{check_keyex, ecdh_ecdsa} | proplists:delete(check_keyex, Config)]).
%% ECDHE_ECDSA
client_ecdh_rsa_server_ecdhe_ecdsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdh_rsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdh_rsa, ecdhe_ecdsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdhe_ecdsa} | proplists:delete(check_keyex, Config)]).
client_ecdh_ecdsa_server_ecdhe_ecdsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdh_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdh_ecdsa, ecdhe_ecdsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdhe_ecdsa} | proplists:delete(check_keyex, Config)]).
client_ecdhe_ecdsa_server_ecdhe_ecdsa(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
basic_test(COpts, SOpts, [{check_keyex, ecdhe_ecdsa} | proplists:delete(check_keyex, Config)]).
client_ecdsa_server_ecdsa_with_raw_key(Config) when is_list(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}]
+ , ecdhe_ecdsa, ecdhe_ecdsa, Config),
ServerKeyFile = proplists:get_value(keyfile, SOpts),
{ok, PemBin} = file:read_file(ServerKeyFile),
PemEntries = public_key:pem_decode(PemBin),
- {'ECPrivateKey', Key, not_encrypted} = proplists:lookup('ECPrivateKey', PemEntries),
+ {'ECPrivateKey', Key, not_encrypted} = proplists:lookup('ECPrivateKey', PemEntries),
ServerKey = {'ECPrivateKey', Key},
SType = proplists:get_value(server_type, Config),
CType = proplists:get_value(client_type, Config),
{Server, Port} = start_server_with_raw_key(SType,
[{key, ServerKey} | proplists:delete(keyfile, SOpts)],
- Config),
+ Config),
Client = start_client(CType, Port, COpts, Config),
- check_result(Server, SType, Client, CType),
+ check_result(Server, SType, Client, CType),
close(Server, Client).
ecc_default_order(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [],
case supported_eccs([{eccs, [sect571r1]}]) of
true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
false -> {skip, "unsupported named curves"}
- end.
+ end.
ecc_default_order_custom_curves(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [{eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
- true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
false -> {skip, "unsupported named curves"}
end.
ecc_client_order(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [{honor_ecc_order, false}],
case supported_eccs([{eccs, [sect571r1]}]) of
- true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
+ true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
false -> {skip, "unsupported named curves"}
end.
ecc_client_order_custom_curves(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [{honor_ecc_order, false}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(sect571r1, COpts, SOpts, [], ECCOpts, Config);
@@ -336,45 +383,62 @@ ecc_client_order_custom_curves(Config) ->
end.
ecc_unknown_curve(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [{eccs, ['123_fake_curve']}],
ecc_test_error(COpts, SOpts, [], ECCOpts, Config).
client_ecdh_rsa_server_ecdhe_ecdsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdh_rsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdh_rsa, ecdhe_ecdsa, Config),
ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
- case supported_eccs(ECCOpts) of
- true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
- false -> {skip, "unsupported named curves"}
- end.
+ case supported_eccs(ECCOpts) of
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ false -> {skip, "unsupported named curves"}
+ end.
client_ecdh_rsa_server_ecdhe_rsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdh_rsa, ecdhe_rsa, Config),
- ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdh_rsa, ecdhe_rsa, Config),
+ ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
false -> {skip, "unsupported named curves"}
end.
client_ecdhe_rsa_server_ecdhe_ecdsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_rsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_rsa, ecdhe_ecdsa, Config),
ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
- true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
+ true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
false -> {skip, "unsupported named curves"}
end.
client_ecdhe_rsa_server_ecdhe_rsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_rsa, ecdhe_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_rsa, ecdhe_rsa, Config),
ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
false -> {skip, "unsupported named curves"}
- end.
+ end.
client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_peer_opts,
- [{extensions, [{key_usage, [keyEncipherment]
- }]}]}], ecdhe_rsa, ecdh_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ Ext = x509_test:extensions([{key_usage, [keyEncipherment]}]),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, [[], [], [{extensions, Ext}]]},
+ {client_chain, Default}],
+ ecdhe_rsa, ecdh_rsa, Config),
ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
@@ -382,7 +446,10 @@ client_ecdhe_rsa_server_ecdh_rsa_server_custom(Config) ->
end.
client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([], ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(secp256r1, COpts, SOpts, [], ECCOpts, Config);
@@ -390,7 +457,10 @@ client_ecdhe_ecdsa_server_ecdhe_ecdsa_server_custom(Config) ->
end.
client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_rsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_rsa, Config),
ECCOpts = [{honor_ecc_order, true}, {eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(undefined, COpts, SOpts, [], ECCOpts, Config);
@@ -398,7 +468,10 @@ client_ecdhe_ecdsa_server_ecdhe_rsa_server_custom(Config) ->
end.
client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_ecdsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_ecdsa, ecdhe_ecdsa, Config),
ECCOpts = [{eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config);
@@ -406,7 +479,10 @@ client_ecdhe_ecdsa_server_ecdhe_ecdsa_client_custom(Config) ->
end.
client_ecdhe_rsa_server_ecdhe_ecdsa_client_custom(Config) ->
- {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([],ecdhe_rsa, ecdhe_ecdsa, Config),
+ Default = ssl_test_lib:default_cert_chain_conf(),
+ {COpts, SOpts} = ssl_test_lib:make_ec_cert_chains([{server_chain, Default},
+ {client_chain, Default}],
+ ecdhe_rsa, ecdhe_ecdsa, Config),
ECCOpts = [{eccs, [secp256r1, sect571r1]}],
case supported_eccs(ECCOpts) of
true -> ecc_test(secp256r1, COpts, SOpts, ECCOpts, [], Config);
diff --git a/lib/ssl/test/ssl_certificate_verify_SUITE.erl b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
index c3fd73bf09..0bc265fa10 100644
--- a/lib/ssl/test/ssl_certificate_verify_SUITE.erl
+++ b/lib/ssl/test/ssl_certificate_verify_SUITE.erl
@@ -439,7 +439,7 @@ server_require_peer_cert_partial_chain_fun_fail(Config) when is_list(Config) ->
[{_,_,_}, {_, IntermidiateCA, _} | _] = public_key:pem_decode(ServerCAs),
PartialChain = fun(_CertChain) ->
- ture = false %% crash on purpose
+ ture = false %% crash on purpose
end,
Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
@@ -567,9 +567,12 @@ cert_expired() ->
cert_expired(Config) when is_list(Config) ->
{Year, Month, Day} = date(),
Active = proplists:get_value(active, Config),
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_ca_0,
- [{validity, {{Year-2, Month, Day},
- {Year-1, Month, Day}}}]}],
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],
+ [{validity, {{Year-2, Month, Day},
+ {Year-1, Month, Day}}}],
+ []
+ ]}],
Config, "_expired"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
@@ -598,11 +601,11 @@ extended_key_usage_verify_server() ->
[{doc,"Test cert that has a critical extended_key_usage extension in server cert"}].
extended_key_usage_verify_server(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
- [{extensions,
- [{?'id-ce-extKeyUsage',
- [?'id-kp-serverAuth'], true}]
- }]}], Config, "_keyusage_server"),
+ Ext = x509_test:extensions([{?'id-ce-extKeyUsage',
+ [?'id-kp-serverAuth'], true}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],[], [{extensions, Ext}]]}], Config,
+ "_keyusage_server"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
@@ -632,14 +635,13 @@ extended_key_usage_verify_both() ->
[{doc,"Test cert that has a critical extended_key_usage extension in client verify_peer mode"}].
extended_key_usage_verify_both(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
- [{extensions, [{?'id-ce-extKeyUsage',
- [?'id-kp-serverAuth'], true}]
- }]},
- {client_peer_opts,
- [{extensions, [{?'id-ce-extKeyUsage',
- [?'id-kp-clientAuth'], true}]
- }]}], Config, "_keyusage_both"),
+ ServerExt = x509_test:extensions([{?'id-ce-extKeyUsage',
+ [?'id-kp-serverAuth'], true}]),
+ ClientExt = x509_test:extensions([{?'id-ce-extKeyUsage',
+ [?'id-kp-clientAuth'], true}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_chain, [[],[],[{extensions, ClientExt}]]},
+ {server_chain, [[],[],[{extensions, ServerExt}]]}],
+ Config, "_keyusage_both"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
@@ -668,10 +670,10 @@ critical_extension_verify_server() ->
[{doc,"Test cert that has a critical unknown extension in verify_peer mode"}].
critical_extension_verify_server(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_peer_opts,
- [{extensions, [{{2,16,840,1,113730,1,1},
- <<3,2,6,192>>, true}]
- }]}], Config, "_client_unknown_extension"),
+ Ext = x509_test:extensions([{{2,16,840,1,113730,1,1}, <<3,2,6,192>>, true}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_chain,
+ [[],[], [{extensions, Ext}]]}],
+ Config, "_client_unknown_extension"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
@@ -705,10 +707,10 @@ critical_extension_verify_client() ->
[{doc,"Test cert that has a critical unknown extension in verify_peer mode"}].
critical_extension_verify_client(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
- [{extensions, [{{2,16,840,1,113730,1,1},
- <<3,2,6,192>>, true}]
- }]}], Config, "_server_unknown_extensions"),
+ Ext = x509_test:extensions([{{2,16,840,1,113730,1,1}, <<3,2,6,192>>, true}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],[],[{extensions, Ext}]]}],
+ Config, "_server_unknown_extensions"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
@@ -741,11 +743,10 @@ critical_extension_verify_none() ->
[{doc,"Test cert that has a critical unknown extension in verify_none mode"}].
critical_extension_verify_none(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_peer_opts,
- [{extensions,
- [{{2,16,840,1,113730,1,1},
- <<3,2,6,192>>, true}]
- }]}], Config, "_unknown_extensions"),
+ Ext = x509_test:extensions([{{2,16,840,1,113730,1,1}, <<3,2,6,192>>, true}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_chain,
+ [[],[], [{extensions, Ext}]]}],
+ Config, "_unknown_extensions"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
Active = proplists:get_value(active, Config),
@@ -780,12 +781,7 @@ no_authority_key_identifier() ->
" but are present in trusted certs db."}].
no_authority_key_identifier(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
- [{extensions, [{auth_key_id, undefined}]
- }]},
- {client_peer_opts,
- [{extensions, [{auth_key_id, undefined}]
- }]}], Config, "_peer_no_auth_key_id"),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([], Config, "_peer_no_auth_key_id"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
@@ -822,14 +818,10 @@ no_authority_key_identifier_keyEncipherment() ->
" authorityKeyIdentifier extension, but are present in trusted certs db."}].
no_authority_key_identifier_keyEncipherment(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{server_peer_opts,
- [{extensions, [{auth_key_id, undefined},
- {key_usage, [digitalSignature,
- keyEncipherment]}]
- }]},
- {client_peer_opts,
- [{extensions, [{auth_key_id, undefined}]
- }]}], Config, "_peer_keyEncipherment"),
+ ClientExt = x509_test:extensions([{key_usage, [digitalSignature, keyEncipherment]}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_chain,
+ [[],[],[{extensions, ClientExt}]]}],
+ Config, "_peer_keyEncipherment"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
{ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
@@ -932,12 +924,10 @@ client_with_cert_cipher_suites_handshake() ->
[{doc, "Test that client with a certificate without keyEncipherment usage "
" extension can connect to a server with restricted cipher suites "}].
client_with_cert_cipher_suites_handshake(Config) when is_list(Config) ->
- {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_peer_opts,
- [{extensions,
- [{key_usage, [digitalSignature]}]
- }]}], Config, "_sign_only_extensions"),
-
-
+ Ext = x509_test:extensions([{key_usage, [digitalSignature]}]),
+ {ClientOpts0, ServerOpts0} = ssl_test_lib:make_rsa_cert_chains([{client_chain,
+ [[], [], [{extensions, Ext}]]}],
+ Config, "_sign_only_extensions"),
ClientOpts = ssl_test_lib:ssl_options(ClientOpts0, Config),
ServerOpts = ssl_test_lib:ssl_options(ServerOpts0, Config),
diff --git a/lib/ssl/test/ssl_test_lib.erl b/lib/ssl/test/ssl_test_lib.erl
index a5f03a1f15..4e7252f469 100644
--- a/lib/ssl/test/ssl_test_lib.erl
+++ b/lib/ssl/test/ssl_test_lib.erl
@@ -449,11 +449,12 @@ make_dsa_cert(Config) ->
CryptoSupport = crypto:supports(),
case proplists:get_bool(dss, proplists:get_value(public_keys, CryptoSupport)) of
true ->
+ ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()),
+ CertChainConf = gen_conf(dsa, dsa, ClientChain, ServerChain),
ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "dsa"]),
ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "dsa"]),
- KeyGenSpec = key_gen_info(dsa, dsa),
-
- GenCertData = x509_test:gen_test_certs([{digest, sha} | KeyGenSpec]),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
[{server_config, ServerConf},
{client_config, ClientConf}] =
x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
@@ -469,12 +470,13 @@ make_dsa_cert(Config) ->
false ->
Config
end.
-make_rsa_cert_chains(ChainConf, Config, Suffix) ->
- CryptoSupport = crypto:supports(),
- KeyGenSpec = key_gen_info(rsa, rsa),
+make_rsa_cert_chains(UserConf, Config, Suffix) ->
+ ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()),
+ CertChainConf = gen_conf(rsa, rsa, ClientChain, ServerChain),
ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa" ++ Suffix]),
ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa" ++ Suffix]),
- GenCertData = x509_test:gen_test_certs([{digest, appropriate_sha(CryptoSupport)} | KeyGenSpec] ++ ChainConf),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
[{server_config, ServerConf},
{client_config, ClientConf}] =
x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
@@ -482,12 +484,13 @@ make_rsa_cert_chains(ChainConf, Config, Suffix) ->
[{reuseaddr, true}, {verify, verify_peer} | ServerConf]
}.
-make_ec_cert_chains(ChainConf, ClientChainType, ServerChainType, Config) ->
- CryptoSupport = crypto:supports(),
- KeyGenSpec = key_gen_info(ClientChainType, ServerChainType),
+make_ec_cert_chains(UserConf, ClientChainType, ServerChainType, Config) ->
+ ClientChain = proplists:get_value(client_chain, UserConf, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, UserConf, default_cert_chain_conf()),
+ CertChainConf = gen_conf(ClientChainType, ServerChainType, ClientChain, ServerChain),
ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(ClientChainType)]),
ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), atom_to_list(ServerChainType)]),
- GenCertData = x509_test:gen_test_certs([{digest, appropriate_sha(CryptoSupport)} | KeyGenSpec] ++ ChainConf),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
[{server_config, ServerConf},
{client_config, ClientConf}] =
x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
@@ -495,56 +498,113 @@ make_ec_cert_chains(ChainConf, ClientChainType, ServerChainType, Config) ->
[{reuseaddr, true}, {verify, verify_peer} | ServerConf]
}.
-key_gen_info(ClientChainType, ServerChainType) ->
- key_gen_spec("client", ClientChainType) ++ key_gen_spec("server", ServerChainType).
+default_cert_chain_conf() ->
+ %% Use only default options
+ [[],[],[]].
+
+gen_conf(ClientChainType, ServerChainType, UserClient, UserServer) ->
+ ClientTag = conf_tag("client"),
+ ServerTag = conf_tag("server"),
+
+ DefaultClient = chain_spec(client, ClientChainType),
+ DefaultServer = chain_spec(server, ServerChainType),
+
+ ClientConf = merge_chain_spec(UserClient, DefaultClient, []),
+ ServerConf = merge_chain_spec(UserServer, DefaultServer, []),
+
+ new_format([{ClientTag, ClientConf}, {ServerTag, ServerConf}]).
+
+new_format(Conf) ->
+ CConf = proplists:get_value(client_chain, Conf),
+ SConf = proplists:get_value(server_chain, Conf),
+ #{server_chain => proplist_to_map(SConf),
+ client_chain => proplist_to_map(CConf)}.
+
+proplist_to_map([Head | Rest]) ->
+ [Last | Tail] = lists:reverse(Rest),
+ #{root => Head,
+ intermediates => lists:reverse(Tail),
+ peer => Last}.
+
+conf_tag(Role) ->
+ list_to_atom(Role ++ "_chain").
-key_gen_spec(Role, ecdh_rsa) ->
+chain_spec(_Role, ecdh_rsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
CurveOid = hd(tls_v1:ecc_curves(0)),
- [{list_to_atom(Role ++ "_key_gen"), {namedCurve, CurveOid}},
- {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_rsa_key(1),
- {namedCurve, CurveOid}]}
- ];
-key_gen_spec(Role, ecdhe_ecdsa) ->
+ [[Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, hardcode_rsa_key(1)}],
+ [Digest, {key, {namedCurve, CurveOid}}]];
+
+chain_spec(_Role, ecdhe_ecdsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
CurveOid = hd(tls_v1:ecc_curves(0)),
- [{list_to_atom(Role ++ "_key_gen"), {namedCurve, CurveOid}},
- {list_to_atom(Role ++ "_key_gen_chain"), [{namedCurve, CurveOid},
- {namedCurve, CurveOid}]}
- ];
-key_gen_spec(Role, ecdh_ecdsa) ->
+ [[Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, {namedCurve, CurveOid}}]];
+
+chain_spec(_Role, ecdh_ecdsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
CurveOid = hd(tls_v1:ecc_curves(0)),
- [{list_to_atom(Role ++ "_key_gen"), {namedCurve, CurveOid}},
- {list_to_atom(Role ++ "_key_gen_chain"), [{namedCurve, CurveOid},
- {namedCurve, CurveOid}]}
- ];
-key_gen_spec(Role, ecdhe_rsa) ->
- [{list_to_atom(Role ++ "_key_gen"), hardcode_rsa_key(1)},
- {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_rsa_key(2),
- hardcode_rsa_key(3)]}
- ];
-key_gen_spec(Role, rsa) ->
- [{list_to_atom(Role ++ "_key_gen"), hardcode_rsa_key(1)},
- {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_rsa_key(2),
- hardcode_rsa_key(3)]}
- ];
-key_gen_spec(Role, dsa) ->
- [{list_to_atom(Role ++ "_key_gen"), hardcode_dsa_key(1)},
- {list_to_atom(Role ++ "_key_gen_chain"), [hardcode_dsa_key(2),
- hardcode_dsa_key(3)]}
- ].
+ [[Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, {namedCurve, CurveOid}}]];
+chain_spec(_Role, ecdhe_rsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
+ [[Digest, {key, hardcode_rsa_key(1)}],
+ [Digest, {key, hardcode_rsa_key(2)}],
+ [Digest, {key, hardcode_rsa_key(3)}]];
+chain_spec(_Role, ecdsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
+ CurveOid = hd(tls_v1:ecc_curves(0)),
+ [[Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, {namedCurve, CurveOid}}],
+ [Digest, {key, {namedCurve, CurveOid}}]];
+chain_spec(_Role, rsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
+ [[Digest, {key, hardcode_rsa_key(1)}],
+ [Digest, {key, hardcode_rsa_key(2)}],
+ [Digest, {key, hardcode_rsa_key(3)}]];
+chain_spec(_Role, dsa) ->
+ Digest = {digest, appropriate_sha(crypto:supports())},
+ [[Digest, {key, hardcode_dsa_key(1)}],
+ [Digest, {key, hardcode_dsa_key(2)}],
+ [Digest, {key, hardcode_dsa_key(3)}]].
+
+merge_chain_spec([], [], Acc)->
+ lists:reverse(Acc);
+merge_chain_spec([User| UserRest], [Default | DefaultRest], Acc) ->
+ Merge = merge_spec(User, Default, confs(), []),
+ merge_chain_spec(UserRest, DefaultRest, [Merge | Acc]).
+
+confs() ->
+ [key, digest, validity, extensions].
+
+merge_spec(_, _, [], Acc) ->
+ Acc;
+merge_spec(User, Default, [Conf | Rest], Acc) ->
+ case proplists:get_value(Conf, User, undefined) of
+ undefined ->
+ case proplists:get_value(Conf, Default, undefined) of
+ undefined ->
+ merge_spec(User, Default, Rest, Acc);
+ Value ->
+ merge_spec(User, Default, Rest, [{Conf, Value} | Acc])
+ end;
+ Value ->
+ merge_spec(User, Default, Rest, [{Conf, Value} | Acc])
+ end.
+
make_ecdsa_cert(Config) ->
CryptoSupport = crypto:supports(),
case proplists:get_bool(ecdsa, proplists:get_value(public_keys, CryptoSupport)) of
true ->
ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa"]),
ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdsa"]),
- CurveOid = hd(tls_v1:ecc_curves(0)),
- GenCertData = x509_test:gen_test_certs([{server_key_gen, {namedCurve, CurveOid}},
- {client_key_gen, {namedCurve, CurveOid}},
- {server_key_gen_chain, [{namedCurve, CurveOid},
- {namedCurve, CurveOid}]},
- {client_key_gen_chain, [{namedCurve, CurveOid},
- {namedCurve, CurveOid}]},
- {digest, appropriate_sha(CryptoSupport)}]),
+ ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()),
+ CertChainConf = gen_conf(ecdsa, ecdsa, ClientChain, ServerChain),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
[{server_config, ServerConf},
{client_config, ClientConf}] =
x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
@@ -563,13 +623,10 @@ make_rsa_cert(Config) ->
true ->
ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa"]),
ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "rsa"]),
- GenCertData = x509_test:gen_test_certs([{server_key_gen, hardcode_rsa_key(1)},
- {client_key_gen, hardcode_rsa_key(2)},
- {server_key_gen_chain, [hardcode_rsa_key(3),
- hardcode_rsa_key(4)]},
- {client_key_gen_chain, [hardcode_rsa_key(5),
- hardcode_rsa_key(6)]},
- {digest, appropriate_sha(CryptoSupport)}]),
+ ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()),
+ CertChainConf = gen_conf(rsa, rsa, ClientChain, ServerChain),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
[{server_config, ServerConf},
{client_config, ClientConf}] =
x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
@@ -601,16 +658,10 @@ make_ecdh_rsa_cert(Config) ->
true ->
ClientFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdh_rsa"]),
ServerFileBase = filename:join([proplists:get_value(priv_dir, Config), "ecdh_rsa"]),
- CurveOid = hd(tls_v1:ecc_curves(0)),
- GenCertData = x509_test:gen_test_certs([{server_key_gen, {namedCurve, CurveOid}},
- {client_key_gen, {namedCurve, CurveOid}},
- {server_key_gen_chain, [hardcode_rsa_key(1),
- {namedCurve, CurveOid}
- ]},
- {client_key_gen_chain, [hardcode_rsa_key(2),
- {namedCurve, CurveOid}
- ]},
- {digest, appropriate_sha(CryptoSupport)}]),
+ ClientChain = proplists:get_value(client_chain, Config, default_cert_chain_conf()),
+ ServerChain = proplists:get_value(server_chain, Config, default_cert_chain_conf()),
+ CertChainConf = gen_conf(ecdh_rsa, ecdh_rsa, ClientChain, ServerChain),
+ GenCertData = public_key:pkix_test_data(CertChainConf),
[{server_config, ServerConf},
{client_config, ClientConf}] =
x509_test:gen_pem_config_files(GenCertData, ClientFileBase, ServerFileBase),
@@ -1509,73 +1560,79 @@ tls_version(Atom) ->
tls_record:protocol_version(Atom).
hardcode_rsa_key(1) ->
- {'RSAPrivateKey', 'two-prime',
- 23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669,
- 17,
- 11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657,
- 169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197,
- 141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577,
- 119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609,
- 41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993,
- 76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441,
- asn1_NOVALUE};
+ #'RSAPrivateKey'{
+ version = 'two-prime',
+ modulus = 23995666614853919027835084074500048897452890537492185072956789802729257783422306095699263934587064480357348855732149402060270996295002843755712064937715826848741191927820899197493902093529581182351132392364214171173881547273475904587683433713767834856230531387991145055273426806331200574039205571401702219159773947658558490957010003143162250693492642996408861265758000254664396313741422909188635443907373976005987612936763564996605457102336549804831742940035613780926178523017685712710473543251580072875247250504243621640157403744718833162626193206685233710319205099867303242759099560438381385658382486042995679707669,
+ publicExponent = 17,
+ privateExponent = 11292078406990079542510627799764728892919007311761028269626724613049062486316379339152594792746853873109340637991599718616598115903530750002688030558925094987642913848386305504703012749896273497577003478759630198199473669305165131570674557041773098755873191241407597673069847908861741446606684974777271632545629600685952292605647052193819136445675100211504432575554351515262198132231537860917084269870590492135731720141577986787033006338680118008484613510063003323516659048210893001173583018220214626635609151105287049126443102976056146630518124476470236027123782297108342869049542023328584384300970694412006494684657,
+ prime1 = 169371138592582642967021557955633494538845517070305333860805485424261447791289944610138334410987654265476540480228705481960508520379619587635662291973699651583489223555422528867090299996446070521801757353675026048850480903160224210802452555900007597342687137394192939372218903554801584969667104937092080815197,
+ prime2 = 141675062317286527042995673340952251894209529891636708844197799307963834958115010129693036021381525952081167155681637592199810112261679449166276939178032066869788822014115556349519329537177920752776047051833616197615329017439297361972726138285974555338480581117881706656603857310337984049152655480389797687577,
+ exponent1 = 119556097830058336212015217380447172615655659108450823901745048534772786676204666783627059584226579481512852103690850928442711896738555003036938088452023283470698275450886490965004917644550167427154181661417665446247398284583687678213495921811770068712485038160606780733330990744565824684470897602653233516609,
+ exponent2 = 41669135975672507953822256864985956439473391144599032012999352737636422046504414744027363535700448809435637398729893409470532385959317485048904982111185902020526124121798693043976273393287623750816484427009887116945685005129205106462566511260580751570141347387612266663707016855981760014456663376585234613993,
+ coefficient = 76837684977089699359024365285678488693966186052769523357232308621548155587515525857011429902602352279058920284048929101483304120686557782043616693940283344235057989514310975192908256494992960578961614059245280827077951132083993754797053182279229469590276271658395444955906108899267024101096069475145863928441,
+ otherPrimeInfos = asn1_NOVALUE};
hardcode_rsa_key(2) ->
-{'RSAPrivateKey', 'two-prime',
- 21343679768589700771839799834197557895311746244621307033143551583788179817796325695589283169969489517156931770973490560582341832744966317712674900833543896521418422508485833901274928542544381247956820115082240721897193055368570146764204557110415281995205343662628196075590438954399631753508888358737971039058298703003743872818150364935790613286541190842600031570570099801682794056444451081563070538409720109449780410837763602317050353477918147758267825417201591905091231778937606362076129350476690460157227101296599527319242747999737801698427160817755293383890373574621116766934110792127739174475029121017282777887777,
- 17,
- 18832658619343853622211588088997845201745658451136447382185486691577805721584993260814073385267196632785528033211903435807948675951440868570007265441362261636545666919252206383477878125774454042314841278013741813438699754736973658909592256273895837054592950290554290654932740253882028017801960316533503857992358685308186680144968293076156011747178275038098868263178095174694099811498968993700538293188879611375604635940554394589807673542938082281934965292051746326331046224291377703201248790910007232374006151098976879987912446997911775904329728563222485791845480864283470332826504617837402078265424772379987120023773,
- 146807662748886761089048448970170315054939768171908279335181627815919052012991509112344782731265837727551849787333310044397991034789843793140419387740928103541736452627413492093463231242466386868459637115999163097726153692593711599245170083315894262154838974616739452594203727376460632750934355508361223110419,
- 145385325050081892763917667176962991350872697916072592966410309213561884732628046256782356731057378829876640317801978404203665761131810712267778698468684631707642938779964806354584156202882543264893826268426566901882487709510744074274965029453915224310656287149777603803201831202222853023280023478269485417083,
- 51814469205489445090252393754177758254684624060673510353593515699736136004585238510239335081623236845018299924941168250963996835808180162284853901555621683602965806809675350150634081614988136541809283687999704622726877773856604093851236499993845033701707873394143336209718962603456693912094478414715725803677,
- 51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029,
- 30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540,
- asn1_NOVALUE};
-
+ #'RSAPrivateKey'{
+ version = 'two-prime',
+ modulus = 21343679768589700771839799834197557895311746244621307033143551583788179817796325695589283169969489517156931770973490560582341832744966317712674900833543896521418422508485833901274928542544381247956820115082240721897193055368570146764204557110415281995205343662628196075590438954399631753508888358737971039058298703003743872818150364935790613286541190842600031570570099801682794056444451081563070538409720109449780410837763602317050353477918147758267825417201591905091231778937606362076129350476690460157227101296599527319242747999737801698427160817755293383890373574621116766934110792127739174475029121017282777887777,
+ publicExponent = 17,
+ privateExponent = 18832658619343853622211588088997845201745658451136447382185486691577805721584993260814073385267196632785528033211903435807948675951440868570007265441362261636545666919252206383477878125774454042314841278013741813438699754736973658909592256273895837054592950290554290654932740253882028017801960316533503857992358685308186680144968293076156011747178275038098868263178095174694099811498968993700538293188879611375604635940554394589807673542938082281934965292051746326331046224291377703201248790910007232374006151098976879987912446997911775904329728563222485791845480864283470332826504617837402078265424772379987120023773,
+ prime1 = 146807662748886761089048448970170315054939768171908279335181627815919052012991509112344782731265837727551849787333310044397991034789843793140419387740928103541736452627413492093463231242466386868459637115999163097726153692593711599245170083315894262154838974616739452594203727376460632750934355508361223110419,
+ prime2 = 145385325050081892763917667176962991350872697916072592966410309213561884732628046256782356731057378829876640317801978404203665761131810712267778698468684631707642938779964806354584156202882543264893826268426566901882487709510744074274965029453915224310656287149777603803201831202222853023280023478269485417083,
+ exponent1 = 51814469205489445090252393754177758254684624060673510353593515699736136004585238510239335081623236845018299924941168250963996835808180162284853901555621683602965806809675350150634081614988136541809283687999704622726877773856604093851236499993845033701707873394143336209718962603456693912094478414715725803677,
+ exponent2 = 51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029,
+ coefficient = 30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540,
+ otherPrimeInfos = asn1_NOVALUE};
hardcode_rsa_key(3) ->
-{'RSAPrivateKey', 'two-prime',
- 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429,
- 17,
- 8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265,
- 171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823,
- 146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523,
- 60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349,
- 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609,
- 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612,
- asn1_NOVALUE};
+ #'RSAPrivateKey'{
+ version = 'two-prime',
+ modulus = 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429,
+ publicExponent = 17,
+ privateExponent = 8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265,
+ prime1 = 171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823,
+ prime2 =146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523,
+ exponent1 = 60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349,
+ exponent2 = 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609,
+ coefficient = 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612,
+ otherPrimeInfos = asn1_NOVALUE};
hardcode_rsa_key(4) ->
-{'RSAPrivateKey', 'two-prime',
- 28617237755030755643854803617273584643843067580642149032833640135949799721163782522787597288521902619948688786051081993247908700824196122780349730169173433743054172191054872553484065655968335396052034378669869864779940355219732200954630251223541048434478476115391643898092650304645086338265930608997389611376417609043761464100338332976874588396803891301015812818307951159858145399281035705713082131199940309445719678087542976246147777388465712394062188801177717719764254900022006288880246925156931391594131839991579403409541227225173269459173129377291869028712271737734702830877034334838181789916127814298794576266389,
- 17,
- 26933870828264240605980991639786903194205240075898493207372837775011576208154148256741268036255908348187001210401018346586267012540419880263858569570986761169933338532757527109161473558558433313931326474042230460969355628442100895016122589386862163232450330461545076609969553227901257730132640573174013751883368376011370428995523268034111482031427024082719896108094847702954695363285832195666458915142143884210891427766607838346722974883433132513540317964796373298134261669479023445911856492129270184781873446960437310543998533283339488055776892320162032014809906169940882070478200435536171854883284366514852906334641,
- 177342190816702392178883147766999616783253285436834252111702533617098994535049411784501174309695427674025956656849179054202187436663487378682303508229883753383891163725167367039879190685255046547908384208614573353917213168937832054054779266431207529839577747601879940934691505396807977946728204814969824442867,
- 161367340863680900415977542864139121629424927689088951345472941851682581254789586032968359551717004797621579428672968948552429138154521719743297455351687337112710712475376510559020211584326773715482918387500187602625572442687231345855402020688502483137168684570635690059254866684191216155909970061793538842967,
- 62591361464718491357252875682470452982324688977706206627659717747211409835899792394529826226951327414362102349476180842659595565881230839534930649963488383547255704844176717778780890830090016428673547367746320007264898765507470136725216211681602657590439205035957626212244060728285168687080542875871702744541,
- 28476589564178982426348978152495139111074987239250991413906989738532220221433456358759122273832412611344984605059935696803369847909621479954699550944415412431654831613301737157474154985469430655673456186029444871051571607533040825739188591886206320553618003159523945304574388238386685203984112363845918619347,
- 34340318160575773065401929915821192439103777558577109939078671096408836197675640654693301707202885840826672396546056002756167635035389371579540325327619480512374920136684787633921441576901246290213545161954865184290700344352088099063404416346968182170720521708773285279884132629954461545103181082503707725012,
- asn1_NOVALUE};
+ #'RSAPrivateKey'{
+ version ='two-prime',
+ modulus = 28617237755030755643854803617273584643843067580642149032833640135949799721163782522787597288521902619948688786051081993247908700824196122780349730169173433743054172191054872553484065655968335396052034378669869864779940355219732200954630251223541048434478476115391643898092650304645086338265930608997389611376417609043761464100338332976874588396803891301015812818307951159858145399281035705713082131199940309445719678087542976246147777388465712394062188801177717719764254900022006288880246925156931391594131839991579403409541227225173269459173129377291869028712271737734702830877034334838181789916127814298794576266389,
+ publicExponent = 17,
+ privateExponent = 26933870828264240605980991639786903194205240075898493207372837775011576208154148256741268036255908348187001210401018346586267012540419880263858569570986761169933338532757527109161473558558433313931326474042230460969355628442100895016122589386862163232450330461545076609969553227901257730132640573174013751883368376011370428995523268034111482031427024082719896108094847702954695363285832195666458915142143884210891427766607838346722974883433132513540317964796373298134261669479023445911856492129270184781873446960437310543998533283339488055776892320162032014809906169940882070478200435536171854883284366514852906334641,
+ prime1 = 177342190816702392178883147766999616783253285436834252111702533617098994535049411784501174309695427674025956656849179054202187436663487378682303508229883753383891163725167367039879190685255046547908384208614573353917213168937832054054779266431207529839577747601879940934691505396807977946728204814969824442867,
+ prime2 = 161367340863680900415977542864139121629424927689088951345472941851682581254789586032968359551717004797621579428672968948552429138154521719743297455351687337112710712475376510559020211584326773715482918387500187602625572442687231345855402020688502483137168684570635690059254866684191216155909970061793538842967,
+ exponent1 = 62591361464718491357252875682470452982324688977706206627659717747211409835899792394529826226951327414362102349476180842659595565881230839534930649963488383547255704844176717778780890830090016428673547367746320007264898765507470136725216211681602657590439205035957626212244060728285168687080542875871702744541,
+ exponent2 = 28476589564178982426348978152495139111074987239250991413906989738532220221433456358759122273832412611344984605059935696803369847909621479954699550944415412431654831613301737157474154985469430655673456186029444871051571607533040825739188591886206320553618003159523945304574388238386685203984112363845918619347,
+ coefficient = 34340318160575773065401929915821192439103777558577109939078671096408836197675640654693301707202885840826672396546056002756167635035389371579540325327619480512374920136684787633921441576901246290213545161954865184290700344352088099063404416346968182170720521708773285279884132629954461545103181082503707725012,
+ otherPrimeInfos = asn1_NOVALUE};
+
hardcode_rsa_key(5) ->
-{'RSAPrivateKey', 'two-prime',
- 26363170152814518327068346871197765236382539835597898797762992537312221863402655353436079974302838986536256364057947538018476963115004626096654613827403121905035011992899481598437933532388248462251770039307078647864188314916665766359828262009578648593031111569685489178543405615478739906285223620987558499488359880003693226535420421293716164794046859453204135383236667988765227190694994861629971618548127529849059769249520775574008363789050621665120207265361610436965088511042779948238320901918522125988916609088415989475825860046571847719492980547438560049874493788767083330042728150253120940100665370844282489982633,
- 17,
- 10855423004100095781734025182257903332628104638187370093196526338893267826106975733767797636477639582691399679317978398007608161282648963686857782164224814902073240232370374775827384395689278778574258251479385325591136364965685903795223402003944149420659869469870495544106108194608892902588033255700759382142132115013969680562678811046675523365751498355532768935784747314021422035957153013494814430893022253205880275287307995039363642554998244274484818208792520243113824379110193356010059999642946040953102866271737127640405568982049887176990990501963784502429481034227543991366980671390566584211881030995602076468001,
- 163564135568104310461344551909369650951960301778977149705601170951529791054750122905880591964737953456660497440730575925978769763154927541340839715938951226089095007207042122512586007411328664679011914120351043948122025612160733403945093961374276707993674792189646478659304624413958625254578122842556295400709,
- 161179405627326572739107057023381254841260287988433675196680483761672455172873134522398837271764104320975746111042211695289319249471386600030523328069395763313848583139553961129874895374324504709512019736703349829576024049432816885712623938437949550266365056310544300920756181033500610331519029869549723159637,
- 115457036871603042678596154288966812436677860079277988027483179495197499568058910286503947269226790675289762899339230065396778656344654735064122152427494983121714122734382674714766593466820233891067233496718383963380253373289929461608301619793607087995535147427985749641862087821617853120878674947686796753441,
- 142217122612346975946270932667689342506994371754500301644129838613240401623123353990351915239791856753802128921507833848784693455415929352968108818884760967629866396887841730408713142977345151214275311532385308673155315337734838428569962298621720191411498579097539089047726042088382891468987379296661520434973,
- 40624877259097915043489529504071755460170951428490878553842519165800720914888257733191322215286203357356050737713125202129282154441426952501134581314792133018830748896123382106683994268028624341502298766844710276939303555637478596035491641473828661569958212421472263269629366559343208764012473880251174832392,
- asn1_NOVALUE};
+ #'RSAPrivateKey'{
+ version= 'two-prime',
+ modulus = 26363170152814518327068346871197765236382539835597898797762992537312221863402655353436079974302838986536256364057947538018476963115004626096654613827403121905035011992899481598437933532388248462251770039307078647864188314916665766359828262009578648593031111569685489178543405615478739906285223620987558499488359880003693226535420421293716164794046859453204135383236667988765227190694994861629971618548127529849059769249520775574008363789050621665120207265361610436965088511042779948238320901918522125988916609088415989475825860046571847719492980547438560049874493788767083330042728150253120940100665370844282489982633,
+ publicExponent = 17,
+ privateExponent = 10855423004100095781734025182257903332628104638187370093196526338893267826106975733767797636477639582691399679317978398007608161282648963686857782164224814902073240232370374775827384395689278778574258251479385325591136364965685903795223402003944149420659869469870495544106108194608892902588033255700759382142132115013969680562678811046675523365751498355532768935784747314021422035957153013494814430893022253205880275287307995039363642554998244274484818208792520243113824379110193356010059999642946040953102866271737127640405568982049887176990990501963784502429481034227543991366980671390566584211881030995602076468001,
+ prime1 =163564135568104310461344551909369650951960301778977149705601170951529791054750122905880591964737953456660497440730575925978769763154927541340839715938951226089095007207042122512586007411328664679011914120351043948122025612160733403945093961374276707993674792189646478659304624413958625254578122842556295400709,
+ prime2 = 161179405627326572739107057023381254841260287988433675196680483761672455172873134522398837271764104320975746111042211695289319249471386600030523328069395763313848583139553961129874895374324504709512019736703349829576024049432816885712623938437949550266365056310544300920756181033500610331519029869549723159637,
+ exponent1 = 115457036871603042678596154288966812436677860079277988027483179495197499568058910286503947269226790675289762899339230065396778656344654735064122152427494983121714122734382674714766593466820233891067233496718383963380253373289929461608301619793607087995535147427985749641862087821617853120878674947686796753441,
+ exponent2 = 142217122612346975946270932667689342506994371754500301644129838613240401623123353990351915239791856753802128921507833848784693455415929352968108818884760967629866396887841730408713142977345151214275311532385308673155315337734838428569962298621720191411498579097539089047726042088382891468987379296661520434973,
+ coefficient = 40624877259097915043489529504071755460170951428490878553842519165800720914888257733191322215286203357356050737713125202129282154441426952501134581314792133018830748896123382106683994268028624341502298766844710276939303555637478596035491641473828661569958212421472263269629366559343208764012473880251174832392,
+ otherPrimeInfos = asn1_NOVALUE};
hardcode_rsa_key(6) ->
-{'RSAPrivateKey', 'two-prime',
- 22748888494866396715768692484866595111939200209856056370972713870125588774286266397044592487895293134537316190976192161177144143633669641697309689280475257429554879273045671863645233402796222694405634510241820106743648116753479926387434021380537483429927516962909367257212902212159798399531316965145618774905828756510318897899298783143203190245236381440043169622358239226123652592179006905016804587837199618842875361941208299410035232803124113612082221121192550063791073372276763648926636149384299189072950588522522800393261949880796214514243704858378436010975184294077063518776479282353562934591448646412389762167039,
- 17,
- 6690849557313646092873144848490175032923294179369428344403739373566349639495960705013115437616262686628622409110644753287395336362844012263914614494257428655751435080307550548130951000822418439531068973600535325512837681398082331290421770994275730420566916753796872722709677121223470117509210872101652580854566448661533030419787125312956120661097410038933324613372774190658239039998357548275441758790939430824924502690997433186652165055694361752689819209062683281242276039100201318203707142383491769671330743466041394101421674581185260900666085723130684175548215193875544802254923825103844262661010117443222587769713,
- 164748737139489923768181260808494855987398781964531448608652166632780898215212977127034263859971474195908846263894581556691971503119888726148555271179103885786024920582830105413607436718060544856016793981261118694063993837665813285582095833772675610567592660039821387740255651489996976698808018635344299728063,
- 138082323967104548254375818343885141517788525705334488282154811252858957969378263753268344088034079842223206527922445018725900110643394926788280539200323021781309918753249061620424428562366627334409266756720941754364262467100514166396917565961434203543659974860389803369482625510495464845206228470088664021953,
- 19382204369351755737433089506881747763223386113474288071606137250915399790025056132592266336467232258342217207517009594904937823896457497193947678962247515974826461245038835931012639613889475865413740468383661022831058098548919210068481862796785365949128548239978986792971253116470232552800943368864035262125,
- 48734937870742781736838524121371226418043009072470995864289933383361985165662916618800592031070851709019955245149098241903258862580021738866451955011878713569874088971734962924855680669070574353320917678842685325069739694270769705787147376221682660074232932303666989424523279591939575827719845342384234360689,
- 81173034184183681160439870161505779100040258708276674532866007896310418779840630960490793104541748007902477778658270784073595697910785917474138815202903114440800310078464142273778315781957021015333260021813037604142367434117205299831740956310682461174553260184078272196958146289378701001596552915990080834227,
- asn1_NOVALUE}.
+ #'RSAPrivateKey'{
+ version = 'two-prime',
+ modulus = 22748888494866396715768692484866595111939200209856056370972713870125588774286266397044592487895293134537316190976192161177144143633669641697309689280475257429554879273045671863645233402796222694405634510241820106743648116753479926387434021380537483429927516962909367257212902212159798399531316965145618774905828756510318897899298783143203190245236381440043169622358239226123652592179006905016804587837199618842875361941208299410035232803124113612082221121192550063791073372276763648926636149384299189072950588522522800393261949880796214514243704858378436010975184294077063518776479282353562934591448646412389762167039,
+ publicExponent = 17,
+ privateExponent = 6690849557313646092873144848490175032923294179369428344403739373566349639495960705013115437616262686628622409110644753287395336362844012263914614494257428655751435080307550548130951000822418439531068973600535325512837681398082331290421770994275730420566916753796872722709677121223470117509210872101652580854566448661533030419787125312956120661097410038933324613372774190658239039998357548275441758790939430824924502690997433186652165055694361752689819209062683281242276039100201318203707142383491769671330743466041394101421674581185260900666085723130684175548215193875544802254923825103844262661010117443222587769713,
+ prime1 = 164748737139489923768181260808494855987398781964531448608652166632780898215212977127034263859971474195908846263894581556691971503119888726148555271179103885786024920582830105413607436718060544856016793981261118694063993837665813285582095833772675610567592660039821387740255651489996976698808018635344299728063,
+ prime2 = 138082323967104548254375818343885141517788525705334488282154811252858957969378263753268344088034079842223206527922445018725900110643394926788280539200323021781309918753249061620424428562366627334409266756720941754364262467100514166396917565961434203543659974860389803369482625510495464845206228470088664021953,
+ exponent1 = 19382204369351755737433089506881747763223386113474288071606137250915399790025056132592266336467232258342217207517009594904937823896457497193947678962247515974826461245038835931012639613889475865413740468383661022831058098548919210068481862796785365949128548239978986792971253116470232552800943368864035262125,
+ exponent2 = 48734937870742781736838524121371226418043009072470995864289933383361985165662916618800592031070851709019955245149098241903258862580021738866451955011878713569874088971734962924855680669070574353320917678842685325069739694270769705787147376221682660074232932303666989424523279591939575827719845342384234360689,
+ coefficient = 81173034184183681160439870161505779100040258708276674532866007896310418779840630960490793104541748007902477778658270784073595697910785917474138815202903114440800310078464142273778315781957021015333260021813037604142367434117205299831740956310682461174553260184078272196958146289378701001596552915990080834227,
+ otherPrimeInfos = asn1_NOVALUE}.
hardcode_dsa_key(1) ->
{'DSAPrivateKey',0,
@@ -1585,19 +1642,21 @@ hardcode_dsa_key(1) ->
48598545580251057979126570873881530215432219542526130654707948736559463436274835406081281466091739849794036308281564299754438126857606949027748889019480936572605967021944405048011118039171039273602705998112739400664375208228641666852589396502386172780433510070337359132965412405544709871654840859752776060358,
1457508827177594730669011716588605181448418352823};
hardcode_dsa_key(2) ->
- {'DSAPrivateKey',0,
- 145447354557382582722944332987784622105075065624518040072393858097520305927329240484963764783346271194321683798321743658303478090647837211867389721684646254999291098347011037298359107547264573476540026676832159205689428125157386525591130716464335426605521884822982379206842523670736739023467072341958074788151,
- 742801637799670234315651916144768554943688916729,
- 79727684678125120155622004643594683941478642656111969487719464672433839064387954070113655822700268007902716505761008423792735229036965034283173483862273639257533568978482104785033927768441235063983341565088899599358397638308472931049309161811156189887217888328371767967629005149630676763492409067382020352505,
- 35853727034965131665219275925554159789667905059030049940938124723126925435403746979702929280654735557166864135215989313820464108440192507913554896358611966877432546584986661291483639036057475682547385322659469460385785257933737832719745145778223672383438466035853830832837226950912832515496378486927322864228,
- 801315110178350279541885862867982846569980443911};
+ #'DSAPrivateKey'{
+ version = 0,
+ p = 145447354557382582722944332987784622105075065624518040072393858097520305927329240484963764783346271194321683798321743658303478090647837211867389721684646254999291098347011037298359107547264573476540026676832159205689428125157386525591130716464335426605521884822982379206842523670736739023467072341958074788151,
+ q = 742801637799670234315651916144768554943688916729,
+ g = 79727684678125120155622004643594683941478642656111969487719464672433839064387954070113655822700268007902716505761008423792735229036965034283173483862273639257533568978482104785033927768441235063983341565088899599358397638308472931049309161811156189887217888328371767967629005149630676763492409067382020352505,
+ y = 35853727034965131665219275925554159789667905059030049940938124723126925435403746979702929280654735557166864135215989313820464108440192507913554896358611966877432546584986661291483639036057475682547385322659469460385785257933737832719745145778223672383438466035853830832837226950912832515496378486927322864228,
+ x = 801315110178350279541885862867982846569980443911};
hardcode_dsa_key(3) ->
- {'DSAPrivateKey',0,
- 99438313664986922963487511141216248076486724382260996073922424025828494981416579966171753999204426907349400798052572573634137057487829150578821328280864500098312146772602202702021153757550650696224643730869835650674962433068943942837519621267815961566259265204876799778977478160416743037274938277357237615491,
- 1454908511695148818053325447108751926908854531909,
- 20302424198893709525243209250470907105157816851043773596964076323184805650258390738340248469444700378962907756890306095615785481696522324901068493502141775433048117442554163252381401915027666416630898618301033737438756165023568220631119672502120011809327566543827706483229480417066316015458225612363927682579,
- 48598545580251057979126570873881530215432219542526130654707948736559463436274835406081281466091739849794036308281564299754438126857606949027748889019480936572605967021944405048011118039171039273602705998112739400664375208228641666852589396502386172780433510070337359132965412405544709871654840859752776060358,
- 1457508827177594730669011716588605181448418352823}.
+ #'DSAPrivateKey'{
+ version = 0,
+ p = 99438313664986922963487511141216248076486724382260996073922424025828494981416579966171753999204426907349400798052572573634137057487829150578821328280864500098312146772602202702021153757550650696224643730869835650674962433068943942837519621267815961566259265204876799778977478160416743037274938277357237615491,
+ q = 1454908511695148818053325447108751926908854531909,
+ g = 20302424198893709525243209250470907105157816851043773596964076323184805650258390738340248469444700378962907756890306095615785481696522324901068493502141775433048117442554163252381401915027666416630898618301033737438756165023568220631119672502120011809327566543827706483229480417066316015458225612363927682579,
+ y = 48598545580251057979126570873881530215432219542526130654707948736559463436274835406081281466091739849794036308281564299754438126857606949027748889019480936572605967021944405048011118039171039273602705998112739400664375208228641666852589396502386172780433510070337359132965412405544709871654840859752776060358,
+ x = 1457508827177594730669011716588605181448418352823}.
dtls_hello() ->
[1,
diff --git a/lib/ssl/test/x509_test.erl b/lib/ssl/test/x509_test.erl
index 4da1537ef6..031fad1216 100644
--- a/lib/ssl/test/x509_test.erl
+++ b/lib/ssl/test/x509_test.erl
@@ -24,23 +24,10 @@
-include_lib("public_key/include/public_key.hrl").
- -export([gen_test_certs/1, gen_pem_config_files/3]).
+-export([extensions/1, gen_pem_config_files/3]).
- gen_test_certs(Opts) ->
- SRootKey = gen_key(proplists:get_value(server_key_gen, Opts)),
- CRootKey = gen_key(proplists:get_value(client_key_gen, Opts)),
- ServerRoot = root_cert("server", SRootKey, Opts),
- ClientRoot = root_cert("client", CRootKey, Opts),
- [{ServerCert, ServerKey} | ServerCAsKeys] = config(server, ServerRoot, SRootKey, Opts),
- [{ClientCert, ClientKey} | ClientCAsKeys] = config(client, ClientRoot, CRootKey, Opts),
- ServerCAs = ca_config(ClientRoot, ServerCAsKeys),
- ClientCAs = ca_config(ServerRoot, ClientCAsKeys),
- [{server_config, [{cert, ServerCert}, {key, ServerKey}, {cacerts, ServerCAs}]},
- {client_config, [{cert, ClientCert}, {key, ClientKey}, {cacerts, ClientCAs}]}].
-
-gen_pem_config_files(GenCertData, ClientBase, ServerBase) ->
- ServerConf = proplists:get_value(server_config, GenCertData),
- ClientConf = proplists:get_value(client_config, GenCertData),
+gen_pem_config_files(#{server_config := ServerConf,
+ client_config := ClientConf}, ClientBase, ServerBase) ->
ServerCaCertFile = ServerBase ++ "_server_cacerts.pem",
ServerCertFile = ServerBase ++ "_server_cert.pem",
@@ -62,147 +49,33 @@ gen_pem_config_files(GenCertData, ClientBase, ServerBase) ->
{keyfile, ServerKeyFile}, {cacertfile, ServerCaCertFile}]},
{client_config, [{certfile, ClientCertFile},
{keyfile, ClientKeyFile}, {cacertfile, ClientCaCertFile}]}].
-
-
- do_gen_pem_config_files(Config, CertFile, KeyFile, CAFile) ->
- CAs = proplists:get_value(cacerts, Config),
- Cert = proplists:get_value(cert, Config),
- Key = proplists:get_value(key, Config),
- der_to_pem(CertFile, [cert_entry(Cert)]),
- der_to_pem(KeyFile, [key_entry(Key)]),
- der_to_pem(CAFile, ca_entries(CAs)).
-
- cert_entry(Cert) ->
- {'Certificate', Cert, not_encrypted}.
-
- key_entry(Key = #'RSAPrivateKey'{}) ->
- Der = public_key:der_encode('RSAPrivateKey', Key),
- {'RSAPrivateKey', Der, not_encrypted};
- key_entry(Key = #'DSAPrivateKey'{}) ->
- Der = public_key:der_encode('DSAPrivateKey', Key),
- {'DSAPrivateKey', Der, not_encrypted};
- key_entry(Key = #'ECPrivateKey'{}) ->
- Der = public_key:der_encode('ECPrivateKey', Key),
- {'ECPrivateKey', Der, not_encrypted}.
-
- ca_entries(CAs) ->
- [{'Certificate', CACert, not_encrypted} || CACert <- CAs].
-
- gen_key(KeyGen) ->
- case is_key(KeyGen) of
- true ->
- KeyGen;
- false ->
- public_key:generate_key(KeyGen)
- end.
-
-root_cert(Role, PrivKey, Opts) ->
- TBS = cert_template(),
- Issuer = issuer("root", Role, " ROOT CA"),
- OTPTBS = TBS#'OTPTBSCertificate'{
- signature = sign_algorithm(PrivKey, Opts),
- issuer = Issuer,
- validity = validity(Opts),
- subject = Issuer,
- subjectPublicKeyInfo = public_key(PrivKey),
- extensions = extensions(Role, ca, Opts)
- },
- public_key:pkix_sign(OTPTBS, PrivKey).
-
-config(Role, Root, Key, Opts) ->
- KeyGenOpt = list_to_atom(atom_to_list(Role) ++ "_key_gen_chain"),
- KeyGens = proplists:get_value(KeyGenOpt, Opts, default_key_gen()),
- Keys = lists:map(fun gen_key/1, KeyGens),
- cert_chain(Role, Root, Key, Opts, Keys).
-
-cert_template() ->
- #'OTPTBSCertificate'{
- version = v3,
- serialNumber = trunc(rand:uniform()*100000000)*10000 + 1,
- issuerUniqueID = asn1_NOVALUE,
- subjectUniqueID = asn1_NOVALUE
- }.
-
-issuer(Contact, Role, Name) ->
- subject(Contact, Role ++ Name).
-
-subject(Contact, Name) ->
- Opts = [{email, Contact ++ "@erlang.org"},
- {name, Name},
- {city, "Stockholm"},
- {country, "SE"},
- {org, "erlang"},
- {org_unit, "automated testing"}],
- subject(Opts).
-
-subject(SubjectOpts) when is_list(SubjectOpts) ->
- Encode = fun(Opt) ->
- {Type,Value} = subject_enc(Opt),
- [#'AttributeTypeAndValue'{type=Type, value=Value}]
- end,
- {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}.
-
-subject_enc({name, Name}) ->
- {?'id-at-commonName', {printableString, Name}};
-subject_enc({email, Email}) ->
- {?'id-emailAddress', Email};
-subject_enc({city, City}) ->
- {?'id-at-localityName', {printableString, City}};
-subject_enc({state, State}) ->
- {?'id-at-stateOrProvinceName', {printableString, State}};
-subject_enc({org, Org}) ->
- {?'id-at-organizationName', {printableString, Org}};
-subject_enc({org_unit, OrgUnit}) ->
- {?'id-at-organizationalUnitName', {printableString, OrgUnit}};
-subject_enc({country, Country}) ->
- {?'id-at-countryName', Country};
-subject_enc({serial, Serial}) ->
- {?'id-at-serialNumber', Serial};
-subject_enc({title, Title}) ->
- {?'id-at-title', {printableString, Title}};
-subject_enc({dnQualifer, DnQ}) ->
- {?'id-at-dnQualifier', DnQ};
-subject_enc(Other) ->
- Other.
-
-validity(Opts) ->
- DefFrom0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())-1),
- DefTo0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+7),
- {DefFrom, DefTo} = proplists:get_value(validity, Opts, {DefFrom0, DefTo0}),
- Format = fun({Y,M,D}) ->
- lists:flatten(io_lib:format("~w~2..0w~2..0w000000Z",[Y,M,D]))
- end,
- #'Validity'{notBefore={generalTime, Format(DefFrom)},
- notAfter ={generalTime, Format(DefTo)}}.
-
-extensions(Role, Type, Opts) ->
- Exts = proplists:get_value(extensions, Opts, []),
- lists:flatten([extension(Ext) || Ext <- default_extensions(Role, Type, Exts)]).
-
-%% Common extension: name_constraints, policy_constraints, ext_key_usage, inhibit_any,
-%% auth_key_id, subject_key_id, policy_mapping,
-
-default_extensions(_, ca, Exts) ->
- Def = [{key_usage, [keyCertSign, cRLSign]},
- {basic_constraints, default}],
- add_default_extensions(Def, Exts);
-
-default_extensions(server, peer, Exts) ->
- Hostname = net_adm:localhost(),
- Def = [{key_usage, [digitalSignature, keyAgreement]},
- {subject_alt, Hostname}],
- add_default_extensions(Def, Exts);
-
-default_extensions(_, peer, Exts) ->
- Exts.
-
-add_default_extensions(Def, Exts) ->
- Filter = fun({Key, _}, D) ->
- lists:keydelete(Key, 1, D);
- ({Key, _, _}, D) ->
- lists:keydelete(Key, 1, D)
- end,
- Exts ++ lists:foldl(Filter, Def, Exts).
+extensions(Exts) ->
+ [extension(Ext) || Ext <- Exts].
+
+
+do_gen_pem_config_files(Config, CertFile, KeyFile, CAFile) ->
+ CAs = proplists:get_value(cacerts, Config),
+ Cert = proplists:get_value(cert, Config),
+ Key = proplists:get_value(key, Config),
+ der_to_pem(CertFile, [cert_entry(Cert)]),
+ der_to_pem(KeyFile, [key_entry(Key)]),
+ der_to_pem(CAFile, ca_entries(CAs)).
+
+cert_entry(Cert) ->
+ {'Certificate', Cert, not_encrypted}.
+
+key_entry(Key = #'RSAPrivateKey'{}) ->
+ Der = public_key:der_encode('RSAPrivateKey', Key),
+ {'RSAPrivateKey', Der, not_encrypted};
+key_entry(Key = #'DSAPrivateKey'{}) ->
+ Der = public_key:der_encode('DSAPrivateKey', Key),
+ {'DSAPrivateKey', Der, not_encrypted};
+key_entry(Key = #'ECPrivateKey'{}) ->
+ Der = public_key:der_encode('ECPrivateKey', Key),
+ {'ECPrivateKey', Der, not_encrypted}.
+
+ca_entries(CAs) ->
+ [{'Certificate', CACert, not_encrypted} || CACert <- CAs].
extension({_, undefined}) ->
[];
@@ -222,13 +95,6 @@ extension({basic_constraints, Data}) ->
#'Extension'{extnID = ?'id-ce-basicConstraints',
extnValue = Data}
end;
-extension({auth_key_id, {Oid, Issuer, SNr}}) ->
- #'Extension'{extnID = ?'id-ce-authorityKeyIdentifier',
- extnValue = #'AuthorityKeyIdentifier'{
- keyIdentifier = Oid,
- authorityCertIssuer = Issuer,
- authorityCertSerialNumber = SNr},
- critical = false};
extension({key_usage, Value}) ->
#'Extension'{extnID = ?'id-ce-keyUsage',
extnValue = Value,
@@ -240,113 +106,6 @@ extension({subject_alt, Hostname}) ->
extension({Id, Data, Critical}) ->
#'Extension'{extnID = Id, extnValue = Data, critical = Critical}.
-public_key(#'RSAPrivateKey'{modulus=N, publicExponent=E}) ->
- Public = #'RSAPublicKey'{modulus=N, publicExponent=E},
- Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'},
- #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
- subjectPublicKey = Public};
-public_key(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) ->
- Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa',
- parameters={params, #'Dss-Parms'{p=P, q=Q, g=G}}},
- #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y};
-public_key(#'ECPrivateKey'{version = _Version,
- privateKey = _PrivKey,
- parameters = Params,
- publicKey = PubKey}) ->
- Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-ecPublicKey', parameters=Params},
- #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
- subjectPublicKey = #'ECPoint'{point = PubKey}}.
-
-sign_algorithm(#'RSAPrivateKey'{}, Opts) ->
- Type = rsa_digest_oid(proplists:get_value(digest, Opts, sha1)),
- #'SignatureAlgorithm'{algorithm = Type,
- parameters = 'NULL'};
-sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) ->
- #'SignatureAlgorithm'{algorithm = ?'id-dsa-with-sha1',
- parameters = {params,#'Dss-Parms'{p=P, q=Q, g=G}}};
-sign_algorithm(#'ECPrivateKey'{parameters = Parms}, Opts) ->
- Type = ecdsa_digest_oid(proplists:get_value(digest, Opts, sha1)),
- #'SignatureAlgorithm'{algorithm = Type,
- parameters = Parms}.
-
-rsa_digest_oid(sha1) ->
- ?'sha1WithRSAEncryption';
-rsa_digest_oid(sha512) ->
- ?'sha512WithRSAEncryption';
-rsa_digest_oid(sha384) ->
- ?'sha384WithRSAEncryption';
-rsa_digest_oid(sha256) ->
- ?'sha256WithRSAEncryption';
-rsa_digest_oid(md5) ->
- ?'md5WithRSAEncryption'.
-
-ecdsa_digest_oid(sha1) ->
- ?'ecdsa-with-SHA1';
-ecdsa_digest_oid(sha512) ->
- ?'ecdsa-with-SHA512';
-ecdsa_digest_oid(sha384) ->
- ?'ecdsa-with-SHA384';
-ecdsa_digest_oid(sha256) ->
- ?'ecdsa-with-SHA256'.
-
-ca_config(Root, CAsKeys) ->
- [Root | [CA || {CA, _} <- CAsKeys]].
-
-cert_chain(Role, Root, RootKey, Opts, Keys) ->
- cert_chain(Role, Root, RootKey, Opts, Keys, 0, []).
-
-cert_chain(Role, IssuerCert, IssuerKey, Opts, [Key], _, Acc) ->
- PeerOpts = list_to_atom(atom_to_list(Role) ++ "_peer_opts"),
- Cert = cert(Role, public_key:pkix_decode_cert(IssuerCert, otp),
- IssuerKey, Key, "admin", " Peer cert", Opts, PeerOpts, peer),
- [{Cert, Key}, {IssuerCert, IssuerKey} | Acc];
-cert_chain(Role, IssuerCert, IssuerKey, Opts, [Key | Keys], N, Acc) ->
- CAOpts = list_to_atom(atom_to_list(Role) ++ "_ca_" ++ integer_to_list(N)),
- Cert = cert(Role, public_key:pkix_decode_cert(IssuerCert, otp), IssuerKey, Key, "webadmin",
- " Intermidiate CA " ++ integer_to_list(N), Opts, CAOpts, ca),
- cert_chain(Role, Cert, Key, Opts, Keys, N+1, [{IssuerCert, IssuerKey} | Acc]).
-
-cert(Role, #'OTPCertificate'{tbsCertificate = #'OTPTBSCertificate'{subject = Issuer,
- serialNumber = SNr
- }},
- PrivKey, Key, Contact, Name, Opts, CertOptsName, Type) ->
- CertOpts = proplists:get_value(CertOptsName, Opts, []),
- TBS = cert_template(),
- OTPTBS = TBS#'OTPTBSCertificate'{
- signature = sign_algorithm(PrivKey, Opts),
- issuer = Issuer,
- validity = validity(CertOpts),
- subject = subject(Contact, atom_to_list(Role) ++ Name),
- subjectPublicKeyInfo = public_key(Key),
- extensions = extensions(Role, Type,
- add_default_extensions([{auth_key_id, {auth_key_oid(Role), Issuer, SNr}}],
- CertOpts))
- },
- public_key:pkix_sign(OTPTBS, PrivKey).
-
-is_key(#'DSAPrivateKey'{}) ->
- true;
-is_key(#'RSAPrivateKey'{}) ->
- true;
-is_key(#'ECPrivateKey'{}) ->
- true;
-is_key(_) ->
- false.
-
der_to_pem(File, Entries) ->
PemBin = public_key:pem_encode(Entries),
file:write_file(File, PemBin).
-
-default_key_gen() ->
- case tls_v1:ecc_curves(0) of
- [] ->
- [{rsa, 2048, 17}, {rsa, 2048, 17}];
- [_|_] ->
- [{namedCurve, hd(tls_v1:ecc_curves(0))},
- {namedCurve, hd(tls_v1:ecc_curves(0))}]
- end.
-
-auth_key_oid(server) ->
- ?'id-kp-serverAuth';
-auth_key_oid(client) ->
- ?'id-kp-clientAuth'.
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 25b2a2bec0..bb77326751 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -1 +1 @@
-SSL_VSN = 8.2
+SSL_VSN = 8.2.1
diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl
index 7605ac763d..122b476ddb 100644
--- a/lib/stdlib/src/otp_internal.erl
+++ b/lib/stdlib/src/otp_internal.erl
@@ -466,8 +466,6 @@ obsolete_1(inviso, _, _) ->
{removed,"the inviso application was removed in R16"};
%% Added in R15B01.
-obsolete_1(gs, _, _) ->
- {removed,"the gs application has been removed; use the wx application instead"};
obsolete_1(ssh, sign_data, 2) ->
{removed,"removed in R16A; use public_key:pem_decode/1, public_key:pem_entry_decode/1 "
"and public_key:sign/3 instead"};
diff --git a/lib/syntax_tools/src/syntax_tools.app.src b/lib/syntax_tools/src/syntax_tools.app.src
index 5c6008a5f0..af50b7495b 100644
--- a/lib/syntax_tools/src/syntax_tools.app.src
+++ b/lib/syntax_tools/src/syntax_tools.app.src
@@ -18,4 +18,4 @@
{applications, [stdlib]},
{env, []},
{runtime_dependencies,
- ["compiler-7.0","erts-8.0","kernel-5.0","stdlib-3.0"]}]}.
+ ["compiler-7.0","erts-9.0","kernel-5.0","stdlib-3.4"]}]}.
diff --git a/lib/tools/src/fprof.erl b/lib/tools/src/fprof.erl
index 2fe42beb03..fb657c2928 100644
--- a/lib/tools/src/fprof.erl
+++ b/lib/tools/src/fprof.erl
@@ -1136,7 +1136,7 @@ ensure_open(Pid, _Options) when is_pid(Pid) ->
ensure_open([], _Options) ->
{already_open, undefined};
ensure_open(Filename, Options) when is_atom(Filename); is_list(Filename) ->
- file:open(Filename, Options).
+ file:open(Filename, [{encoding, utf8} | Options]).
%%%---------------------------------
%%% Fairly generic utility functions
diff --git a/lib/tools/src/tools.app.src b/lib/tools/src/tools.app.src
index 8beef49bf9..f8c6aa22cb 100644
--- a/lib/tools/src/tools.app.src
+++ b/lib/tools/src/tools.app.src
@@ -40,7 +40,7 @@
{env, [{file_util_search_methods,[{"", ""}, {"ebin", "esrc"}, {"ebin", "src"}]}
]
},
- {runtime_dependencies, ["stdlib-3.1","runtime_tools-1.8.14",
+ {runtime_dependencies, ["stdlib-3.4","runtime_tools-1.8.14",
"kernel-5.4","erts-9.1","compiler-5.0"]}
]
}.
diff --git a/lib/tools/test/fprof_SUITE.erl b/lib/tools/test/fprof_SUITE.erl
index affb45b7a6..8fd164a4b3 100644
--- a/lib/tools/test/fprof_SUITE.erl
+++ b/lib/tools/test/fprof_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
%% Test suites
-export([stack_seq/1, tail_seq/1, create_file_slow/1, spawn_simple/1,
imm_tail_seq/1, imm_create_file_slow/1, imm_compile/1,
- cpu_create_file_slow/1]).
+ cpu_create_file_slow/1, unicode/1]).
%% Other exports
-export([create_file_slow/2]).
@@ -59,7 +59,7 @@ all() ->
false ->
[stack_seq, tail_seq, create_file_slow, spawn_simple,
imm_tail_seq, imm_create_file_slow, imm_compile,
- cpu_create_file_slow]
+ cpu_create_file_slow, unicode]
end.
@@ -533,6 +533,17 @@ cpu_create_file_slow(Config) when is_list(Config) ->
TestResult.
+unicode(Config) when is_list(Config) ->
+ DataDir = proplists:get_value(data_dir, Config),
+ SourceFile = filename:join(DataDir, "fprof_unicode.erl"),
+ PrivDir = proplists:get_value(priv_dir, Config),
+ AnalysisFile = filename:join(PrivDir, "fprof_unicode.analysis"),
+ {ok, fprof_unicode} = compile:file(SourceFile, [{outdir, PrivDir}]),
+ true = code:add_path(PrivDir),
+ fprof:apply(fprof_unicode, t, []),
+ ok = fprof:profile(dump, AnalysisFile),
+ ok = fprof:analyse(dest, AnalysisFile).
+
%%%---------------------------------------------------------------------
%%% Functions to test
%%%---------------------------------------------------------------------
diff --git a/lib/tools/test/fprof_SUITE_data/fprof_unicode.erl b/lib/tools/test/fprof_SUITE_data/fprof_unicode.erl
new file mode 100644
index 0000000000..8b58efc5fe
--- /dev/null
+++ b/lib/tools/test/fprof_SUITE_data/fprof_unicode.erl
@@ -0,0 +1,36 @@
+-module(fprof_unicode).
+
+-export([t/0, 'кирилли́ческий атом'/0, annan/0, c_break/1,
+ 'кирилли́ческий атомB'/1]).
+
+t() ->
+ _Atom = 'кирилли́ческий атом',
+ 'кирилли́ческий атом'().
+
+'кирилли́ческий атом'() ->
+ 'кирилли́ческий атом'('кирилли́ческий атом').
+
+'кирилли́ческий атом'(_Atom) ->
+ self() ! 'кирилли́ческий атом',
+ G = fun (X) ->
+ catch foo:bar()
+ end,
+ G("кирилли́ческий атом"), % line 17
+ Pid = spawn_link(fun() -> waiting() end),
+ true = register('кирилли́ческий атом', Pid),
+ F = fun() -> 'кирилли́ческий атом' end,
+ F().
+
+annan() ->
+ foo.
+
+waiting() ->
+ receive
+ X -> X
+ end.
+
+c_break(_B) ->
+ true.
+
+'кирилли́ческий атомB'(_B) ->
+ true.
diff --git a/make/fakefop b/make/fakefop
index 7beeddf0a5..7a34c4faf1 100755
--- a/make/fakefop
+++ b/make/fakefop
@@ -22,13 +22,13 @@
# Author: Tuncer Ayaz
#
-if [ $# -lt 6 ]
+if [ $# -lt 8 ]
then
- echo "Usage: fakefop -c IGNORED -fo IGNORED -pdf OUTFILE"
+ echo "Usage: fakefop -c IGNORED -cache IGNORED -fo IGNORED -pdf OUTFILE"
exit 1
fi
-OUTFILE=$6
+OUTFILE=$8
echo -n -e '%PDF-1.4\n%\0342\0343\0317\0323\n\n' > $OUTFILE
@@ -87,12 +87,12 @@ endobj
xref
0 6
-0000000000 65536 f
-0000000016 00000 n
-0000000070 00000 n
-0000000136 00000 n
-0000000291 00000 n
-0000000410 00000 n
+0000000000 65536 f
+0000000016 00000 n
+0000000070 00000 n
+0000000136 00000 n
+0000000291 00000 n
+0000000410 00000 n
trailer
<<
diff --git a/make/otp.mk.in b/make/otp.mk.in
index 4232d37c2e..1d538fa528 100644
--- a/make/otp.mk.in
+++ b/make/otp.mk.in
@@ -139,7 +139,7 @@ endif
#
.PRECIOUS: %.erl %.fo
-## Uncomment these lines and add .idl to suffixes above to have erlc
+## Uncomment these lines and add .idl to suffixes above to have erlc
## eat IDL files
##$(EGEN)/%.erl: $(ESRC)/%.idl
## $(ERLC) $(IDL_FLAGS) $<
@@ -239,7 +239,7 @@ ifeq ($(PDFCOLOR),)
PDFCOLOR = \#960003
endif
-# HTML & GIF files that always are generated and must be delivered
+# HTML & GIF files that always are generated and must be delivered
SGML_COLL_FILES = $(SGML_APPLICATION_FILES) $(SGML_PART_FILES)
XML_COLL_FILES = $(XML_APPLICATION_FILES) $(XML_PART_FILES)
DEFAULT_HTML_FILES = \
@@ -327,5 +327,4 @@ $(MAN9DIR)/%.9: %.xml
escript $(DOCGEN)/priv/bin/codeline_preprocessing.escript $< $@
.fo.pdf:
- $(FOP) -c $(FOP_CONFIG) -fo $< -pdf $@
-
+ $(FOP) -c $(FOP_CONFIG) -cache $(ERL_TOP)/make/$(TARGET)/fop-fonts.cache -fo $< -pdf $@
diff --git a/system/doc/design_principles/des_princ.xml b/system/doc/design_principles/des_princ.xml
index af5904ce78..e21f2a7f4e 100644
--- a/system/doc/design_principles/des_princ.xml
+++ b/system/doc/design_principles/des_princ.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/system/doc/oam/oam_intro.xml b/system/doc/oam/oam_intro.xml
index b4142b3cc5..d3867f03ca 100644
--- a/system/doc/oam/oam_intro.xml
+++ b/system/doc/oam/oam_intro.xml
@@ -4,7 +4,7 @@
<chapter>
<header>
<copyright>
- <year>1997</year><year>2016</year>
+ <year>1997</year><year>2017</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>