File 0151-New-makecerts-replacement-changes-to-httpd_bench_SUI.patch of Package erlang

From b806cfd95b70e47ad13bd0cfde2754adc8d0fdd3 Mon Sep 17 00:00:00 2001
From: Dmytro Lytovchenko <dima.lytovchenko@ericsson.com>
Date: Wed, 27 Aug 2025 18:09:02 +0200
Subject: [PATCH 1/3] New makecerts replacement, changes to httpd_bench_SUITE
 to make it work Remove HDLT

---
 lib/inets/examples/httpd_load_test/Makefile   |  127 --
 .../examples/httpd_load_test/hdlt.config.skel |   20 -
 lib/inets/examples/httpd_load_test/hdlt.erl   |   77 -
 .../examples/httpd_load_test/hdlt.sh.skel     |   47 -
 .../examples/httpd_load_test/hdlt_client.erl  |  373 ----
 .../examples/httpd_load_test/hdlt_ctrl.erl    | 1527 -----------------
 .../examples/httpd_load_test/hdlt_logger.erl  |  141 --
 .../examples/httpd_load_test/hdlt_logger.hrl  |   36 -
 .../httpd_load_test/hdlt_random_html.erl      |   51 -
 .../examples/httpd_load_test/hdlt_server.erl  |  166 --
 .../examples/httpd_load_test/hdlt_slave.erl   |  293 ----
 .../httpd_load_test/hdlt_ssl_client_cert.pem  |    1 -
 .../httpd_load_test/hdlt_ssl_server_cert.pem  |    1 -
 lib/inets/examples/httpd_load_test/modules.mk |   47 -
 lib/inets/examples/subdirs.mk                 |   23 +-
 lib/inets/test/Makefile                       |   24 +-
 lib/inets/test/httpd_bench_SUITE.erl          |  416 ++---
 lib/inets/test/httpd_bench_certs.erl          |  128 ++
 lib/inets/test/inets.spec                     |   23 +-
 lib/inets/test/inets_test_lib.erl             |  112 +-
 lib/inets/test/make_certs.erl                 |  533 ------
 21 files changed, 453 insertions(+), 3713 deletions(-)
 delete mode 100644 lib/inets/examples/httpd_load_test/Makefile
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt.config.skel
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt.erl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt.sh.skel
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_client.erl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_ctrl.erl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_logger.erl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_logger.hrl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_random_html.erl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_server.erl
 delete mode 100644 lib/inets/examples/httpd_load_test/hdlt_slave.erl
 delete mode 120000 lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem
 delete mode 120000 lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem
 delete mode 100644 lib/inets/examples/httpd_load_test/modules.mk
 create mode 100644 lib/inets/test/httpd_bench_certs.erl
 delete mode 100644 lib/inets/test/make_certs.erl

diff --git a/lib/inets/examples/httpd_load_test/Makefile b/lib/inets/examples/httpd_load_test/Makefile
deleted file mode 100644
index 18c2414231..0000000000
--- a/lib/inets/examples/httpd_load_test/Makefile
+++ /dev/null
@@ -1,127 +0,0 @@
-# 
-# %CopyrightBegin%
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Copyright Ericsson AB 2010-2025. 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.
-# 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.
-#
-# %CopyrightEnd%
-
-include $(ERL_TOP)/make/target.mk
-
-EBIN = .
-
-include $(ERL_TOP)/make/$(TARGET)/otp.mk
-
-# ----------------------------------------------------
-# Application version
-# ----------------------------------------------------
-include ../../vsn.mk
-
-VSN=$(INETS_VSN)
-
-
-# ----------------------------------------------------
-# Release directory specification
-# ----------------------------------------------------
-RELSYSDIR         = $(RELEASE_PATH)/lib/inets-$(VSN)
-EXAMPLE_RELSYSDIR = "$(RELSYSDIR)/examples"
-HDLT_RELSYSDIR    = $(EXAMPLE_RELSYSDIR)/httpd_load_test
-
-
-# ----------------------------------------------------
-# Target Specs
-# ----------------------------------------------------
-
-include modules.mk
-
-ERL_FILES = $(MODULES:%=%.erl)
-
-SOURCE = $(ERL_FILES) $(INTERNAL_HRL_FILES)
-
-TARGET_FILES =  \
-	$(ERL_FILES:%.erl=$(EBIN)/%.$(EMULATOR))
-
-ifeq ($(TYPE),debug)
-ERL_COMPILE_FLAGS += -Ddebug -W
-endif
-ERL_COMPILE_FLAGS += +nowarn_missing_doc +nowarn_missing_spec_documented
-
-
-# ----------------------------------------------------
-# FLAGS
-# ----------------------------------------------------
-
-include ../../src/inets_app/inets.mk
-
-ERL_COMPILE_FLAGS += \
-	$(INETS_FLAGS) \
-	$(INETS_ERL_COMPILE_FLAGS) \
-	-I../../include
-
-
-# ----------------------------------------------------
-# Special Build Targets
-# ----------------------------------------------------
-
-
-# ----------------------------------------------------
-# Targets
-# ----------------------------------------------------
-$(filter-out opt, $(TYPES)):
-	@${MAKE} TYPE=$@ opt
-
-opt: $(TARGET_FILES) 
-
-clean:
-	rm -f $(TARGET_FILES) 
-	rm -f errs core *~
-
-docs:
-
-
-# ----------------------------------------------------
-# Release Target
-# ---------------------------------------------------- 
-include $(ERL_TOP)/make/otp_release_targets.mk
-
-
-release_spec: opt
-	$(INSTALL_DIR)  $(EXAMPLE_RELSYSDIR)
-	$(INSTALL_DIR)  $(HDLT_RELSYSDIR)
-	$(INSTALL_DATA) $(SCRIPT_SKELETONS) $(HDLT_RELSYSDIR)
-	$(INSTALL_DATA) $(CONF_SKELETONS)   $(HDLT_RELSYSDIR)
-	$(INSTALL_DATA) $(CERT_FILES)       $(HDLT_RELSYSDIR)
-	$(INSTALL_DATA) $(TARGET_FILES)     $(HDLT_RELSYSDIR)
-	$(INSTALL_DATA) $(ERL_FILES)        $(HDLT_RELSYSDIR)
-
-
-release_docs_spec:
-
-
-# ----------------------------------------------------
-# Include dependencies
-# ----------------------------------------------------
-
-megaco_codec_transform.$(EMULATOR): megaco_codec_transform.erl
-
-megaco_codec_meas.$(EMULATOR): megaco_codec_meas.erl
-
-megaco_codec_mstone1.$(EMULATOR): megaco_codec_mstone1.erl
-
-megaco_codec_mstone2.$(EMULATOR): megaco_codec_mstone2.erl
-
-megaco_codec_mstone_lib.$(EMULATOR): megaco_codec_mstone_lib.erl
-
diff --git a/lib/inets/examples/httpd_load_test/hdlt.config.skel b/lib/inets/examples/httpd_load_test/hdlt.config.skel
deleted file mode 100644
index 640867ebac..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt.config.skel
+++ /dev/null
@@ -1,20 +0,0 @@
-%% Debug: silence | info | log | debug
-{debug,  [{ctrl, info}, {proxy, silence}, {slave, silence}, {client, silence}]}.
-{server, {"/usr/local/bin", "fooserver"}}.
-%% {port,   8888}.             % integer() > 0
-{server_dir, "/tmp/hdlt"}. % Absolute path
-{work_dir,   "/tmp/hdlt"}. % Absolute path
-{clients, 
- [
-  {"/opt/local/bin", "foo"}, 
-  {"/usr/local/bin", "bar"}
- ]
-}.
-%% {send_rate, 80}.     % Max number of outstanding requests, integer() > 0
-%% {test_time, 120}.    % Number of seconds, 
-%% {max_nof_schedulers, 8}. % integer() >= 0
-%% {work_simulator, 10000}.  % integer() > 0
-%% {data_size, {100, 500, 2}}. % {integer() > 0, integer() > 0, integer() > 0}
-%% {socket_type, ip_comm}. % ip_comm | ssl | essl | ossl
-%% {server_cert_file, "hdlt_ssl_server_cert.pem"}.
-%% {client_cert_file, "hdlt_ssl_client_cert.pem"}.
\ No newline at end of file
diff --git a/lib/inets/examples/httpd_load_test/hdlt.erl b/lib/inets/examples/httpd_load_test/hdlt.erl
deleted file mode 100644
index a148b88e21..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt.erl
+++ /dev/null
@@ -1,77 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: Main API module for the httpd load test utility
-%%----------------------------------------------------------------------
-
--module(hdlt).
-
-
-%%-----------------------------------------------------------------
-%% Public interface
-%%-----------------------------------------------------------------
-
--export([start/0, start/1, stop/0, help/0]).
-
-
-%%-----------------------------------------------------------------
-%% Start the HDLT utility
-%%-----------------------------------------------------------------
-
-start() ->
-    ConfigFile = "hdlt.config",
-    case file:consult(ConfigFile) of
-	{ok, Config} when is_list(Config) ->
-	    start(Config);
-	Error ->
-	    Error
-    end.
-
-start(Config) ->
-    Flag = process_flag(trap_exit, true),
-    Result = 
-	case hdlt_ctrl:start(Config) of
-	    {ok, Pid} ->
-		receive
-		    {'EXIT', Pid, normal} ->
-			ok;
-		    {'EXIT', Pid, Reason} ->
-			io:format("HDLT failed: "
-				  "~n   ~p"
-				  "~n", [Reason]),
-			{error, Reason}
-		end;
-	    Error ->
-		Error
-	end,
-    process_flag(trap_exit, Flag),
-    Result.
-
-
-
-stop() ->
-    hdlt_ctrl:stop().
-
-    
-help() ->
-    hdlt_ctrl:help().
diff --git a/lib/inets/examples/httpd_load_test/hdlt.sh.skel b/lib/inets/examples/httpd_load_test/hdlt.sh.skel
deleted file mode 100644
index ebc63c0ec4..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt.sh.skel
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-
-#
-# %CopyrightBegin%
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Copyright Ericsson AB 2010-2025. 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.
-# 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.
-#
-# %CopyrightEnd%
-
-# Skeleton for a script intended to run the hdlt(N) 
-# performance test.
-# 
-# This test can be used for several things depending on the 
-# configuration: SMP or SocketType performance tests
-#
-
-ERL_HOME=<path to otp top dir>
-INETS_HOME=$ERL_HOME/lib/erlang/lib/<inets dir>
-HDLT_HOME=$INETS_HOME/examples/httpd_load_test
-PATH=$ERL_HOME/bin:$PATH
-
-HDLT="-s hdlt start"
-STOP="-s init stop"
-
-ERL="erl \
-     -noshell \
-     -pa $HDLT_HOME \
-     $HDLT \
-     $STOP"
-
-echo $ERL
-$ERL | tee hdlt.log
-
diff --git a/lib/inets/examples/httpd_load_test/hdlt_client.erl b/lib/inets/examples/httpd_load_test/hdlt_client.erl
deleted file mode 100644
index 907cd76d57..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_client.erl
+++ /dev/null
@@ -1,373 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: The HDLT client module.
-%%          This is the traffic generator
-%%----------------------------------------------------------------------
-
--module(hdlt_client).
-
--export([
-	 start/1, 
-	 stop/0, 
-	 start_inets/0, 
-	 start_service/1, 
-	 release/0, 
-	 node_info/0
-	]).
-
--export([
-	 proxy/1
-	]).
-
--include("hdlt_logger.hrl").
-
--define(CTRL,   hdlt_ctrl).
--define(PROXY,  hdlt_proxy).
-
--record(state, 
-	{
-	 mode = initial,
-	 send_rate,
-	 time, 
-	 stop_time, 
-	 url,
-	 nof_reqs = 0,
-	 nof_reps = 0,
-	 last_req,
-	 sizes,
-	 socket_type, 
-	 cert_file
-	}).
-
-
-
-start(Debug) ->
-    proc_lib:start_link(?MODULE, proxy, [Debug]).
-
-stop() ->
-    (catch erlang:send(?PROXY, stop)),
-    ok.
-
-start_inets() ->
-    ?PROXY ! start_inets.
-
-start_service(Args) ->
-    ?PROXY ! {start_client, Args, self()},
-    receive
-	client_started ->
-	    %% ?LOG("client service started"),
-	    ok
-    end.
-
-release() ->
-    ?PROXY ! release.
-
-node_info() ->
-    ?PROXY ! {node_info, self()},
-    receive 
-	{node_info, NodeInfo} ->
-	    NodeInfo
-    end.
-
-
-%% ---------------------------------------------------------------------
-%% 
-%% The proxy process
-%% 
-
-proxy(Debug) ->
-    process_flag(trap_exit, true),
-    erlang:register(?PROXY, self()),
-    SName = lists:flatten(
-	      io_lib:format("HDLT PROXY[~p,~p]", [self(), node()])), 
-    ?SET_NAME(SName),
-    ?SET_LEVEL(Debug), 
-    ?LOG("starting", []),
-    Ref = await_for_controller(10), 
-    CtrlNode = node(Ref), 
-    erlang:monitor_node(CtrlNode, true),
-    proc_lib:init_ack({ok, self()}),
-    ?DEBUG("started", []),
-    proxy_loop(Ref, CtrlNode, undefined).
-
-await_for_controller(N) when N > 0 ->
-    case global:whereis_name(hdlt_ctrl) of
-	Pid when is_pid(Pid) ->
-	    erlang:monitor(process, Pid);
-	_ ->
-	    timer:sleep(1000),
-	    await_for_controller(N-1)
-    end;
-await_for_controller(_) ->
-    proc_lib:init_ack({error, controller_not_found, nodes()}),
-    timer:sleep(500),
-    init:stop().
-
-
-proxy_loop(Ref, CtrlNode, Client) ->
-    ?DEBUG("await command", []),
-    receive
-	stop ->
-	    ?LOG("stop", []),
-	    timer:sleep(1000),
-	    halt();
-
-	start_inets ->
-	    ?LOG("start the inets service framework", []),
-	    %% inets:enable_trace(max, "/tmp/inets-httpc-trace.log", all),
-	    case (catch inets:start()) of
-		ok ->
-		    ?LOG("framework started", []),
-		    proxy_loop(Ref, CtrlNode, Client);
-		Error ->
-		    ?LOG("failed starting inets service framework: "
-			"~n   Error: ~p", [Error]),
-		    timer:sleep(1000),
-		    halt()
-	    end;
-
-	{start_client, Args, From} ->
-	    ?LOG("start client with"
-		"~n   Args: ~p", [Args]),
-	    Client2 = spawn_link(fun() -> client(Args) end),
-	    From ! client_started,
-	    proxy_loop(Ref, CtrlNode, Client2);
-
-	release ->
-	    ?LOG("release", []),
-	    Client ! go,
-	    proxy_loop(Ref, CtrlNode, Client);
-
-	{node_info, Pid} ->
-	    ?LOG("received requets for node info", []),
-	    NodeInfo = get_node_info(),
-	    Pid ! {node_info, NodeInfo}, 
-	    proxy_loop(Ref, CtrlNode, Client);
-
-	{'EXIT', Client, normal} ->
-	    ?LOG("received normal exit message from client (~p)", 
-		 [Client]),
-	    exit(normal);
-	
-	{'EXIT', Client, Reason} ->
-	    ?INFO("received exit message from client (~p)"
-		 "~n   Reason: ~p", [Client, Reason]),
-	    %% Unexpected client termination, inform the controller and die
-	    global:send(hdlt_ctrl, {client_exit, Client, node(), Reason}),
-	    exit({client_exit, Reason});
-
-	{nodedown, CtrlNode} ->
-	    ?LOG("received nodedown for controller node - terminate", []), 
-	    halt();
-
-	{'DOWN', Ref, process, _, _} ->
-	    ?INFO("received DOWN message for controller - terminate", []),
-	    %% The controller has terminated, dont care why, time to die
-	    halt()
-
-    end.
-
-
-
-%% ---------------------------------------------------------------------
-%% 
-%% The client process
-%% 
-
-client([SocketType, CertFile, URLBase, Sizes, Time, SendRate, Debug]) ->
-    SName = lists:flatten(
-	      io_lib:format("HDLT CLIENT[~p,~p]", [self(), node()])), 
-    ?SET_NAME(SName),
-    ?SET_LEVEL(Debug), 
-    ?LOG("starting with"
-	 "~n   SocketType: ~p"
-	 "~n   Time:       ~p"
-	 "~n   SendRate:   ~p", [SocketType, Time, SendRate]),
-    httpc:set_options([{max_pipeline_length, 0}]),
-    if
-	(SocketType =:= ssl) orelse
-	(SocketType =:= ossl) orelse
-	(SocketType =:= essl) ->
-	    %% Ensure crypto and ssl started:
-	    application:start(crypto),
-	    ssl:start();
-	true ->
-	    ok
-    end,
-    State = #state{mode        = idle, 
-		   url         = URLBase, 
-		   time        = Time, 
-		   send_rate   = SendRate,
-		   sizes       = Sizes,
-		   socket_type = SocketType,
-		   cert_file   = CertFile},
-    ?DEBUG("started", []),
-    client_loop(State).
-
-%% The point is to first start all client nodes and then this
-%% process. Then, when they are all started, the go-ahead, go, 
-%% message is sent to let them lose at the same time.
-client_loop(#state{mode      = idle, 
-		   time      = Time, 
-		   send_rate = SendRate} = State) ->
-    ?DEBUG("[idle] awaiting the go command", []),
-    receive 
-	go ->
-	    ?LOG("[idle] received go", []),
-	    erlang:send_after(Time, self(), stop),
-	    NewState = send_requests(State, SendRate),	    
-	    client_loop(NewState#state{mode     = generating, 
-				       nof_reqs = SendRate})
-    end;
-
-%% In this mode the client is generating traffic.
-%% It will continue to do so until the stop message
-%% is received. 
-client_loop(#state{mode = generating} = State) -> 
-    receive 
-	stop ->
-	    ?LOG("[generating] received stop", []),
-	    StopTime = timestamp(), 
-	    req_reply(State),
-	    client_loop(State#state{mode = stopping, stop_time = StopTime});
-
-	{http, {_, {{_, 200, _}, _, _}}} ->
-	    %% ?DEBUG("[generating] received reply - send another request", []),
-	    NewState = send_requests(State, 1),
-	    client_loop(NewState#state{nof_reps = NewState#state.nof_reps + 1,
-				       nof_reqs = NewState#state.nof_reqs + 1});
-
-	{http, {ReqId, {error, Reason}}} ->
-	    ?INFO("[generating] request ~p failed: "
-		  "~n   Reason:  ~p"
-		  "~n   NofReqs: ~p"
-		  "~n   NofReps: ~p", 
-		  [ReqId, Reason, State#state.nof_reqs, State#state.nof_reps]),
-	    exit({Reason, generating, State#state.nof_reqs, State#state.nof_reps});
-
-	Else ->
-	    ?LOG("[generating] received unexpected message: "
-		 "~n~p", [Else]),
-	    unexpected_data(Else), 
-	    client_loop(State)
-    end;
-
-%% The client no longer issues any new requests, instead it 
-%% waits for replies for all the outstanding requests to 
-%% arrive.
-client_loop(#state{mode     = stopping, 
-		   time     = Time, 
-		   last_req = LastReqId} = State) ->
-    receive 
-	{http, {LastReqId, {{_, 200, _}, _, _}}} ->
-	    ?DEBUG("[stopping] received reply for last request (~p)", [LastReqId]),
-	    time_to_complete(State),
-	    ok;
-
-	{http, {ReqId, {{_, 200, _}, _, _}}} ->
-	    ?DEBUG("[stopping] received reply ~p", [ReqId]),
-	    client_loop(State);
-
-	{http, {ReqId, {error, Reason}}} ->
-	    ?INFO("[stopping] request ~p failed: "
-		  "~n   Reason:  ~p"
-		  "~n   NofReqs: ~p"
-		  "~n   NofReps: ~p", 
-		  [ReqId, Reason, State#state.nof_reqs, State#state.nof_reps]),
-	    exit({Reason, stopping, State#state.nof_reqs, State#state.nof_reps});
-
-	Else ->
-	    ?LOG("[stopping] received unexpected message: "
-		 "~n~p", [Else]),
-	    unexpected_data(Else), 
-	    client_loop(State)
-
-    after Time ->
-	    ?INFO("timeout when"
-		  "~n   Number of requests: ~p"
-		  "~n   Number of replies:  ~p", 
-		  [State#state.nof_reqs, State#state.nof_reps]),
-	    exit({timeout, State#state.nof_reqs, State#state.nof_reps})
-    end.
-
-req_reply(#state{nof_reqs = NofReqs, nof_reps = NofReps}) ->
-    load_data({req_reply, node(), NofReqs, NofReps}).
-
-time_to_complete(#state{stop_time = StopTime}) ->
-    StoppedTime = os:timestamp(),
-    load_data({time_to_complete, node(), StopTime, StoppedTime}).
-
-load_data(Data) ->
-    global:send(?CTRL, {load_data, Data}).
-
-unexpected_data(Else) ->
-    global:send(?CTRL, {unexpected_data, Else}).
-
-
-send_requests(#state{sizes = Sizes} = State, N) ->
-    send_requests(State, N, Sizes).
-
-send_requests(State, 0, Sizes) ->
-    State#state{sizes = Sizes};
-send_requests(#state{socket_type = SocketType, 
-		     cert_file   = CertFile} = State, N, [Sz | Sizes]) ->
-    URL = lists:flatten(io_lib:format("~s~w", [State#state.url, Sz])),
-    Method      = get,
-    Request     = {URL, []},
-    HTTPOptions = 
-	case SocketType of
-	    ip_comm ->
-		[];
-	    _ ->
-		SslOpts = [{verify, 0},
-			   {certfile, CertFile},
-			   {keyfile,  CertFile}],
-		case SocketType of
-		    ssl ->
-			[{ssl, SslOpts}];
-		    ossl ->
-			[{ssl, {ossl, SslOpts}}];
-		    essl ->
-			[{ssl, {essl, SslOpts}}]
-		end
-	end,
-    Options = [{sync, false}], 
-    {ok, Ref} = httpc:request(Method, Request, HTTPOptions, Options), 
-    send_requests(State#state{last_req = Ref}, N-1, lists:append(Sizes, [Sz])).
-
-
-timestamp() ->
-   os:timestamp().
- 
-
-get_node_info() ->
-    [{cpu_topology,        erlang:system_info(cpu_topology)},
-     {heap_type,           erlang:system_info(heap_type)},
-     {nof_schedulers,      erlang:system_info(schedulers)},
-     {otp_release,         erlang:system_info(otp_release)}, 
-     {version,             erlang:system_info(version)}, 
-     {system_version,      erlang:system_info(system_version)},
-     {system_architecture, erlang:system_info(system_architecture)}].
-
-
diff --git a/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl b/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl
deleted file mode 100644
index 6ff137be58..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_ctrl.erl
+++ /dev/null
@@ -1,1527 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: The httpd load test (hdlt) controller/collector module, 
-%%          This module contains all the code of the httpd load test 
-%%          controller/collector. It sets up the test, starts all
-%%          server and client nodes and applications and finally 
-%%          collects test data.
-%%----------------------------------------------------------------------
-
--module(hdlt_ctrl).
--dialyzer({no_fail_call, proxy_loop/1}).
--export([start/1, stop/0, help/0]).
-
--export([init/1, proxy/7]).
-
--include_lib("kernel/include/file.hrl").
--include("hdlt_logger.hrl").
-
--define(DEFAULT_SENDRATE,           89).
--define(DEFAULT_TEST_TIME,          120). % 2 minutes
--define(DEFAULT_PORT,               8889).
--define(TIMEOUT,                    60000).
--define(DEFAULT_MAX_NOF_SCHEDULERS, 8).
--define(DEFAULT_SERVER_DIR,         "/tmp/hdlt").
--define(DEFAULT_WORK_DIR,           "/tmp/hdlt").
--define(SSH_PORT,                   22).
--define(DEFAULT_SOCKET_TYPE,        ip_comm).
--define(DEFAULT_SERVER_CERT,        "hdlt_ssl_server_cert.pem").
--define(DEFAULT_CLIENT_CERT,        "hdlt_ssl_client_cert.pem").
--define(SSH_CONNECT_TIMEOUT,        5000).
--define(NODE_START_TIMEOUT,         5000).
--define(LOCAL_PROXY_START_TIMEOUT,  ?NODE_START_TIMEOUT * 4).
--define(DEFAULT_DEBUGS, 
-	[{ctrl, info}, {slave, silence}, {proxy, silence}, {client, silence}]).
--define(DEFAULT_WORK_SIM,           10000).
--define(DEFAULT_DATA_SIZE_START,    500).
--define(DEFAULT_DATA_SIZE_END,      1500).
--define(DEFAULT_DATA_SIZE_INCR,     1).
--define(DEFAULT_DATA_SIZE,          {?DEFAULT_DATA_SIZE_START,
-				     ?DEFAULT_DATA_SIZE_END,
-				     ?DEFAULT_DATA_SIZE_INCR}).
-
-
-%% hdlt = httpd load test
-
--define(COLLECTOR,   hdlt_ctrl).
--define(RESULTS_TAB, hdlt_results).
-
--define(CLIENT_MOD,       hdlt_client).
--define(CLIENT_NODE_NAME, ?CLIENT_MOD).
-
--define(SERVER_MOD,       hdlt_server).
--define(SERVER_NODE_NAME, ?SERVER_MOD).
-
--define(LOGGER, hdlt_logger).
-
-
--record(state, 
-	{
-	 url,
-	 test_time,
-	 send_rate,
-	 http_server, 
-	 http_port,
-	 results = ?RESULTS_TAB, 
-	 nodes,
-	 server_root,
-	 doc_root,
-	 server_dir,
-	 work_dir,
-	 server_conn,
-	 client_conns = [],
-	 client_mod   = ?CLIENT_MOD, 
-	 clients,
-	 nof_schedulers = 0,
-	 max_nof_schedulers,
-	 socket_type,
-	 server_cert_file,
-	 client_cert_file,
-	 debugs,
-	 client_sz_from, 
-	 client_sz_to, 
-	 client_sz_incr 
-	}
-       ).
-
--record(proxy, 
-	{
-	 mode,
-	 mod, 
-	 connection, 
-	 channel, 
-	 host, 
-	 cmd, 
-	 node_name, 
-	 node,
-	 ref,
-	 erl_path, 
-	 paths, 
-	 args
-	}).
-
--record(connection, 
-	{
-	 proxy,
-	 node, 
-	 node_name,
-	 host
-	}).
-
-
--record(client, {host, path, version}).
--record(server, {host, path, version}).
-
-
-start(Config) when is_list(Config) ->
-    proc_lib:start_link(?MODULE, init, [Config]).
-
-stop() ->
-    global:send(?COLLECTOR, stop).
-
-init(Config) ->
-    %% io:format("Config: ~n~p~n", [Config]),
-    case (catch do_init(Config)) of
-	{ok, State} ->
-	    proc_lib:init_ack({ok, self()}),
-	    loop(State);
-	{error, _Reason} = Error ->
-	    proc_lib:init_ack(Error),
-	    ok;
-	{'EXIT', Reason} ->
-	    proc_lib:init_ack({error, Reason}),
-	    ok
-    end.
-
-do_init(Config) ->
-    %% Do not trap exit, but register ourself
-    global:register_name(?COLLECTOR, self()), 
-
-    State = #state{},
-    ets:new(State#state.results, [bag, named_table]),
-    
-    hdlt_logger:start(),
-    global:sync(),
-    
-    %% Maybe enable debug
-    Debugs = get_debugs(Config),
-    ?SET_NAME("HDLT CTRL"),
-    set_debug_level(Debugs), 
-
-    ?DEBUG("network info: "
-	   "~n   Global names: ~p"
-	   "~n   Nodes:        ~p", [global:registered_names(), nodes()]),
-
-    %% Read config
-    ?LOG("read config", []),
-    SendRate         = get_send_rate(Config),
-    Clients          = get_clients(Config), 
-    TestTime         = get_test_time(Config), 
-    Server           = get_server(Config),
-    Port             = get_port(Config),
-    ServerDir        = get_server_dir(Config),
-    WorkingDir       = get_work_dir(Config),
-    MaxNofSchedulers = get_max_nof_schedulers(Config),
-    SocketType       = get_socket_type(Config),
-    ServerCertFile   = get_server_cert_file(Config),
-    ClientCertFile   = get_client_cert_file(Config),
-    WorkSim          = get_work_sim(Config),
-    {From, To, Incr} = get_data_size(Config),
-
-    URL        = url(Server, Port, SocketType, WorkSim), 
-    ServerRoot = filename:join(ServerDir, "server_root"),  
-    DocRoot    = ServerRoot, %% Not really used in this test
-
-    %% Start used applications
-    ?DEBUG("ensure crypto started", []), 
-    application:start(crypto),
-    ?DEBUG("ensure ssh started", []), 
-    ssh:start(),
-
-    State2 = State#state{server_root        = ServerRoot, 
-			 doc_root           = DocRoot,
-			 server_dir         = ServerDir, 
-			 work_dir           = WorkingDir,
-			 max_nof_schedulers = MaxNofSchedulers, 
-			 socket_type        = SocketType,
-			 server_cert_file   = ServerCertFile,
-			 client_cert_file   = ClientCertFile,
-			 http_server        = Server, 
-			 http_port          = Port, 
-			 url                = URL,
-			 test_time          = TestTime, 
-			 send_rate          = SendRate,
-			 clients            = Clients,
-			 debugs             = Debugs, 
-			 client_sz_from     = From, 
-			 client_sz_to       = To, 
-			 client_sz_incr     = Incr},
-    
-    ?LOG("prepare server host", []),
-    prepare_server_host(State2),
-
-    ?LOG("prepare client hosts", []),
-    State3 = prepare_client_hosts(State2),
-
-    ?LOG("basic init done", []),
-    {ok, State3}.
-
-
-loop(#state{nof_schedulers = N, max_nof_schedulers = M} = State) when N > M -> 
-    
-    ?INFO("Starting to analyse data", []),
-    
-    AnalysedTab = analyse_data(State),
-    
-    Files = save_results_to_file(AnalysedTab, State),
-    io:format("~n******************************************************"
-	      "~n~nResult(s) saved to: ~n~p~n", [Files]),
-    clean_up(State);
-
-loop(#state{url            = URL, 
-	    test_time      = TestTime, 
-	    send_rate      = SendRate,
-	    nof_schedulers = NofSchedulers} = State) ->
-    
-    {StartH, StartM, StartS} = erlang:time(),
-	
-    ?INFO("Performing test with ~p smp-scheduler(s): ~n"
-	  "  It will take a minimum of: ~p seconds. ~n"
-	  "  Start time:                ~.2.0w:~.2.0w:~.2.0w", 
-	  [NofSchedulers, round(TestTime/1000), StartH, StartM, StartS]),
-
-    %% Start the server node 
-    %% (The local proxy, the node, the remote proxy, and the inets framework)
-    State1 = start_server_node(State),
-    ?DEBUG("nodes after server start: ~p", [nodes() -- [node()]]),
-    
-    %% Start the client node(s)
-    %% (The local proxy, the node, the remote proxy, and the inets framework)
-    ?LOG("start client node(s)", []),
-    State2 = start_client_nodes(State1),
-    ?DEBUG("nodes after client(s) start: ~p", [nodes() -- [node()]]),
-
-    ?LOG("start server", []),
-    start_server(State2), 
-
-    ?LOG("start clients", []),
-    start_clients(State2, URL, TestTime, SendRate),
-
-    ?LOG("release clients", []),
-    release_clients(State2),
-
-    ?LOG("collect data", []),
-    collect_data(State2),
-
-    ?LOG("stop all nodes", []),
-    State3 = stop_nodes(State2),
-
-    ?INFO("Test with ~p smp-scheduler(s) complete"
-	  "~n~n"
-	  "****************************************************************"
-	  "~n", 
-	  [NofSchedulers]),
-    loop(State3#state{nof_schedulers = NofSchedulers + 1}).
-    
-
-prepare_server_host(#state{server_root      = ServerRoot, 
-			   http_server      = #server{host = Host},
-			   socket_type      = SocketType,
-			   server_cert_file = CertFile}) ->
-    ?INFO("prepare server host ~s", [Host]),
-    Opts = [{user_interaction,      false},
-	    {silently_accept_hosts, true},
-	    {timeout,               2*?SSH_CONNECT_TIMEOUT}, 
-	    {connect_timeout,       ?SSH_CONNECT_TIMEOUT}], 
-    case ssh_sftp:start_channel(Host, Opts) of
-	{ok, Sftp, ConnectionRef} ->
-	    ?DEBUG("sftp connection established - now transfer server content",
-		   []),
-	    create_server_content(Sftp, ServerRoot, SocketType, CertFile),
-	    ?DEBUG("server content transferred - now close ssh connection ", 
-		   []),
-	    ssh:close(ConnectionRef),
-	    ?DEBUG("server preparation complete ", []),
-	    ok;
-	Error ->
-	    ?INFO("FAILED creating sftp channel to server host ~s: "
-		  "~n   ~p", [Host, Error]),
-	    exit({failed_establishing_sftp_connection, Error})
-    end.
-
-create_server_content(Sftp, ServerRoot, SocketType, CertFile) -> 
-    %% Create server root
-    ?DEBUG("ensure existence of ~p", [ServerRoot]),
-    ensure_remote_dir_exist(Sftp, ServerRoot),
-
-    %% Create the server ebin dir (for the starter module)
-    EBIN = filename:join(ServerRoot, "ebin"), 
-    ?DEBUG("make ebin dir: ~p", [EBIN]),
-    maybe_create_remote_dir(Sftp, EBIN),
-
-    %% Create the server ebin dir (for the starter module)
-    LOG = filename:join(ServerRoot, "log"), 
-    ?DEBUG("make log dir: ~p", [LOG]),
-    maybe_create_remote_dir(Sftp, LOG),
-
-    LocalServerMod = local_server_module(), 
-    ?DEBUG("copy server stub/proxy module ~s", [LocalServerMod]), 
-    RemoteServerMod = remote_server_module(EBIN), 
-    {ok, ServerModBin} = file:read_file(LocalServerMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteServerMod, ServerModBin),
-
-    LocalSlaveMod = local_slave_module(), 
-    ?DEBUG("copy slave module ~s", [LocalSlaveMod]), 
-    RemoteSlaveMod = remote_slave_module(EBIN), 
-    {ok, SlaveModBin} = file:read_file(LocalSlaveMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteSlaveMod, SlaveModBin),
-
-    LocalLoggerMod = local_logger_module(), 
-    ?DEBUG("copy logger module ~s", [LocalLoggerMod]), 
-    RemoteLoggerMod = remote_logger_module(EBIN), 
-    {ok, LoggerModBin} = file:read_file(LocalLoggerMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteLoggerMod, LoggerModBin),
-
-    %% Create the inets server data dir
-    CGI = filename:join(ServerRoot, "cgi-bin"), 
-    ?DEBUG("make cgi dir: ~p", [CGI]),
-    maybe_create_remote_dir(Sftp, CGI),
-    
-    LocalRandomMod = local_random_html_module(), 
-    ?DEBUG("copy random-html module ~s", [LocalRandomMod]), 
-    RemoteRandomMod = remote_random_html_module(EBIN), 
-    {ok, RandomModBin} = file:read_file(LocalRandomMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteRandomMod, RandomModBin),
-
-    case SocketType of
-	ip_comm ->
-	    ok;
-	_ ->
-	    SSLDir = filename:join(ServerRoot, "ssl"), 
-	    ?DEBUG("make conf dir: ~p", [SSLDir]),
-	    maybe_create_remote_dir(Sftp, SSLDir),
-	    ?DEBUG("copy ssl cert file ~s", [CertFile]),
-	    {ok, CertBin} = file:read_file(CertFile),
-	    RemoteCertFile = filename:join(SSLDir, 
-					   filename:basename(CertFile)),
-	    ok = ssh_sftp:write_file(Sftp, RemoteCertFile, CertBin),
-	    ok
-    end,
-
-    ?DEBUG("done", []),
-    ok.
-
-remote_server_module(Path) ->
-    Mod = server_module(), 
-    filename:join(Path, Mod).
-
-local_server_module() ->
-    Mod = server_module(), 
-    case code:where_is_file(Mod) of
-	Path when is_list(Path) ->
-	    Path;
-	_ ->
-	    exit({server_module_not_found, Mod})
-    end.
-
-server_module() ->
-    module(?SERVER_MOD).
-
-
-prepare_client_hosts(#state{work_dir         = WorkDir, 
-			    clients          = Clients,
-			    socket_type      = SocketType,
-			    client_cert_file = CertFile} = State) ->
-    Clients2 = 
-	prepare_client_hosts(WorkDir, SocketType, CertFile, Clients, []),
-    State#state{clients = Clients2}.
-
-prepare_client_hosts(_WorkDir, _SocketType, _CertFile, [], Acc) ->
-    lists:reverse(Acc);
-prepare_client_hosts(WorkDir, SocketType, CertFile, [Client|Clients], Acc) ->
-    case prepare_client_host(WorkDir, SocketType, CertFile, Client) of
-	ok ->
-	    prepare_client_hosts(WorkDir, SocketType, CertFile, Clients, 
-				 [Client|Acc]);
-	_ ->
-	    prepare_client_hosts(WorkDir, SocketType, CertFile, Clients, Acc)
-    end.
-
-prepare_client_host(WorkDir, SocketType, CertFile, #client{host = Host}) ->
-    ?INFO("prepare client host ~s", [Host]),
-    Opts = [{user_interaction,      false},
-	    {silently_accept_hosts, true},
-	    {timeout,               2*?SSH_CONNECT_TIMEOUT}, 
-	    {connect_timeout,       ?SSH_CONNECT_TIMEOUT}], 
-    case ssh_sftp:start_channel(Host, Opts) of
-	{ok, Sftp, ConnectionRef} ->
-	    ?DEBUG("sftp connection established - now transfer client content",
-		   []),
-	    create_client_content(Sftp, WorkDir, SocketType, CertFile),
-	    ?DEBUG("client content transered - now close ssh connection ", []),
-	    ssh:close(ConnectionRef),
-	    ?DEBUG("client preparation complete ", []),
-	    ok;
-	Error ->
-	    ?INFO("FAILED creating sftp channel to client host ~s: skipping"
-		  "~n   ~p", [Host, Error]),
-	    Error
-    end.
-
-create_client_content(Sftp, WorkDir, SocketType, CertFile) -> 
-    %% Create work dir
-    ?DEBUG("ensure existence of ~p", [WorkDir]),
-    ensure_remote_dir_exist(Sftp, WorkDir),
-
-    %% Create the client ebin dir
-    EBIN = filename:join(WorkDir, "ebin"), 
-    RemoteClientMod = remote_client_module(EBIN), 
-    ?DEBUG("make ebin dir: ~p", [EBIN]),
-    maybe_create_remote_dir(Sftp, EBIN),
-
-    LocalClientMod = local_client_module(), 
-    ?DEBUG("copy client stub/proxy module ~s", [LocalClientMod]), 
-    {ok, ClientModBin} = file:read_file(LocalClientMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteClientMod, ClientModBin),
-
-    LocalSlaveMod = local_slave_module(), 
-    ?DEBUG("copy slave module ~s", [LocalSlaveMod]), 
-    RemoteSlaveMod = remote_slave_module(EBIN), 
-    {ok, SlaveModBin} = file:read_file(LocalSlaveMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteSlaveMod, SlaveModBin),
-
-    LocalLoggerMod = local_logger_module(), 
-    ?DEBUG("copy logger module ~s", [LocalLoggerMod]), 
-    RemoteLoggerMod = remote_logger_module(EBIN), 
-    {ok, LoggerModBin} = file:read_file(LocalLoggerMod),
-    ok = ssh_sftp:write_file(Sftp, RemoteLoggerMod, LoggerModBin),
-
-    case SocketType of
-	ip_comm ->
-	    ok;
-	_ ->
-	    %% We should really store the remote path somewhere as
-	    %% we use it when starting the client service...
-	    SSLDir = filename:join(WorkDir, "ssl"), 
-	    ?DEBUG("make ssl dir: ~p", [SSLDir]),
-	    maybe_create_remote_dir(Sftp, SSLDir),
-	    ?DEBUG("copy ssl cert file ~s", [CertFile]),
-	    {ok, CertBin} = file:read_file(CertFile),
-	    RemoteCertFile = filename:join(SSLDir, 
-					   filename:basename(CertFile)),
-	    ok = ssh_sftp:write_file(Sftp, RemoteCertFile, CertBin),
-	    ok
-    end,
-
-    ?DEBUG("done", []),
-    ok.
-
-remote_client_module(Path) ->
-    Mod = client_module(), 
-    filename:join(Path, Mod).
-
-local_client_module() ->
-    Mod = client_module(), 
-    case code:where_is_file(Mod) of
-	Path when is_list(Path) ->
-	    Path;
-	_ ->
-	    exit({client_module_not_found, Mod})
-    end.
-
-client_module() ->
-    module(?CLIENT_MOD).
-
-
-remote_slave_module(Path) ->
-    Mod = slave_module(), 
-    filename:join(Path, Mod).
-
-local_slave_module() ->
-    Mod = slave_module(), 
-    case code:where_is_file(Mod) of
-	Path when is_list(Path) ->
-	    Path;
-	_ ->
-	    exit({slave_module_not_found, Mod})
-    end.
-
-slave_module() ->
-    module(hdlt_slave).
-
-
-remote_logger_module(Path) ->
-    Mod = logger_module(), 
-    filename:join(Path, Mod).
-
-local_logger_module() ->
-    Mod = logger_module(), 
-    case code:where_is_file(Mod) of
-	Path when is_list(Path) ->
-	    Path;
-	_ ->
-	    exit({logger_module_not_found, Mod})
-    end.
-
-logger_module() ->
-    module(hdlt_logger).
-
-
-remote_random_html_module(Path) ->
-    Mod = random_html_module(), 
-    filename:join(Path, Mod).
-
-local_random_html_module() ->
-    Mod = random_html_module(), 
-    case code:where_is_file(Mod) of
-	Path when is_list(Path) ->
-	    Path;
-	_ ->
-	    exit({random_module_not_found, Mod})
-    end.
-
-random_html_module() ->
-    module(hdlt_random_html).
-
-
-module(Mod) ->
-    Ext = string:to_lower(erlang:system_info(machine)), 
-    lists:flatten(io_lib:format("~w.~s", [Mod, Ext])).
-
-
-%% -----------------------------------------------------------------------
-%% - For every node created (server and client both) there is both 
-%%   a local and remote proxy. 
-%% - The local proxy is running on the local (controller/collector) node.
-%% - The remote proxy is running on the client or server node(s).
-%% - The local (ctrl) proxy monitor the remote (server/client) proxy.
-%% - The remote (server/client) proxy monitor the local (ctrl) proxy.
-%% 
-
-start_client_nodes(#state{clients = Clients, 
-			  work_dir = WorkDir,
-			  debugs   = Debugs} = State) ->
-    Connections = 
-	[start_client_node(Client, WorkDir, Debugs) || Client <- Clients],
-    State#state{client_conns = Connections}.
-
-start_client_node(#client{path = ErlPath, host = Host}, WorkDir, Debugs) ->
-    ?INFO("start client on host ~p", [Host]),
-    EbinDir = filename:join(WorkDir, "ebin"), 
-    start_client_node(Host, ErlPath, [EbinDir], Debugs).
-
-start_client_node(Host, ErlPath, Paths, Debugs) ->
-    start_node(Host, ?CLIENT_NODE_NAME, 
-	       ErlPath, Paths, [], ?CLIENT_MOD, Debugs).
-
-
-start_server_node(#state{http_server    = #server{path = ErlPath, host = Host},
-			 server_root    = ServerRoot,
-			 nof_schedulers = NofScheds,
-			 debugs         = Debugs} = State) ->
-    ?INFO("start server on host ~p", [Host]),
-    CgiBinDir  = filename:join(ServerRoot, "cgi-bin"),
-    EbinDir    = filename:join(ServerRoot, "ebin"), 
-    Connection = 
-	start_server_node(Host, ErlPath, [CgiBinDir, EbinDir], 
-			  Debugs, NofScheds),
-    State#state{server_conn = Connection}.
-
-start_server_node(Host, ErlPath, Paths, Debugs, NofScheds) ->
-    Args = 
-	if
-	    NofScheds =:= 0 ->
-		"-smp disable";
-	    true ->
-		lists:flatten(io_lib:format("-smp +S ~w", [NofScheds]))
-	end,
-    start_node(Host, ?SERVER_NODE_NAME, 
-	       ErlPath, Paths, Args, ?SERVER_MOD, Debugs).
-
-
-%% -----------------------------------------------------------------------
-%% - For every node created (server and client both) there is both 
-%%   a local and remote proxy. 
-%% - The local proxy is running on the local (controller/collector) node.
-%% - The remote proxy is running on the client or server node(s).
-%% - The local (ctrl) proxy monitor the remote (server/client) proxy.
-%% - The remote (server/client) proxy monitor the local (ctrl) proxy.
-%% 
-
-start_node(Host, NodeName, ErlPath, Paths, Args, Module, Debugs) ->
-    %% Start the (local) proxy
-    ?DEBUG("start_node -> start local proxy and remote node", []),
-    ProxyDebug = proplists:get_value(proxy, Debugs, silence), 
-    Proxy = proxy_start(Host, NodeName, ErlPath, Paths, Args, Module, 
-			ProxyDebug),
-
-    ?DEBUG("start_node -> local proxy started - now start node", []),
-    SlaveDebug = proplists:get_value(slave, Debugs, silence), 
-    Node = proxy_start_node(Proxy, SlaveDebug),
-
-    ?DEBUG("start_node -> sync global", []),
-    global:sync(),
-
-    ?DEBUG("start_node -> start remote proxy", []),
-    proxy_start_remote(Proxy),
-
-    ?DEBUG("start_node -> start (remote) inets framework", []),
-    proxy_start_inets(Proxy), 
-
-    ?DEBUG("start_node -> done", []),
-    #connection{proxy = Proxy, node = Node, node_name = NodeName, host = Host}.
-
-    
-proxy_start(Host, NodeName, ErlPath, Paths, Args, Module, Debug) ->
-    ?LOG("try starting local proxy for ~p@~s", [NodeName, Host]), 
-    ProxyArgs = [Host, NodeName, ErlPath, Paths, Args, Module, Debug], 
-    case proc_lib:start_link(?MODULE, proxy, 
-			     ProxyArgs, ?LOCAL_PROXY_START_TIMEOUT) of
-	{ok, Proxy} ->
-	    Proxy;
-	Error ->
-	    exit({failed_starting_proxy, Error})
-    end.
-
-proxy_start_node(Proxy, Debug) ->
-    {ok, Node} = proxy_request(Proxy, {start_node, Debug}),
-    Node.
-
-proxy_start_remote(Proxy) ->
-    proxy_request(Proxy, start_remote_proxy).
-
-proxy_start_inets(Proxy) ->
-    proxy_request(Proxy, start_inets).
-
-proxy_start_service(Proxy, Args) ->
-    proxy_request(Proxy, {start_service, Args}).
-
-proxy_release(Proxy) ->
-    proxy_request(Proxy, release).
-
-proxy_stop(Proxy) ->
-    StopResult = proxy_request(Proxy, stop),
-    ?DEBUG("proxy stop result: ~p", [StopResult]),
-    StopResult.
-
-proxy_request(Proxy, Req) ->
-    Ref = make_ref(),
-    Proxy ! {proxy_request, Ref, self(), Req},
-    receive
-	{proxy_reply, Ref, Proxy, Rep} ->
-	    Rep
-    end.
-
-proxy_reply(From, Ref, Rep) ->
-    From ! {proxy_reply, Ref, self(), Rep}.
-
-proxy(Host, NodeName, ErlPath, Paths, Args, Module, Debug) ->
-    process_flag(trap_exit, true),
-    SName = lists:flatten(
-	      io_lib:format("HDLT CTRL PROXY[~p,~s,~w]", 
-			    [self(), Host, NodeName])), 
-    ?SET_NAME(SName),
-    ?SET_LEVEL(Debug), 
-    ?LOG("starting with"
-	"~n   Host:     ~p"
-	"~n   NodeName: ~p"
-	"~n   ErlPath:  ~p"
-	"~n   Paths:    ~p"
-	"~n   Args:     ~p"
-	"~n   Module:   ~p", [Host, NodeName, ErlPath, Paths, Args, Module]), 
-    State = #proxy{mode      = started,
-		   mod       = Module, 
-		   host      = Host,
-		   node_name = NodeName,
-		   erl_path  = ErlPath,
-		   paths     = Paths,
-		   args      = Args},
-    proc_lib:init_ack({ok, self()}),
-    ?DEBUG("started", []), 
-    proxy_loop(State).
-
-
-proxy_loop(#proxy{mode = stopping}) ->
-    receive
-	{proxy_request, Ref, From, stop} ->
-	    ?LOG("[stopping] received stop order", []),
-	    proxy_reply(From, Ref, ok),
-	    exit(normal);
-
-	{'EXIT', Pid, Reason} ->
-	    ?INFO("[stopping] received exit message from ~p: "
-		  "~n   Reason: ~p", [Pid, Reason]),
-	    exit(Reason)
-    
-    end;
-
-proxy_loop(#proxy{mode      = started,
-		  host      = Host,
-		  node_name = NodeName,
-		  erl_path  = ErlPath,
-		  paths     = Paths,
-		  args      = Args} = State) ->
-    receive
-	{proxy_request, Ref, From, {start_node, Debug}} ->
-	    ?LOG("[starting] received start_node order", []),
-	    case hdlt_slave:start_link(Host, NodeName, 
-				       ErlPath, Paths, Args, 
-				       Debug) of
-		{ok, Node} ->
-		    ?DEBUG("[starting] node ~p started - now monitor", [Node]),
-		    erlang:monitor_node(Node, true),
-		    State2 = State#proxy{mode = operational,
-					node = Node},
-		    proxy_reply(From, Ref, {ok, Node}),
-		    proxy_loop(State2);
-		{error, Reason} ->
-		    ?INFO("[starting] failed starting node: "
-			  "~n   Reason: ~p", [Reason]),
-		    exit({failed_starting_node, {Host, NodeName, Reason}})
-	    end;
-
-	{'EXIT', Pid, Reason} ->
-	    ?INFO("[stopping] received exit message from ~p: "
-		  "~n   Reason: ~p", [Pid, Reason]),
-	    exit(Reason)
-    
-    end;
-
-proxy_loop(#proxy{mode = operational,
-		  mod  = Mod,
-		  node = Node} = State) ->
-    ?DEBUG("[operational] await command", []),
-    receive 
-	{proxy_request, Ref, From, start_remote_proxy} ->
-	    ?LOG("[operational] start remote proxy", []),
-	    case rpc:call(Node, Mod, start, [?GET_LEVEL()]) of
-		{ok, Pid} ->
-		    ?DEBUG("[operational] remote proxy started (~p) - "
-			   "create monitor", [Pid]),
-		    ProxyRef = erlang:monitor(process, Pid),
-		    ?DEBUG("[operational] monitor: ~p", [Ref]),
-		    proxy_reply(From, Ref, ok),
-		    proxy_loop(State#proxy{ref = ProxyRef});
-		Error ->
-		    ?INFO("[operational] failed starting remote proxy"
-			 "~n   Error: ~p", [Error]),
-		    ReplyReason = {failed_starting_remote_proxy, 
-				   {Node, Error}},
-		    Reply = {error, ReplyReason}, 
-		    proxy_reply(From, Ref, Reply),
-		    exit({failed_starting_remote_proxy, {Node, Error}})
-	    end;
-
-	{proxy_request, Ref, From, start_inets} ->
-	    ?INFO("[operational] start inets framework", []),
-	    rpc:cast(Node, Mod, start_inets, []),
-	    proxy_reply(From, Ref, ok),
-	    proxy_loop(State);
-
-	{proxy_request, Ref, From, {start_service, Args}} ->
-	    ?INFO("[operational] start service with"
-		  "~n   ~p", [Args]),
-	    case rpc:call(Node, Mod, start_service, Args) of
-		ok ->
-		    ?DEBUG("[operational] service started", []),
-		    proxy_reply(From, Ref, ok), 
-		    proxy_loop(State);
-		Error ->
-		    ?INFO("[operational] failed starting service: "
-			  "~n   Args.  ~p"
-			  "~n   Error: ~p", [Args, Error]),
-		    erlang:demonitor(State#proxy.ref, [flush]),
-		    Reply = {error, {failed_starting_service, Node, Error}}, 
-		    proxy_reply(From, Ref, Reply),
-		    exit({failed_starting_service, Node, Error})
-	    end;
-
-	{proxy_request, Ref, From, release} ->
-	    ?INFO("[operational] release", []),
-	    rpc:call(Node, Mod, release, []),
-	    proxy_reply(From, Ref, ok), 
-	    proxy_loop(State);
-
-	{proxy_request, Ref, From, stop} ->
-	    ?INFO("[operational] received stop order", []),
-	    erlang:demonitor(State#proxy.ref, [flush]),
-	    ?DEBUG("[operational] rpc cast stop order", []),
-	    rpc:cast(Node, Mod, stop, []), 
-	    %% And wait for the node death to be reported
-	    Reason = 
-		receive 
-		    {nodedown, Node} when State#proxy.node =:= Node ->
-			ok
-		after 10000 ->
-			?INFO("Node did not die within expected time frame", 
-			      []),
-			{node_death_timeout, Node}
-		end,
-	    ?DEBUG("[operational] ack stop", []),
-	    proxy_reply(From, Ref, Reason),
-	    exit(normal);
-
-	{nodedown, Node} when State#proxy.node =:= Node ->
-	    ?INFO("[operational] received unexpected nodedoen message", []),
-	    exit({node_died, Node});
-
-	{'DOWN', Ref, process, _, normal} when State#proxy.ref =:= Ref ->
-	    ?INFO("[operational] remote proxy terminated normally", []),
-	    proxy_loop(State#proxy{ref        = undefined,
-				   connection = undefined,
-				   mode       = stopping});
-
-	{'DOWN', Ref, process, _, noconnection} when State#proxy.ref =:= Ref ->
-	    ?INFO("[operational] remote proxy terminated - no node", []),
-	    proxy_loop(State#proxy{ref        = undefined,
-				   connection = undefined,
-				   mode       = stopping});
-
-	{'DOWN', Ref, process, _, Reason} when State#proxy.ref =:= Ref ->
-	    ?INFO("[operational] remote proxy terminated: "
-		  "~n   Reason: ~p", [Reason]),
-	    exit({remote_proxy_crash, Reason});
-
-	{'EXIT', Pid, Reason} ->
-	    ?INFO("[operational] received unexpected exit message from ~p: "
-		  "~n   Reason: ~p", [Pid, Reason]),
-	    proxy_loop(State)
-    
-    end.
-
-
-stop_nodes(#state{server_conn  = ServerConn, 
-		  client_conns = ClientConns} = State) ->
-    lists:foreach(
-      fun(#connection{proxy = Proxy, node_name = NodeName, host = Host}) -> 
-	      ?DEBUG("stop_erlang_nodes -> send stop order to local proxy ~p"
-		  "~n   for node ~p on ~s", [Proxy, NodeName, Host]),
-	      proxy_stop(Proxy)
-      end, 
-      ClientConns ++ [ServerConn]),
-    ?DEBUG("stop_erlang_nodes -> sleep some to give the nodes time to die", 
-	   []),
-    timer:sleep(1000),
-    ?DEBUG("stop_erlang_nodes -> and a final cleanup round", []),
-    lists:foreach(fun(Node) ->
-			  ?INFO("try brutal stop node ~p", [Node]),
-			  rpc:cast(Node, erlang, halt, [])
-		  end, 
-		  nodes() -- [node()]),
-    ?DEBUG("stop_erlang_nodes -> done", []),
-    State#state{server_conn = undefined, client_conns = []}.
-
-
-%% The nodes on which the HDLT clients run have been started previously
-start_clients(#state{client_conns     = Connections, 
-		     debugs           = Debugs,
-		     work_dir         = WorkDir,
-		     socket_type      = SocketType,
-		     client_cert_file = CertFile, 
-		     client_sz_from   = From,
-		     client_sz_to     = To,
-		     client_sz_incr   = Incr}, 
-	      URL, TestTime, SendRate) ->
-    Debug = proplists:get_value(client, Debugs, silence), 
-    StartClient = 
-	fun(#connection{host = Host} = Connection) ->
-		?DEBUG("start client on ~p", [Host]),
-		start_client(Connection, 
-			     WorkDir, SocketType, CertFile, 
-			     URL, From, To, Incr, 
-			     TestTime, SendRate, Debug);
-	   (_) ->
-		ok
-	end,
-    lists:foreach(StartClient, Connections).
-
-start_client(#connection{proxy = Proxy}, 
-	     WorkDir, SocketType, LocalCertFile, 
-	     URL, From, To, Incr, 
-	     TestTime, SendRate, Debug) ->
-    SSLDir  = filename:join(WorkDir, "ssl"), 
-    CertFile = filename:join(SSLDir, filename:basename(LocalCertFile)),
-    Sizes    = randomized_sizes(From, To, Incr),
-    Args = [SocketType, CertFile, URL, Sizes, TestTime, SendRate, Debug],
-    proxy_start_service(Proxy, [Args]).
-    
-release_clients(#state{client_conns = Connections}) ->
-    ReleaseClient = 
-	fun(#connection{proxy = Proxy,
-			host  = Host}) ->
-		?DEBUG("release client on ~p", [Host]),
-		proxy_release(Proxy);
-	   (_) ->
-		ok
-	end,
-    lists:foreach(ReleaseClient, Connections).
-
-    
-start_server(#state{server_conn      = #connection{proxy = Proxy}, 
-		    http_port        = Port,
-		    server_root      = ServerRoot,
-		    doc_root         = DocRoot,
-		    socket_type      = SocketType,
-		    server_cert_file = CertFile}) ->
-
-    HttpdConfig = 
-	httpd_config(Port, "hdlt", ServerRoot, DocRoot, SocketType, CertFile),
-    ?LOG("start the httpd inets service with config: "
-	 "~n   ~p", [HttpdConfig]),
-    proxy_start_service(Proxy, [HttpdConfig]), 
-    ?DEBUG("start_server -> done", []),
-    ok.
- 
-
-httpd_config(Port, ServerName, ServerRoot, DocRoot, 
-	     SocketType, LocalCertFile) ->  
-    LogDir = filename:join(ServerRoot, "log"),
-    ErrorLog = filename:join(LogDir, "error_log"),
-    TransferLog = filename:join(LogDir, "access_log"),
-    
-    SSL = 
-	case SocketType of
-	    ip_comm ->
-		[];
-	    _ -> % ssl
-		SSLDir = filename:join(ServerRoot, "ssl"), 
-		CertFile = 
-		    filename:join(SSLDir, filename:basename(LocalCertFile)),
-		[
-		 {ssl_certificate_file,     CertFile},
-		 {ssl_certificate_key_file, CertFile},
-		 {ssl_verify_client,        0}
-		]
-	end,
-    [{port,          Port},
-     {server_name,   ServerName}, 
-     {server_root,   ServerRoot},
-     {document_root, DocRoot}, 
-     {error_log,     ErrorLog}, 
-     {error_log_format, pretty}, 
-     {transfer_log,  TransferLog}, 
-     {socket_type,   SocketType},
-     {max_clients,   10000},
-     {modules,       [mod_alias, mod_auth, mod_esi, mod_actions, mod_cgi, 
-		      mod_dir, mod_get, mod_head, mod_log, mod_disk_log]}, 
-     {script_alias,       {"/cgi-bin", filename:join(ServerRoot, "cgi-bin")}},
-     {erl_script_alias,   {"/cgi-bin", [hdlt_random_html]}}, 
-     {erl_script_timeout, 120000} | SSL].
-
-
-clean_up(#state{server_root = ServerRoot, 
-		work_dir    = WorkDir, 
-		http_server = #server{host = Host},
-		clients     = Clients}) ->
-    ?DEBUG("begin server cleanup", []),
-    server_clean_up(ServerRoot, WorkDir, Host),
-    ?DEBUG("begin client cleanup", []),
-    clients_clean_up(WorkDir, Clients),
-    ?DEBUG("cleanup done", []),
-    ok.
-
-server_clean_up(ServerRoot, WorkDir, Host) ->
-    ?DEBUG("server cleanup - create sftp channel", []),
-    {ok, Sftp, ConnectionRef} = 
-	ssh_sftp:start_channel(Host, [{user_interaction, false},
-				      {silently_accept_hosts, true}]),
-    ?DEBUG("server cleanup - delete ~p dirs", [ServerRoot]),
-    del_dirs(Sftp, ServerRoot),
-    ?DEBUG("server cleanup - delete ~p dirs", [WorkDir]),
-    del_dirs(Sftp, WorkDir),
-    ?DEBUG("server cleanup - close sftp channel", []),
-    ssh:close(ConnectionRef).
-
-clients_clean_up(_WorkDir, []) ->
-    ok;
-clients_clean_up(WorkDir, [Client|Clients]) ->
-    client_clean_up(WorkDir, Client),
-    clients_clean_up(WorkDir, Clients).
-
-client_clean_up(WorkDir, #client{host = Host}) ->
-    ?DEBUG("client cleanup - create sftp channel to ~p", [Host]),
-    {ok, Sftp, ConnectionRef} = 
-	ssh_sftp:start_channel(Host, [{user_interaction, false},
-				      {silently_accept_hosts, true}]),
-    ?DEBUG("client cleanup - delete ~p dirs", [WorkDir]),
-    del_dirs(Sftp, WorkDir),
-    ?DEBUG("client cleanup - close sftp channel", []),
-    ssh:close(ConnectionRef).
-    
-
-del_dirs(Sftp, Dir) ->
-    case ssh_sftp:list_dir(Sftp, Dir) of
-	{ok, []} ->
-	    ssh_sftp:del_dir(Sftp, Dir);
-	{ok, Files} ->
-	    Files2 = [F || F <- Files, (F =/= "..") andalso (F =/= ".")], 
-	    lists:foreach(fun(File) when ((File =/= "..") andalso 
-					  (File =/= ".")) ->
-				  FullPath = filename:join(Dir, File),
-				  case ssh_sftp:read_file_info(Sftp, 
-							       FullPath) of
-				      {ok, #file_info{type = directory}} ->
-					  del_dirs(Sftp, FullPath),
-					  ssh_sftp:del_dir(Sftp, FullPath);
-				      {ok, _} ->
-					  ssh_sftp:delete(Sftp, FullPath)
-				  end 
-			  end, Files2);
-	_ ->
-	    ok
-    end.
-
-collect_data(#state{clients = Clients} = State) ->
-    N = length(Clients),
-    collect_req_reply(N, State),
-    collect_time(N, State).
-     
-collect_req_reply(0, _State) ->
-    ?DEBUG("all reply data collected", []), 
-    ok;
-collect_req_reply(N, #state{nof_schedulers = NofScheduler, 
-			    results        = Db,
-			    client_conns   = Conns} = State) ->
-    ?DEBUG("await reply data from ~p client(s)", [N]),
-    receive 
-	{load_data, 
-	 {req_reply, Client, NoRequests, NoReplys}} ->
-	    ?DEBUG("received req_reply load-data from client ~p: "
-		 "~n   Number of requests: ~p"
-		 "~n   Number of replies:  ~p", 
-		 [Client, NoRequests, NoReplys]),
-	    ets:insert(Db, {{NofScheduler, Client}, 
-			    {req_reply, NoRequests, NoReplys}});
-	stop ->
-	    ?INFO("received stop", []),
-	    exit(self(), stop);
-
-	{client_exit, Client, Node, Reason} ->
-	    ?INFO("Received unexpected client exit from ~p on node ~p "
-		  "while collecting replies: "
-		  "~n   ~p", [Client, Node, Reason]),
-	    case lists:keysearch(Node, #connection.node, Conns) of
-		{value, Conn} ->
-		    ?LOG("Found problem connection: "
-			 "~n   ~p", [Conn]),
-		    exit({unexpected_client_exit, Reason});
-		false ->
-		    collect_req_reply(N, State)
-	    end
-    end,
-    collect_req_reply(N-1, State).		 
-	 
-collect_time(0, _State) -> 
-    ?DEBUG("all time data collected", []), 
-    ok;
-collect_time(N, #state{nof_schedulers = NofScheduler, 
-		       results        = Db,
-		       client_conns   = Conns} = State) ->
-    ?DEBUG("await time data from ~p clients", [N]),
-    receive 
-	{load_data, 
-	 {time_to_complete, Client, StopTime, LastResponseTime}} ->
-	    ?LOG("received time load-data from client ~p: "
-		 "~n   Time of stop:           ~p"
-		 "~n   Time of last response:  ~p", 
-		 [Client, StopTime, LastResponseTime]),
-	    ets:insert(Db, {{NofScheduler, Client}, 
-			    {time, StopTime, LastResponseTime}});
-	stop ->
-	    ?INFO("received stop while collecting data, when N = ~p", [N]),
-	    exit(self(), stop);
-
-	{client_exit, Client, Node, Reason} ->
-	    ?INFO("Received unexpected exit from client ~p on node ~p "
-		  "while collecting time data: "
-		  "~n   ~p", [Client, Node, Reason]),
-	    case lists:keysearch(Node, #connection.node, Conns) of
-		{value, Conn} ->
-		    ?LOG("Found problem connection: "
-			 "~n   ~p", [Conn]),
-		    exit({unexpected_client_exit, Reason});
-		false ->
-		    collect_req_reply(N, State)
-	    end;
-	    
-	Else -> %%% Something is wrong!
-	    ?INFO("RECEIVED UNEXPECTED MESSAGE WHILE COLLECTING TIME DATA: "
-		  "~n   ~p", [Else]),
-	    collect_time(N, State)	     
-    end,
-    collect_time(N-1, State).
-
-analyse_data(#state{results            = Db, 
-		    max_nof_schedulers = MaxNofSchedulers,
-		    test_time          = MicroSec}) ->
-    Tab = ets:new(analysed_results, [set]),
-    lists:foreach(fun(NofSchedulers) ->
-			  Result = analyse(NofSchedulers, Db, MicroSec),
-			  ets:insert(Tab, Result)
-		  end, [N || N <- lists:seq(0, MaxNofSchedulers)]),
-    Tab.
-
-    
-no_requests_replys(NoSchedulers, Tab) ->
-    NoRequests = 
-	ets:select(Tab, [{{{NoSchedulers,'_'},{req_reply, '$1', '_'}},
-			  [],['$$']}]),
-    NoReplys = 
-	ets:select(Tab, [{{{NoSchedulers, '_'}, {req_reply, '_', '$1'}}, 
-			  [], ['$$']}]),
-    
-    {lists:sum(lists:append(NoRequests)), 
-     lists:sum(lists:append(NoReplys))}. 
-
-max_time_to_final_response(NofSchedulers, Tab) ->
-    Candidates = 
-	ets:select(Tab, [{{{NofSchedulers, '_'}, {time, '$1', '$2'}},
-			  [], ['$$']}]),
-    
-    NewCandidates = lists:map(
-		      fun([StopTime, LastTime]) ->
-			      round(
-				timer:now_diff(LastTime, StopTime) / 100000)/10
-			      end, Candidates),
-    
-    lists:max(NewCandidates).
-
-
-analyse(NofSchedulers, Db, TestTime) ->
-    Sec = TestTime / 1000,
-    {NoRequests, NoReplys} = no_requests_replys(NofSchedulers, Db),
-    {NofSchedulers, round(NoReplys / Sec), NoRequests,
-     max_time_to_final_response(NofSchedulers, Db)}.
-
-
-save_results_to_file(AnalysedTab, 
-		     #state{socket_type        = SocketType, 
-			    http_server        = #server{host = Server},
-			    max_nof_schedulers = MaxNofSchedulers}) ->
-    FileName = fun(Post) -> 
-		       File = 
-			   lists:flatten(
-			     io_lib:format("~s_~w_~s", 
-					   [Server, SocketType, Post])),
-		       filename:join("./", File) 
-	       end,
-    Reps     = FileName("replys_per_sec.txt"),
-    Reqs     = FileName("total_requests.txt"),
-    Decay    = FileName("decay_time.txt"),
-    
-    [FdReps, FdReqs, FdDecay] = 
-	lists:map(fun(File) ->
-			  {ok, Fd} = file:open(File, [write]),
-			  Fd
-		  end, [Reps, Reqs, Decay]),
-    lists:foreach(fun(NofSchedulers) ->
-			  save_result_to_file(NofSchedulers,
-					       FdReps, FdReqs, 
-					       FdDecay, AnalysedTab)
-		  end, [N || N <- lists:seq(0, MaxNofSchedulers)]),
-    [Reps, Reqs, Decay].
-    
-save_result_to_file(NofSchedulers,
-		    FdReps, FdReqs, FdDecay, AnalysedTab) ->
-
-    [{NofSchedulers, NofRepsPerSec, NofReqs, MaxFinalResponseTime}] = 
-	ets:lookup(AnalysedTab, NofSchedulers),
-    
-    file:write(FdReps, io_lib:format("~p,~p~n", 
-				       [NofRepsPerSec, NofSchedulers])),
-    file:write(FdReqs,  io_lib:format("~p,~p~n", 
-					  [NofReqs, NofSchedulers])),
-    file:write(FdDecay, io_lib:format("~p,~p~n", [MaxFinalResponseTime,
-						  NofSchedulers])).
-
-
-help() ->
-    io:format("hdlt:start(Options). Where options:~n "
-	      " ~n~p~n~n hdlt:start([]). -> hdlt:start(~p)~n~n",
-	      [[{send_rate, "integer()", 
-		 "Number of outstanding requests that a client "
-		 "should have during the test to create a load situation."},
-		{clients, "[{path(), host()}]", "Paths to erlang and names of hosts to run clients on."},
-		{test_time, "{hours(), mins(), sec()}", 
-		 "How long the test should be run."},
-		{server, "{path(), host()}", "Path to erl and name of host to run the HTTP-server on."},
-		{port, "port()", "The port that the HTTP-server should use."},
-		{server_dir, "dir()", "The directory where the HTTP server "
-		 " stores its contents and configuration."},
-		{work_dir, "dir()", "Path on the computer, where the test "
-		 "is run, to a directory where the results can be saved."},
- 		{max_no_schedulers, "integer()", 
-		 "Max number of schedulers to run."},
-	       {socket_type, "Httpd configuration option socket_type"}],
-	       defaults()]).
-
-
-defaults() ->
-    [{send_rate,          ?DEFAULT_SENDRATE},
-     %% {clients,           []},
-     {test_time,          ?DEFAULT_TEST_TIME}, 
-     %% {server,            ?DEFAULT_SERVER},
-     {port,               ?DEFAULT_PORT},
-     {server_dir,         ?DEFAULT_SERVER_DIR},
-     {work_dir,           ?DEFAULT_WORK_DIR},
-     {max_nof_schedulers, ?DEFAULT_MAX_NOF_SCHEDULERS},
-     {socket_type,        ?DEFAULT_SOCKET_TYPE}].
-
-
-get_debugs(Config) ->
-    ?DEBUG("get debugs", []),
-    Debugs = proplists:get_value(debug, Config, ?DEFAULT_DEBUGS),
-    verify_debugs(Debugs),
-    Debugs.
-
-verify_debugs([]) ->
-    ok;
-verify_debugs([{Tag, Debug}|Debugs]) ->
-    verify_debug(Tag, Debug),
-    verify_debugs(Debugs).
-
-verify_debug(Tag, Debug) ->
-    case lists:member(Tag, [ctrl, proxy, slave, client]) of
-	true ->
-	    ok;
-	false ->
-	    exit({bad_debug_tag, Tag})
-    end,
-    case lists:member(Debug, [silence, info, log, debug]) of
-	true ->
-	    ok;
-	false ->
-	    exit({bad_debug_level, Debug})
-    end.
-
-get_send_rate(Config) ->
-    ?DEBUG("get send_rate", []),
-    case proplists:get_value(send_rate, Config, ?DEFAULT_SENDRATE) of
-	SendRate when is_integer(SendRate) andalso (SendRate > 0) ->
-	    SendRate;
-	BadSendRate ->
-	    exit({bad_sendrate, BadSendRate})
-    end.
-    
-
-get_clients(Config) ->
-    ?DEBUG("get clients", []),
-    case proplists:get_value(clients, Config, undefined) of
-	undefined ->
-	    missing_mandatory_config(clients);
-	Clients when is_list(Clients) andalso (length(Clients) > 0) ->
-	    case [#client{path = Path, host = Host} || 
-		     {Path, Host} <- Clients] of
-		Clients2 when (length(Clients2) > 0) ->
-		    Clients2;
-		_ ->
-		    exit({bad_clients, Clients})
-	    end;
-	
-	BadClients ->
-	    exit({bad_clients, BadClients})
-
-    end.
-    
-get_server(Config) ->	     
-    ?DEBUG("get server", []),
-    case proplists:get_value(server, Config) of
-	{Path, Host} when is_list(Path) andalso is_list(Host) ->
-	    #server{path = Path, host = Host};
-	undefined ->
-	    missing_mandatory_config(server)
-    end.
-
-get_server_dir(Config) ->
-    ?DEBUG("get server_dir", []),
-    get_dir(server_dir, Config, ?DEFAULT_SERVER_DIR).
-
-get_work_dir(Config) ->
-    ?DEBUG("get work_dir", []),
-    get_dir(work_dir, Config, ?DEFAULT_WORK_DIR).
-
-get_dir(Key, Config, Default) ->
-    Dir = proplists:get_value(Key, Config, Default),
-    ensure_absolute(Dir),
-    Dir.
-    
-ensure_absolute(Path) ->
-    case filename:pathtype(Path) of
-	absolute ->
-	    ok;
-	PathType ->
-	    exit({bad_pathtype, Path, PathType})
-    end.
-
-get_port(Config) ->
-    ?DEBUG("get port", []),
-    case proplists:get_value(port, Config, ?DEFAULT_PORT) of
-	Port when is_integer(Port) andalso (Port > 0) ->
-	    Port;
-	BadPort ->
-	    exit({bad_port, BadPort})
-    end.
-
-get_socket_type(Config) ->
-    ?DEBUG("get socket_type", []),
-    case proplists:get_value(socket_type, Config, ?DEFAULT_SOCKET_TYPE) of
-	SocketType when ((SocketType =:= ip_comm) orelse
-			 (SocketType =:= ssl) orelse
-			 (SocketType =:= essl) orelse
-			 (SocketType =:= ossl)) ->
-	    SocketType;
-	BadSocketType ->
-	    exit({bad_socket_type, BadSocketType})
-    end.
-
-get_test_time(Config) ->
-    ?DEBUG("get test_time", []),
-    case proplists:get_value(test_time, Config, ?DEFAULT_TEST_TIME) of
-	Seconds when is_integer(Seconds) andalso (Seconds > 0) -> 
-	    timer:seconds(Seconds);
-	BadTestTime ->
-	    exit({bad_test_time, BadTestTime})
-    end.
-
-get_max_nof_schedulers(Config) ->
-    ?DEBUG("get max_nof_schedulers", []),
-    case proplists:get_value(max_nof_schedulers, 
-			     Config, 
-			     ?DEFAULT_MAX_NOF_SCHEDULERS) of
-	MaxNofScheds when (is_integer(MaxNofScheds) andalso 
-			   (MaxNofScheds >= 0)) ->
-	    MaxNofScheds;
-	BadMaxNofScheds ->
-	    exit({bad_max_nof_schedulers, BadMaxNofScheds})
-    end.
-	    
-
-get_server_cert_file(Config) ->
-    ?DEBUG("get server cert file", []),
-    get_cert_file(server_cert_file, ?DEFAULT_SERVER_CERT, Config).
-
-get_client_cert_file(Config) ->
-    ?DEBUG("get client cert file", []),
-    get_cert_file(client_cert_file, ?DEFAULT_CLIENT_CERT, Config).
-
-get_cert_file(Tag, DefaultCertFileName, Config) -> 
-    LibDir  = code:lib_dir(inets),
-    HdltDir = filename:join(LibDir, "examples/httpd_load_test"),
-    DefaultCertFile = filename:join(HdltDir, DefaultCertFileName),
-    case proplists:get_value(Tag, Config, DefaultCertFile) of
-	F when is_list(F) ->
-	    case file:read_file_info(F) of
-		{ok, #file_info{type = regular}} ->
-		    F;
-		{ok, #file_info{type = Type}} ->
-		    exit({wrong_file_type, Tag, F, Type});
-		{error, Reason} ->
-		    exit({failed_readin_file_info, Tag, F, Reason})
-	    end;
-	BadFile ->
-	    exit({bad_cert_file, Tag, BadFile})
-    end.
-
-	    
-get_work_sim(Config) ->
-    ?DEBUG("get work_sim", []),
-    case proplists:get_value(work_simulator, Config, ?DEFAULT_WORK_SIM) of
-	WS when is_integer(WS) andalso (WS > 0) ->
-	    WS;
-	BadWS ->
-	    exit({bad_work_simulator, BadWS})
-    end.
-
-	    
-get_data_size(Config) ->
-    ?DEBUG("get data_size", []),
-    case proplists:get_value(data_size, Config, ?DEFAULT_DATA_SIZE) of
-	{From, To, Incr} = DS when (is_integer(From) andalso 
-				    is_integer(To)   andalso 
-				    is_integer(Incr) andalso 
-				    (To > From)      andalso 
-				    (From > 0)       andalso 
-				    (Incr > 0)) ->
-	    DS;
-	{From, To} when (is_integer(From) andalso 
-			 is_integer(To)   andalso 
-			 (To > From)      andalso 
-			 (From > 0)) ->
-	    {From, To, ?DEFAULT_DATA_SIZE_INCR};
-	BadDS ->
-	    exit({bad_data_size, BadDS})
-    end.
-
-	    
-url(#server{host = Host}, Port, SocketType, WorkSim) ->
-    Scheme = 
-	case SocketType of
-	    ip_comm ->
-		"http";
-	    _ -> %% SSL
-		"https"
-	end,
-    lists:flatten(
-      io_lib:format("~s://~s:~w/cgi-bin/hdlt_random_html:page?~w:", 
-		    [Scheme, Host, Port, WorkSim])).
-
-
-missing_mandatory_config(Missing) ->
-    exit({missing_mandatory_config, Missing}).
-
-
-ensure_remote_dir_exist(Sftp, Path0) ->
-    case filename:split(Path0) of
-	[Root, Dir | Rest] ->
-	    %% We never accept creating the root directory, 
-	    %% or the next level, so these *must* exist:
-	    Path = filename:join(Root, Dir),
-	    case ssh_sftp:read_file_info(Sftp, Path) of
-		{ok, #file_info{type = directory}} ->
-		    ensure_remote_dir_exist(Sftp, Path, Rest);
-		{ok, #file_info{type = Type}} ->
-		    ?INFO("Not a dir: ~p (~p)", [Path, Type]),
-		    exit({not_a_dir, Path, Type});
-		{error, Reason} ->
-		    ?INFO("Failed reading file info for ~p: ~p", 
-			  [Path, Reason]),
-		    exit({failed_reading_file_info, Path, Reason})
-	    end;
-	BadSplit ->
-	    ?INFO("Bad remote dir path: ~p -> ~p", [Path0, BadSplit]),
-	    exit({bad_dir, Path0})
-    end.
-
-ensure_remote_dir_exist(_Sftp, _Dir, []) ->
-    ok;
-ensure_remote_dir_exist(Sftp, Path, [Dir|Rest]) ->
-    NewPath = filename:join(Path, Dir),
-    case ssh_sftp:read_file_info(Sftp, NewPath) of
-	{ok, #file_info{type = directory}} ->
-	    ensure_remote_dir_exist(Sftp, NewPath, Rest);
-	{ok, #file_info{type = Type}} ->
-	    %% Exist, but is not a dir
-	    ?INFO("Not a dir: ~p (~p)", [NewPath, Type]),
-	    exit({not_a_dir, NewPath, Type});
-	{error, Reason} ->
-	    %% This *could* be because the dir does not exist,
-	    %% but it could also be some other error.
-	    %% As usual, the error reason of the sftp is
-	    %% a pease of crap, so we cannot use the 
-	    %% error reason. 
-	    %% The simplest way to test this is to simply
-	    %% try to create the directory, since we should
-	    %% ensure its existence anyway..
-	    case ssh_sftp:make_dir(Sftp, NewPath) of
-		ok ->
-		    ensure_remote_dir_exist(Sftp, NewPath, Rest);
-		_ ->
-		    ?INFO("Failed reading file info for ~p: ~p", 
-			  [Dir, Reason]),
-		    exit({failed_reading_file_info, NewPath, Reason})
-	    end
-    end.
-    
-maybe_create_remote_dir(Sftp, Dir) ->
-    case ssh_sftp:read_file_info(Sftp, Dir) of
-	{ok, #file_info{type = directory}} ->
-	    ok;
-	{ok, #file_info{type = Type}} ->
-	    %% Exist, but is not a dir
-	    ?INFO("Not a dir: ~p (~p)", [Dir, Type]),
-	    exit({not_a_dir, Dir, Type});
-	{error, Reason} ->
-	    %% Assume dir noes not exist...
-	    case ssh_sftp:make_dir(Sftp, Dir) of
-		ok ->
-		    ok;
-		_ ->
-		    ?INFO("Failed reading file info for ~p: ~p", 
-			  [Dir, Reason]),
-		    exit({failed_reading_file_info, Dir, Reason})
-	    end
-    end.
-    
-
-set_debug_level(Debugs) ->
-    Debug = proplists:get_value(ctrl, Debugs, silence), 
-    ?SET_LEVEL(Debug).
-
-
-%% Generates a list of numbers between A and B, such that 
-%% there is exact one number between A and B and then 
-%% randomizes that list.
-
-
-randomized_sizes(From, To, Incr) ->
-    L   = lists:seq(From, To, Incr),
-    Len = length(L),
-    randomized_sizes2(L, 0, Len-1).
-
-randomized_sizes2(L, N, Len) when N >= Len ->
-    L;
-randomized_sizes2(L, N, Len) ->
-    SplitWhere = rand:uniform(Len),
-    {A, B} = lists:split(SplitWhere, L),
-    randomized_sizes2(B ++ A, N+1, Len).
diff --git a/lib/inets/examples/httpd_load_test/hdlt_logger.erl b/lib/inets/examples/httpd_load_test/hdlt_logger.erl
deleted file mode 100644
index 8bbd53e0de..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_logger.erl
+++ /dev/null
@@ -1,141 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: This is a simple logger utility for the HDLT toolkit.
-%%          It assumesd that the debug level and the "name" of the 
-%%          logging entity has been put in process environment
-%%          (using the set_level and set_name functions respectively).
-%%----------------------------------------------------------------------
-
-%%
-
--module(hdlt_logger).
-
--export([
-	 start/0,
-	 set_level/1, get_level/0, set_name/1,
-	 info/2, log/2, debug/2
-	]).
-
--export([logger/1]).
-
--define(LOGGER,    ?MODULE).
--define(MSG,       hdlt_logger_msg).
--define(LEVEL,     hdlt_logger_level).
--define(NAME,      hdlt_logger_name).
--define(INFO_STR,  "INFO").
--define(LOG_STR,   "LOG ").
--define(DEBUG_STR, "DBG ").
-
-
-start() ->
-    Self = self(), 
-    proc_lib:start(?MODULE, logger, [Self]).
-
-set_name(Name) when is_list(Name) ->
-    put(?NAME, Name),
-    ok.
-
-get_level() ->
-    get(?LEVEL).
-
-set_level(Level) ->
-    case lists:member(Level, [silence, info, log, debug]) of
-	true ->
-	    put(?LEVEL, Level),
-	    ok;
-	false ->
-	    erlang:error({bad_debug_level, Level})
-    end.
-
-
-info(F, A) ->
-%%     io:format("info -> " ++ F ++ "~n", A),
-    do_log(info, get(?LEVEL), F, A).
-
-log(F, A) ->
-%%     io:format("log -> " ++ F ++ "~n", A),
-    do_log(log, get(?LEVEL), F, A).
-
-debug(F, A) ->
-%%     io:format("debug -> " ++ F ++ "~n", A),
-    do_log(debug, get(?LEVEL), F, A).
-
-
-logger(Parent) ->
-    global:register_name(?LOGGER, self()),
-    Ref = erlang:monitor(process, Parent),
-    proc_lib:init_ack(self()),
-    logger_loop(Ref).
-
-logger_loop(Ref) ->
-    receive
-	{?MSG, F, A} ->
-	    io:format(F, A),
-	    logger_loop(Ref);
-	{'DOWN', Ref, process, _Object, _Info} ->
-	    %% start the stop timer
-	    erlang:send_after(timer:seconds(5), self(), stop),
-	    logger_loop(undefined);
-	stop ->
-	    global:unregister_name(?LOGGER),
-	    ok
-    end.
-
-
-formated_timestamp() ->
-    {Date, Time}   = erlang:localtime(),
-    {YYYY,MM,DD}   = Date,
-    {Hour,Min,Sec} = Time,
-    FormatDate =
-        io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w",
-                      [YYYY,MM,DD,Hour,Min,Sec]),
-    lists:flatten(FormatDate).
-
-do_log(_, silence, _, _) ->
-    ok;
-do_log(info, info, F, A) ->
-    do_log(?INFO_STR, F, A);
-do_log(info, log, F, A) ->
-    do_log(?INFO_STR, F, A);
-do_log(log, log, F, A) ->
-    do_log(?LOG_STR, F, A);
-do_log(info, debug, F, A) ->
-    do_log(?INFO_STR, F, A);
-do_log(log, debug, F, A) ->
-    do_log(?LOG_STR, F, A);
-do_log(debug, debug, F, A) ->
-    do_log(?DEBUG_STR, F, A);
-do_log(_, _, _F, _A) ->
-    ok.
-
-do_log(SEV, F, A) ->
-    Name = 
-	case get(?NAME) of
-	    L when is_list(L) ->
-		L;
-	    _ ->
-		"UNDEFINED"
-	end,
-    Msg = {?MSG, "~s ~s [~s] " ++ F ++ "~n", 
-	   [SEV, Name, formated_timestamp() | A]}, 
-    (catch global:send(?LOGGER, Msg)).
diff --git a/lib/inets/examples/httpd_load_test/hdlt_logger.hrl b/lib/inets/examples/httpd_load_test/hdlt_logger.hrl
deleted file mode 100644
index 6fbe9bd393..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_logger.hrl
+++ /dev/null
@@ -1,36 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%
-
--ifndef(hdlt_logger_hrl).
--define(hdlt_logger_hrl, true).
-
-%% Various log macros
--define(SET_LEVEL(N), hdlt_logger:set_level(N)).
--define(GET_LEVEL(),  hdlt_logger:get_level()).
--define(SET_NAME(N),  hdlt_logger:set_name(N)).
-
--define(INFO(F, A),   hdlt_logger:info(F, A)).
--define(LOG(F, A),    hdlt_logger:log(F, A)).
--define(DEBUG(F, A),  hdlt_logger:debug(F, A)).
-
--endif. % -ifdef(hdlt_logger_hrl).
diff --git a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl b/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
deleted file mode 100644
index 2f2a23f82d..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_random_html.erl
+++ /dev/null
@@ -1,51 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%
-
--module(hdlt_random_html). 
--export([page/3]). 
-
-page(SessionID, _Env, Input) -> 
-    [WorkSimStr, SzSimStr] = string:tokens(Input, [$:]),
-    WorkSim = list_to_integer(WorkSimStr),
-    SzSim   = list_to_integer(SzSimStr),
-    mod_esi:deliver(SessionID,  "Content-Type:text/html\r\n\r\n"),  
-    mod_esi:deliver(SessionID, start("Random test page")),  
-    mod_esi:deliver(SessionID, content(WorkSim, SzSim)),  
-    mod_esi:deliver(SessionID, stop()),
-    ok.
-
-start(Title) ->  
-    "<HTML>  
-<HEAD>  
-<TITLE>" ++ Title ++ "</TITLE> 
- </HEAD>  
-<BODY>\n".  
-
-stop() ->  
-    "</BODY>  
-</HTML>
-". 
- 
-content(WorkSim, SzSim) ->  
-    lists:sort([rand:uniform(X) || X <- lists:seq(1, WorkSim)]),  
-    lists:flatten(lists:duplicate(SzSim, "Dummy data ")). 
diff --git a/lib/inets/examples/httpd_load_test/hdlt_server.erl b/lib/inets/examples/httpd_load_test/hdlt_server.erl
deleted file mode 100644
index a46c0b01b0..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_server.erl
+++ /dev/null
@@ -1,166 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-%%
-%%----------------------------------------------------------------------
-%% Purpose: The HDLT server module.
-%%          This is just a stub, making future expansion easy.
-%%          All code in this module is executed in the local node!
-%%----------------------------------------------------------------------
-
--module(hdlt_server).
-
--export([start/1, stop/0, start_inets/0, start_service/1]).
-
--export([proxy/1]).
-
--include_lib("kernel/include/file.hrl").
--include("hdlt_logger.hrl").
-
-
--define(PROXY, hdlt_proxy).
-
-
-%% This function is used to start the proxy process
-%% This function is called *after* the nodes has been 
-%% "connected" with the controller/collector node.
-
-start(Debug) ->
-    proc_lib:start(?MODULE, proxy, [Debug]).
-
-stop() ->
-    ?PROXY ! stop.
-
-start_inets() ->
-    ?PROXY ! start_inets.
-
-start_service(Config) ->
-    ?PROXY ! {server_start, Config, self()},
-    receive
-	{server_start_result, Result} ->
-	    Result
-    after 15000 ->
-	    {error, timeout}
-    end.
-
-
-proxy(Debug) ->
-    process_flag(trap_exit, true),
-    erlang:register(?PROXY, self()),
-    ?SET_NAME("HDLT PROXY"),
-    ?SET_LEVEL(Debug), 
-    ?LOG("starting", []),
-    Ref = await_for_controller(10), 
-    CtrlNode = node(Ref), 
-    erlang:monitor_node(CtrlNode, true),
-    proc_lib:init_ack({ok, self()}),
-    ?DEBUG("started", []),
-    proxy_loop(Ref, CtrlNode).
-
-await_for_controller(N) when N > 0 ->
-    case global:whereis_name(hdlt_ctrl) of
-	Pid when is_pid(Pid) ->
-	    erlang:monitor(process, Pid);
-	_ ->
-	    timer:sleep(1000),
-	    await_for_controller(N-1)
-    end;
-await_for_controller(_) ->
-    proc_lib:init_ack({error, controller_not_found, nodes()}),
-    timer:sleep(500),
-    halt().
-
-    
-proxy_loop(Ref, CtrlNode) ->
-    ?DEBUG("await command", []),
-    receive
-	stop ->
-	    ?LOG("received stop", []),
-	    halt();
-
-	start_inets ->
-	    ?LOG("start the inets service framework", []),
-	    case (catch inets:start()) of
-		ok ->
-		    ?LOG("framework started", []),
-		    proxy_loop(Ref, CtrlNode);
-		Error ->
-		    ?LOG("failed starting inets service framework: "
-			 "~n   Error: ~p", [Error]),
-		    halt()
-	    end;
-
-	{server_start, Config, From} ->
-	    ?LOG("start-server", []),
-	    maybe_start_crypto_and_ssl(Config),
-	    %% inets:enable_trace(max, "/tmp/inets-httpd-trace.log", httpd),
-	    %% inets:enable_trace(max, "/tmp/inets-httpd-trace.log", all),
-	    case (catch inets:start(httpd, Config)) of
-		{ok, _} ->
-		    ?LOG("server started when"
-			 "~n   which(inets): ~p"
-			 "~n   RootDir:      ~p"
-			 "~n   System info:  ~p", [code:which(inets), 
-						   code:root_dir(), 
-						   get_node_info()]),
-		    From ! {server_start_result, ok},
-		    proxy_loop(Ref, CtrlNode);
-		Error ->
-		    ?INFO("server start failed"
-			  "~n   Error: ~p", [Error]),
-		    From ! {server_start_result, Error},
-		    halt()
-	    end;
-
-	{nodedown, CtrlNode} ->
-	    ?LOG("received nodedown for controller node - terminate", []), 
-	    halt();
-
-	{'DOWN', Ref, process, _, _} ->
-	    ?LOG("received DOWN message for controller - terminate", []),
-	    %% The controller has terminated, time to die
-	    halt()
-
-    end.
-
-
-maybe_start_crypto_and_ssl(Config) ->
-    case lists:keysearch(socket_type, 1, Config) of
-	{value, {socket_type, SocketType}} when ((SocketType =:= ssl) orelse
-						 (SocketType =:= ossl) orelse
-						 (SocketType =:= essl)) ->
-	    ?LOG("maybe start crypto and ssl", []),
-	    (catch application:start(crypto)),
-	    ssl:start();
-	_ ->
-	    ok
-    end.
-
-
-get_node_info() ->
-    [{cpu_topology,        erlang:system_info(cpu_topology)},
-     {heap_type,           erlang:system_info(heap_type)},
-     {nof_schedulers,      erlang:system_info(schedulers)},
-     {otp_release,         erlang:system_info(otp_release)}, 
-     {version,             erlang:system_info(version)}, 
-     {system_version,      erlang:system_info(system_version)},
-     {system_architecture, erlang:system_info(system_architecture)}].
-
diff --git a/lib/inets/examples/httpd_load_test/hdlt_slave.erl b/lib/inets/examples/httpd_load_test/hdlt_slave.erl
deleted file mode 100644
index 4daccef5da..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_slave.erl
+++ /dev/null
@@ -1,293 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2010-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
--module(hdlt_slave).
-
-
--export([start_link/4, start_link/5, start_link/6, stop/1]).
-
-%% Internal exports 
--export([wait_for_slave/9, slave_start/1, wait_for_master_to_die/3]).
-
--include("hdlt_logger.hrl").
-
--define(SSH_PORT, 22).
--define(TIMEOUT,  60000).
--define(LOGGER,   hdlt_logger).
-
-
-%% ***********************************************************************
-%% start_link/4,5 --
-%%
-%% The start/4,5 functions are used to start a slave Erlang node.
-%% The node on which the start/N functions are used is called the
-%% master in the description below.
-%%
-%% If hostname is the same for the master and the slave,
-%% the Erlang node will simply be spawned.  The only requirement for
-%% this to work is that the 'erl' program can be found in PATH.
-%%
-%% If the master and slave are on different hosts, start/N uses
-%% the 'ssh' program to spawn an Erlang node on the other host.
-%% Alternative, if the master was started as
-%% 'erl -sname xxx -rsh my_rsh...', then 'my_rsh' will be used instead
-%% of 'ssh' (this is useful for systems still using rsh or remsh).
-%%
-%% For this to work, the following conditions must be fulfilled:
-%%
-%% 1. There must be an ssh program on computer; if not an error
-%%    is returned.
-%%
-%% 2. The hosts must be configured to allow 'ssh' access without
-%%    prompts for password.
-%%
-%% The slave node will have its filer and user server redirected
-%% to the master.  When the master node dies, the slave node will
-%% terminate.  For the start_link functions, the slave node will
-%% terminate also if the process which called start_link terminates.
-%%
-%% Returns: {ok, Name@Host} |
-%%	    {error, timeout} |
-%%          {error, no_rsh} |
-%%	    {error, {already_running, Name@Host}}
-
-start_link(Host, Name, ErlPath, Paths) ->
-    start_link(Host, Name, ErlPath, Paths, [], silence).
-
-start_link(Host, Name, ErlPath, Paths, DebugLevel) when is_atom(DebugLevel) ->
-    start_link(Host, Name, ErlPath, Paths, [], DebugLevel);
-start_link(Host, Name, ErlPath, Paths, Args) when is_list(Args) ->
-    start_link(Host, Name, ErlPath, Paths, Args, silence).
-
-start_link(Host, Name, ErlPath, Paths, Args, DebugLevel) ->
-    Node = list_to_atom(lists:concat([Name, "@", Host])),
-    case net_adm:ping(Node) of
-	pang ->
-	    start_it(Host, Name, Node, ErlPath, Paths, Args, DebugLevel);
-	pong -> 
-	    {error, {already_running, Node}}
-    end.
-
-%% Stops a running node.
-
-stop(Node) ->
-    rpc:call(Node, erlang, halt, []),
-    ok.
-
-
-%% Starts a new slave node.
-
-start_it(Host, Name, Node, ErlPath, Paths, Args, DebugLevel) ->
-    Prog = filename:join([ErlPath, "erl"]), 
-    spawn(?MODULE, wait_for_slave, [self(), Host, Name, Node, Paths, Args, self(), Prog, DebugLevel]),
-    receive
-	{result, Result} -> Result
-    end.
-
-%% Waits for the slave to start.
-
-wait_for_slave(Parent, Host, Name, Node, Paths, Args, 
-	       LinkTo, Prog, DebugLevel) ->
-    ?SET_NAME("HDLT SLAVE STARTER"), 
-    ?SET_LEVEL(DebugLevel),
-    ?DEBUG("begin", []),
-    Waiter = register_unique_name(0),
-    case (catch mk_cmd(Host, Name, Paths, Args, Waiter, Prog)) of
-	{ok, Cmd} ->
-  	    ?DEBUG("command generated: ~n~s", [Cmd]),
-	    case (catch ssh_slave_start(Host, Cmd)) of
-		{ok, Conn, _Chan} ->
- 		    ?DEBUG("ssh channel created", []),
-		    receive
-			{SlavePid, slave_started} ->
- 			    ?DEBUG("slave started: ~p", [SlavePid]),
-			    unregister(Waiter),
-			    slave_started(Parent, LinkTo, SlavePid, Conn, 
-					  DebugLevel)
-		    after 32000 ->
-			    ?INFO("slave node failed to report in on time", 
-				  []),
-			    %% If it seems that the node was partially started,
-			    %% try to kill it.
-			    case net_adm:ping(Node) of
-				pong ->
-				    spawn(Node, erlang, halt, []),
-				    ok;
-				_ ->
-				    ok
-			    end,
-			    Parent ! {result, {error, timeout}}
-		    end;
-		{error, Reason} = Error ->
-		    ?INFO("FAILED starting node: "
-			  "~n   ~p"
-			  "~n   ~p", [Reason, Cmd]),
-		    Parent ! {result, Error}
-	    end;
-	Other ->
-	    ?INFO("FAILED creating node command string: "
-		  "~n   ~p", [Other]),
-	    Parent ! {result, Other}
-    end.
-
-
-ssh_slave_start(Host, ErlCmd) ->
-    ?DEBUG("ssh_slave_start -> try connect to ~p", [Host]),
-    Connection = 
-	case (catch ssh:connect(Host, ?SSH_PORT, 
-				[{silently_accept_hosts, true}])) of
-	    {ok, Conn} ->
- 		?DEBUG("ssh_exec_erl -> connected: ~p", [Conn]),
-		Conn;
-	    Error1 ->
- 		?LOG("failed connecting to ~p: ~p", [Host, Error1]),
-		throw({error, {ssh_connect_failed, Error1}})
-	end,
-
-    ?DEBUG("ssh_exec_erl -> connected - now create channel", []), 
-    Channel = 
-	case (catch ssh_connection:session_channel(Connection, ?TIMEOUT)) of
-	    {ok, Chan} ->
- 		?DEBUG("ssh_exec_erl -> channel ~p created", [Chan]),
-		Chan;
-	    Error2 ->
- 		?LOG("failed creating channel: ~p", [Error2]),
-		throw({error, {ssh_channel_create_failed, Error2}})
-	end,
-
-    ?DEBUG("ssh_exec_erl -> channel created - now exec command: "
- 	"~n   ~p", [ErlCmd]), 
-    case (catch ssh_connection:exec(Connection, Channel, ErlCmd, infinity)) of
-	success ->
-	    ?DEBUG("ssh_exec_erl -> command exec'ed - clean ssh msg", []), 
-	    clean_ssh_msg(),
- 	    ?DEBUG("ssh_exec_erl -> done", []), 
-	    {ok, Connection, Channel};
-	Error3 ->
-	    ?LOG("failed exec command: ~p", [Error3]),
-	    throw({error, {ssh_exec_failed, Error3}})
-    end.
-
-clean_ssh_msg() ->
-    receive
-	{ssh_cm, _X, _Y} ->
-	    clean_ssh_msg()
-    after 1000 ->
-	    ok
-    end.
-    
-
-slave_started(ReplyTo, Master, Slave, Conn, Level) 
-  when is_pid(Master) andalso is_pid(Slave) ->
-    process_flag(trap_exit, true),
-    SName = lists:flatten(
-	      io_lib:format("HDLT SLAVE CTRL[~p,~p]", 
-			    [self(), node(Slave)])), 
-    ?SET_NAME(SName),
-    ?SET_LEVEL(Level), 
-    ?LOG("initiating", []),
-    MasterRef = erlang:monitor(process, Master),
-    SlaveRef  = erlang:monitor(process, Slave),
-    ReplyTo ! {result, {ok, node(Slave)}},
-    slave_running(Master, MasterRef, Slave, SlaveRef, Conn).
-
-
-%% The slave node will be killed if the master process terminates, 
-%% The master process will not be killed if the slave node terminates.
-
-slave_running(Master, MasterRef, Slave, SlaveRef, Conn) ->
-    ?DEBUG("await message", []),
-    receive
-	{'DOWN', MasterRef, process, _Object, _Info} ->
-	    ?LOG("received DOWN from master", []),
-	    erlang:demonitor(SlaveRef, [flush]),
-	    Slave ! {nodedown, node()},
-	    ssh:close(Conn);
-
-	{'DOWN', SlaveRef, process, Object, _Info} ->
-	    ?LOG("received DOWN from slave (~p)", [Object]),
-	    erlang:demonitor(MasterRef, [flush]),
-	    ssh:close(Conn);
-
-	Other ->
-	    ?DEBUG("received unknown: ~n~p", [Other]),
-	    slave_running(Master, MasterRef, Slave, SlaveRef, Conn)
-
-    end.
-
-register_unique_name(Number) ->
-    Name = list_to_atom(lists:concat([?MODULE, "_waiter_", Number])),
-    case catch register(Name, self()) of
-	true ->
-	    Name;
-	{'EXIT', {badarg, _}} ->
-	    register_unique_name(Number+1)
-    end.
-
-
-%% Makes up the command to start the nodes.
-%% If the node should run on the local host, there is
-%% no need to use ssh.
-
-mk_cmd(Host, Name, Paths, Args, Waiter, Prog) ->
-    PaPaths = [[" -pa ", Path] || Path <- Paths], 
-    {ok, lists:flatten(
-	   lists:concat([Prog,
-			 " -detached -nopinput ", 
-			 Args, " ", 
-			 " -sname ", Name, "@", Host,
-			 " -s ", ?MODULE, " slave_start ", node(),
-			 " ", Waiter,
-			 " ", PaPaths]))}.
-
-
-%% This function will be invoked on the slave, using the -s option of erl.
-%% It will wait for the master node to terminate.
-
-slave_start([Master, Waiter]) ->
-    spawn(?MODULE, wait_for_master_to_die, [Master, Waiter, silence]);
-slave_start([Master, Waiter, Level]) ->
-    spawn(?MODULE, wait_for_master_to_die, [Master, Waiter, Level]).
-	
-
-wait_for_master_to_die(Master, Waiter, Level) ->
-    process_flag(trap_exit, true),
-    SName = lists:flatten(
-	      io_lib:format("HDLT-SLAVE MASTER MONITOR[~p,~p,~p]", 
-			    [self(), node(), Master])), 
-    ?SET_NAME(SName),
-    ?SET_LEVEL(Level), 
-    erlang:monitor_node(Master, true),
-    {Waiter, Master} ! {self(), slave_started},
-    wloop(Master).
-
-wloop(Master) ->
-    ?DEBUG("await message", []),
-    receive
-	{nodedown, Master} ->
-	    ?INFO("received master nodedown", []),
-	    halt();
-	_Other ->
-	    wloop(Master)
-    end.
-
-
-
diff --git a/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem b/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem
deleted file mode 120000
index 41644a1098..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_ssl_client_cert.pem
+++ /dev/null
@@ -1 +0,0 @@
-../../test/httpc_SUITE_data/ssl_client_cert.pem
\ No newline at end of file
diff --git a/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem b/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem
deleted file mode 120000
index 41644a1098..0000000000
--- a/lib/inets/examples/httpd_load_test/hdlt_ssl_server_cert.pem
+++ /dev/null
@@ -1 +0,0 @@
-../../test/httpc_SUITE_data/ssl_client_cert.pem
\ No newline at end of file
diff --git a/lib/inets/examples/httpd_load_test/modules.mk b/lib/inets/examples/httpd_load_test/modules.mk
deleted file mode 100644
index 3613467751..0000000000
--- a/lib/inets/examples/httpd_load_test/modules.mk
+++ /dev/null
@@ -1,47 +0,0 @@
-#-*-makefile-*-   ; force emacs to enter makefile-mode
-
-# %CopyrightBegin%
-#
-# SPDX-License-Identifier: Apache-2.0
-#
-# Copyright Ericsson AB 2010-2025. 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.
-# 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.
-#
-# %CopyrightEnd%
-
-SCRIPT_SKELETONS = \
-	hdlt.sh.skel
-
-CONF_SKELETONS = \
-	hdlt.config.skel
-
-CERT_FILES = \
-	hdlt_ssl_client_cert.pem \
-	hdlt_ssl_server_cert.pem
-
-README = HDLT_README
-
-MODULES = \
-        hdlt \
-        hdlt_ctrl \
-        hdlt_client \
-	hdlt_logger \
-	hdlt_random_html \
-	hdlt_server \
-	hdlt_slave
-
-INTERNAL_HRL_FILES = \
-        hdlt_logger.hrl
-
-
diff --git a/lib/inets/examples/subdirs.mk b/lib/inets/examples/subdirs.mk
index 10a331fc26..28f388e354 100644
--- a/lib/inets/examples/subdirs.mk
+++ b/lib/inets/examples/subdirs.mk
@@ -1,3 +1,22 @@
 #-*-makefile-*-   ; force emacs to enter makefile-mode
-
-SUB_DIRECTORIES = server_root httpd_load_test
\ No newline at end of file
+# %CopyrightBegin%
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+# Copyright Ericsson AB 2009-2025. 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.
+# 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.
+#
+# %CopyrightEnd%
+#
+SUB_DIRECTORIES = server_root
diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile
index 256408282d..3050c006b0 100644
--- a/lib/inets/test/Makefile
+++ b/lib/inets/test/Makefile
@@ -66,9 +66,9 @@ INETS_FLAGS = -Dinets_data_dir='"$(INETS_DATA_DIR)"'       \
               -Dinets_priv_dir='"$(INETS_PRIV_DIR)"'
 
 
-### 
+###
 ### test suite debug flags
-### 
+###
 ifeq ($(INETS_DEBUG),)
   INETS_DEBUG = d
 endif
@@ -82,9 +82,9 @@ ifeq ($(INETS_DEBUG),d)
 endif
 
 
-### 
+###
 ### HTTPD verbosity flags
-### 
+###
 
 ifneq ($(MANV),)
   INETS_FLAGS += -Dhttpd_manager_verbosity=$(MANV)
@@ -122,13 +122,13 @@ INETS_ROOT = ../../inets
 
 MODULES =                 		\
 	inets_test_lib    		\
-	make_certs                      \
+	httpd_bench_certs		\
 	http_format_SUITE 		\
 	httpc_SUITE	  		\
 	httpc_cookie_SUITE		\
 	httpc_proxy_SUITE		\
 	httpd_SUITE       		\
-	httpd_bench_SUITE               \
+	httpd_bench_SUITE		\
 	http_test_lib    		\
 	httpd_basic_SUITE		\
 	httpd_serve_SUITE       	\
@@ -152,7 +152,7 @@ HRL_FILES = inets_test_lib.hrl \
 
 ERL_FILES = $(MODULES:%=%.erl)
 
-SOURCE = $(ERL_FILES) $(HRL_FILES) 
+SOURCE = $(ERL_FILES) $(HRL_FILES)
 
 TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
 
@@ -196,7 +196,7 @@ RELTESTSYSBINDIR     = $(RELTESTSYSALLDATADIR)/bin
 
 # ----------------------------------------------------
 # FLAGS
-# The path to the test_server ebin dir is needed when 
+# The path to the test_server ebin dir is needed when
 # running the target "targets".
 # ----------------------------------------------------
 ERL_COMPILE_FLAGS += \
@@ -213,7 +213,7 @@ ERL_COMPILE_FLAGS := $(filter-out +deterministic,$(ERL_COMPILE_FLAGS))
 # 1) INETS_PRIV_DIR must be created
 # ----------------------------------------------------
 
-tests $(TYPES): $(BUILDTARGET) 
+tests $(TYPES): $(BUILDTARGET)
 
 targets: $(TARGET_FILES)
 
@@ -221,7 +221,7 @@ targets: $(TARGET_FILES)
 
 emakebuild: $(EMAKEFILE)
 
-$(EMAKEFILE): 
+$(EMAKEFILE):
 	$(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) '*_SUITE_make' | grep -v Warning > $(EMAKEFILE)
 	$(MAKE_EMAKE) $(ERL_COMPILE_FLAGS) -o$(EBIN) $(MODULES) | grep -v Warning >> $(EMAKEFILE)
 
@@ -235,7 +235,7 @@ docs:
 
 # ----------------------------------------------------
 # Release Target
-# ---------------------------------------------------- 
+# ----------------------------------------------------
 include $(ERL_TOP)/make/otp_release_targets.mk
 
 release_spec: opt
@@ -268,7 +268,7 @@ release_tests_spec: opt
 	$(INSTALL_DIR) $(RELTESTSYSALLDATADIR)
 	$(INSTALL_DIR) $(RELTESTSYSBINDIR)
 	chmod -R +x $(RELTESTSYSBINDIR)
-	$(INSTALL_DIR) $(RELTESTSYSALLDATADIR)/win32/lib	
+	$(INSTALL_DIR) $(RELTESTSYSALLDATADIR)/win32/lib
 
 release_docs_spec:
 
diff --git a/lib/inets/test/httpd_bench_SUITE.erl b/lib/inets/test/httpd_bench_SUITE.erl
index 6fba8b919a..d1019da363 100644
--- a/lib/inets/test/httpd_bench_SUITE.erl
+++ b/lib/inets/test/httpd_bench_SUITE.erl
@@ -23,13 +23,18 @@
 
 %%
 -module(httpd_bench_SUITE).
--compile(export_all).
 
 -include_lib("common_test/include/ct.hrl").
 -include_lib("common_test/include/ct_event.hrl").
--include_lib("public_key/include/public_key.hrl").
 -include_lib("kernel/include/file.hrl").
 
+-export([suite/0, all/0, groups/0, init_per_suite/1, end_per_suite/1, init_per_group/2, end_per_group/2,
+    init_per_testcase/2, end_per_testcase/2, wget_small/1, erl_dummy_small/1, httpc_small/1, wget_big/1,
+    erl_dummy_big/1, httpc_big/1]).
+-export([httpc_client/1, httpc_client/2, httpd_lib_client/1, httpd_lib_client/2,
+    wget_client/1, wget_client/2, wget/4]).
+-export([handle_http_msg/3]).
+
 -define(remote_host, "NETMARKS_REMOTE_HOST").
 -define(LF, [10]).
 -define(CR, [13]).
@@ -38,11 +43,10 @@
 %%--------------------------------------------------------------------
 %% Common Test interface functions -----------------------------------
 %%--------------------------------------------------------------------
-suite() -> 
-    [{timetrap, {minutes, 1}},
-     {ct_hooks,[{ts_install_cth,[{nodenames,2}]}]}].
+suite() ->
+    [{timetrap, {minutes, 1}}].
 
-all() -> 
+all() ->
     [
      {group, http_dummy},
      {group, http_inets},
@@ -58,12 +62,12 @@ all() ->
      {group, https_nginx_keep_alive}
     ].
 
-groups() -> 
+groups() ->
     [
      {http_dummy, [],  client_tests()},
      {http_inets, [],   client_tests()},
      {http_nginx, [],   client_tests()},
-     {https_dummy, [],  client_tests()}, 
+     {https_dummy, [],  client_tests()},
      {https_inets, [],  client_tests()},
      {https_nginx, [],  client_tests()},
      {http_dummy_keep_alive, [],  client_tests()},
@@ -74,54 +78,58 @@ groups() ->
      {https_nginx_keep_alive, [], client_tests()}
     ].
 
-    
+
 client_tests() ->
     [wget_small,
      erl_dummy_small,
      httpc_small,
      wget_big,
-     erl_dummy_big, 
+     erl_dummy_big,
      httpc_big
     ].
 
-init_per_suite(Config) -> 
-    try	
-	{Node, Host} = setup(Config, node()),
-	init_ssl(Config),
-	[{iter, 10}, {server_node, Node}, {server_host, Host} | Config]
+init_per_suite(Config) ->
+    try
+        Setup = setup(Config, node()),
+        init_ssl(Config),
+        Setup ++ [{iter, 10} | Config]
     catch E:R:ST ->
-            ct:log("~p:~p:~p",[E,R,ST]),
-	    {skipped, "Benchmark machines only"}
+        ct:log("~p:~p:~p",[E,R,ST]),
+        {skipped, "Benchmark machines only"}
     end.
 
-end_per_suite(_Config) -> 
-    [application:stop(App) || App <- [asn1, crypto, public_key, ssl, inets]].
+end_per_suite(Config) ->
+    [application:stop(App) || App <- [asn1, crypto, public_key, ssl, inets]],
+    PeerPid = proplists:get_value(server_pid, Config),
+    peer:stop(PeerPid).
 
-init_per_group(Group, Config) when Group == http_dummy_keep_alive; 
+%% Init keepalive servers group
+init_per_group(Group, Config) when Group == http_dummy_keep_alive;
 				   Group == https_dummy_keep_alive;
-				   Group == http_inets_keep_alive; 
+				   Group == http_inets_keep_alive;
 				   Group == https_inets_keep_alive;
 				   Group == http_nginx_keep_alive;
 				   Group == https_nginx_keep_alive ->
     Version = http_version(Group),
     start_web_server(Group,
-		     [{keep_alive, true}, 
+		     [{keep_alive, true},
 		      {reuse_sessions, false},
 		      {http_version, Version},
 		      {http_opts,[{version, Version}]},
 		      {http_headers, [{"connection", "keep-alive"}]},
-		      {httpc_opts, [{keep_alive_timeout, 1500}, 
+		      {httpc_opts, [{keep_alive_timeout, 1500},
 				    {max_keep_alive_length, ?config(iter, Config)}]}
 		      | Config]);
-init_per_group(Group, Config)  when Group == http_dummy; 
+%% Init non-keepalive servers group
+init_per_group(Group, Config)  when Group == http_dummy;
 				    Group == https_dummy;
-				    Group == http_inets; 
+				    Group == http_inets;
 				    Group == https_inets;
 				    Group == http_nginx;
 				    Group == https_nginx ->
     Version = http_version(Group),
-    start_web_server(Group, 
-		     [{keep_alive, false}, 
+    start_web_server(Group,
+		     [{keep_alive, false},
 		      {reuse_sessions, false},
 		      {http_version, Version},
 		      {http_headers, [{"connection", "close"}]},
@@ -138,60 +146,61 @@ end_per_group(Group, Config) ->
 
 init_per_testcase(TestCase, Config) when TestCase == httpc_small;
 					 TestCase == httpc_big
-					 -> 
+					 ->
     Opts = ?config(httpc_opts, Config),
     inets:start(httpc, [{profile, TestCase}, {socket_opts, [{nodelay, true}]}]),
     httpc:set_options(Opts, TestCase),
     [{profile, TestCase} | proplists:delete(profile, Config)];
 
-init_per_testcase(_, Config) -> 
+init_per_testcase(_, Config) ->
     Config.
 end_per_testcase(TestCase, _Config) when TestCase == httpc_small;
-					 TestCase == httpc_big ->	
+					 TestCase == httpc_big ->
     ok = inets:stop(httpc, TestCase);
-end_per_testcase(_TestCase, Config) ->	
+end_per_testcase(_TestCase, Config) ->
     Config.
 %%--------------------------------------------------------------------
 %% Test Cases --------------------------------------------------------
 %%--------------------------------------------------------------------
 
-erl_dummy_small(Config) when is_list(Config) -> 
+erl_dummy_small(Config) when is_list(Config) ->
     {ok, Result} = run_test(httpd_lib_client, "1k_file", Config),
-    notify(Result, Config, "erl_1k_file"). 
+    notify(Result, Config, "erl_1k_file").
 
-erl_dummy_big(Config)  when is_list(Config) -> 
+erl_dummy_big(Config)  when is_list(Config) ->
     {ok, Result} = run_test(httpd_lib_client, "1M_file", Config),
-    notify(Result, Config, "erl_1M_file"). 
+    notify(Result, Config, "erl_1M_file").
 
-wget_small(Config) when is_list(Config) -> 
+wget_small(Config) when is_list(Config) ->
     {ok, Result} = run_test(wget_client, "1k_file", Config),
-    notify(Result, Config, "wget_1k_file"). 
+    notify(Result, Config, "wget_1k_file").
 
-wget_big(Config)  when is_list(Config) -> 
+wget_big(Config)  when is_list(Config) ->
     {ok, Result} = run_test(wget_client, "1M_file", Config),
-    notify(Result, Config, "wget_1M_file"). 
+    notify(Result, Config, "wget_1M_file").
 
-httpc_small(Config) when is_list(Config) -> 
+httpc_small(Config) when is_list(Config) ->
     {ok, Result} = run_test(httpc_client, "1k_file", Config),
-    notify(Result, Config, "httpc_1k_file"). 
+    notify(Result, Config, "httpc_1k_file").
 
-httpc_big(Config)  when is_list(Config) -> 
+httpc_big(Config)  when is_list(Config) ->
     {ok, Result} = run_test(httpc_client, "1M_file", Config),
-    notify(Result, Config, "httpc_1M_file"). 
+    notify(Result, Config, "httpc_1M_file").
 
 %%--------------------------------------------------------------------
 %% Internal functions ------------------------------------------------
 %%--------------------------------------------------------------------
+%%
 
 %%--------------------------------------------------------------------
 %% Report benchmark results  ------------------------------------------------
 %%--------------------------------------------------------------------
 
 notify({TestPerSec, _MBps}, Config, Suffix) ->
-    Name = lists:concat([?config(protocol,Config), " ", 
-			 server_name(Config, [dummy_pid, httpd_pid, nginx_port]), 
+    Name = lists:concat([?config(protocol,Config), " ",
+			 server_name(Config, [dummy_pid, httpd_pid, nginx_port]),
 			 "", Suffix]),
-    ct:comment("~p tps", [TestPerSec]),
+    ct:comment("~p tests/s", [TestPerSec]),
     ct_event:notify(#event{name = benchmark_data,
 			   data=[{value, TestPerSec},
 				 {suite, ?MODULE},
@@ -209,9 +218,9 @@ server_name(Config, [Server | Rest]) ->
 	    server_name(Server)
     end.
 
-server_name(httpd_pid) ->   
-   "inets";
-server_name(nginx_port) -> 
+server_name(httpd_pid) ->
+    "inets";
+server_name(nginx_port) ->
     "nginx";
 server_name(dummy_pid) ->
     "erlang".
@@ -220,34 +229,33 @@ setup(_Config, nonode@nohost) ->
     exit(dist_not_enabled);
 setup(_Config, _LocalNode) ->
     Host = case os:getenv(?remote_host) of
-	       false ->
-		   {ok, This} = inet:gethostname(),
-		   This;
-	       RemHost ->
-		   RemHost
-	   end,
-    Node = list_to_atom("inets_perf_server@" ++ Host),
-    SlaveArgs = case init:get_argument(pa) of
-	       {ok, PaPaths} ->
-		   lists:append([" -pa " ++ P || [P] <- PaPaths]);
-	       _ -> []
-	   end,
-    Prog =
-	case os:find_executable("erl") of
-	    false -> "erl";
-	    P -> P
-	end,
-    case net_adm:ping(Node) of
-	pong -> ok;
-	pang ->
-	    {ok, Node} = slave:start(Host, inets_perf_server, SlaveArgs, no_link, Prog)
-    end,
+               false -> net_adm:localhost();
+               RemHost -> RemHost
+           end,
+    PeerArgs = case init:get_argument(pa) of
+                   {ok, PaPaths} -> ["-pa"] ++ lists:concat(PaPaths);
+                   _ -> []
+               end,
+    Prog = case os:find_executable("erl") of
+               false -> "erl";
+               P -> P
+           end,
+    PeerOpts = #{
+        name => inets_perf_server,
+        args => PeerArgs,
+        peer_down => crash,
+        exec => Prog
+    },
+    ct:pal("about to start peer...", []),
+    {ok, PeerPid, Node} = peer:start(PeerOpts),
+    ct:pal("started peer ~0p", [Node]),
     Path = code:get_path(),
     true = rpc:call(Node, code, set_path, [Path]),
     [ensure_started(Node, App) || App <- [asn1, crypto, public_key, ssl, inets]],
     [ensure_started(node(), App) || App <- [asn1, crypto, public_key, ssl, inets]],
     (Node =:= node()) andalso restrict_schedulers(client),
-    {Node, Host}.
+    %% Return also the pid for peer control
+    [{server_node, Node}, {server_host, Host}, {server_pid, PeerPid}].
 
 ensure_started(Node, App) ->
      ok = rpc:call(Node, application, ensure_started, [App]).
@@ -265,42 +273,31 @@ restrict_schedulers(Type) ->
 %%--------------------------------------------------------------------
 
 init_ssl(Config) ->
-    DDir = ?config(data_dir, Config),
+%%    DDir = ?config(data_dir, Config),
     PDir = ?config(priv_dir, Config),
-    {ok, _} = make_certs:all(DDir,
-			     PDir).
+%%    {ok, _} = make_certs:all(DDir, PDir).
+    httpd_bench_certs:make_cert_files(PDir).
+
 cert_opts(Config) ->
-    ClientCaCertFile = filename:join([?config(priv_dir, Config), 
-				      "client", "cacerts.pem"]),
-    ClientCertFile = filename:join([?config(priv_dir, Config), 
-				    "client", "cert.pem"]),
-    ServerCaCertFile = filename:join([?config(priv_dir, Config), 
-				      "server", "cacerts.pem"]),
-    ServerCertFile = filename:join([?config(priv_dir, Config), 
-				    "server", "cert.pem"]),
-    ServerKeyFile = filename:join([?config(priv_dir, Config), 
-			     "server", "key.pem"]),
-    ClientKeyFile = filename:join([?config(priv_dir, Config), 
-				   "client", "key.pem"]),
+    PrivDir = ?config(priv_dir, Config),
+    ServerCaCertFile = filename:join([PrivDir, "server-cacerts.pem"]),
+    ServerCertFile = filename:join([PrivDir, "server-cert.pem"]),
+    ServerKeyFile = filename:join([PrivDir, "server-key.pem"]),
     [{server_verification_opts, [{cacertfile, ServerCaCertFile},
-				 {ciphers, ["ECDHE-RSA-AES256-GCM-SHA384",
-                                            "TLS_AES_256_GCM_SHA384"]},
-				 {certfile, ServerCertFile}, {keyfile, ServerKeyFile}]},
-     {client_verification_opts, [
-				 %%{verify, verify_peer},
-				 {cacertfile, ClientCaCertFile}, 
-				 {certfile, ClientCertFile},  
-				 {keyfile, ClientKeyFile}]}]. 
+                                 {ciphers, ["ECDHE-RSA-AES256-GCM-SHA384", "TLS_AES_256_GCM_SHA384"]},
+                                 {certfile, ServerCertFile},
+                                 {keyfile, ServerKeyFile}]},
+     {client_verification_opts, [{cacertfile, ServerCaCertFile}]}].
 
 %%--------------------------------------------------------------------
 %% Run clients  ------------------------------------------------
 %%--------------------------------------------------------------------
 
-run_test(Client, File, Config) -> 
+run_test(Client, File, Config) ->
     Parent = self(),
     Pid = spawn(fun() ->
 			receive
-			    go -> 
+			    go ->
 				Parent ! {self(),
 					  do_runs(Client, [{file, File} | Config])}
 			end
@@ -316,13 +313,12 @@ do_runs(Client, Config) ->
     N = ?config(iter, Config),
     DataDir = ?config(data_dir, Config),
     File = ?config(file, Config),
-    Name = filename:join(DataDir, File), 
+    Name = filename:join(DataDir, File),
     Args = ?MODULE:Client(Config),
     ?MODULE:Client({init, Args}),
-    Run = 
-	fun() ->
-		ok = ?MODULE:Client(Args, N)	
-	end,
+    Run = fun() ->
+              ok = ?MODULE:Client(Args, N)
+          end,
     {ok, Info} = file:read_file_info(Name, []),
     Length = Info#file_info.size,
     {TimeInMicro, _} = timer:tc(Run),
@@ -330,12 +326,15 @@ do_runs(Client, Config) ->
     BytesPerSecond = (1000000 * N * Length) div TimeInMicro,
     {{tps, ReqPerSecond}, {mbps, BytesPerSecond}}.
 
-
+%% Client handler for httpc-based test cases
+%% httpc_client/1 is called once with the config, to create args which will be then passed
+%% again into httpc_client/1 as {init, Args}.
 httpc_client({init, [_, Profile, URL, Headers, HTTPOpts]}) ->
-     %% Make sure pipelining feature will kick in when appropriate. 
-    {ok, {{_ ,200, "OK"}, _,_}} = httpc:request(get,{URL, Headers}, HTTPOpts, 
-						[{body_format, binary}, 
-						 {socket_opts, [{nodelay, true}]}], Profile),
+    %% Make sure pipelining feature will kick in when appropriate.
+    {ok, {{_ ,200, "OK"}, _,_}} = httpc:request(
+        get,{URL, Headers}, HTTPOpts,
+        [{body_format, binary}, {socket_opts, [{nodelay, true}]}],
+        Profile),
     ct:sleep(1000);
 httpc_client(Config) ->
     File = ?config(file, Config),
@@ -343,18 +342,36 @@ httpc_client(Config) ->
     Profile = ?config(profile, Config),
     URL = (?config(urlfun,Config))(File),
     Headers =  ?config(http_headers, Config),
-    HTTPOpts = ?config(http_opts, Config),
+    HTTPOpts = ?config(http_opts, Config)
+        ++ case Protocol of
+            "http" -> [];
+            "https" -> % httpc would like to know more about certificates used in the test
+                AllCertOpts = proplists:get_value(client_verification_opts, cert_opts(Config)),
+                SSLOpts = [
+                    {verify, verify_peer}, % this is the default
+                    {cacertfile, proplists:get_value(cacertfile, AllCertOpts)}
+                ],
+                [{ssl, SSLOpts}]
+        end,
     [Protocol, Profile, URL, Headers, HTTPOpts].
+
+%% This will receive arguments (Args, N) where N is iterations count,
+%% with Args produced by httpc_client/1 above.
 httpc_client(_,0) ->
     ok;
 httpc_client([Protocol, Profile, URL, Headers, HTTPOpts], N) ->
-    {ok, {{_ ,200,"OK"}, _,_}} = httpc:request(get,{URL, Headers}, HTTPOpts, [{body_format, binary},
-									     {socket_opts, [{nodelay, true}]}], Profile),
+    {ok, {{_ ,200,"OK"}, _,_}} = httpc:request(
+        get,{URL, Headers}, HTTPOpts,
+        [{body_format, binary}, {socket_opts, [{nodelay, true}]}],
+        Profile),
     httpc_client([Protocol, Profile, URL, Headers, HTTPOpts], N-1).
 
+%% Client handler based on httpd_test_lib
+%% httpd_lib_client/1 is called once with the config, to create args which will be then passed
+%% again into httpd_lib_client/1 as {init, Args}.
 httpd_lib_client({init, [_, Type, Version, Request, Host, Port, Opts]}) ->
-    ok = httpd_test_lib:verify_request(Type, Host, 
-     				       Port,  
+    ok = httpd_test_lib:verify_request(Type, Host,
+     				       Port,
      				       Opts, node(),
      				       Request,
      				       [{statuscode, 200},
@@ -366,15 +383,15 @@ httpd_lib_client(Config) ->
     Host = ?config(server_host, Config),
     Port = ?config(port, Config),
     ReuseSession = ?config(reuse_sessions, Config),
-    {Type, Opts} = 
+    {Type, Opts} =
 	case ?config(protocol, Config) of
 	    "http" ->
 		{ip_comm, [{active, true}, {mode, binary},{nodelay, true}]};
-	    "https" ->	
+	    "https" ->
 		SSLOpts =  proplists:get_value(client_verification_opts, cert_opts(Config)),
-		{ssl, [{active, true}, {mode, binary}, {nodelay, true},  
+		{ssl, [{active, true}, {mode, binary}, {nodelay, true},
 		       {reuse_sessions, ReuseSession} | SSLOpts]}
-		    
+
 	end,
     Version = ?config(http_version, Config),
     Request = case KeepAlive of
@@ -383,29 +400,34 @@ httpd_lib_client(Config) ->
 		  false ->
 		      http_request("GET /" ++ File ++ " ", Version, Host)
 	      end,
-    
+
     Args = [KeepAlive, Type, Version, Request, Host, Port, Opts],
     httpd_lib_client(Args, 1),
     Args.
 
+%% This will receive arguments (Args, N) where N is iterations count,
+%% with Args produced by httpd_lib_client/1 above.
 httpd_lib_client(_, 0) ->
     ok;
 httpd_lib_client([true, Type, Version, Request, Host, Port, Opts], N) ->
-    ok = httpd_test_lib:verify_request_N(Type, Host, 
-					 Port,  
+    ok = httpd_test_lib:verify_request_N(Type, Host,
+					 Port,
 					 Opts, node(),
 					 Request,
 					 [{statuscode, 200},
 					  {version, Version}], infinity, N);
 httpd_lib_client([false, Type, Version, Request, Host, Port, Opts] = List, N) ->
-    ok = httpd_test_lib:verify_request(Type, Host, 
-				       Port,  
+    ok = httpd_test_lib:verify_request(Type, Host,
+				       Port,
 				       Opts, node(),
 				       Request,
 				       [{statuscode, 200},
 					{version, Version}], infinity),
     httpd_lib_client(List, N-1).
 
+%% Client handler for wget-based test cases
+%% wget_client/1 is called once with the config, to create args which will be then passed
+%% again into wget_client/1 as {init, Args}.
 wget_client({init,_}) ->
     ok;
 wget_client(Config) ->
@@ -417,18 +439,19 @@ wget_client(Config) ->
     Iter = ?config(iter, Config),
     FileName = filename:join(PrivDir, "wget_req"),
     ProtocolOpts = case Protocol of
-		    "http" ->
-			   [];
-		       "https" ->
-			   proplists:get_value(client_verification_opts, cert_opts(Config))
-		   end,
+                    "http" -> [];
+                    "https" -> proplists:get_value(client_verification_opts, cert_opts(Config))
+                   end,
     wget_req_file(FileName,URL,Iter),
     [KeepAlive, FileName, URL, Protocol, ProtocolOpts, Iter].
-wget_client([KeepAlive, WgetFile, _URL, Protocol, ProtocolOpts, _], _) ->
+
+%% This will receive arguments (Args, N) where N is iterations count,
+%% with Args produced by wget_client/1 above.
+wget_client([KeepAlive, WgetFile, _URL, Protocol, ProtocolOpts, _], _Iter) ->
     process_flag(trap_exit, true),
     Cmd = wget_N(KeepAlive, WgetFile, Protocol, ProtocolOpts),
     %%ct:log("Wget cmd: ~p", [Cmd]),
-    Port = open_port({spawn, Cmd}, [stderr_to_stdout]), 
+    Port = open_port({spawn, Cmd}, [stderr_to_stdout]),
     wait_for_wget(Port).
 
 
@@ -446,13 +469,14 @@ start_web_server(Group, Config) when Group == https_dummy;
 start_web_server(Group, Config) when Group == http_inets;
 				     Group == http_inets_keep_alive ->
     start_inets("http", [], Config);
-    
+
 start_web_server(Group, Config) when Group == https_inets;
 				     Group == https_inets_keep_alive ->
     Opts = proplists:get_value(server_verification_opts, cert_opts(Config)),
     ReuseSessions = ?config(reuse_sessions, Config),
-    SSLConfHttpd = [{socket_type, {ssl,
-				   [{nodelay, true}, {reuse_sessions, ReuseSessions} | Opts]}}],
+    SSLConfHttpd = [{socket_type,
+        {ssl, [{nodelay, true}, {reuse_sessions, ReuseSessions} | Opts]}
+    }],
     start_inets("https", SSLConfHttpd, Config);
 
 start_web_server(Group, Config)  when Group == http_nginx;
@@ -470,33 +494,33 @@ start_web_server(Group, Config)  when Group == https_nginx;
 	false ->
 	    {skip, "nginx not found"};
 	 _ ->
-	     start_nginx("https",  cert_opts(Config) ++ Config)  
+	     start_nginx("https",  cert_opts(Config) ++ Config)
      end.
-   
+
 start_inets(Protocol, ConfHttpd, Config) ->
     PrivDir = ?config(priv_dir, Config),
     DataDir = ?config(data_dir, Config),
     Node = ?config(server_node, Config),
-    Host = ?config(server_host, Config),    
-    HTTPVersion = ?config(http_version, Config),    
+    Host = ?config(server_host, Config),
+    HTTPVersion = ?config(http_version, Config),
     Conf = [httpd, [{port,0},
 		    {http_version, HTTPVersion},
 		    {ipfamily, inet},
-		    {server_name, "inets_test"},
-		    {server_root, PrivDir}, 
+		    {server_name, net_adm:localhost()}, % also the default
+		    {server_root, PrivDir},
 		    {document_root, DataDir},
 		    {keep_alive, ?config(keep_alive, Config)},
 		    {keep_alive_timeout, 360}
 		    | ConfHttpd]],
     {ok, Pid} = rpc:call(Node, inets, start, Conf),
     Port = proplists:get_value(port,  rpc:call(Node, httpd, info, [Pid])),
-    F = fun(File) -> 
-		lists:concat([Protocol,"://",Host,":",Port,"/",File]) 
+    F = fun(File) ->
+		lists:concat([Protocol,"://",Host,":",Port,"/",File])
 	end,
     [{httpd_pid,Pid},{urlfun,F},{protocol,Protocol},{port,Port} | Config].
 
 start_dummy("http"= Protocol, Config) ->
-    HTTPVersion = ?config(http_version, Config),    
+    HTTPVersion = ?config(http_version, Config),
     Node = ?config(server_node, Config),
     %%DataDir= ?config(data_dir, Config),
     Host = ?config(server_host, Config),
@@ -509,13 +533,13 @@ start_dummy("http"= Protocol, Config) ->
 	    {keep_alive,  ?config(keep_alive, Config)}
 	   ],
     {Pid, Port} = rpc:call(Node, http_test_lib, dummy_server, [ip_comm, inet, [{content_cb, ?MODULE}, {conf, Conf}]]),
-    F = fun(File) -> 
-		lists:concat([Protocol,"://",Host,":",Port,"/",File]) 
+    F = fun(File) ->
+		lists:concat([Protocol,"://",Host,":",Port,"/",File])
 	end,
     [{dummy_pid,Pid},{urlfun,F},{protocol, Protocol},{port,Port} | Config];
 
 start_dummy("https" = Protocol, Config) ->
-    HTTPVersion = ?config(http_version, Config),    
+    HTTPVersion = ?config(http_version, Config),
     Node = ?config(server_node, Config),
     %% DataDir= ?config(data_dir, Config),
     Host = ?config(server_host, Config),
@@ -530,55 +554,55 @@ start_dummy("https" = Protocol, Config) ->
 	   ],
     {Pid, Port} = rpc:call(Node, http_test_lib, dummy_server,
 			   [ssl, inet, [{ssl, Opts}, {content_cb, ?MODULE}, {conf, Conf}]]),
-    F = fun(File) -> 
-		lists:concat([Protocol,"://",Host,":",Port,"/",File]) 
+    F = fun(File) ->
+		lists:concat([Protocol,"://",Host,":",Port,"/",File])
 	end,
     [{dummy_pid,Pid},{urlfun,F},{protocol,Protocol},{port,Port} | Config].
 
 start_nginx(Protocol, Config) ->
     PrivDir = ?config(priv_dir, Config),
     DataDir = ?config(data_dir, Config),
-    Host = ?config(server_host, Config),    
+    Host = ?config(server_host, Config),
     Port = inet_port(node()),
-    
+
     ConfFile = filename:join(PrivDir, "nginx.conf"),
     nginx_conf(ConfFile, [{port, Port}, {protocol, Protocol} | Config]),
-    Cmd = "nginx -c " ++ ConfFile, 
-    NginxPort =  open_port({spawn, Cmd}, [{cd, DataDir}, stderr_to_stdout]), 
+    Cmd = "nginx -c " ++ ConfFile,
+    NginxPort =  open_port({spawn, Cmd}, [{cd, DataDir}, stderr_to_stdout]),
 
-    F = fun(File) -> 
- 		lists:concat([Protocol,"://",Host,":",Port,"/",File]) 
+    F = fun(File) ->
+ 		lists:concat([Protocol,"://",Host,":",Port,"/",File])
 	end,
-    
+
     wait_for_nginx_up(Host, Port),
-   
+
     [{port, Port},{nginx_port, NginxPort},{urlfun,F},{protocol, Protocol} | Config ].
 
 stop_nginx(Config)->
-    PrivDir = ?config(priv_dir, Config),    
+    PrivDir = ?config(priv_dir, Config),
     {ok, Bin} = file:read_file(filename:join(PrivDir, "nginx.pid")),
     Pid = string:strip(binary_to_list(Bin), right, $\n),
     Cmd = "kill " ++ Pid,
     os:cmd(Cmd).
-    
+
 stop_web_server(Group, Config) when  Group == http_inets;
 				     Group == http_inets_keep_alive;
 				     Group == https_inets;
-				     Group == https_inets_keep_alive -> 
+				     Group == https_inets_keep_alive ->
     ServerNode = ?config(server_node, Config),
     rpc:call(ServerNode, inets, stop, [httpd, ?config(httpd_pid, Config)]);
 stop_web_server(Group, Config) when  Group == http_dummy;
 				     Group == http_dummy_keep_alive;
 				     Group == https_dummy;
-				     Group == https_dummy_keep_alive -> 
+				     Group == https_dummy_keep_alive ->
     stop_dummy_server(Config);
 stop_web_server(Group, Config) when  Group == http_nginx;
 				     Group == http_nginx_keep_alive;
 				     Group == https_nginx;
-				     Group == https_nginx_keep_alive -> 
+				     Group == https_nginx_keep_alive ->
     stop_nginx(Config).
 
-stop_dummy_server(Config) ->    
+stop_dummy_server(Config) ->
       case ?config(dummy_pid, Config) of
 	  Pid when is_pid(Pid) ->
 	      exit(Pid, kill);
@@ -611,7 +635,7 @@ do_inet_port(Node) ->
     {ok, Socket} = rpc:call(Node, gen_tcp, listen, [0, [{reuseaddr, true}]]),
     {ok, Port} = rpc:call(Node, inet, port, [Socket]),
     {Port, Socket}.
- 
+
 %%--------------------------------------------------------------------
 %% Dummy server callbacks  ------------------------------------------------
 %%--------------------------------------------------------------------
@@ -630,18 +654,18 @@ do_handle_request(CB, S, Name, Opts, KeepAlive) when is_list(Name) ->
     {ok, Fdesc} = file:open(Name, [read, binary]),
     {ok, Info} = file:read_file_info(Name, []),
     Length = Info#file_info.size,
-    Response = response_status_line_and_headers(Version, "Content-Length:" 
-						++ integer_to_list(Length) ++ ?CRLF, keep_alive(KeepAlive)), 
+    Response = response_status_line_and_headers(Version, "Content-Length:"
+						++ integer_to_list(Length) ++ ?CRLF, keep_alive(KeepAlive)),
     CB:send(S, Response),
     send_file(CB, S, Fdesc);
 do_handle_request(CB, S, {gen, Data}, Opts, KeepAlive) ->
     Version = proplists:get_value(http_version, Opts),
     Length = byte_size(Data),
-    Response = response_status_line_and_headers(Version, "Content-Length:" 
-						++ integer_to_list(Length) ++ ?CRLF, keep_alive(KeepAlive)), 
+    Response = response_status_line_and_headers(Version, "Content-Length:"
+						++ integer_to_list(Length) ++ ?CRLF, keep_alive(KeepAlive)),
     CB:send(S, Response),
     send_file(CB, S, {gen, Data}).
-    
+
 send_file(CB, S, {gen, Data})  ->
     CB:send(S, Data);
     %% ChunkSize = 64*1024,
@@ -653,19 +677,19 @@ send_file(CB, S, {gen, Data})  ->
     %% 	    send_file(CB, S, {gen, Rest});
     %% 	_ ->
     %% 	    CB:send(S, Data)
-    %% end; 
+    %% end;
 
 send_file(CB, S, FileDesc) ->
     case file:read(FileDesc, 64*1024) of
 	{ok, Chunk} ->
 	    CB:send(S, Chunk),
-	    send_file(CB, S, FileDesc);	
+	    send_file(CB, S, FileDesc);
 	eof ->
 	    file:close(FileDesc),
 	    ok
     end.
 
-response_status_line_and_headers(Version, Headers,  ConnectionHeader) -> 
+response_status_line_and_headers(Version, Headers,  ConnectionHeader) ->
     StatusLine = [Version, " ", "200 OK", ?CRLF],
     [StatusLine, Headers, ConnectionHeader, ?CRLF].
 
@@ -682,8 +706,9 @@ handle_http_msg({_Method, RelUri, _, {_, _Headers}, _Body}, Socket, Conf) ->
 	false ->
 	    stop
     end.
-    
-connect_cb({sslsocket, _, _}) ->
+
+%% arity has increased in later versions of OTP, not arity 3 anymore
+connect_cb(SSLSocket) when element(1, SSLSocket) =:= sslsocket ->
     ssl;
 connect_cb(_) ->
     gen_tcp.
@@ -696,41 +721,37 @@ wget_req_file(FileName, Url, Iter) ->
     write_urls(File, Url, Iter).
 
 write_urls(File, Url, 1) ->
-    file:write(File, Url), 
+    file:write(File, Url),
     file:close(File);
 write_urls(File, Url, N) ->
-    file:write(File, Url), 
+    file:write(File, Url),
     file:write(File, "\n"),
     write_urls(File, Url, N-1).
-    
+
 wait_for_wget(Port) ->
-    receive 
+    receive
 	{Port, {data, _Data}} when is_port(Port) ->
 	    wait_for_wget(Port);
-	{Port, closed} -> 
+	{Port, closed} ->
 	    ok;
 	{'EXIT', Port, _Reason} ->
 	    ok
     end.
 
 wget_N(KeepAlive, WegetFile, "http", _ProtocolOpts) ->
-    "wget -i " ++ WegetFile ++ " " ++ wget_keep_alive(KeepAlive) ++ 
+    "wget -i " ++ WegetFile ++ " " ++ wget_keep_alive(KeepAlive) ++
 	" --no-cache --timeout=120" ;
 wget_N(KeepAlive, WegetFile, "https", ProtocolOpts) ->
-    
-    "wget -i " ++ WegetFile ++ " " ++ wget_keep_alive(KeepAlive) 
-	++ wget_cert(ProtocolOpts) ++ wget_key(ProtocolOpts)
-	++ wget_cacert(ProtocolOpts) ++ 
+    "wget -i " ++ WegetFile ++ " " ++ wget_keep_alive(KeepAlive)
+	++ wget_cacert(ProtocolOpts) ++
 	" --no-cache --timeout=120".
 
 wget(KeepAlive, URL, "http", _ProtocolOpts) ->
-    "wget " ++ URL ++ " " ++ wget_keep_alive(KeepAlive) ++ 
+    "wget " ++ URL ++ " " ++ wget_keep_alive(KeepAlive) ++
 	" --no-cache --timeout=120" ;
 wget(KeepAlive, URL, "https", ProtocolOpts) ->
-    
-    "wget " ++ URL ++ " " ++ wget_keep_alive(KeepAlive) 
-	++ wget_cert(ProtocolOpts) ++ wget_key(ProtocolOpts)
-	++ wget_cacert(ProtocolOpts) ++ 
+    "wget " ++ URL ++ " " ++ wget_keep_alive(KeepAlive)
+	++ wget_cacert(ProtocolOpts) ++
 	" --no-cache --timeout=120".
 
 wget_keep_alive(true)->
@@ -741,27 +762,21 @@ wget_keep_alive(false) ->
 wget_cacert(ProtocolOpts) ->
     "--ca-certificate=" ++ proplists:get_value(cacertfile, ProtocolOpts) ++ " ".
 
-wget_cert(ProtocolOpts) ->
-    "--certificate=" ++ proplists:get_value(certfile, ProtocolOpts) ++ " ".
-
-wget_key(ProtocolOpts) ->
-    "--private-key=" ++ proplists:get_value(keyfile, ProtocolOpts) ++ " ".
-
 %%--------------------------------------------------------------------
 %% Setup nginx  ------------------------------------------------
 %%--------------------------------------------------------------------
-nginx_conf(ConfFile, Config)->
+nginx_conf(ConfFile, Config) ->
     Protocol = ?config(protocol, Config),
     file:write_file(ConfFile,
 		    [format_nginx_conf(nginx_global(Config)),
 		     format_nginx_conf(nginx_events(Config)),
 		     format_nginx_conf(nginx_http(Protocol, Config))]).
-       
+
 format_nginx_conf(Directives) ->
     lists:map(fun({Key, Value}) ->
 			  io_lib:format("~s ~s;\n", [Key, Value]);
 		     (Str) ->
-			  Str    
+			  Str
 		  end, Directives).
 
 
@@ -784,13 +799,13 @@ nginx_http("http", Config) ->
     ["http {\n" |
      nginx_defaults(PrivDir) ++
 	 [" server {",
-	  {root,                DataDir}, 
+	  {root,                DataDir},
 	  {listen,              integer_to_list(Port)},
 	  " location / {\n  try_files $uri $uri/ /index.html;\n}"
 	  "}\n", "}\n"
 	 ]
     ];
-	
+
 nginx_http("https", Config) ->
     PrivDir = ?config(priv_dir, Config),
     DataDir = ?config(data_dir, Config),
@@ -801,24 +816,24 @@ nginx_http("https", Config) ->
     ["http {" |
      nginx_defaults(PrivDir) ++
 	 [" server {",
-	  {"root",                DataDir}, 
+	  {"root",                DataDir},
 	  {"listen",              integer_to_list(Port) ++ " ssl"},
 	  {"ssl_certificate",     ?config(certfile, SSLOpts)},
 	  {"ssl_certificate_key", ?config(keyfile, SSLOpts)},
 	  {"ssl_protocols",       "TLSv1 TLSv1.1 TLSv1.2"},
-	  {"ssl_ciphers",         Ciphers}, 
+	  {"ssl_ciphers",         Ciphers},
 	  {"ssl_session_cache",    nginx_reuse_session(ReuseSession)},
 	  " location / {\n  try_files $uri $uri/ /index.html;\n}"
 	  "}\n", "}\n"
 	 ]
     ].
-	
+
 nginx_defaults(PrivDir) ->
     [
      %% Set temp and cache file options that will otherwise default to
      %% restricted locations accessible only to root.
      {"client_body_temp_path", filename:join(PrivDir, "client_body")},
-     {"fastcgi_temp_path",   filename:join(PrivDir, "fastcgi_temp")}, 
+     {"fastcgi_temp_path",   filename:join(PrivDir, "fastcgi_temp")},
      {"proxy_temp_path", filename:join(PrivDir, "proxy_temp")},
      {"scgi_temp_path", filename:join(PrivDir, "scgi_temp")},
      {"uwsgi_temp_path", filename:join(PrivDir, "uwsgi_temp_path")},
@@ -847,4 +862,3 @@ wait_for_nginx_up(Host, Port) ->
 	    ct:sleep(100),
 	    wait_for_nginx_up(Host, Port)
     end.
-		
diff --git a/lib/inets/test/httpd_bench_certs.erl b/lib/inets/test/httpd_bench_certs.erl
new file mode 100644
index 0000000000..0c3940bfe8
--- /dev/null
+++ b/lib/inets/test/httpd_bench_certs.erl
@@ -0,0 +1,128 @@
+%%% %CopyrightBegin%
+%%%
+%%% SPDX-License-Identifier: Apache-2.0
+%%%
+%%% Copyright Ericsson AB 2025-2025. 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.
+%%% 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.
+%%%
+%%% %CopyrightEnd%
+
+-module(httpd_bench_certs).
+
+-export([hardcode_rsa_key/1, choose_sha_function/0, der_to_pem/2, cert_entry/1,
+    key_entry/1, ca_entries/1, make_cert_files/1]).
+
+-include_lib("public_key/include/public_key.hrl").
+
+%% The subjectAltName extension is included and equal to net_adm:localhost() of the test host
+make_cert_files(Dir) ->
+    #{server_config := ServerConf,
+      client_config := _} = public_key:pkix_test_data(
+        #{server_chain =>
+        #{
+            root => [{key, hardcode_rsa_key(1)}, {digest, choose_sha_function()}],
+            intermediates => [[{key, hardcode_rsa_key(2)}, {digest, choose_sha_function()}]],
+            peer => [{key, hardcode_rsa_key(3)}, {digest, choose_sha_function()}]
+        },
+        client_chain =>
+        #{
+            root => [{key, hardcode_rsa_key(1)}, {digest, choose_sha_function()}],
+            intermediates => [[{key, hardcode_rsa_key(3)}, {digest, choose_sha_function()}]],
+            peer => [{key, hardcode_rsa_key(2)}, {digest, choose_sha_function()}]
+        }
+    }),
+
+    CaCertFile = filename:join([Dir, "server-cacerts.pem"]),
+    CertFile = filename:join([Dir, "server-cert.pem"]),
+    KeyFile = filename:join([Dir, "server-key.pem"]),
+
+    CAs = proplists:get_value(cacerts, ServerConf),
+    Cert = proplists:get_value(cert, ServerConf),
+    Key = proplists:get_value(key, ServerConf),
+    der_to_pem(CertFile, [cert_entry(Cert)]),
+    der_to_pem(KeyFile, [key_entry(Key)]),
+    der_to_pem(CaCertFile, ca_entries(CAs)).
+
+
+der_to_pem(File, Entries) ->
+    PemBin = public_key:pem_encode(Entries),
+    file:write_file(File, PemBin).
+
+
+choose_sha_function() ->
+    Hashes = proplists:get_value(hashs, crypto:supports()),
+    case os:cmd("openssl version") of
+        "OpenSSL 0.9.8" ++ _ -> sha;
+        _ ->
+            case lists:member(sha256, Hashes) of
+                true -> sha256;
+                false -> sha
+            end
+    end.
+
+
+cert_entry(Cert) ->
+    {'Certificate', Cert, not_encrypted}.
+
+
+key_entry({'RSAPrivateKey', DERKey}) ->
+    {'RSAPrivateKey', DERKey, not_encrypted};
+key_entry({'DSAPrivateKey', DERKey}) ->
+    {'DSAPrivateKey', DERKey, not_encrypted};
+key_entry({'ECPrivateKey', DERKey}) ->
+    {'ECPrivateKey', DERKey, not_encrypted}.
+
+
+ca_entries(CAs) ->
+    [{'Certificate', CACert, not_encrypted} || CACert <- CAs].
+
+
+hardcode_rsa_key(1) ->
+    #'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'{
+        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'{
+        version = 'two-prime',
+        modulus = 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429,
+        publicExponent = 17,
+        privateExponent = 8854955455098659953931539407470495621824836570223697404931489960185796768872145882893348383311931058684147950284994536954265831032005645344696294253579799360912014817761873358888796545955974191021709753644575521998041827642041589721895044045980930852625485916835514940558187965584358347452650930302268008446431977397918214293502821599497633970075862760001650736520566952260001423171553461362588848929781360590057040212831994258783694027013289053834376791974167294527043946669963760259975273650548116897900664646809242902841107022557239712438496384819445301703021164043324282687280801738470244471443835900160721870265,
+        prime1 = 171641816401041100605063917111691927706183918906535463031548413586331728772311589438043965564336865070070922328258143588739626712299625805650832695450270566547004154065267940032684307994238248203186986569945677705100224518137694769557564475390859269797990555863306972197736879644001860925483629009305104925823,
+        prime2 = 146170909759497809922264016492088453282310383272504533061020897155289106805616042710009332510822455269704884883705830985184223718261139908416790475825625309815234508695722132706422885088219618698987115562577878897003573425367881351537506046253616435685549396767356003663417208105346307649599145759863108910523,
+        exponent1 = 60579464612132153154728441333538327425711971378777222246428851853999433684345266860486105493295364142377972586444050678378691780811632637288529186629507258781295583787741625893888579292084087601124818789392592131211843947578009918667375697196773859928702549128225990187436545756706539150170692591519448797349,
+        exponent2 = 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609,
+        coefficient = 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612,
+        otherPrimeInfos = asn1_NOVALUE}.
diff --git a/lib/inets/test/inets.spec b/lib/inets/test/inets.spec
index 027b0f1630..b12b699624 100644
--- a/lib/inets/test/inets.spec
+++ b/lib/inets/test/inets.spec
@@ -1,6 +1,25 @@
+%%
+%% %CopyrightBegin%
+%%
+%% SPDX-License-Identifier: Apache-2.0
+%%
+%% Copyright Ericsson AB 2012-2025. 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.
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
 {suites,"../inets_test", all}.
-{skip_suites, "../inets_test", [httpd_bench_SUITE],
-    "Benchmarks run separately"}.
 {event_handler, {cte_track, []}}.
 {enable_builtin_hooks, false}.
 {ct_hooks, [{cth_log_redirect, [{mode, replace}]}]}.
diff --git a/lib/inets/test/inets_test_lib.erl b/lib/inets/test/inets_test_lib.erl
index 27521ef7e8..796b2e1c20 100644
--- a/lib/inets/test/inets_test_lib.erl
+++ b/lib/inets/test/inets_test_lib.erl
@@ -36,10 +36,10 @@ has_ipv6_support() ->
     tsp("has_ipv6_support -> no ipv6_hosts config"),
     {ok, Hostname} = inet:gethostname(),
     case inet:getaddrs(Hostname, inet6) of
-	{ok, [Addr|_]} when is_tuple(Addr) andalso 
+	{ok, [Addr|_]} when is_tuple(Addr) andalso
 			    (element(1, Addr) =/= 0) ->
-	    %% We actually need to test that the addr can be used, 
-	    %% this is done by attempting to create a (tcp) 
+	    %% We actually need to test that the addr can be used,
+	    %% this is done by attempting to create a (tcp)
 	    %% listen socket
 	    tsp("has_ipv6_support -> check Addr: ~p", [Addr]),
 	    case (catch gen_tcp:listen(0, [inet6, {ip, Addr}])) of
@@ -53,11 +53,11 @@ has_ipv6_support() ->
 	_ ->
 	    undefined
     end.
-    
+
 has_ipv6_support(Config) ->
     case lists:keysearch(ipv6_hosts, 1, Config) of
 	false ->
-	    %% Do a basic check to se if 
+	    %% Do a basic check to se if
 	    %% our own host has a working IPv6 address...
 	    has_ipv6_support();
 
@@ -73,7 +73,7 @@ has_ipv6_support(Config) ->
 		false ->
 		    undefined
 	    end;
-	
+
 	_ ->
 	    undefined
 
@@ -86,7 +86,7 @@ oscmd(Cmd) ->
 print_system_info([]) ->
     do_print_system_info("System Info");
 print_system_info(Prefix) when is_list(Prefix) ->
-    NewPrefix = lists:flatten(io_lib:format("~s: System Info", [Prefix])), 
+    NewPrefix = lists:flatten(io_lib:format("~s: System Info", [Prefix])),
     do_print_system_info(NewPrefix).
 
 do_print_system_info(Prefix) ->
@@ -101,8 +101,8 @@ do_print_system_info(Prefix) ->
 	"~n   Num schedulers:     ~p"
 	"~n   Scheduler bindings: ~p"
 	"~n   Wordsize:           ~p"
-	"~n~n", [Prefix, 
-		 os:type(), os:version(), 
+	"~n~n", [Prefix,
+		 os:type(), os:version(),
 		 erlang:system_info(system_architecture),
 		 erlang:system_info(cpu_topology),
 		 erlang:system_info(logical_processors),
@@ -111,8 +111,8 @@ do_print_system_info(Prefix) ->
 		 erlang:system_info(scheduler_bindings),
 		 erlang:system_info(wordsize)]),
     ok.
-    
-    
+
+
 run_on_windows(Fun) ->
     run_on_os(windows, Fun).
 
@@ -123,8 +123,8 @@ run_on_os(windows, Fun) ->
 	_ ->
 	    ok
     end.
-	    
-    
+
+
 %% -- Misc node operation wrapper functions --
 
 start_node(Name) ->
@@ -139,7 +139,7 @@ start_node(Name) ->
               end,
     A = Args ++ " -pa " ++ Pa,
     Opts = [{cleanup,false}, {args, A}],
-    case (catch test_server:start_node(Name, slave, Opts)) of
+    case (catch test_server:start_node(Name, peer, Opts)) of
         {ok, Node} ->
             Node;
         Else ->
@@ -165,7 +165,7 @@ await_stopped(Node, N) ->
 
 %% ----------------------------------------------------------------
 %% Ensure apps are started
-%% This to ensure we dont attempt to run teatcases on platforms 
+%% This to ensure we dont attempt to run teatcases on platforms
 %% where there is no working ssl app.
 
 ensure_started([]) ->
@@ -174,9 +174,9 @@ ensure_started([App|Apps]) ->
     ensure_started(App),
     ensure_started(Apps);
 ensure_started(crypto = App) ->
-    %% We have to treat crypto in this special way because 
+    %% We have to treat crypto in this special way because
     %% only this function ensures that the NIF lib is actually
-    %% loaded. And only by loading that lib can we know if it 
+    %% loaded. And only by loading that lib can we know if it
     %% is even possible to run crypto.
     do_ensure_started(App, fun() -> application:start(crypto) end);
 ensure_started(App) when is_atom(App) ->
@@ -214,9 +214,9 @@ start_http_server(Conf) ->
 
 start_http_server(Conf, ssl = _SslTag) ->
     tsp("start_http_server(ssl) -> try start crypto"),
-    application:start(crypto), 
+    application:start(crypto),
     tsp("start_http_server(ssl) -> try start public_key"),
-    application:start(public_key), 
+    application:start(public_key),
     do_start_http_server(Conf);
 start_http_server(Conf, SslTag) ->
     tsp("start_http_server(~w) -> entry", [SslTag]),
@@ -253,12 +253,12 @@ do_start_http_server(Conf) ->
 		"~n   Reason: ~p", [Reason]),
 	    tsf({failed_loading_inets, Reason})
     end.
-	    
+
 start_http_server_ssl(FileName) ->
     start_http_server_ssl(FileName, ssl).
 
 start_http_server_ssl(FileName, ssl = _SslTag) ->
-    application:start(crypto), 
+    application:start(crypto),
     do_start_http_server_ssl(FileName);
 start_http_server_ssl(FileName, _SslTag) ->
     do_start_http_server_ssl(FileName).
@@ -267,7 +267,7 @@ do_start_http_server_ssl(FileName) ->
     tsp("start (ssl) http server with "
 	"~n   FileName: ~p"
 	"~n", [FileName]),
-    application:start(ssl),	       
+    application:start(ssl),
     catch do_start_http_server(FileName).
 
 
@@ -303,9 +303,9 @@ from(_, []) -> [].
 copy_file(File, From, To) ->
     file:copy(filename:join(From, File), filename:join(To, File)).
 
-copy_files(FromDir, ToDir) -> 
+copy_files(FromDir, ToDir) ->
     {ok, Files} = file:list_dir(FromDir),
-    lists:foreach(fun(File) -> 
+    lists:foreach(fun(File) ->
 			  FullPath = filename:join(FromDir, File),
 			  case filelib:is_file(FullPath) of
 			      true ->
@@ -321,9 +321,9 @@ copy_dirs(FromDirRoot, ToDirRoot) ->
     case file:list_dir(FromDirRoot) of
 	{ok, Files}  ->
 	    lists:foreach(
-	      fun(FileOrDir) -> 
+	      fun(FileOrDir) ->
 		      %% Check if it's a directory or a file
-		      case filelib:is_dir(filename:join(FromDirRoot, 
+		      case filelib:is_dir(filename:join(FromDirRoot,
 							FileOrDir)) of
 			  true ->
 			      FromDir = filename:join([FromDirRoot, FileOrDir]),
@@ -337,10 +337,10 @@ copy_dirs(FromDirRoot, ToDirRoot) ->
 					  "~n   Reason: ~p"
 					  "~nwhen"
 					  "~n   ToDirRoot:           ~p"
-					  "~n   ToDirRoot file info: ~p", 
-					  [ToDir, 
-					   Reason, 
-					   ToDirRoot, 
+					  "~n   ToDirRoot file info: ~p",
+					  [ToDir,
+					   Reason,
+					   ToDirRoot,
 					   file:read_file_info(ToDirRoot)]),
 				      tsf({failed_copy_dir, ToDir, Reason})
 			      end;
@@ -353,14 +353,14 @@ copy_dirs(FromDirRoot, ToDirRoot) ->
 		"~n   FromDirRoot: ~p"
 		"~n   Reason:      ~p"
 		"~nwhen"
-		"~n   FromDirRoot file info: ~p", 
-		[FromDirRoot, 
-		 Reason, 
+		"~n   FromDirRoot file info: ~p",
+		[FromDirRoot,
+		 Reason,
 		 file:read_file_info(FromDirRoot)]),
 	    tsf({failed_list_dir, FromDirRoot, Reason})
     end.
-	    
-		
+
+
 
 del_dirs(Dir) ->
     case file:list_dir(Dir) of
@@ -372,10 +372,10 @@ del_dirs(Dir) ->
 				  case filelib:is_dir(FullPath) of
 				      true ->
 					  del_dirs(FullPath),
-					  file:del_dir(FullPath);	       
+					  file:del_dir(FullPath);
 				      false ->
 					  file:delete(FullPath)
-				  end 
+				  end
 			  end, Files);
 	_ ->
 	    ok
@@ -453,7 +453,7 @@ os_based_skip(_) ->
 %% Socket functions:
 %% open(SocketType, Host, Port) -> {ok, Socket} | {error, Reason}
 %% SocketType -> ssl | ip_comm
-%% Host       -> atom() | string() | {A, B, C, D} 
+%% Host       -> atom() | string() | {A, B, C, D}
 %% Port       -> integer()
 
 connect_bin(SockType, Host, Port) ->
@@ -470,7 +470,7 @@ connect_bin(Type, Host, Port, Opts) ->
 
 connect_byte(SockType, Host, Port) ->
     connect_byte(SockType, Host, Port, []).
-    
+
 connect_byte(ssl, Host, Port, Opts0) ->
     Opts = [list, {packet,0}, {verify, verify_none} | Opts0],
     connect(ssl, Host, Port, Opts);
@@ -486,7 +486,7 @@ connect(ssl, Host, Port, Opts) ->
     ssl:connect(Host, Port, Opts);
 connect(openssl_port, Host, Port, Opts) ->
     CaCertFile = proplists:get_value(cacertfile, Opts),
-    Cmd = "openssl s_client -quiet -port " ++ integer_to_list(Port)  ++ " -host " ++ Host 
+    Cmd = "openssl s_client -quiet -port " ++ integer_to_list(Port)  ++ " -host " ++ Host
 	++ " -CAfile " ++ CaCertFile,
     ct:log("openssl cmd: ~p~n", [Cmd]),
     OpensslPort =  open_port({spawn, Cmd}, [stderr_to_stdout]),
@@ -549,7 +549,7 @@ tsp(F) ->
     tsp(F, []).
 tsp(F, A) ->
     Timestamp = inets_lib:formated_timestamp(),
-    ct:log("*** ~s ~p ~p " ++ F ++ "~n", 
+    ct:log("*** ~s ~p ~p " ++ F ++ "~n",
 		       [Timestamp, node(), self() | A]).
 
 tsf(Reason) ->
@@ -585,8 +585,8 @@ read_junk(OpensslPort) ->
     receive
 	{OpensslPort, _} ->
 	    read_junk(OpensslPort)
-    after 500 -> 
-	    ok    
+    after 500 ->
+	    ok
     end.
 hardcode_rsa_key(1) ->
     #'RSAPrivateKey'{
@@ -613,8 +613,8 @@ hardcode_rsa_key(2) ->
        exponent2 = 51312467664734785681382706062457526359131540440966797517556579722433606376221663384746714140373192528191755406283051201483646739222992016094510128871300458249756331334105225772206172777487956446433115153562317730076172132768497908567634716277852432109643395464627389577600646306666889302334125933506877206029,
        coefficient = 30504662229874176232343608562807118278893368758027179776313787938167236952567905398252901545019583024374163153775359371298239336609182249464886717948407152570850677549297935773605431024166978281486607154204888016179709037883348099374995148481968169438302456074511782717758301581202874062062542434218011141540,
        otherPrimeInfos = asn1_NOVALUE};
-hardcode_rsa_key(3) -> 
-    #'RSAPrivateKey'{ 
+hardcode_rsa_key(3) ->
+    #'RSAPrivateKey'{
        version = 'two-prime',
        modulus = 25089040456112869869472694987833070928503703615633809313972554887193090845137746668197820419383804666271752525807484521370419854590682661809972833718476098189250708650325307850184923546875260207894844301992963978994451844985784504212035958130279304082438876764367292331581532569155681984449177635856426023931875082020262146075451989132180409962870105455517050416234175675478291534563995772675388370042873175344937421148321291640477650173765084699931690748536036544188863178325887393475703801759010864779559318631816411493486934507417755306337476945299570726975433250753415110141783026008347194577506976486290259135429,
        publicExponent = 17,
@@ -625,7 +625,7 @@ hardcode_rsa_key(3) ->
        exponent2 = 137572620950115585809189662580789132500998007785886619351549079675566218169991569609420548245479957900898715184664311515467504676010484619686391036071176762179044243478326713135456833024206699951987873470661533079532774988581535389682358631768109586527575902839864474036157372334443583670210960715165278974609,
        coefficient = 15068630434698373319269196003209754243798959461311186548759287649485250508074064775263867418602372588394608558985183294561315208336731894947137343239541687540387209051236354318837334154993136528453613256169847839789803932725339395739618592522865156272771578671216082079933457043120923342632744996962853951612,
        otherPrimeInfos = asn1_NOVALUE};
-hardcode_rsa_key(4) -> 
+hardcode_rsa_key(4) ->
     #'RSAPrivateKey'{
        version ='two-prime',
        modulus = 28617237755030755643854803617273584643843067580642149032833640135949799721163782522787597288521902619948688786051081993247908700824196122780349730169173433743054172191054872553484065655968335396052034378669869864779940355219732200954630251223541048434478476115391643898092650304645086338265930608997389611376417609043761464100338332976874588396803891301015812818307951159858145399281035705713082131199940309445719678087542976246147777388465712394062188801177717719764254900022006288880246925156931391594131839991579403409541227225173269459173129377291869028712271737734702830877034334838181789916127814298794576266389,
@@ -638,8 +638,8 @@ hardcode_rsa_key(4) ->
        coefficient = 34340318160575773065401929915821192439103777558577109939078671096408836197675640654693301707202885840826672396546056002756167635035389371579540325327619480512374920136684787633921441576901246290213545161954865184290700344352088099063404416346968182170720521708773285279884132629954461545103181082503707725012,
        otherPrimeInfos = asn1_NOVALUE};
 
-hardcode_rsa_key(5) -> 
-    #'RSAPrivateKey'{ 
+hardcode_rsa_key(5) ->
+    #'RSAPrivateKey'{
        version= 'two-prime',
        modulus = 26363170152814518327068346871197765236382539835597898797762992537312221863402655353436079974302838986536256364057947538018476963115004626096654613827403121905035011992899481598437933532388248462251770039307078647864188314916665766359828262009578648593031111569685489178543405615478739906285223620987558499488359880003693226535420421293716164794046859453204135383236667988765227190694994861629971618548127529849059769249520775574008363789050621665120207265361610436965088511042779948238320901918522125988916609088415989475825860046571847719492980547438560049874493788767083330042728150253120940100665370844282489982633,
        publicExponent = 17,
@@ -650,8 +650,8 @@ hardcode_rsa_key(5) ->
        exponent2 = 142217122612346975946270932667689342506994371754500301644129838613240401623123353990351915239791856753802128921507833848784693455415929352968108818884760967629866396887841730408713142977345151214275311532385308673155315337734838428569962298621720191411498579097539089047726042088382891468987379296661520434973,
        coefficient = 40624877259097915043489529504071755460170951428490878553842519165800720914888257733191322215286203357356050737713125202129282154441426952501134581314792133018830748896123382106683994268028624341502298766844710276939303555637478596035491641473828661569958212421472263269629366559343208764012473880251174832392,
        otherPrimeInfos = asn1_NOVALUE};
-hardcode_rsa_key(6) -> 
-    #'RSAPrivateKey'{ 
+hardcode_rsa_key(6) ->
+    #'RSAPrivateKey'{
        version = 'two-prime',
        modulus = 22748888494866396715768692484866595111939200209856056370972713870125588774286266397044592487895293134537316190976192161177144143633669641697309689280475257429554879273045671863645233402796222694405634510241820106743648116753479926387434021380537483429927516962909367257212902212159798399531316965145618774905828756510318897899298783143203190245236381440043169622358239226123652592179006905016804587837199618842875361941208299410035232803124113612082221121192550063791073372276763648926636149384299189072950588522522800393261949880796214514243704858378436010975184294077063518776479282353562934591448646412389762167039,
        publicExponent = 17,
@@ -665,11 +665,11 @@ hardcode_rsa_key(6) ->
 
 gen_pem_config_files(#{server_config := ServerConf,
                        client_config := ClientConf}, ClientBase, ServerBase) ->
-    
+
     ServerCaCertFile = ServerBase ++ "_server_cacerts.pem",
     ServerCertFile = ServerBase ++ "_server_cert.pem",
     ServerKeyFile = ServerBase ++ "_server_key.pem",
-    
+
     ClientCaCertFile = ClientBase ++ "_client_cacerts.pem",
     ClientCertFile =  ClientBase ++ "_client_cert.pem",
     ClientKeyFile = ClientBase ++ "_client_key.pem",
@@ -677,13 +677,13 @@ gen_pem_config_files(#{server_config := ServerConf,
     do_gen_pem_config_files(ServerConf,
                             ServerCertFile,
                             ServerKeyFile,
-                            ServerCaCertFile),        
+                            ServerCaCertFile),
     do_gen_pem_config_files(ClientConf,
                             ClientCertFile,
                             ClientKeyFile,
                             ClientCaCertFile),
-    [{server_config, [{certfile, ServerCertFile}, 
-                      {keyfile, ServerKeyFile}, {cacertfile, ServerCaCertFile}]}, 
+    [{server_config, [{certfile, ServerCertFile},
+                      {keyfile, ServerKeyFile}, {cacertfile, ServerCaCertFile}]},
      {client_config, [{certfile, ClientCertFile},
                       {keyfile, ClientKeyFile}, {cacertfile, ClientCaCertFile}]}].
 extensions(Exts) ->
@@ -719,7 +719,7 @@ extension({basic_constraints, Data}) ->
 	    #'Extension'{extnID = ?'id-ce-basicConstraints',
 			 extnValue = #'BasicConstraints'{cA=true},
 			 critical=true};
-	false -> 
+	false ->
 	    [];
 	Len when is_integer(Len) ->
 	    #'Extension'{extnID = ?'id-ce-basicConstraints',
diff --git a/lib/inets/test/make_certs.erl b/lib/inets/test/make_certs.erl
deleted file mode 100644
index cc2db5158c..0000000000
--- a/lib/inets/test/make_certs.erl
+++ /dev/null
@@ -1,533 +0,0 @@
-%%
-%% %CopyrightBegin%
-%%
-%% SPDX-License-Identifier: Apache-2.0
-%%
-%% Copyright Ericsson AB 2007-2025. 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.
-%% 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.
-%%
-%% %CopyrightEnd%
-%%
-
--module(make_certs).
--compile([export_all]).
--compile(nowarn_export_all).
-
-%-export([all/1, all/2, rootCA/2, intermediateCA/3, endusers/3, enduser/3, revoke/3, gencrl/2, verify/3]).
-
--record(config, {commonName, 
-	     organizationalUnitName = "Erlang OTP",
-	     organizationName = "Ericsson AB",
-	     localityName = "Stockholm",
-	     countryName = "SE",
-	     emailAddress = "peter@erix.ericsson.se",
-	     default_bits = 2048,
-	     v2_crls = true,
-	     ecc_certs = false,
-	     issuing_distribution_point = false,
-	     crl_port = 8000,
-	     openssl_cmd = "openssl"}).
-
-
-default_config() ->
-    #config{}.
-
-make_config(Args) ->
-    make_config(Args, #config{}).
-
-make_config([], C) ->
-    C;
-make_config([{organizationalUnitName, Name}|T], C) when is_list(Name) ->
-    make_config(T, C#config{organizationalUnitName = Name});
-make_config([{organizationName, Name}|T], C) when is_list(Name) ->
-    make_config(T, C#config{organizationName = Name});
-make_config([{localityName, Name}|T], C) when is_list(Name) ->
-    make_config(T, C#config{localityName = Name});
-make_config([{countryName, Name}|T], C) when is_list(Name) ->
-    make_config(T, C#config{countryName = Name});
-make_config([{emailAddress, Name}|T], C) when is_list(Name) ->
-    make_config(T, C#config{emailAddress = Name});
-make_config([{default_bits, Bits}|T], C) when is_integer(Bits) ->
-    make_config(T, C#config{default_bits = Bits});
-make_config([{v2_crls, Bool}|T], C) when is_boolean(Bool) ->
-    make_config(T, C#config{v2_crls = Bool});
-make_config([{crl_port, Port}|T], C) when is_integer(Port) ->
-    make_config(T, C#config{crl_port = Port});
-make_config([{ecc_certs, Bool}|T], C) when is_boolean(Bool) ->
-    make_config(T, C#config{ecc_certs = Bool});
-make_config([{issuing_distribution_point, Bool}|T], C) when is_boolean(Bool) ->
-    make_config(T, C#config{issuing_distribution_point = Bool});
-make_config([{openssl_cmd, Cmd}|T], C) when is_list(Cmd) ->
-    make_config(T, C#config{openssl_cmd = Cmd}).
-
-
-all([DataDir, PrivDir]) ->
-    all(DataDir, PrivDir).
-
-all(DataDir, PrivDir) ->
-    all(DataDir, PrivDir, #config{}).
-
-all(DataDir, PrivDir, C) when is_list(C) ->
-    all(DataDir, PrivDir, make_config(C));
-all(DataDir, PrivDir, C = #config{}) ->
-    ok = filelib:ensure_dir(filename:join(PrivDir, "erlangCA")),
-    create_rnd(DataDir, PrivDir),			% For all requests
-    rootCA(PrivDir, "erlangCA", C),
-    intermediateCA(PrivDir, "otpCA", "erlangCA", C),
-    endusers(PrivDir, "otpCA", ["client", "server", "revoked", "a.server", "b.server"], C),
-    endusers(PrivDir, "erlangCA", ["localhost"], C),
-    %% Create keycert files 
-    SDir = filename:join([PrivDir, "server"]),
-    SC = filename:join([SDir, "cert.pem"]),
-    SK = filename:join([SDir, "key.pem"]),
-    SKC = filename:join([SDir, "keycert.pem"]),
-    append_files([SK, SC], SKC),
-    CDir = filename:join([PrivDir, "client"]),
-    CC = filename:join([CDir, "cert.pem"]),
-    CK = filename:join([CDir, "key.pem"]),
-    CKC = filename:join([CDir, "keycert.pem"]),
-    append_files([CK, CC], CKC),
-    RDir = filename:join([PrivDir, "revoked"]),
-    RC = filename:join([RDir, "cert.pem"]),
-    RK = filename:join([RDir, "key.pem"]),
-    RKC = filename:join([RDir, "keycert.pem"]),
-    revoke(PrivDir, "otpCA", "revoked", C),
-    append_files([RK, RC], RKC),
-    remove_rnd(PrivDir),
-    {ok, C}.
-
-append_files(FileNames, ResultFileName) ->
-    {ok, ResultFile} = file:open(ResultFileName, [write]),
-    do_append_files(FileNames, ResultFile).
-
-do_append_files([], RF) ->
-    ok = file:close(RF);
-do_append_files([F|Fs], RF) ->
-    {ok, Data} = file:read_file(F),
-    ok = file:write(RF, Data),
-    do_append_files(Fs, RF).
-
-rootCA(Root, Name, C) ->
-    create_ca_dir(Root, Name, ca_cnf(C#config{commonName = Name})),
-    create_self_signed_cert(Root, Name, req_cnf(C#config{commonName = Name}), C),
-    file:copy(filename:join([Root, Name, "cert.pem"]), filename:join([Root, Name, "cacerts.pem"])),
-    gencrl(Root, Name, C).
-
-intermediateCA(Root, CA, ParentCA, C) ->
-    create_ca_dir(Root, CA, ca_cnf(C#config{commonName = CA})),
-    CARoot = filename:join([Root, CA]),
-    CnfFile = filename:join([CARoot, "req.cnf"]),
-    file:write_file(CnfFile, req_cnf(C#config{commonName = CA})),
-    KeyFile = filename:join([CARoot, "private", "key.pem"]), 
-    ReqFile =  filename:join([CARoot, "req.pem"]), 
-    create_req(Root, CnfFile, KeyFile, ReqFile, C),
-    CertFile = filename:join([CARoot, "cert.pem"]),
-    sign_req(Root, ParentCA, "ca_cert", ReqFile, CertFile, C),
-    CACertsFile = filename:join(CARoot, "cacerts.pem"),
-    file:copy(filename:join([Root, ParentCA, "cacerts.pem"]), CACertsFile),
-    %% append this CA's cert to the cacerts file
-    {ok, Bin} = file:read_file(CertFile),
-    {ok, FD} = file:open(CACertsFile, [append]),
-    file:write(FD, ["\n", Bin]),
-    file:close(FD),
-    gencrl(Root, CA, C).
-
-endusers(Root, CA, Users, C) ->
-    [enduser(Root, CA, User, C) || User <- Users].
-
-enduser(Root, CA, User, C) ->
-    UsrRoot = filename:join([Root, User]),
-    file:make_dir(UsrRoot),
-    CnfFile = filename:join([UsrRoot, "req.cnf"]),
-    file:write_file(CnfFile, req_cnf(C#config{commonName = User})),
-    KeyFile = filename:join([UsrRoot, "key.pem"]), 
-    ReqFile =  filename:join([UsrRoot, "req.pem"]), 
-    create_req(Root, CnfFile, KeyFile, ReqFile, C),
-    %create_req(Root, CnfFile, KeyFile, ReqFile),
-    CertFileAllUsage =  filename:join([UsrRoot, "cert.pem"]),
-    sign_req(Root, CA, "user_cert", ReqFile, CertFileAllUsage, C),
-    CertFileDigitalSigOnly =  filename:join([UsrRoot, "digital_signature_only_cert.pem"]),
-    sign_req(Root, CA, "user_cert_digital_signature_only", ReqFile, CertFileDigitalSigOnly, C),
-    CACertsFile = filename:join(UsrRoot, "cacerts.pem"),
-    file:copy(filename:join([Root, CA, "cacerts.pem"]), CACertsFile),
-    ok.
-
-revoke(Root, CA, User, C) ->
-    UsrCert = filename:join([Root, User, "cert.pem"]),
-    CACnfFile = filename:join([Root, CA, "ca.cnf"]),
-    Cmd = [C#config.openssl_cmd, " ca"
-	   " -revoke ", UsrCert,
-	   [" -crl_reason keyCompromise" || C#config.v2_crls ],
-	   " -config ", CACnfFile],
-    Env = [{"ROOTDIR", filename:absname(Root)}], 
-    cmd(Cmd, Env),
-    gencrl(Root, CA, C).
-
-gencrl(Root, CA, C) ->
-    CACnfFile = filename:join([Root, CA, "ca.cnf"]),
-    CACRLFile = filename:join([Root, CA, "crl.pem"]),
-    Cmd = [C#config.openssl_cmd, " ca"
-	   " -gencrl ",
-	   " -crlhours 24",
-	   " -out ", CACRLFile,
-	   " -config ", CACnfFile],
-    Env = [{"ROOTDIR", filename:absname(Root)}], 
-    cmd(Cmd, Env).
-
-verify(Root, CA, User, C) ->
-    CAFile = filename:join([Root, User, "cacerts.pem"]),
-    CACRLFile = filename:join([Root, CA, "crl.pem"]),
-    CertFile = filename:join([Root, User, "cert.pem"]),
-    Cmd = [C#config.openssl_cmd, " verify"
-	   " -CAfile ", CAFile,
-	   " -CRLfile ", CACRLFile, %% this is undocumented, but seems to work
-	   " -crl_check ",
-	   CertFile],
-    Env = [{"ROOTDIR", filename:absname(Root)}],
-    try cmd(Cmd, Env) catch
-	   exit:{eval_cmd, _, _} ->
-		invalid
-    end.
-
-create_self_signed_cert(Root, CAName, Cnf, C = #config{ecc_certs = true}) ->
-    CARoot = filename:join([Root, CAName]),
-    CnfFile = filename:join([CARoot, "req.cnf"]),
-    file:write_file(CnfFile, Cnf),
-    KeyFile = filename:join([CARoot, "private", "key.pem"]), 
-    CertFile = filename:join([CARoot, "cert.pem"]), 
-    Cmd = [C#config.openssl_cmd, " ecparam"
-	   " -out ", KeyFile,
-	   " -name secp521r1 ",
-	   %" -name sect283k1 ",
-	   " -genkey "],
-    Env = [{"ROOTDIR", filename:absname(Root)}], 
-    cmd(Cmd, Env),
-
-    Cmd2 = [C#config.openssl_cmd, " req"
-	   " -new"
-	   " -x509"
-	   " -config ", CnfFile,
-	   " -key ", KeyFile, 
-		 " -outform PEM ",
-	   " -out ", CertFile], 
-    cmd(Cmd2, Env);
-create_self_signed_cert(Root, CAName, Cnf, C) ->
-    CARoot = filename:join([Root, CAName]),
-    CnfFile = filename:join([CARoot, "req.cnf"]),
-    file:write_file(CnfFile, Cnf),
-    KeyFile = filename:join([CARoot, "private", "key.pem"]), 
-    CertFile = filename:join([CARoot, "cert.pem"]), 
-    Cmd = [C#config.openssl_cmd, " req"
-	   " -new"
-	   " -x509"
-	   " -config ", CnfFile,
-	   " -keyout ", KeyFile,
-	   " -outform PEM",
-	   " -out ", CertFile], 
-    Env = [{"ROOTDIR", filename:absname(Root)}],  
-    cmd(Cmd, Env).
-
-
-create_ca_dir(Root, CAName, Cnf) ->
-    CARoot = filename:join([Root, CAName]),
-    ok = filelib:ensure_dir(CARoot),
-    file:make_dir(CARoot),
-    create_dirs(CARoot, ["certs", "crl", "newcerts", "private"]),
-    create_rnd(Root, filename:join([CAName, "private"])),
-    create_files(CARoot, [{"serial", "01\n"},
-			  {"crlnumber", "01"},
-			  {"index.txt", ""},
-			  {"ca.cnf", Cnf}]).
-
-create_req(Root, CnfFile, KeyFile, ReqFile, C = #config{ecc_certs = true}) ->
-    Cmd = [C#config.openssl_cmd, " ecparam"
-	   " -out ", KeyFile,
-	   " -name secp521r1 ",
-	   %" -name sect283k1 ",
-	   " -genkey "],
-    Env = [{"ROOTDIR", filename:absname(Root)}], 
-    cmd(Cmd, Env),
-    Cmd2 = [C#config.openssl_cmd, " req"
-	   " -new ",
-	   " -key ", KeyFile,
-	   " -outform PEM ",
-	   " -out ", ReqFile,
-	   " -config ", CnfFile],
-    cmd(Cmd2, Env);
-    %fix_key_file(KeyFile).
-create_req(Root, CnfFile, KeyFile, ReqFile, C) ->
-    Cmd = [C#config.openssl_cmd, " req"
-	   " -new"
-	   " -config ", CnfFile,
-	   " -outform PEM ",
-	   " -keyout ", KeyFile, 
-	   " -out ", ReqFile], 
-    Env = [{"ROOTDIR", filename:absname(Root)}], 
-    cmd(Cmd, Env).
-    %fix_key_file(KeyFile).
-
-
-sign_req(Root, CA, CertType, ReqFile, CertFile, C) ->
-    CACnfFile = filename:join([Root, CA, "ca.cnf"]),
-    Cmd = [C#config.openssl_cmd, " ca"
-	   " -batch"
-	   " -notext"
-	   " -config ", CACnfFile, 
-	   " -extensions ", CertType,
-	   " -in ", ReqFile, 
-	   " -out ", CertFile],
-    Env = [{"ROOTDIR", filename:absname(Root)}], 
-    cmd(Cmd, Env).
-    
-%%
-%%  Misc
-%%
-    
-create_dirs(Root, Dirs) ->
-    lists:foreach(fun(Dir) ->
-			  file:make_dir(filename:join([Root, Dir])) end,
-		  Dirs).
-
-create_files(Root, NameContents) ->
-    lists:foreach(
-      fun({Name, Contents}) ->
-	      file:write_file(filename:join([Root, Name]), Contents) end,
-      NameContents).
-
-create_rnd(FromDir, ToDir) ->
-     From = filename:join([FromDir, "RAND"]),
-     To = filename:join([ToDir, "RAND"]),
-     file:copy(From, To).
-
-remove_rnd(Dir) ->
-    File = filename:join([Dir, "RAND"]),
-    file:delete(File).
-
-cmd(Cmd, Env) ->
-    FCmd = lists:flatten(Cmd),
-    Port = open_port({spawn, FCmd}, [stream, eof, exit_status, stderr_to_stdout, 
-				    {env, Env}]),
-    eval_cmd(Port, FCmd).
-
-eval_cmd(Port, Cmd) ->
-    receive 
-	{Port, {data, _}} ->
-	    eval_cmd(Port, Cmd);
-	{Port, eof} ->
-	    ok
-    end,
-    receive
-	{Port, {exit_status, 0}}  ->
-	    ok;
-	{Port, {exit_status, Status}} ->
-	    exit({eval_cmd, Cmd, Status})
-    after 0 ->
-	    ok
-    end.
-
-%%
-%% Contents of configuration files 
-%%
-
-req_cnf(C) ->
-    ["# Purpose: Configuration for requests (end users and CAs)."
-     "\n"
-     "ROOTDIR	        = $ENV::ROOTDIR\n"
-     "\n"
-
-     "[req]\n"
-     "input_password	= secret\n"
-     "output_password	= secret\n"
-     "default_bits	= ", integer_to_list(C#config.default_bits), "\n"
-     "RANDFILE		= $ROOTDIR/RAND\n"
-     "encrypt_key	= no\n"
-     "default_md	= md5\n"
-     "#string_mask	= pkix\n"
-     "x509_extensions	= ca_ext\n"
-     "prompt		= no\n"
-     "distinguished_name= name\n"
-     "\n"
-
-     "[name]\n"
-     "commonName		= ", C#config.commonName, "\n"
-     "organizationalUnitName	= ", C#config.organizationalUnitName, "\n"
-     "organizationName	        = ", C#config.organizationName, "\n" 
-     "localityName		= ", C#config.localityName, "\n"
-     "countryName		= ", C#config.countryName, "\n"
-     "emailAddress		= ", C#config.emailAddress, "\n"
-     "\n"
-
-     "[ca_ext]\n"
-     "basicConstraints 	= critical, CA:true\n"
-     "keyUsage 		= cRLSign, keyCertSign\n"
-     "subjectKeyIdentifier = hash\n"
-     "subjectAltName	= email:copy\n"].
-
-ca_cnf(C = #config{issuing_distribution_point = true}) ->
-    ["# Purpose: Configuration for CAs.\n"
-     "\n"
-     "ROOTDIR	        = $ENV::ROOTDIR\n"
-     "default_ca	= ca\n"
-     "\n"
-
-     "[ca]\n"
-     "dir		= $ROOTDIR/", C#config.commonName, "\n"
-     "certs		= $dir/certs\n"
-     "crl_dir	        = $dir/crl\n"
-     "database	        = $dir/index.txt\n"
-     "new_certs_dir	= $dir/newcerts\n"
-     "certificate	= $dir/cert.pem\n"
-     "serial		= $dir/serial\n"
-     "crl		= $dir/crl.pem\n",
-     ["crlnumber		= $dir/crlnumber\n" || C#config.v2_crls],
-     "private_key	= $dir/private/key.pem\n"
-     "RANDFILE	        = $dir/private/RAND\n"
-     "\n"
-     "x509_extensions   = user_cert\n",
-     ["crl_extensions = crl_ext\n" || C#config.v2_crls],
-     "unique_subject  = no\n"
-     "default_days	= 3600\n"
-     "default_md	= md5\n"
-     "preserve	        = no\n"
-     "policy		= policy_match\n"
-     "\n"
-
-     "[policy_match]\n"
-     "commonName		= supplied\n"
-     "organizationalUnitName	= optional\n"
-     "organizationName	        = match\n"
-     "countryName		= match\n"
-     "localityName		= match\n"
-     "emailAddress		= supplied\n"
-     "\n"
-
-     "[crl_ext]\n"
-     "authorityKeyIdentifier=keyid:always,issuer:always\n",
-     ["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point],
-
-     "[idpsec]\n"
-     "fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n"
-
-     "[user_cert]\n"
-     "basicConstraints	= CA:false\n"
-     "keyUsage 		= nonRepudiation, digitalSignature, keyEncipherment\n"
-     "subjectKeyIdentifier = hash\n"
-     "authorityKeyIdentifier = keyid,issuer:always\n"
-     "subjectAltName	= email:copy\n"
-     "issuerAltName	= issuer:copy\n"
-     "crlDistributionPoints=@crl_section\n"
-
-     "[crl_section]\n"
-     %% intentionally invalid
-     "URI.1=http://localhost/",C#config.commonName,"/crl.pem\n"
-     "URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n"
-     "\n"
-
-     "[user_cert_digital_signature_only]\n"
-     "basicConstraints	= CA:false\n"
-     "keyUsage 		= digitalSignature\n"
-     "subjectKeyIdentifier = hash\n"
-     "authorityKeyIdentifier = keyid,issuer:always\n"
-     "subjectAltName	= email:copy\n"
-     "issuerAltName	= issuer:copy\n"
-     "\n"
-
-     "[ca_cert]\n"
-     "basicConstraints 	= critical,CA:true\n"
-     "keyUsage 		= cRLSign, keyCertSign\n"
-     "subjectKeyIdentifier = hash\n"
-     "authorityKeyIdentifier = keyid:always,issuer:always\n"
-     "subjectAltName	= email:copy\n"
-     "issuerAltName	= issuer:copy\n"
-     "crlDistributionPoints=@crl_section\n"
-    ];
-
-ca_cnf(C = #config{issuing_distribution_point = false}) ->
-    ["# Purpose: Configuration for CAs.\n"
-     "\n"
-     "ROOTDIR	        = $ENV::ROOTDIR\n"
-     "default_ca	= ca\n"
-     "\n"
-
-     "[ca]\n"
-     "dir		= $ROOTDIR/", C#config.commonName, "\n"
-     "certs		= $dir/certs\n"
-     "crl_dir	        = $dir/crl\n"
-     "database	        = $dir/index.txt\n"
-     "new_certs_dir	= $dir/newcerts\n"
-     "certificate	= $dir/cert.pem\n"
-     "serial		= $dir/serial\n"
-     "crl		= $dir/crl.pem\n",
-     ["crlnumber		= $dir/crlnumber\n" || C#config.v2_crls],
-     "private_key	= $dir/private/key.pem\n"
-     "RANDFILE	        = $dir/private/RAND\n"
-     "\n"
-     "x509_extensions   = user_cert\n",
-     ["crl_extensions = crl_ext\n" || C#config.v2_crls],
-     "unique_subject  = no\n"
-     "default_days	= 3600\n"
-     "default_md	= md5\n"
-     "preserve	        = no\n"
-     "policy		= policy_match\n"
-     "\n"
-
-     "[policy_match]\n"
-     "commonName		= supplied\n"
-     "organizationalUnitName	= optional\n"
-     "organizationName	        = match\n"
-     "countryName		= match\n"
-     "localityName		= match\n"
-     "emailAddress		= supplied\n"
-     "\n"
-
-     "[crl_ext]\n"
-     "authorityKeyIdentifier=keyid:always,issuer:always\n",
-     %["issuingDistributionPoint=critical, @idpsec\n" || C#config.issuing_distribution_point],
-
-     %"[idpsec]\n"
-     %"fullname=URI:http://localhost:8000/",C#config.commonName,"/crl.pem\n"
-
-     "[user_cert]\n"
-     "basicConstraints	= CA:false\n"
-     "keyUsage 		= nonRepudiation, digitalSignature, keyEncipherment\n"
-     "subjectKeyIdentifier = hash\n"
-     "authorityKeyIdentifier = keyid,issuer:always\n"
-     "subjectAltName	= email:copy\n"
-     "issuerAltName	= issuer:copy\n"
-     %"crlDistributionPoints=@crl_section\n"
-
-     %%"[crl_section]\n"
-     %% intentionally invalid
-     %%"URI.1=http://localhost/",C#config.commonName,"/crl.pem\n"
-     %%"URI.2=http://localhost:",integer_to_list(C#config.crl_port),"/",C#config.commonName,"/crl.pem\n"
-     %%"\n"
-
-     "[user_cert_digital_signature_only]\n"
-     "basicConstraints	= CA:false\n"
-     "keyUsage 		= digitalSignature\n"
-     "subjectKeyIdentifier = hash\n"
-     "authorityKeyIdentifier = keyid,issuer:always\n"
-     "subjectAltName	= email:copy\n"
-     "issuerAltName	= issuer:copy\n"
-     "\n"
-
-     "[ca_cert]\n"
-     "basicConstraints 	= critical,CA:true\n"
-     "keyUsage 		= cRLSign, keyCertSign\n"
-     "subjectKeyIdentifier = hash\n"
-     "authorityKeyIdentifier = keyid:always,issuer:always\n"
-     "subjectAltName	= email:copy\n"
-     "issuerAltName	= issuer:copy\n"
-     %"crlDistributionPoints=@crl_section\n"
-    ].
-- 
2.51.0

openSUSE Build Service is sponsored by