File 2882-Finish-fix-redirect-example.patch of Package erlang

From 3068ec1700dca6eb60aa25fe4cb22d895fa6a427 Mon Sep 17 00:00:00 2001
From: Anders Svensson <anders@erlang.org>
Date: Sun, 26 Jan 2020 11:22:09 +0100
Subject: [PATCH 02/11] Finish/fix redirect example

The code was both broken and incomplete. Now it answers as it should,
albeit using some encode functionality (ie. 3-tuple as diameter_avp
value) that isn't currently documented.
---
 lib/diameter/examples/code/GNUmakefile     |  2 +-
 lib/diameter/examples/code/redirect.erl    | 66 +++++++++++++++++++++---------
 lib/diameter/examples/code/redirect_cb.erl | 62 +++++++++++++++++++++++-----
 lib/diameter/src/modules.mk                |  2 +
 4 files changed, 101 insertions(+), 31 deletions(-)

diff --git a/lib/diameter/examples/code/GNUmakefile b/lib/diameter/examples/code/GNUmakefile
index c0be5b59f4..9efb966e65 100644
--- a/lib/diameter/examples/code/GNUmakefile
+++ b/lib/diameter/examples/code/GNUmakefile
@@ -18,7 +18,7 @@
 # %CopyrightEnd%
 #
 
-EXAMPLES  = client server relay # redirect proxy
+EXAMPLES  = client server relay redirect # proxy
 
 CALLBACKS = $(EXAMPLES:%=%_cb)
 MODULES   = $(EXAMPLES) $(EXAMPLES:%=%_cb)
diff --git a/lib/diameter/examples/code/redirect.erl b/lib/diameter/examples/code/redirect.erl
index 6934e54507..1f9749ba84 100644
--- a/lib/diameter/examples/code/redirect.erl
+++ b/lib/diameter/examples/code/redirect.erl
@@ -1,7 +1,7 @@
 %%
 %% %CopyrightBegin%
 %%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -20,52 +20,80 @@
 
 -module(redirect).
 
--include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc3588.hrl").
+%%
+%% An example Diameter redirect agent.
+%%
+%% Simplest usage to listen on TCP at 127.0.0.1:3868.
+%%
+%%   redirect:start().
+%%   redirect:listen(tcp).
+%%
 
+%% Interface.
 -export([start/1,
          listen/2,
          stop/1]).
 
+%% Convenience functions using the default service name.
 -export([start/0,
          listen/1,
          stop/0]).
 
--define(APP_ALIAS,    ?MODULE).
--define(SVC_NAME,     ?MODULE).
--define(CALLBACK_MOD, redirect_mod).
+-define(DEF_SVC_NAME, ?MODULE).
 
 %% The service configuration.
 -define(SERVICE(Name), [{'Origin-Host', atom_to_list(Name) ++ ".example.com"},
                         {'Origin-Realm', "example.com"},
                         {'Vendor-Id', 193},
                         {'Product-Name', "RedirectAgent"},
-                        {'Auth-Application-Id', [?DIAMETER_APP_ID_RELAY]},
-                        {application, [{alias, ?APP_ALIAS},
-                                       {dictionary, ?DIAMETER_DICT_RELAY},
-                                       {module, ?CALLBACK_MOD}]}]).
+                        {'Auth-Application-Id', [16#FFFFFFFF]},
+                        {decode_format, map},
+                        {restrict_connections, false},
+                        {strict_mbit, false},
+                        {string_decode, false},
+                        {application, [{alias, redirect},
+                                       {dictionary, diameter_gen_relay},
+                                       {module, redirect_cb},
+                                       {call_mutates_state, false}]}]).
+
+%% start/0
+
+start() ->
+    start(?DEF_SVC_NAME).
 
 %% start/1
 
 start(Name)
   when is_atom(Name) ->
-    peer:start(Name, ?SERVICE(Name)).
+    start(Name, []);
 
-start() ->
-    start(?SVC_NAME).
+start(Opts)
+  when is_list(Opts) ->
+    start(?DEF_SVC_NAME, Opts).
+
+%% start/2
+
+start(Name, Opts) ->
+    Defaults = [T || {K,_} = T <- ?SERVICE(Name),
+                     not lists:keymember(K, 1, Opts)],
+    diameter:start_service(Name, Opts ++ Defaults).
 
 %% listen/2
 
-listen(Name, T) ->
-    peer:listen(Name, T).
+listen(Name, Opts) ->
+    server:listen(Name, Opts).
+
+%% listen/1
 
-listen(T) ->
-    listen(?SVC_NAME, T).
+listen(Opts) ->
+    listen(?DEF_SVC_NAME, Opts).
 
 %% stop/1
 
 stop(Name) ->
-    peer:stop(Name).
+    diameter:stop_service(Name).
+
+%% stop.0
 
 stop() ->
-    stop(?SVC_NAME).
+    stop(?DEF_SVC_NAME).
diff --git a/lib/diameter/examples/code/redirect_cb.erl b/lib/diameter/examples/code/redirect_cb.erl
index 8325e86391..76ab091be3 100644
--- a/lib/diameter/examples/code/redirect_cb.erl
+++ b/lib/diameter/examples/code/redirect_cb.erl
@@ -1,7 +1,7 @@
 %%
 %% %CopyrightBegin%
 %%
-%% Copyright Ericsson AB 2010-2016. All Rights Reserved.
+%% Copyright Ericsson AB 2010-2020. 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.
@@ -21,7 +21,6 @@
 -module(redirect_cb).
 
 -include_lib("diameter/include/diameter.hrl").
--include_lib("diameter/include/diameter_gen_base_rfc3588.hrl").
 
 %% diameter callbacks
 -export([peer_up/3,
@@ -33,30 +32,71 @@
          handle_error/4,
          handle_request/3]).
 
--define(UNEXPECTED, erlang:error({unexpected, ?MODULE, ?LINE})).
+%% Dictionary to encode answer-message AVPs with.
+-define(Dict, diameter_gen_base_rfc6733).
+
+%% Raise an error on callbacks that aren't expected.
+-define(ERROR, error({unexpected, ?MODULE, ?LINE})).
+
+%% peer_up/3
 
 peer_up(_SvcName, _Peer, State) ->
     State.
 
+%% peer_down/3
+
 peer_down(_SvcName, _Peer, State) ->
     State.
 
+%% pick_peer/4
+
 pick_peer(_, _, _SvcName, _State) ->
-    ?UNEXPECTED.
+    false.
+
+%% prepare_request/3
 
 prepare_request(_, _SvcName, _Peer) ->
-    ?UNEXPECTED.
+    ?ERROR.
+
+%% prepare_retransmit/3
 
 prepare_retransmit(_Packet, _SvcName, _Peer) ->
-    ?UNEXPECTED.
+    ?ERROR.
+
+%% handle_answer/4
 
 handle_answer(_Packet, _Request, _SvcName, _Peer) ->
-    ?UNEXPECTED.
+    ?ERROR.
+
+%% handle_error/4
 
 handle_error(_Reason, _Request, _SvcName, _Peer) ->
-    ?UNEXPECTED.
+    ?ERROR.
+
+%% handle_request/3
 
-handle_request(#diameter_packet{msg = _, errors = []}, _SvcName, {_, Caps}) ->
-    #diameter_caps{}
+handle_request(#diameter_packet{avps = Avps}, _, {_, Caps}) ->
+    #diameter_caps{origin_host = {OH, _},
+                   origin_realm = {OR, _}}
         = Caps,
-    discard.   %% TODO
+
+    Tail = [#diameter_avp{data = {?Dict, A, V}}
+            || {A,V} <- [{'Origin-Host', OH},
+                        {'Origin-Realm', OR},
+                       {'Result-Code', 3006}, %% DIAMETER_REDIRECT_INDICATION
+                      {'Redirect-Host', <<"aaa://server.example.com:3868">>}]],
+
+    {reply, ['answer-message' | lists:append([session(Avps), Tail])]}.
+
+%% ===========================================================================
+
+%% session/1
+
+session(Avps) ->
+    try
+        [] = [A || #diameter_avp{code = 263, vendor_id = undefined} = A
+                       <- Avps,
+                   throw(A)]
+    catch
+        Avp -> [Avp]
+    end.
diff --git a/lib/diameter/src/modules.mk b/lib/diameter/src/modules.mk
index 144d08fcba..cf938785e3 100644
--- a/lib/diameter/src/modules.mk
+++ b/lib/diameter/src/modules.mk
@@ -104,6 +104,8 @@ EXAMPLES = \
 	code/server_cb.erl \
 	code/relay.erl \
 	code/relay_cb.erl \
+	code/redirect.erl \
+	code/redirect_cb.erl \
 	dict/rfc4004_mip.dia \
 	dict/rfc4005_nas.dia \
 	dict/rfc4006_cc.dia \
-- 
2.16.4

openSUSE Build Service is sponsored by