2023-04-05 17:26:20 -07:00
|
|
|
#***************************************************************************
|
|
|
|
|
# _ _ ____ _
|
|
|
|
|
# Project ___| | | | _ \| |
|
|
|
|
|
# / __| | | | |_) | |
|
|
|
|
|
# | (__| |_| | _ <| |___
|
|
|
|
|
# \___|\___/|_| \_\_____|
|
|
|
|
|
#
|
|
|
|
|
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
|
|
|
#
|
|
|
|
|
# This software is licensed as described in the file COPYING, which
|
|
|
|
|
# you should have received as part of this distribution. The terms
|
|
|
|
|
# are also available at https://curl.se/docs/copyright.html.
|
|
|
|
|
#
|
|
|
|
|
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
|
|
|
# copies of the Software, and permit persons to whom the Software is
|
|
|
|
|
# furnished to do so, under the terms of the COPYING file.
|
|
|
|
|
#
|
|
|
|
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
|
# KIND, either express or implied.
|
|
|
|
|
#
|
|
|
|
|
# SPDX-License-Identifier: curl
|
|
|
|
|
#
|
|
|
|
|
###########################################################################
|
|
|
|
|
|
|
|
|
|
# This module contains functions that are useful for managing the lifecycle of
|
|
|
|
|
# test servers required when running tests. It is not intended for use within
|
|
|
|
|
# those servers, but rather for starting and stopping them.
|
|
|
|
|
|
|
|
|
|
package servers;
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
use IO::Socket;
|
2025-05-31 13:31:03 +02:00
|
|
|
use Time::HiRes;
|
2023-04-05 17:26:20 -07:00
|
|
|
use strict;
|
|
|
|
|
use warnings;
|
|
|
|
|
|
|
|
|
|
BEGIN {
|
|
|
|
|
use base qw(Exporter);
|
|
|
|
|
|
|
|
|
|
our @EXPORT = (
|
|
|
|
|
# variables
|
|
|
|
|
qw(
|
|
|
|
|
$SOCKSIN
|
|
|
|
|
$err_unexpected
|
|
|
|
|
$debugprotocol
|
|
|
|
|
$stunnel
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
# functions
|
|
|
|
|
qw(
|
|
|
|
|
initserverconfig
|
2023-04-21 14:07:06 -07:00
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
our @EXPORT_OK = (
|
|
|
|
|
# functions
|
|
|
|
|
qw(
|
2023-04-05 17:26:20 -07:00
|
|
|
checkcmd
|
|
|
|
|
serverfortest
|
|
|
|
|
stopserver
|
2023-04-21 15:00:00 -07:00
|
|
|
stopservers
|
2023-04-14 17:22:05 -07:00
|
|
|
subvariables
|
2024-09-25 13:53:17 +02:00
|
|
|
localhttp
|
2023-04-21 14:07:06 -07:00
|
|
|
),
|
|
|
|
|
|
|
|
|
|
# for debugging only
|
|
|
|
|
qw(
|
|
|
|
|
protoport
|
2023-04-05 17:26:20 -07:00
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use serverhelp qw(
|
|
|
|
|
serverfactors
|
|
|
|
|
servername_id
|
|
|
|
|
servername_str
|
|
|
|
|
servername_canon
|
|
|
|
|
server_pidfilename
|
|
|
|
|
server_portfilename
|
|
|
|
|
server_logfilename
|
2025-02-24 15:27:35 +01:00
|
|
|
server_exe
|
2023-04-05 17:26:20 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
use sshhelp qw(
|
|
|
|
|
$hstpubmd5f
|
|
|
|
|
$hstpubsha256f
|
|
|
|
|
$sshexe
|
|
|
|
|
$sftpexe
|
|
|
|
|
$sftpconfig
|
|
|
|
|
$sshdlog
|
|
|
|
|
$sftplog
|
|
|
|
|
$sftpcmds
|
|
|
|
|
display_sshdconfig
|
|
|
|
|
display_sftpconfig
|
|
|
|
|
display_sshdlog
|
|
|
|
|
display_sftplog
|
|
|
|
|
find_sshd
|
|
|
|
|
find_ssh
|
|
|
|
|
find_sftp
|
|
|
|
|
sshversioninfo
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
use pathhelp qw(
|
|
|
|
|
exe_ext
|
|
|
|
|
os_is_win
|
2024-10-01 12:16:50 +02:00
|
|
|
build_sys_abs_path
|
2023-04-05 17:26:20 -07:00
|
|
|
sys_native_abs_path
|
2025-09-25 01:54:28 +02:00
|
|
|
shell_quote
|
2023-04-05 17:26:20 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
use processhelp;
|
|
|
|
|
use globalconfig;
|
2023-04-21 14:07:31 -07:00
|
|
|
use testutil qw(
|
|
|
|
|
logmsg
|
|
|
|
|
runclient
|
|
|
|
|
runclientoutput
|
2025-03-28 22:21:06 +01:00
|
|
|
exerunner
|
2023-04-21 14:07:31 -07:00
|
|
|
);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
my %serverpidfile; # all server pid filenames, identified by server id
|
|
|
|
|
my %serverportfile;# all server port filenames, identified by server id
|
2026-06-11 17:22:30 +02:00
|
|
|
my $sshdvernum; # for socks server, ssh daemon version number
|
|
|
|
|
my $sshdverstr; # for socks server, ssh daemon version string
|
|
|
|
|
my $sshderror; # for socks server, ssh daemon version error
|
|
|
|
|
my %doesntrun; # servers that do not work, identified by pidfile
|
2023-04-05 17:26:20 -07:00
|
|
|
my %PORT = (nolisten => 47); # port we use for a local non-listening service
|
2026-06-11 17:22:30 +02:00
|
|
|
my $server_response_maxtime = 13;
|
|
|
|
|
my %run; # running server
|
|
|
|
|
my %runcert; # cert file currently in use by an SSL running server
|
|
|
|
|
my $CLIENTIP = "127.0.0.1"; # address which curl uses for incoming connections
|
|
|
|
|
my $CLIENT6IP = "[::1]"; # address which curl uses for incoming connections
|
2024-10-01 12:16:50 +02:00
|
|
|
my $posix_pwd = build_sys_abs_path($pwd); # current working directory in POSIX format
|
2026-06-11 17:22:30 +02:00
|
|
|
my $h2cver = "h2c"; # this version is decided by the nghttp2 lib being used
|
|
|
|
|
my $HOSTIP = "127.0.0.1"; # address on which the test server listens
|
|
|
|
|
my $HOST6IP = "[::1]"; # address on which the test server listens
|
|
|
|
|
my $HTTPUNIXPATH; # HTTP server Unix domain socket path
|
|
|
|
|
my $SOCKSUNIXPATH; # socks server Unix domain socket path
|
2023-04-27 10:02:32 -07:00
|
|
|
my $SSHSRVMD5 = "[uninitialized]"; # MD5 of ssh server public key
|
|
|
|
|
my $SSHSRVSHA256 = "[uninitialized]"; # SHA256 of ssh server public key
|
2026-06-11 17:22:30 +02:00
|
|
|
my $USER; # name of the current user
|
|
|
|
|
my $sshdid; # for socks server, ssh daemon version id
|
|
|
|
|
my $ftpchecktime = 1; # time it took to verify our test FTP server
|
2025-06-02 10:41:20 +02:00
|
|
|
my $SERVER_TIMEOUT_SEC = 15; # time for a server to spin up
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# Variables shared with runtests.pl
|
2026-06-11 17:22:30 +02:00
|
|
|
our $SOCKSIN = "socksd-request.log"; # what curl sent to the SOCKS proxy
|
2023-04-05 17:26:20 -07:00
|
|
|
our $err_unexpected; # error instead of warning on server unexpectedly alive
|
2023-04-27 10:02:32 -07:00
|
|
|
our $debugprotocol; # nonzero for verbose server logs
|
|
|
|
|
our $stunnel; # path to stunnel command
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Check for a command in the PATH of the test server.
|
|
|
|
|
#
|
|
|
|
|
sub checkcmd {
|
2026-06-11 17:22:30 +02:00
|
|
|
my ($cmd, @extrapaths) = @_;
|
2024-10-01 12:25:21 +02:00
|
|
|
my @paths;
|
2025-07-08 13:59:32 +02:00
|
|
|
if($^O eq 'MSWin32' || $^O eq 'dos' || $^O eq 'os2') {
|
2023-10-13 11:46:39 -07:00
|
|
|
# PATH separator is different
|
2026-06-11 17:22:30 +02:00
|
|
|
@paths = (split(';', $ENV{'PATH'}), @extrapaths);
|
2024-10-01 12:25:21 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2026-06-11 17:22:30 +02:00
|
|
|
@paths = (split(':', $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
|
|
|
|
|
"/sbin", "/usr/bin", "/usr/local/bin", @extrapaths);
|
2023-10-13 11:46:39 -07:00
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
for(@paths) {
|
2025-07-11 16:04:24 +02:00
|
|
|
if(-x "$_/$cmd" . exe_ext('SYS') && ! -d "$_/$cmd" . exe_ext('SYS')) {
|
2023-04-05 17:26:20 -07:00
|
|
|
# executable bit but not a directory!
|
|
|
|
|
return "$_/$cmd";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
#######################################################################
|
|
|
|
|
# Create a server socket on a random (unused) port, then close it and
|
|
|
|
|
# return the port number
|
|
|
|
|
#
|
|
|
|
|
sub getfreeport {
|
|
|
|
|
my ($ipnum) = @_;
|
|
|
|
|
my $server = IO::Socket->new(LocalPort => 0,
|
|
|
|
|
Domain => $ipnum == 6 ? AF_INET6 : AF_INET,
|
|
|
|
|
Type => SOCK_STREAM,
|
|
|
|
|
Reuse => 1,
|
|
|
|
|
Listen => 10 )
|
2025-11-15 00:27:38 +01:00
|
|
|
or die "Could not create tcp server socket: $@\n";
|
2023-05-29 20:25:09 +02:00
|
|
|
|
|
|
|
|
return $server->sockport();
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-20 17:56:37 +02:00
|
|
|
use File::Temp qw/ tempfile/;
|
|
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
#######################################################################
|
|
|
|
|
# Initialize configuration variables
|
|
|
|
|
sub initserverconfig {
|
2025-12-02 15:53:29 +01:00
|
|
|
$SOCKSUNIXPATH = "$pwd/$LOGDIR/$PIDDIR/socks-uds"; # SOCKS Unix domain socket
|
|
|
|
|
$HTTPUNIXPATH = "$pwd/$LOGDIR/$PIDDIR/http-uds"; # HTTP Unix domain socket
|
2023-04-05 17:26:20 -07:00
|
|
|
$stunnel = checkcmd("stunnel4") || checkcmd("tstunnel") || checkcmd("stunnel");
|
|
|
|
|
|
|
|
|
|
# get the name of the current user
|
|
|
|
|
$USER = $ENV{USER}; # Linux
|
2025-07-08 13:59:32 +02:00
|
|
|
if(!$USER) {
|
2023-04-05 17:26:20 -07:00
|
|
|
$USER = $ENV{USERNAME}; # Windows
|
2025-06-05 23:37:59 +02:00
|
|
|
}
|
2025-07-08 13:59:32 +02:00
|
|
|
if(!$USER) {
|
2025-06-05 23:37:59 +02:00
|
|
|
$USER = $ENV{LOGNAME}; # Some Unix (I think)
|
|
|
|
|
}
|
2025-07-08 13:59:32 +02:00
|
|
|
if(!$USER) {
|
2026-05-19 17:41:07 +02:00
|
|
|
$USER = qx(whoami);
|
2025-06-05 23:37:59 +02:00
|
|
|
chomp $USER;
|
|
|
|
|
}
|
2025-07-08 13:59:32 +02:00
|
|
|
if(!$USER) {
|
2026-05-19 17:41:07 +02:00
|
|
|
$USER = qx(id -un);
|
2025-06-05 23:37:59 +02:00
|
|
|
chomp $USER;
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
init_serverpidfile_hash();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
2025-11-15 00:27:38 +01:00
|
|
|
# Load serverpidfile and serverportfile hashes with filenames for all
|
2023-04-05 17:26:20 -07:00
|
|
|
# possible servers.
|
|
|
|
|
#
|
|
|
|
|
sub init_serverpidfile_hash {
|
2025-04-28 14:57:16 +02:00
|
|
|
for my $proto (('ftp', 'gopher', 'http', 'imap', 'pop3', 'smtp', 'http/2', 'http/3')) {
|
|
|
|
|
for my $ssl (('', 's')) {
|
|
|
|
|
for my $ipvnum ((4, 6)) {
|
|
|
|
|
for my $idnum ((1, 2, 3)) {
|
|
|
|
|
my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
|
|
|
|
|
my $pidf = server_pidfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
|
|
|
|
|
$ipvnum, $idnum);
|
|
|
|
|
$serverpidfile{$serv} = $pidf;
|
|
|
|
|
my $portf = server_portfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
|
|
|
|
|
$ipvnum, $idnum);
|
|
|
|
|
$serverportfile{$serv} = $portf;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2026-07-04 12:19:47 +02:00
|
|
|
for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp',
|
2026-01-17 17:23:44 +01:00
|
|
|
'dict', 'smb', 'smbs', 'telnet', 'mqtt', 'mqtts',
|
|
|
|
|
'https-mtls', 'dns')) {
|
2025-04-28 14:57:16 +02:00
|
|
|
for my $ipvnum ((4, 6)) {
|
|
|
|
|
for my $idnum ((1, 2)) {
|
|
|
|
|
my $serv = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
my $pidf = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
|
|
|
|
|
$idnum);
|
|
|
|
|
$serverpidfile{$serv} = $pidf;
|
|
|
|
|
my $portf = server_portfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
|
|
|
|
|
$idnum);
|
|
|
|
|
$serverportfile{$serv} = $portf;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2025-04-28 14:57:16 +02:00
|
|
|
for my $proto (('http', 'imap', 'pop3', 'smtp', 'http/2', 'http/3')) {
|
|
|
|
|
for my $ssl (('', 's')) {
|
|
|
|
|
my $serv = servername_id("$proto$ssl", "unix", 1);
|
|
|
|
|
my $pidf = server_pidfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
|
|
|
|
|
"unix", 1);
|
|
|
|
|
$serverpidfile{$serv} = $pidf;
|
|
|
|
|
my $portf = server_portfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
|
|
|
|
|
"unix", 1);
|
|
|
|
|
$serverportfile{$serv} = $portf;
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
2026-05-28 23:50:52 +02:00
|
|
|
# Check if a given child process has died. Reaps it if so.
|
2023-04-05 17:26:20 -07:00
|
|
|
#
|
|
|
|
|
sub checkdied {
|
|
|
|
|
my $pid = $_[0];
|
|
|
|
|
if((not defined $pid) || $pid <= 0) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
use POSIX ":sys_wait_h";
|
|
|
|
|
my $rc = pidwait($pid, &WNOHANG);
|
2026-02-01 01:56:43 +01:00
|
|
|
return ($rc == $pid) ? 1 : 0;
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
##############################################################################
|
|
|
|
|
# This function makes sure the right set of server is running for the
|
|
|
|
|
# specified test case. This is a useful design when we run single tests as not
|
|
|
|
|
# all servers need to run then!
|
|
|
|
|
#
|
2023-04-08 17:13:16 -07:00
|
|
|
# Returns: a string, blank if everything is fine or a reason why it failed, and
|
|
|
|
|
# an integer:
|
|
|
|
|
# 0 for success
|
|
|
|
|
# 1 for an error starting the server
|
|
|
|
|
# 2 for not the first time getting an error starting the server
|
|
|
|
|
# 3 for a failure to stop a server in order to restart it
|
|
|
|
|
# 4 for an unsupported server type
|
2023-04-05 17:26:20 -07:00
|
|
|
#
|
|
|
|
|
sub serverfortest {
|
2026-06-11 17:22:30 +02:00
|
|
|
my (@what) = @_;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
|
|
|
|
|
my $srvrline = $what[$i];
|
|
|
|
|
chomp $srvrline if($srvrline);
|
2025-04-09 09:47:43 +02:00
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
if($srvrline =~ /^(\S+)((\s*)(.*))/) {
|
|
|
|
|
my $server = "${1}";
|
|
|
|
|
my $lnrest = "${2}";
|
|
|
|
|
my $tlsext;
|
2025-04-09 09:47:43 +02:00
|
|
|
|
|
|
|
|
my @lprotocols = @protocols;
|
|
|
|
|
|
|
|
|
|
push @lprotocols, "dns";
|
|
|
|
|
|
|
|
|
|
if(! grep /^\Q$server\E$/, @lprotocols) {
|
2026-02-13 01:47:10 +01:00
|
|
|
if(substr($server, 0, 5) ne "socks") {
|
2023-04-05 17:26:20 -07:00
|
|
|
if($tlsext) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("curl lacks $tlsext support", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
else {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("curl lacks $server server support", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$what[$i] = "$server$lnrest" if($tlsext);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &startservers(@what);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Start a new thread/process and run the given command line in there.
|
|
|
|
|
# Return the pids (yes plural) of the new child process to the parent.
|
|
|
|
|
#
|
|
|
|
|
sub startnew {
|
2026-06-11 17:22:30 +02:00
|
|
|
my ($cmd, $pidfile, $timeout, $fakepidfile) = @_;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2025-07-11 16:04:24 +02:00
|
|
|
logmsg "startnew: $cmd\n" if($verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my $child = fork();
|
|
|
|
|
|
|
|
|
|
if(not defined $child) {
|
|
|
|
|
logmsg "startnew: fork() failure detected\n";
|
2026-06-29 19:01:04 +02:00
|
|
|
return (-1, -1);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(0 == $child) {
|
|
|
|
|
# Here we are the child. Run the given command.
|
|
|
|
|
|
|
|
|
|
# Flush output.
|
|
|
|
|
$| = 1;
|
|
|
|
|
|
|
|
|
|
# Put an "exec" in front of the command so that the child process
|
|
|
|
|
# keeps this child's process ID.
|
2026-06-15 01:26:04 +02:00
|
|
|
exec("exec $cmd") or die "Cannot exec() $cmd: $!";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# exec() should never return back here to this process. We protect
|
2026-05-28 23:50:52 +02:00
|
|
|
# ourselves by calling die() in case something goes really bad.
|
2023-04-05 17:26:20 -07:00
|
|
|
die "error: exec() has returned";
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# Ugly hack but ssh client and gnutls-serv do not support pid files
|
2025-07-08 13:59:32 +02:00
|
|
|
if($fakepidfile) {
|
2026-03-19 01:15:43 +01:00
|
|
|
if(open(my $out, ">", $pidfile)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
print $out $child . "\n";
|
2026-06-15 01:26:04 +02:00
|
|
|
close($out) or die "Failure writing pidfile";
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
|
|
|
|
|
}
|
|
|
|
|
# could/should do a while connect fails sleep a bit and loop
|
2025-08-14 13:36:04 +02:00
|
|
|
Time::HiRes::sleep($timeout);
|
2025-07-08 13:59:32 +02:00
|
|
|
if(checkdied($child)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "startnew: child process has failed to start\n" if($verbose);
|
2026-06-29 19:01:04 +02:00
|
|
|
return (-1, -1);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid2 = 0;
|
|
|
|
|
my $count = $timeout;
|
|
|
|
|
while($count--) {
|
2025-06-02 10:41:20 +02:00
|
|
|
$pid2 = pidfromfile($pidfile, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
if(($pid2 > 0) && pidexists($pid2)) {
|
|
|
|
|
# if $pid2 is valid, then make sure this pid is alive, as
|
2026-05-28 23:50:52 +02:00
|
|
|
# otherwise it is likely to be the _previous_ pidfile or
|
2023-04-05 17:26:20 -07:00
|
|
|
# similar!
|
|
|
|
|
last;
|
|
|
|
|
}
|
2025-07-08 13:59:32 +02:00
|
|
|
if(checkdied($child)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "startnew: child process has died, server might start up\n"
|
|
|
|
|
if($verbose);
|
2026-05-28 23:50:52 +02:00
|
|
|
# We cannot abort waiting for the server with a
|
2026-06-29 19:01:04 +02:00
|
|
|
# return (-1, -1);
|
2023-04-05 17:26:20 -07:00
|
|
|
# because the server might have forked and could still start
|
2026-05-28 23:50:52 +02:00
|
|
|
# up normally. Instead, reduce the amount of time we remain
|
2023-04-05 17:26:20 -07:00
|
|
|
# waiting.
|
|
|
|
|
$count >>= 2;
|
|
|
|
|
}
|
|
|
|
|
sleep(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Return two PIDs, the one for the child process we spawned and the one
|
|
|
|
|
# reported by the server itself (in case it forked again on its own).
|
|
|
|
|
# Both (potentially) need to be killed at the end of the test.
|
|
|
|
|
return ($child, $pid2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Return the port to use for the given protocol.
|
|
|
|
|
#
|
|
|
|
|
sub protoport {
|
|
|
|
|
my ($proto) = @_;
|
|
|
|
|
return $PORT{$proto} || "[not running]";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
2025-11-15 00:27:38 +01:00
|
|
|
# Stop a test server along with pids which are not in the %run hash yet.
|
2023-04-05 17:26:20 -07:00
|
|
|
# This also stops all servers which are relative to the given one.
|
|
|
|
|
#
|
|
|
|
|
sub stopserver {
|
|
|
|
|
my ($server, $pidlist) = @_;
|
2024-09-09 13:52:44 +02:00
|
|
|
my $ipvnum = 4;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
#
|
|
|
|
|
# kill sockfilter processes for pingpong relative server
|
|
|
|
|
#
|
|
|
|
|
if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
|
|
|
|
|
my $proto = $1;
|
|
|
|
|
my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
|
2024-09-09 13:52:44 +02:00
|
|
|
$ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
|
2023-04-27 11:04:13 -07:00
|
|
|
killsockfilters("$LOGDIR/$PIDDIR", $proto, $ipvnum, $idnum, $verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
#
|
|
|
|
|
# All servers relative to the given one must be stopped also
|
|
|
|
|
#
|
|
|
|
|
my @killservers;
|
|
|
|
|
if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
|
2026-05-16 18:47:52 +02:00
|
|
|
# given a stunnel based SSL server, also kill non-SSL underlying one
|
2023-04-05 17:26:20 -07:00
|
|
|
push @killservers, "${1}${2}";
|
|
|
|
|
}
|
|
|
|
|
elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
|
2026-05-16 18:47:52 +02:00
|
|
|
# given a non-SSL server, also kill stunnel based SSL piggybacking one
|
2023-04-05 17:26:20 -07:00
|
|
|
push @killservers, "${1}s${2}";
|
|
|
|
|
}
|
|
|
|
|
elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
|
|
|
|
|
# given a socks server, also kill ssh underlying one
|
|
|
|
|
push @killservers, "ssh${2}";
|
|
|
|
|
}
|
|
|
|
|
elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
|
|
|
|
|
# given a ssh server, also kill socks piggybacking one
|
|
|
|
|
push @killservers, "socks${2}";
|
|
|
|
|
}
|
|
|
|
|
if($server eq "http" or $server eq "https") {
|
|
|
|
|
# since the http2+3 server is a proxy that needs to know about the
|
|
|
|
|
# dynamic http port it too needs to get restarted when the http server
|
|
|
|
|
# is killed
|
|
|
|
|
push @killservers, "http/2";
|
|
|
|
|
push @killservers, "http/3";
|
|
|
|
|
}
|
|
|
|
|
push @killservers, $server;
|
|
|
|
|
#
|
|
|
|
|
# kill given pids and server relative ones clearing them in %run hash
|
|
|
|
|
#
|
|
|
|
|
foreach my $server (@killservers) {
|
|
|
|
|
if($run{$server}) {
|
|
|
|
|
# we must prepend a space since $pidlist may already contain a pid
|
|
|
|
|
$pidlist .= " $run{$server}";
|
|
|
|
|
$run{$server} = 0;
|
|
|
|
|
}
|
|
|
|
|
$runcert{$server} = 0 if($runcert{$server});
|
|
|
|
|
}
|
|
|
|
|
killpid($verbose, $pidlist);
|
|
|
|
|
#
|
|
|
|
|
# cleanup server pid files
|
|
|
|
|
#
|
|
|
|
|
my $result = 0;
|
|
|
|
|
foreach my $server (@killservers) {
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
}
|
2024-09-09 13:52:44 +02:00
|
|
|
#
|
|
|
|
|
# cleanup server lock files
|
|
|
|
|
#
|
|
|
|
|
foreach my $server (@killservers) {
|
|
|
|
|
# servers seem to produce (some of) these lock files
|
|
|
|
|
my @lockfiles = (
|
|
|
|
|
"$LOGDIR/$LOCKDIR/$server.lock",
|
|
|
|
|
"$LOGDIR/$LOCKDIR/$server-IPv$ipvnum.lock",
|
|
|
|
|
"$LOGDIR/$LOCKDIR/sws-".uc($server)."-IPv$ipvnum.lock"
|
|
|
|
|
);
|
|
|
|
|
foreach my $lockfile (@lockfiles) {
|
|
|
|
|
if(-f $lockfile) {
|
|
|
|
|
unlink($lockfile);
|
2025-07-11 16:04:24 +02:00
|
|
|
logmsg "RUN: kill $server, cleaned up $lockfile\n" if($verbose);
|
2024-09-09 13:52:44 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Return flags to let curl use an external HTTP proxy
|
|
|
|
|
#
|
|
|
|
|
sub getexternalproxyflags {
|
|
|
|
|
return " --proxy $proxy_address ";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the server that runs on $ip, $port is our server. This also
|
|
|
|
|
# implies that we can speak with it, as there might be occasions when the
|
2025-11-15 00:27:38 +01:00
|
|
|
# server runs fine but we cannot talk to it ("Failed to connect to ::1: Cannot
|
2023-04-05 17:26:20 -07:00
|
|
|
# assign requested address")
|
|
|
|
|
#
|
|
|
|
|
sub verifyhttp {
|
2024-09-26 14:55:56 +02:00
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port_or_path, $do_http3) = @_;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
2026-06-11 17:22:30 +02:00
|
|
|
my $bonus = "";
|
2023-04-05 17:26:20 -07:00
|
|
|
# $port_or_path contains a path for Unix sockets, sws ignores the port
|
|
|
|
|
my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
|
2024-09-26 14:55:56 +02:00
|
|
|
my $infix = ($do_http3) ? "_h3" : "";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my $verifyout = "$LOGDIR/".
|
2024-09-26 14:55:56 +02:00
|
|
|
servername_canon($proto, $ipvnum, $idnum) .$infix .'_verify.out';
|
2023-04-05 17:26:20 -07:00
|
|
|
unlink($verifyout) if(-f $verifyout);
|
|
|
|
|
|
|
|
|
|
my $verifylog = "$LOGDIR/".
|
2024-09-26 14:55:56 +02:00
|
|
|
servername_canon($proto, $ipvnum, $idnum) .$infix .'_verify.log';
|
2023-04-05 17:26:20 -07:00
|
|
|
unlink($verifylog) if(-f $verifylog);
|
|
|
|
|
|
|
|
|
|
if($proto eq "gopher") {
|
|
|
|
|
# gopher is funny
|
2026-06-11 17:22:30 +02:00
|
|
|
$bonus = "1/";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $flags = "--max-time $server_response_maxtime ";
|
|
|
|
|
$flags .= "--output $verifyout ";
|
|
|
|
|
$flags .= "--silent ";
|
|
|
|
|
$flags .= "--verbose ";
|
|
|
|
|
$flags .= "--globoff ";
|
|
|
|
|
$flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
|
|
|
|
|
$flags .= "--insecure " if($proto eq 'https');
|
|
|
|
|
if($proxy_address) {
|
|
|
|
|
$flags .= getexternalproxyflags();
|
|
|
|
|
}
|
2024-09-26 14:55:56 +02:00
|
|
|
$flags .= "--http3-only " if($do_http3);
|
2023-04-05 17:26:20 -07:00
|
|
|
$flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
|
|
|
|
|
|
2025-03-28 22:21:06 +01:00
|
|
|
my $cmd = exerunner() . "$VCURL $flags 2>$verifylog";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# verify if our/any server is running on this port
|
|
|
|
|
logmsg "RUN: $cmd\n" if($verbose);
|
|
|
|
|
my $res = runclient($cmd);
|
|
|
|
|
|
|
|
|
|
$res >>= 8; # rotate the result
|
|
|
|
|
if($res & 128) {
|
|
|
|
|
logmsg "RUN: curl command died with a coredump\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($res && $verbose) {
|
|
|
|
|
logmsg "RUN: curl command returned $res\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
if(open(my $file, "<", $verifylog)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
while(my $string = <$file>) {
|
|
|
|
|
logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
|
|
|
|
|
}
|
|
|
|
|
close($file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $data;
|
2026-03-19 01:15:43 +01:00
|
|
|
if(open(my $file, "<", $verifyout)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
while(my $string = <$file>) {
|
|
|
|
|
$data = $string;
|
|
|
|
|
last; # only want first line
|
|
|
|
|
}
|
|
|
|
|
close($file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = 0;
|
|
|
|
|
if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
|
|
|
|
|
$pid = 0+$1;
|
|
|
|
|
}
|
|
|
|
|
elsif($res == 6) {
|
2025-11-15 00:27:38 +01:00
|
|
|
# curl: (6) Could not resolve hostname '::1'
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
elsif($data || ($res && ($res != 7))) {
|
|
|
|
|
logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the server that runs on $ip, $port is our server. This also
|
|
|
|
|
# implies that we can speak with it, as there might be occasions when the
|
2025-11-15 00:27:38 +01:00
|
|
|
# server runs fine but we cannot talk to it ("Failed to connect to ::1: Cannot
|
2023-04-05 17:26:20 -07:00
|
|
|
# assign requested address")
|
|
|
|
|
#
|
|
|
|
|
sub verifyftp {
|
|
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
2026-06-11 17:22:30 +02:00
|
|
|
my $time = time();
|
|
|
|
|
my $extra = "";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my $verifylog = "$LOGDIR/".
|
|
|
|
|
servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
|
|
|
|
|
unlink($verifylog) if(-f $verifylog);
|
|
|
|
|
|
|
|
|
|
if($proto eq "ftps") {
|
|
|
|
|
$extra .= "--insecure --ftp-ssl-control ";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $flags = "--max-time $server_response_maxtime ";
|
|
|
|
|
$flags .= "--silent ";
|
|
|
|
|
$flags .= "--verbose ";
|
|
|
|
|
$flags .= "--globoff ";
|
|
|
|
|
$flags .= $extra;
|
|
|
|
|
if($proxy_address) {
|
|
|
|
|
$flags .= getexternalproxyflags();
|
|
|
|
|
}
|
|
|
|
|
$flags .= "\"$proto://$ip:$port/verifiedserver\"";
|
|
|
|
|
|
2025-03-28 22:21:06 +01:00
|
|
|
my $cmd = exerunner() . "$VCURL $flags 2>$verifylog";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# check if this is our server running on this port:
|
|
|
|
|
logmsg "RUN: $cmd\n" if($verbose);
|
|
|
|
|
my @data = runclientoutput($cmd);
|
|
|
|
|
|
|
|
|
|
my $res = $? >> 8; # rotate the result
|
|
|
|
|
if($res & 128) {
|
|
|
|
|
logmsg "RUN: curl command died with a coredump\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = 0;
|
|
|
|
|
foreach my $line (@data) {
|
|
|
|
|
if($line =~ /WE ROOLZ: (\d+)/) {
|
|
|
|
|
# this is our test server with a known pid!
|
|
|
|
|
$pid = 0+$1;
|
|
|
|
|
last;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($pid <= 0 && @data && $data[0]) {
|
|
|
|
|
# this is not a known server
|
|
|
|
|
logmsg "RUN: Unknown server on our $server port: $port\n";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
# we can/should use the time it took to verify the FTP server as a measure
|
|
|
|
|
# on how fast/slow this host/FTP is.
|
2026-02-01 01:56:43 +01:00
|
|
|
my $took = int(0.5 + time() - $time);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
if($verbose) {
|
|
|
|
|
logmsg "RUN: Verifying our test $server server took $took seconds\n";
|
|
|
|
|
}
|
2026-02-01 01:56:43 +01:00
|
|
|
$ftpchecktime = ($took >= 1) ? $took : 1; # make sure it never is below 1
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the server that runs on $ip, $port is our server. This also
|
|
|
|
|
# implies that we can speak with it, as there might be occasions when the
|
2025-11-15 00:27:38 +01:00
|
|
|
# server runs fine but we cannot talk to it ("Failed to connect to ::1: Cannot
|
2023-04-05 17:26:20 -07:00
|
|
|
# assign requested address")
|
|
|
|
|
#
|
|
|
|
|
sub verifyrtsp {
|
|
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $verifyout = "$LOGDIR/".
|
|
|
|
|
servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
|
|
|
|
|
unlink($verifyout) if(-f $verifyout);
|
|
|
|
|
|
|
|
|
|
my $verifylog = "$LOGDIR/".
|
|
|
|
|
servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
|
|
|
|
|
unlink($verifylog) if(-f $verifylog);
|
|
|
|
|
|
|
|
|
|
my $flags = "--max-time $server_response_maxtime ";
|
|
|
|
|
$flags .= "--output $verifyout ";
|
|
|
|
|
$flags .= "--silent ";
|
|
|
|
|
$flags .= "--verbose ";
|
|
|
|
|
$flags .= "--globoff ";
|
|
|
|
|
if($proxy_address) {
|
|
|
|
|
$flags .= getexternalproxyflags();
|
|
|
|
|
}
|
|
|
|
|
# currently verification is done using http
|
|
|
|
|
$flags .= "\"http://$ip:$port/verifiedserver\"";
|
|
|
|
|
|
2025-03-28 22:21:06 +01:00
|
|
|
my $cmd = exerunner() . "$VCURL $flags 2>$verifylog";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# verify if our/any server is running on this port
|
|
|
|
|
logmsg "RUN: $cmd\n" if($verbose);
|
|
|
|
|
my $res = runclient($cmd);
|
|
|
|
|
|
|
|
|
|
$res >>= 8; # rotate the result
|
|
|
|
|
if($res & 128) {
|
|
|
|
|
logmsg "RUN: curl command died with a coredump\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($res && $verbose) {
|
|
|
|
|
logmsg "RUN: curl command returned $res\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
if(open(my $file, "<", $verifylog)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
while(my $string = <$file>) {
|
|
|
|
|
logmsg "RUN: $string" if($string !~ /^[ \t]*$/);
|
|
|
|
|
}
|
|
|
|
|
close($file);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $data;
|
2026-03-19 01:15:43 +01:00
|
|
|
if(open(my $file, "<", $verifyout)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
while(my $string = <$file>) {
|
|
|
|
|
$data = $string;
|
|
|
|
|
last; # only want first line
|
|
|
|
|
}
|
|
|
|
|
close($file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = 0;
|
|
|
|
|
if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
|
|
|
|
|
$pid = 0+$1;
|
|
|
|
|
}
|
|
|
|
|
elsif($res == 6) {
|
2025-11-15 00:27:38 +01:00
|
|
|
# curl: (6) Could not resolve hostname '::1'
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
elsif($data || ($res != 7)) {
|
|
|
|
|
logmsg "RUN: Unknown server on our $server port: $port\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the ssh server has written out its pidfile, recovering
|
|
|
|
|
# the pid from the file and returning it if a process with that pid is
|
|
|
|
|
# actually alive, or a negative value if the process is dead.
|
|
|
|
|
#
|
|
|
|
|
sub verifyssh {
|
|
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
2023-04-27 11:04:13 -07:00
|
|
|
my $pidfile = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
|
|
|
|
|
$idnum);
|
2023-04-05 17:26:20 -07:00
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid < 0) {
|
|
|
|
|
logmsg "RUN: SSH server has died after starting up\n";
|
|
|
|
|
}
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that we can connect to the sftp server, properly authenticate
|
|
|
|
|
# with generated config and key files and run a simple remote pwd.
|
|
|
|
|
#
|
|
|
|
|
sub verifysftp {
|
|
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
my $verified = 0;
|
2025-11-15 00:27:38 +01:00
|
|
|
# Find out sftp client canonical filename
|
2023-04-05 17:26:20 -07:00
|
|
|
my $sftp = find_sftp();
|
|
|
|
|
if(!$sftp) {
|
|
|
|
|
logmsg "RUN: SFTP server cannot find $sftpexe\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2025-11-15 00:27:38 +01:00
|
|
|
# Find out ssh client canonical filename
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ssh = find_ssh();
|
|
|
|
|
if(!$ssh) {
|
|
|
|
|
logmsg "RUN: SFTP server cannot find $sshexe\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
# Connect to sftp server, authenticate and run a remote pwd
|
|
|
|
|
# command using our generated configuration and key files
|
2023-04-27 11:04:13 -07:00
|
|
|
my $cmd = "\"$sftp\" -b $LOGDIR/$PIDDIR/$sftpcmds -F $LOGDIR/$PIDDIR/$sftpconfig -S \"$ssh\" $ip > $sftplog 2>&1";
|
2023-04-05 17:26:20 -07:00
|
|
|
my $res = runclient($cmd);
|
|
|
|
|
# Search for pwd command response in log file
|
2026-03-19 01:15:43 +01:00
|
|
|
if(open(my $sftplogfile, "<", $sftplog)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
while(<$sftplogfile>) {
|
|
|
|
|
if(/^Remote working directory: /) {
|
|
|
|
|
$verified = 1;
|
|
|
|
|
last;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
close($sftplogfile);
|
|
|
|
|
}
|
|
|
|
|
return $verified;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-26 15:00:27 +02:00
|
|
|
#######################################################################
|
2025-04-09 15:22:28 +02:00
|
|
|
# For verifying mqtt and socks
|
2024-09-26 15:00:27 +02:00
|
|
|
#
|
2025-04-09 15:22:28 +02:00
|
|
|
sub verifypid {
|
2024-09-26 15:00:27 +02:00
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
|
|
|
|
my $pidfile = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
|
|
|
|
|
$idnum);
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid < 0) {
|
2025-04-09 15:22:28 +02:00
|
|
|
logmsg "RUN: $proto server has died\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the server that runs on $ip, $port is our server. This also
|
|
|
|
|
# implies that we can speak with it, as there might be occasions when the
|
2025-11-15 00:27:38 +01:00
|
|
|
# server runs fine but we cannot talk to it ("Failed to connect to ::1: Cannot
|
2023-04-05 17:26:20 -07:00
|
|
|
# assign requested address")
|
|
|
|
|
#
|
|
|
|
|
sub verifysmb {
|
|
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
2026-06-11 17:22:30 +02:00
|
|
|
my $time = time();
|
|
|
|
|
my $extra = "";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my $verifylog = "$LOGDIR/".
|
|
|
|
|
servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
|
|
|
|
|
unlink($verifylog) if(-f $verifylog);
|
|
|
|
|
|
|
|
|
|
my $flags = "--max-time $server_response_maxtime ";
|
|
|
|
|
$flags .= "--silent ";
|
|
|
|
|
$flags .= "--verbose ";
|
|
|
|
|
$flags .= "--globoff ";
|
|
|
|
|
$flags .= "-u 'curltest:curltest' ";
|
|
|
|
|
$flags .= $extra;
|
|
|
|
|
$flags .= "\"$proto://$ip:$port/SERVER/verifiedserver\"";
|
|
|
|
|
|
2025-03-28 22:21:06 +01:00
|
|
|
my $cmd = exerunner() . "$VCURL $flags 2>$verifylog";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# check if this is our server running on this port:
|
|
|
|
|
logmsg "RUN: $cmd\n" if($verbose);
|
|
|
|
|
my @data = runclientoutput($cmd);
|
|
|
|
|
|
|
|
|
|
my $res = $? >> 8; # rotate the result
|
|
|
|
|
if($res & 128) {
|
|
|
|
|
logmsg "RUN: curl command died with a coredump\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = 0;
|
|
|
|
|
foreach my $line (@data) {
|
|
|
|
|
if($line =~ /WE ROOLZ: (\d+)/) {
|
|
|
|
|
# this is our test server with a known pid!
|
|
|
|
|
$pid = 0+$1;
|
|
|
|
|
last;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($pid <= 0 && @data && $data[0]) {
|
|
|
|
|
# this is not a known server
|
|
|
|
|
logmsg "RUN: Unknown server on our $server port: $port\n";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
# we can/should use the time it took to verify the server as a measure
|
|
|
|
|
# on how fast/slow this host is.
|
|
|
|
|
my $took = int(0.5+time()-$time);
|
|
|
|
|
|
|
|
|
|
if($verbose) {
|
|
|
|
|
logmsg "RUN: Verifying our test $server server took $took seconds\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the server that runs on $ip, $port is our server. This also
|
|
|
|
|
# implies that we can speak with it, as there might be occasions when the
|
2025-11-15 00:27:38 +01:00
|
|
|
# server runs fine but we cannot talk to it ("Failed to connect to ::1: Cannot
|
2023-04-05 17:26:20 -07:00
|
|
|
# assign requested address")
|
|
|
|
|
#
|
|
|
|
|
sub verifytelnet {
|
|
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
2026-06-11 17:22:30 +02:00
|
|
|
my $time = time();
|
|
|
|
|
my $extra = "";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my $verifylog = "$LOGDIR/".
|
|
|
|
|
servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
|
|
|
|
|
unlink($verifylog) if(-f $verifylog);
|
|
|
|
|
|
|
|
|
|
my $flags = "--max-time $server_response_maxtime ";
|
|
|
|
|
$flags .= "--silent ";
|
|
|
|
|
$flags .= "--verbose ";
|
|
|
|
|
$flags .= "--globoff ";
|
|
|
|
|
$flags .= "--upload-file - ";
|
|
|
|
|
$flags .= $extra;
|
|
|
|
|
$flags .= "\"$proto://$ip:$port\"";
|
|
|
|
|
|
2025-03-28 22:21:06 +01:00
|
|
|
my $cmd = "echo 'verifiedserver' | " .
|
|
|
|
|
exerunner() . "$VCURL $flags 2>$verifylog";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
# check if this is our server running on this port:
|
|
|
|
|
logmsg "RUN: $cmd\n" if($verbose);
|
|
|
|
|
my @data = runclientoutput($cmd);
|
|
|
|
|
|
|
|
|
|
my $res = $? >> 8; # rotate the result
|
|
|
|
|
if($res & 128) {
|
|
|
|
|
logmsg "RUN: curl command died with a coredump\n";
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = 0;
|
|
|
|
|
foreach my $line (@data) {
|
|
|
|
|
if($line =~ /WE ROOLZ: (\d+)/) {
|
|
|
|
|
# this is our test server with a known pid!
|
|
|
|
|
$pid = 0+$1;
|
|
|
|
|
last;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($pid <= 0 && @data && $data[0]) {
|
|
|
|
|
# this is not a known server
|
|
|
|
|
logmsg "RUN: Unknown server on our $server port: $port\n";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
# we can/should use the time it took to verify the server as a measure
|
|
|
|
|
# on how fast/slow this host is.
|
|
|
|
|
my $took = int(0.5+time()-$time);
|
|
|
|
|
|
|
|
|
|
if($verbose) {
|
|
|
|
|
logmsg "RUN: Verifying our test $server server took $took seconds\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $pid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Verify that the server that runs on $ip, $port is our server.
|
|
|
|
|
# Retry over several seconds before giving up. The ssh server in
|
|
|
|
|
# particular can take a long time to start if it needs to generate
|
|
|
|
|
# keys on a slow or loaded host.
|
|
|
|
|
#
|
2026-07-04 12:19:47 +02:00
|
|
|
# For convenience, test harness uses 'https' literal
|
2023-04-05 17:26:20 -07:00
|
|
|
# as values for 'proto' variable in order to differentiate different
|
2026-07-04 12:19:47 +02:00
|
|
|
# servers. 'https' literal is used for stunnel based https test servers.
|
2023-04-05 17:26:20 -07:00
|
|
|
#
|
|
|
|
|
|
|
|
|
|
my %protofunc = ('http' => \&verifyhttp,
|
|
|
|
|
'https' => \&verifyhttp,
|
2025-05-30 18:37:47 +03:00
|
|
|
'https-mtls' => \&verifypid,
|
2023-04-05 17:26:20 -07:00
|
|
|
'rtsp' => \&verifyrtsp,
|
|
|
|
|
'ftp' => \&verifyftp,
|
|
|
|
|
'pop3' => \&verifyftp,
|
|
|
|
|
'imap' => \&verifyftp,
|
|
|
|
|
'smtp' => \&verifyftp,
|
|
|
|
|
'ftps' => \&verifyftp,
|
|
|
|
|
'pop3s' => \&verifyftp,
|
|
|
|
|
'imaps' => \&verifyftp,
|
2025-04-09 15:22:28 +02:00
|
|
|
'mqtt' => \&verifypid,
|
2026-01-17 17:23:44 +01:00
|
|
|
'mqtts' => \&verifypid,
|
2023-04-05 17:26:20 -07:00
|
|
|
'smtps' => \&verifyftp,
|
|
|
|
|
'tftp' => \&verifyftp,
|
|
|
|
|
'ssh' => \&verifyssh,
|
2025-04-09 09:47:43 +02:00
|
|
|
'dns' => \&verifypid,
|
2025-04-09 15:22:28 +02:00
|
|
|
'socks' => \&verifypid,
|
|
|
|
|
'socks5unix' => \&verifypid,
|
2023-04-05 17:26:20 -07:00
|
|
|
'gopher' => \&verifyhttp,
|
|
|
|
|
'dict' => \&verifyftp,
|
|
|
|
|
'smb' => \&verifysmb,
|
|
|
|
|
'telnet' => \&verifytelnet);
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Single shot server responsiveness test. This should only be used
|
|
|
|
|
# to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsiveserver {
|
2024-09-26 14:55:56 +02:00
|
|
|
my ($proto, $ipvnum, $idnum, $ip, $port, $do_http3) = @_;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $prev_verbose = $verbose;
|
|
|
|
|
|
|
|
|
|
$verbose = 0;
|
|
|
|
|
my $fun = $protofunc{$proto};
|
2024-09-26 14:55:56 +02:00
|
|
|
my $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port, $do_http3);
|
2023-04-05 17:26:20 -07:00
|
|
|
$verbose = $prev_verbose;
|
|
|
|
|
|
|
|
|
|
if($pid > 0) {
|
|
|
|
|
return 1; # responsive
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
logmsg " server precheck FAILED (unresponsive $srvrname server)\n";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the http server
|
|
|
|
|
#
|
|
|
|
|
sub runhttpserver {
|
|
|
|
|
my ($proto, $verb, $alt, $port_or_path) = @_;
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
2025-02-06 16:33:31 +01:00
|
|
|
my $exe = "$perl " . shell_quote("$srcdir/http-server.pl");
|
2023-04-05 17:26:20 -07:00
|
|
|
my $verbose_flag = "--verbose ";
|
|
|
|
|
my $keepalive_secs = 30; # forwarded to sws, was 5 by default which
|
|
|
|
|
# led to pukes in CI jobs
|
|
|
|
|
|
|
|
|
|
if($alt eq "ipv6") {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
elsif($alt eq "proxy") {
|
|
|
|
|
# basically the same, but another ID
|
|
|
|
|
$idnum = 2;
|
|
|
|
|
}
|
|
|
|
|
elsif($alt eq "unix") {
|
|
|
|
|
# IP (protocol) is mutually exclusive with Unix sockets
|
|
|
|
|
$ipvnum = "unix";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--gopher " if($proto eq "gopher");
|
|
|
|
|
$flags .= "--connect $HOSTIP " if($alt eq "proxy");
|
|
|
|
|
$flags .= "--keepalive $keepalive_secs ";
|
|
|
|
|
$flags .= $verbose_flag if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--portfile $portfile ";
|
2023-06-14 15:11:40 -07:00
|
|
|
$flags .= "--config $LOGDIR/$SERVERCMD ";
|
2023-04-05 17:26:20 -07:00
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
if($ipvnum eq "unix") {
|
|
|
|
|
$flags .= "--unix-socket '$port_or_path' ";
|
|
|
|
|
} else {
|
|
|
|
|
$flags .= "--ipv$ipvnum --port 0 ";
|
|
|
|
|
}
|
|
|
|
|
$flags .= "--srcdir \"$srcdir\"";
|
|
|
|
|
|
|
|
|
|
my $cmd = "$exe $flags";
|
2025-06-02 10:41:20 +02:00
|
|
|
|
|
|
|
|
unlink($portfile); # need to see a new one
|
2023-04-05 17:26:20 -07:00
|
|
|
my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
|
|
|
|
|
|
|
|
|
if($httppid <= 0 || !pidexists($httppid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-04-05 17:26:20 -07:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2023-04-08 17:13:16 -07:00
|
|
|
return (1, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# where is it?
|
|
|
|
|
my $port = 0;
|
2025-06-02 10:41:20 +02:00
|
|
|
$port = $port_or_path = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
2025-05-31 13:31:03 +02:00
|
|
|
if(!$port) {
|
2025-06-02 10:41:20 +02:00
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2025-05-31 13:31:03 +02:00
|
|
|
return (1, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server is on PID $httppid port $port_or_path\n";
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0, $httppid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the http2 server
|
|
|
|
|
#
|
|
|
|
|
sub runhttp2server {
|
|
|
|
|
my ($verb) = @_;
|
2026-06-11 17:22:30 +02:00
|
|
|
my $proto = "http/2";
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 0;
|
2025-02-06 16:33:31 +01:00
|
|
|
my $exe = "$perl " . shell_quote("$srcdir/http2-server.pl");
|
2023-04-05 17:26:20 -07:00
|
|
|
my $verbose_flag = "--verbose ";
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--nghttpx \"$ENV{'NGHTTPX'}\" ";
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--connect $HOSTIP:" . protoport("http") . " ";
|
|
|
|
|
$flags .= $verbose_flag if($debugprotocol);
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $port2 = getfreeport($ipvnum);
|
|
|
|
|
my $aflags = "--port $port --port2 $port2 $flags";
|
|
|
|
|
my $cmd = "$exe $aflags";
|
|
|
|
|
my ($http2pid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($http2pid <= 0 || !pidexists($http2pid)) {
|
|
|
|
|
# it is NOT alive
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$http2pid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 0;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server PID $http2pid ".
|
|
|
|
|
"http-port $port https-port $port2 ".
|
|
|
|
|
"backend $HOSTIP:" . protoport("http") . "\n";
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$http2pid, $http2pid, $pid2, $port, $port2);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the http3 server
|
|
|
|
|
#
|
|
|
|
|
sub runhttp3server {
|
|
|
|
|
my ($verb, $cert) = @_;
|
2026-06-11 17:22:30 +02:00
|
|
|
my $proto = "http/3";
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 0;
|
2025-02-06 16:33:31 +01:00
|
|
|
my $exe = "$perl " . shell_quote("$srcdir/http3-server.pl");
|
2023-04-05 17:26:20 -07:00
|
|
|
my $verbose_flag = "--verbose ";
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--nghttpx \"$ENV{'NGHTTPX'}\" ";
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--connect $HOSTIP:" . protoport("http") . " ";
|
|
|
|
|
$flags .= "--cert \"$cert\" " if($cert);
|
|
|
|
|
$flags .= $verbose_flag if($debugprotocol);
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $aflags = "--port $port $flags";
|
|
|
|
|
my $cmd = "$exe $aflags";
|
|
|
|
|
my ($http3pid, $pid3) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($http3pid <= 0 || !pidexists($http3pid)) {
|
|
|
|
|
# it is NOT alive
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid3);
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$http3pid = $pid3 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 0;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server PID $http3pid port $port\n";
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$http3pid, $http3pid, $pid3, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the https stunnel based server
|
|
|
|
|
#
|
|
|
|
|
sub runhttpsserver {
|
|
|
|
|
my ($verb, $proto, $proxy, $certfile) = @_;
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($proxy eq "proxy") {
|
|
|
|
|
# the https-proxy runs as https2
|
|
|
|
|
$idnum = 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!$stunnel) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (4, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
2025-03-06 11:01:49 +01:00
|
|
|
$certfile = 'certs/test-localhost.pem' unless($certfile);
|
2023-04-05 17:26:20 -07:00
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--ipv$ipvnum --proto $proto ";
|
2025-03-06 11:01:49 +01:00
|
|
|
$flags .= "--certfile \"$certfile\" " if($certfile ne 'certs/test-localhost.pem');
|
2023-04-05 17:26:20 -07:00
|
|
|
$flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
|
2025-04-03 21:51:32 +03:00
|
|
|
if($proto eq "https-mtls") {
|
|
|
|
|
$flags .= "--mtls ";
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
if($proto eq "gophers") {
|
|
|
|
|
$flags .= "--connect " . protoport("gopher");
|
|
|
|
|
}
|
2026-01-17 17:23:44 +01:00
|
|
|
elsif($proto eq "mqtts") {
|
|
|
|
|
$flags .= "--connect " . protoport("mqtt");
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
elsif(!$proxy) {
|
|
|
|
|
$flags .= "--connect " . protoport("http");
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
# for HTTPS-proxy we connect to the HTTP proxy
|
|
|
|
|
$flags .= "--connect " . protoport("httpproxy");
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $options = "$flags --accept $port";
|
2025-02-06 16:33:31 +01:00
|
|
|
my $cmd = "$perl " . shell_quote("$srcdir/secureserver.pl") . " " . $options;
|
2023-05-29 20:25:09 +02:00
|
|
|
my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-17 16:57:17 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($httpspid <= 0 || !pidexists($httpspid)) {
|
|
|
|
|
# it is NOT alive
|
2026-05-14 20:37:42 +02:00
|
|
|
# do not call stopserver since that also kills the dependent
|
2023-05-29 20:25:09 +02:00
|
|
|
# server that has already been started properly
|
|
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$httpspid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$doesntrun{$pidfile} = 0;
|
|
|
|
|
# we have a server!
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server is PID $httpspid port $port\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-05-29 20:25:09 +02:00
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
$runcert{$server} = $certfile;
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$httpspid, $httpspid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the pingpong server (FTP, POP3, IMAP, SMTP)
|
|
|
|
|
#
|
|
|
|
|
sub runpingpongserver {
|
|
|
|
|
my ($proto, $id, $verb, $ipv6) = @_;
|
2023-04-08 15:27:39 -07:00
|
|
|
|
|
|
|
|
# Check the requested server
|
|
|
|
|
if($proto !~ /^(?:ftp|imap|pop3|smtp)$/) {
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg "Unsupported protocol $proto!!\n";
|
2023-04-08 17:13:16 -07:00
|
|
|
return (4, 0, 0);
|
2023-04-08 15:27:39 -07:00
|
|
|
}
|
|
|
|
|
|
2026-03-19 01:15:43 +01:00
|
|
|
my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? $HOST6IP : $HOSTIP;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--portfile \"$portfile\" ";
|
|
|
|
|
$flags .= "--srcdir \"$srcdir\" --proto $proto ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--ipv$ipvnum --port 0 --addr \"$ip\"";
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
unlink($portfile); # need to see a new one
|
2025-02-06 16:33:31 +01:00
|
|
|
my $cmd = "$perl " . shell_quote("$srcdir/ftpserver.pl") . " " . $flags;
|
2023-04-05 17:26:20 -07:00
|
|
|
my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
|
|
|
|
|
|
|
|
|
if($ftppid <= 0 || !pidexists($ftppid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-04-05 17:26:20 -07:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2023-04-08 17:13:16 -07:00
|
|
|
return (1, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# where is it?
|
2025-06-02 10:41:20 +02:00
|
|
|
my $port = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
|
|
|
|
if(!$port) {
|
|
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
logmsg "PINGPONG runs on port $port ($portfile)\n" if($verb);
|
|
|
|
|
|
|
|
|
|
logmsg "RUN: $srvrname server is PID $ftppid port $port\n" if($verb);
|
|
|
|
|
|
|
|
|
|
# Assign the correct port variable!
|
2023-04-08 15:27:39 -07:00
|
|
|
$PORT{$proto . ($ipvnum == 6? '6': '')} = $port;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0, $pid2, $ftppid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the ftps/imaps/pop3s/smtps server (or rather, tunnel)
|
|
|
|
|
#
|
|
|
|
|
sub runsecureserver {
|
|
|
|
|
my ($verb, $ipv6, $certfile, $proto, $clearport) = @_;
|
2026-03-19 01:15:43 +01:00
|
|
|
my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? $HOST6IP : $HOSTIP;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if(!$stunnel) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (4, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
2025-03-06 11:01:49 +01:00
|
|
|
$certfile = 'certs/test-localhost.pem' unless($certfile);
|
2023-04-05 17:26:20 -07:00
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--ipv$ipvnum --proto $proto ";
|
2025-03-06 11:01:49 +01:00
|
|
|
$flags .= "--certfile \"$certfile\" " if($certfile ne 'certs/test-localhost.pem');
|
2023-04-05 17:26:20 -07:00
|
|
|
$flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
|
|
|
|
|
$flags .= "--connect $clearport";
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $options = "$flags --accept $port";
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2025-02-06 16:33:31 +01:00
|
|
|
my $cmd = "$perl " . shell_quote("$srcdir/secureserver.pl") . " " . $options;
|
2023-05-29 20:25:09 +02:00
|
|
|
my ($protospid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($protospid <= 0 || !pidexists($protospid)) {
|
|
|
|
|
# it is NOT alive
|
2026-05-14 20:37:42 +02:00
|
|
|
# do not call stopserver since that also kills the dependent
|
2023-05-29 20:25:09 +02:00
|
|
|
# server that has already been started properly
|
|
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$protospid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 0;
|
|
|
|
|
$runcert{$server} = $certfile;
|
|
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server is PID $protospid port $port\n";
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$protospid, $protospid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the tftp server
|
|
|
|
|
#
|
|
|
|
|
sub runtftpserver {
|
|
|
|
|
my ($id, $verb, $ipv6) = @_;
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $proto = 'tftp';
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
if($ipv6) {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" ";
|
|
|
|
|
$flags .= "--portfile \"$portfile\" ";
|
|
|
|
|
$flags .= "--logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--ipv$ipvnum --port 0 --srcdir \"$srcdir\"";
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
unlink($portfile); # need to see a new one
|
2025-02-06 16:33:31 +01:00
|
|
|
my $cmd = "$perl " . shell_quote("$srcdir/tftpserver.pl") . " " . $flags;
|
2023-04-05 17:26:20 -07:00
|
|
|
my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
|
|
|
|
|
|
|
|
|
if($tftppid <= 0 || !pidexists($tftppid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-04-05 17:26:20 -07:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2023-04-08 17:13:16 -07:00
|
|
|
return (1, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
my $port = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
|
|
|
|
if(!$port) {
|
|
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server on PID $tftppid port $port\n";
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0, $pid2, $tftppid, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2025-04-09 09:47:43 +02:00
|
|
|
#######################################################################
|
|
|
|
|
# start the dns server
|
|
|
|
|
#
|
|
|
|
|
sub rundnsserver {
|
|
|
|
|
my ($id, $verb, $ipv6) = @_;
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $proto = 'dns';
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
if($ipv6) {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2025-04-09 09:47:43 +02:00
|
|
|
return (2, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2025-04-09 09:47:43 +02:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
2026-06-11 17:22:30 +02:00
|
|
|
my $cmd = server_exe('dnsd');
|
2025-04-09 09:47:43 +02:00
|
|
|
$cmd .= " --port 0";
|
|
|
|
|
$cmd .= " --verbose" if($debugprotocol);
|
|
|
|
|
$cmd .= " --pidfile \"$pidfile\"";
|
|
|
|
|
$cmd .= " --portfile \"$portfile\"";
|
|
|
|
|
$cmd .= " --logfile \"$logfile\"";
|
|
|
|
|
$cmd .= " --logdir \"$LOGDIR\"";
|
|
|
|
|
$cmd .= " --id $idnum" if($idnum > 1);
|
|
|
|
|
$cmd .= " --ipv$ipvnum";
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
unlink($portfile); # need to see a new one
|
2025-04-09 09:47:43 +02:00
|
|
|
# start DNS server on a random port
|
|
|
|
|
my ($dnspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
|
|
|
|
|
|
|
|
|
if($dnspid <= 0 || !pidexists($dnspid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-04-09 09:47:43 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
my $port = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
|
|
|
|
if(!$port) {
|
|
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
2025-04-09 09:47:43 +02:00
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server on PID $dnspid port $port\n";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (0, $pid2, $dnspid, $port);
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the rtsp server
|
|
|
|
|
#
|
|
|
|
|
sub runrtspserver {
|
|
|
|
|
my ($verb, $ipv6) = @_;
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $proto = 'rtsp';
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($ipv6) {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" ";
|
|
|
|
|
$flags .= "--portfile \"$portfile\" ";
|
|
|
|
|
$flags .= "--logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--ipv$ipvnum --port 0 --srcdir \"$srcdir\"";
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
unlink($portfile); # need to see a new one
|
2025-02-06 16:33:31 +01:00
|
|
|
my $cmd = "$perl " . shell_quote("$srcdir/rtspserver.pl") . " " . $flags;
|
2023-04-05 17:26:20 -07:00
|
|
|
my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
|
|
|
|
|
|
|
|
|
if($rtsppid <= 0 || !pidexists($rtsppid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-04-05 17:26:20 -07:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2023-04-08 17:13:16 -07:00
|
|
|
return (1, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
my $port = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
|
|
|
|
if(!$port) {
|
|
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server PID $rtsppid port $port\n";
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0, $rtsppid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2026-04-02 01:05:54 +02:00
|
|
|
#***************************************************************************
|
|
|
|
|
# Return key algorithm string
|
|
|
|
|
#
|
|
|
|
|
sub sshkeyalgostr {
|
|
|
|
|
my ($algo) = @_;
|
|
|
|
|
my %algomap = (
|
|
|
|
|
ecdsa => 'ecdsa-sha2-nistp256',
|
|
|
|
|
);
|
|
|
|
|
return exists $algomap{$algo} ? $algomap{$algo} : 'ssh-' . $algo;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
#######################################################################
|
|
|
|
|
# Start the ssh (scp/sftp) server
|
|
|
|
|
#
|
|
|
|
|
sub runsshserver {
|
|
|
|
|
my ($id, $verb, $ipv6) = @_;
|
2026-06-11 17:22:30 +02:00
|
|
|
my $ip = $HOSTIP;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $proto = 'ssh';
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
if(!$USER) {
|
2025-11-15 00:27:38 +01:00
|
|
|
logmsg "Cannot start ssh server due to lack of username\n";
|
2023-04-08 17:13:16 -07:00
|
|
|
return (4, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $sshd = find_sshd();
|
|
|
|
|
if($sshd) {
|
2026-06-29 19:01:04 +02:00
|
|
|
($sshdid, $sshdvernum, $sshdverstr, $sshderror) = sshversioninfo($sshd);
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg $sshderror if($sshderror);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose " if($verb);
|
|
|
|
|
$flags .= "--debugprotocol " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" ";
|
|
|
|
|
$flags .= "--logdir \"$LOGDIR\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--ipv$ipvnum --addr \"$ip\" ";
|
|
|
|
|
$flags .= "--user \"$USER\"";
|
2026-04-02 01:05:54 +02:00
|
|
|
if(defined $feature{"sshkeyalgo"}) {
|
|
|
|
|
$flags .= ' --keyalgo ' . $feature{"sshkeyalgo"};
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my @tports;
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
push @tports, $port;
|
|
|
|
|
|
|
|
|
|
my $options = "$flags --sshport $port";
|
|
|
|
|
|
2025-02-06 16:33:31 +01:00
|
|
|
my $cmd = "$perl " . shell_quote("$srcdir/sshserver.pl") . " " . $options;
|
2023-05-29 20:25:09 +02:00
|
|
|
my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
|
|
|
|
|
|
|
|
|
|
# on loaded systems sshserver start up can take longer than the
|
|
|
|
|
# timeout passed to startnew, when this happens startnew completes
|
|
|
|
|
# without being able to read the pidfile and consequently returns a
|
|
|
|
|
# zero pid2 above.
|
|
|
|
|
if($sshpid <= 0 || !pidexists($sshpid)) {
|
|
|
|
|
# it is NOT alive
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$sshpid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server on $port\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
# once it is known that the ssh server is alive, sftp server
|
|
|
|
|
# verification is performed actually connecting to it, authenticating
|
2025-11-15 00:27:38 +01:00
|
|
|
# and performing a simple remote command. This verification is tried
|
|
|
|
|
# only one time.
|
2023-05-29 20:25:09 +02:00
|
|
|
|
|
|
|
|
$sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
|
|
|
|
|
$sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
|
|
|
|
|
logmsg "RUN: SFTP server failed verification\n";
|
|
|
|
|
# failed to talk to it properly. Kill the server and return failure
|
|
|
|
|
display_sftplog();
|
|
|
|
|
display_sftpconfig();
|
|
|
|
|
display_sshdlog();
|
|
|
|
|
display_sshdconfig();
|
|
|
|
|
stopserver($server, "$sshpid $pid2");
|
|
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$sshpid = $pid2 = 0;
|
2023-08-01 09:19:58 +00:00
|
|
|
logmsg "RUN: failed to verify the $srvrname server on $port\n";
|
2023-05-29 20:25:09 +02:00
|
|
|
return (5, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2025-11-15 00:27:38 +01:00
|
|
|
# we are happy, no need to loop anymore!
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 0;
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
my $hostfile;
|
2023-04-27 11:04:13 -07:00
|
|
|
if(!open($hostfile, "<", "$LOGDIR/$PIDDIR/$hstpubmd5f") ||
|
2023-04-05 17:26:20 -07:00
|
|
|
(read($hostfile, $SSHSRVMD5, 32) != 32) ||
|
|
|
|
|
!close($hostfile) ||
|
|
|
|
|
($SSHSRVMD5 !~ /^[a-f0-9]{32}$/i))
|
|
|
|
|
{
|
2026-03-09 12:27:12 +01:00
|
|
|
my $msg = "Fatal: $srvrname pubkey MD5 missing : \"$hstpubmd5f\" : $!";
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "$msg\n";
|
|
|
|
|
stopservers($verb);
|
|
|
|
|
die $msg;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-27 11:04:13 -07:00
|
|
|
if(!open($hostfile, "<", "$LOGDIR/$PIDDIR/$hstpubsha256f") ||
|
2023-04-05 17:26:20 -07:00
|
|
|
(read($hostfile, $SSHSRVSHA256, 48) == 0) ||
|
|
|
|
|
!close($hostfile))
|
|
|
|
|
{
|
2026-03-09 12:27:12 +01:00
|
|
|
my $msg = "Fatal: $srvrname pubkey SHA256 missing : \"$hstpubsha256f\" : $!";
|
2023-04-05 17:26:20 -07:00
|
|
|
logmsg "$msg\n";
|
|
|
|
|
stopservers($verb);
|
|
|
|
|
die $msg;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
logmsg "RUN: $srvrname on PID $pid2 port $port\n" if($verb);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
return (0, $pid2, $sshpid, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Start the MQTT server
|
|
|
|
|
#
|
|
|
|
|
sub runmqttserver {
|
|
|
|
|
my ($id, $verb, $ipv6) = @_;
|
2026-06-11 17:22:30 +02:00
|
|
|
my $ip = $HOSTIP;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $proto = 'mqtt';
|
|
|
|
|
my $port = protoport($proto);
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
unlink($portfile); # need to see a new one
|
2023-04-05 17:26:20 -07:00
|
|
|
# start our MQTT server - on a random port!
|
2026-06-11 17:22:30 +02:00
|
|
|
my $cmd = server_exe('mqttd').
|
2025-02-24 15:27:35 +01:00
|
|
|
" --port 0".
|
2023-04-05 17:26:20 -07:00
|
|
|
" --pidfile $pidfile".
|
|
|
|
|
" --portfile $portfile".
|
2023-06-14 15:11:40 -07:00
|
|
|
" --config $LOGDIR/$SERVERCMD".
|
2023-04-05 17:26:20 -07:00
|
|
|
" --logfile $logfile".
|
|
|
|
|
" --logdir $LOGDIR";
|
|
|
|
|
my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
|
|
|
|
|
|
|
|
|
|
if($sockspid <= 0 || !pidexists($sockspid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-04-05 17:26:20 -07:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2023-04-08 17:13:16 -07:00
|
|
|
return (1, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
my $mqttport = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
|
|
|
|
if(!$mqttport) {
|
|
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server is now running PID $pid2 on PORT $mqttport\n";
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-26 15:00:27 +02:00
|
|
|
return (0, $pid2, $sockspid, $mqttport);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Start the socks server
|
|
|
|
|
#
|
|
|
|
|
sub runsocksserver {
|
|
|
|
|
my ($id, $verb, $ipv6, $is_unix) = @_;
|
2026-06-11 17:22:30 +02:00
|
|
|
my $ip = $HOSTIP;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $proto = 'socks';
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $portfile = $serverportfile{$server};
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
unlink($portfile); # need to see a new one
|
2023-04-05 17:26:20 -07:00
|
|
|
# start our socks server, get commands from the FTP cmd file
|
2026-06-11 17:22:30 +02:00
|
|
|
my $cmd = "";
|
2023-04-05 17:26:20 -07:00
|
|
|
if($is_unix) {
|
2026-06-11 17:22:30 +02:00
|
|
|
$cmd = server_exe('socksd').
|
2023-04-05 17:26:20 -07:00
|
|
|
" --pidfile $pidfile".
|
2023-04-27 10:02:32 -07:00
|
|
|
" --reqfile $LOGDIR/$SOCKSIN".
|
2023-04-05 17:26:20 -07:00
|
|
|
" --logfile $logfile".
|
|
|
|
|
" --unix-socket $SOCKSUNIXPATH".
|
|
|
|
|
" --backend $HOSTIP".
|
2023-06-14 15:11:40 -07:00
|
|
|
" --config $LOGDIR/$SERVERCMD";
|
2025-06-02 10:41:20 +02:00
|
|
|
$portfile = "none";
|
2023-04-05 17:26:20 -07:00
|
|
|
} else {
|
2026-06-11 17:22:30 +02:00
|
|
|
$cmd = server_exe('socksd').
|
2025-02-24 15:27:35 +01:00
|
|
|
" --port 0".
|
2023-04-05 17:26:20 -07:00
|
|
|
" --pidfile $pidfile".
|
|
|
|
|
" --portfile $portfile".
|
2023-04-27 10:02:32 -07:00
|
|
|
" --reqfile $LOGDIR/$SOCKSIN".
|
2023-04-05 17:26:20 -07:00
|
|
|
" --logfile $logfile".
|
|
|
|
|
" --backend $HOSTIP".
|
2023-06-14 15:11:40 -07:00
|
|
|
" --config $LOGDIR/$SERVERCMD";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
|
|
|
|
|
|
|
|
|
|
if($sockspid <= 0 || !pidexists($sockspid)) {
|
|
|
|
|
# it is NOT alive
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-04-05 17:26:20 -07:00
|
|
|
$doesntrun{$pidfile} = 1;
|
2023-04-08 17:13:16 -07:00
|
|
|
return (1, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2025-06-02 10:41:20 +02:00
|
|
|
my $port = 0;
|
|
|
|
|
if($portfile ne "none") {
|
|
|
|
|
$port = pidfromfile($portfile, $SERVER_TIMEOUT_SEC);
|
|
|
|
|
if(!$port) {
|
|
|
|
|
logmsg "RUN: timeout for $srvrname to produce port file $portfile\n";
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2025-06-02 10:41:20 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
return (1, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server is now running PID $pid2\n";
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0, $pid2, $sockspid, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the dict server
|
|
|
|
|
#
|
|
|
|
|
sub rundictserver {
|
|
|
|
|
my ($verb, $alt) = @_;
|
|
|
|
|
my $proto = "dict";
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($alt eq "ipv6") {
|
|
|
|
|
# No IPv6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose 1 " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--srcdir \"$srcdir\" ";
|
|
|
|
|
$flags .= "--host $HOSTIP";
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $aflags = "--port $port $flags";
|
|
|
|
|
my $cmd = "$srcdir/dictserver.py $aflags";
|
|
|
|
|
my ($dictpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($dictpid <= 0 || !pidexists($dictpid)) {
|
|
|
|
|
# it is NOT alive
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$dictpid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
$doesntrun{$pidfile} = 0;
|
|
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server PID $dictpid port $port\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$dictpid, $dictpid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the SMB server
|
|
|
|
|
#
|
|
|
|
|
sub runsmbserver {
|
|
|
|
|
my ($verb, $alt) = @_;
|
|
|
|
|
my $proto = "smb";
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($alt eq "ipv6") {
|
|
|
|
|
# No IPv6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose 1 " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--srcdir \"$srcdir\" ";
|
|
|
|
|
$flags .= "--host $HOSTIP";
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $aflags = "--port $port $flags";
|
|
|
|
|
my $cmd = "$srcdir/smbserver.py $aflags";
|
|
|
|
|
my ($smbpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($smbpid <= 0 || !pidexists($smbpid)) {
|
|
|
|
|
# it is NOT alive
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$smbpid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
$doesntrun{$pidfile} = 0;
|
|
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server PID $smbpid port $port\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$smbpid, $smbpid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# start the telnet server
|
|
|
|
|
#
|
|
|
|
|
sub runnegtelnetserver {
|
|
|
|
|
my ($verb, $alt) = @_;
|
|
|
|
|
my $proto = "telnet";
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($alt eq "ipv6") {
|
|
|
|
|
# No IPv6
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $server = servername_id($proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
|
2025-11-15 00:27:38 +01:00
|
|
|
# do not retry if the server does not work
|
2025-07-08 13:59:32 +02:00
|
|
|
if($doesntrun{$pidfile}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return (2, 0, 0, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
|
|
|
|
|
my $srvrname = servername_str($proto, $ipvnum, $idnum);
|
|
|
|
|
my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
|
|
|
|
|
|
|
|
|
|
my $flags = "";
|
|
|
|
|
$flags .= "--verbose 1 " if($debugprotocol);
|
|
|
|
|
$flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
|
|
|
|
|
$flags .= "--id $idnum " if($idnum > 1);
|
|
|
|
|
$flags .= "--srcdir \"$srcdir\"";
|
|
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
my $port = getfreeport($ipvnum);
|
|
|
|
|
my $aflags = "--port $port $flags";
|
|
|
|
|
my $cmd = "$srcdir/negtelnetserver.py $aflags";
|
|
|
|
|
my ($ntelpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
|
2023-05-29 20:25:09 +02:00
|
|
|
if($ntelpid <= 0 || !pidexists($ntelpid)) {
|
|
|
|
|
# it is NOT alive
|
2026-03-19 01:15:43 +01:00
|
|
|
stopserver($server, $pid2);
|
2023-05-29 20:25:09 +02:00
|
|
|
$doesntrun{$pidfile} = 1;
|
|
|
|
|
$ntelpid = $pid2 = 0;
|
|
|
|
|
logmsg "RUN: failed to start the $srvrname server\n";
|
|
|
|
|
return (3, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
$doesntrun{$pidfile} = 0;
|
|
|
|
|
|
|
|
|
|
if($verb) {
|
|
|
|
|
logmsg "RUN: $srvrname server PID $ntelpid port $port\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2023-04-08 17:13:16 -07:00
|
|
|
return (0+!$ntelpid, $ntelpid, $pid2, $port);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Single shot http and gopher server responsiveness test. This should only
|
|
|
|
|
# be used to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsive_http_server {
|
2024-09-26 14:55:56 +02:00
|
|
|
my ($proto, $verb, $alt, $port_or_path, $do_http3) = @_;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($alt eq "ipv6") {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
elsif($alt eq "proxy") {
|
|
|
|
|
$idnum = 2;
|
|
|
|
|
}
|
|
|
|
|
elsif($alt eq "unix") {
|
|
|
|
|
# IP (protocol) is mutually exclusive with Unix sockets
|
|
|
|
|
$ipvnum = "unix";
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-26 14:55:56 +02:00
|
|
|
return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path, $do_http3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
2024-09-26 15:00:27 +02:00
|
|
|
#######################################################################
|
|
|
|
|
# Single shot mqtt server responsiveness test. This should only
|
|
|
|
|
# be used to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsive_mqtt_server {
|
|
|
|
|
my ($proto, $id, $verb, $ipv6) = @_;
|
2026-03-19 01:15:43 +01:00
|
|
|
my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? $HOST6IP : $HOSTIP;
|
2024-09-26 15:00:27 +02:00
|
|
|
my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
return &responsiveserver($proto, $ipvnum, $idnum, $ip);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
#######################################################################
|
|
|
|
|
# Single shot pingpong server responsiveness test. This should only be
|
|
|
|
|
# used to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsive_pingpong_server {
|
|
|
|
|
my ($proto, $id, $verb, $ipv6) = @_;
|
|
|
|
|
my $port;
|
2026-03-19 01:15:43 +01:00
|
|
|
my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? $HOST6IP : $HOSTIP;
|
2023-04-05 17:26:20 -07:00
|
|
|
my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
my $protoip = $proto . ($ipvnum == 6? '6': '');
|
|
|
|
|
|
|
|
|
|
if($proto =~ /^(?:ftp|imap|pop3|smtp)$/) {
|
|
|
|
|
$port = protoport($protoip);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg "Unsupported protocol $proto!!\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Single shot rtsp server responsiveness test. This should only be
|
|
|
|
|
# used to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsive_rtsp_server {
|
|
|
|
|
my ($verb, $ipv6) = @_;
|
|
|
|
|
my $proto = 'rtsp';
|
|
|
|
|
my $port = protoport($proto);
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = 1;
|
|
|
|
|
|
|
|
|
|
if($ipv6) {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$port = protoport('rtsp6');
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Single shot tftp server responsiveness test. This should only be
|
|
|
|
|
# used to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsive_tftp_server {
|
|
|
|
|
my ($id, $verb, $ipv6) = @_;
|
|
|
|
|
my $proto = 'tftp';
|
|
|
|
|
my $port = protoport($proto);
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
if($ipv6) {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$port = protoport('tftp6');
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-09 09:47:43 +02:00
|
|
|
#######################################################################
|
|
|
|
|
# Single shot dns server responsiveness test. This should only be
|
|
|
|
|
# used to verify that a server present in %run hash is still functional
|
|
|
|
|
#
|
|
|
|
|
sub responsive_dns_server {
|
|
|
|
|
my ($id, $verb, $ipv6) = @_;
|
|
|
|
|
my $proto = 'dns';
|
|
|
|
|
my $port = protoport($proto);
|
|
|
|
|
my $ip = $HOSTIP;
|
|
|
|
|
my $ipvnum = 4;
|
|
|
|
|
my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
|
|
|
|
|
|
|
|
|
|
if($ipv6) {
|
|
|
|
|
# if IPv6, use a different setup
|
|
|
|
|
$ipvnum = 6;
|
|
|
|
|
$port = protoport('dns6');
|
|
|
|
|
$ip = $HOST6IP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
#######################################################################
|
|
|
|
|
# startservers() starts all the named servers
|
|
|
|
|
#
|
2023-04-08 17:13:16 -07:00
|
|
|
# Returns: string with error reason or blank for success, and an integer:
|
|
|
|
|
# 0 for success
|
|
|
|
|
# 1 for an error starting the server
|
|
|
|
|
# 2 for not the first time getting an error starting the server
|
|
|
|
|
# 3 for a failure to stop a server in order to restart it
|
|
|
|
|
# 4 for an unsupported server type
|
2023-04-05 17:26:20 -07:00
|
|
|
#
|
|
|
|
|
sub startservers {
|
|
|
|
|
my @what = @_;
|
|
|
|
|
my ($pid, $pid2);
|
2024-08-15 10:47:37 +02:00
|
|
|
my $serr; # error while starting a server (as of the return enumerations)
|
2023-04-05 17:26:20 -07:00
|
|
|
for(@what) {
|
|
|
|
|
my (@whatlist) = split(/\s+/,$_);
|
|
|
|
|
my $what = lc($whatlist[0]);
|
|
|
|
|
$what =~ s/[^a-z0-9\/-]//g;
|
|
|
|
|
|
|
|
|
|
my $certfile;
|
2025-05-30 18:37:47 +03:00
|
|
|
if($what =~ /^(ftp|gopher|http|imap|pop3|smtp)s|https-mtls((\d*)(-ipv6|-unix|))$/) {
|
2025-03-06 11:01:49 +01:00
|
|
|
$certfile = ($whatlist[1]) ? $whatlist[1] : 'certs/test-localhost.pem';
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(($what eq "pop3") ||
|
|
|
|
|
($what eq "ftp") ||
|
|
|
|
|
($what eq "imap") ||
|
|
|
|
|
($what eq "smtp")) {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{$what} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_pingpong_server($what, "", $verbose)) {
|
|
|
|
|
if(stopserver($what)) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive ".uc($what)." server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{$what}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2) = runpingpongserver($what, "", $verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting ". uc($what) ." server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{$what} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "ftp-ipv6") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'ftp-ipv6'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_pingpong_server("ftp", "", $verbose, "ipv6")) {
|
|
|
|
|
if(stopserver('ftp-ipv6')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive FTP-IPv6 server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'ftp-ipv6'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting FTP-IPv6 server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
|
|
|
|
|
$pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'ftp-ipv6'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "gopher") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'gopher'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("gopher", $verbose, 0,
|
|
|
|
|
protoport("gopher"))) {
|
|
|
|
|
if(stopserver('gopher')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive GOPHER server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'gopher'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'gopher'}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("gopher", $verbose, 0);
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting GOPHER server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'gopher'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "gopher-ipv6") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'gopher-ipv6'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("gopher", $verbose, "ipv6",
|
2026-03-19 20:54:43 +01:00
|
|
|
protoport("gopher6"))) {
|
2023-04-05 17:26:20 -07:00
|
|
|
if(stopserver('gopher-ipv6')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive GOPHER-IPv6 server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'gopher-ipv6'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"gopher6"}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("gopher", $verbose, "ipv6");
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting GOPHER-IPv6 server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
|
|
|
|
|
$pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'gopher-ipv6'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "http") {
|
2024-08-07 22:57:43 +08:00
|
|
|
if($run{'http'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("http", $verbose, 0, protoport('http'))) {
|
2024-08-07 22:57:43 +08:00
|
|
|
logmsg "* restarting unresponsive HTTP server\n";
|
2023-04-05 17:26:20 -07:00
|
|
|
if(stopserver('http')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive HTTP server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'http'}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("http", $verbose, 0);
|
|
|
|
|
if($pid <= 0) {
|
2026-01-03 18:44:00 +01:00
|
|
|
return ("failed starting HTTP server (for http)", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "http-proxy") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'http-proxy'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("http", $verbose, "proxy",
|
|
|
|
|
protoport("httpproxy"))) {
|
|
|
|
|
if(stopserver('http-proxy')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive HTTP-proxy server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http-proxy'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"httpproxy"}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("http", $verbose, "proxy");
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting HTTP-proxy server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http-proxy'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "http-ipv6") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'http-ipv6'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("http", $verbose, "ipv6",
|
|
|
|
|
protoport("http6"))) {
|
|
|
|
|
if(stopserver('http-ipv6')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive HTTP-IPv6 server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http-ipv6'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"http6"}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("http", $verbose, "ipv6");
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting HTTP-IPv6 server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http-ipv6'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "rtsp") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'rtsp'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_rtsp_server($verbose)) {
|
|
|
|
|
if(stopserver('rtsp')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive RTSP server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'rtsp'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'rtsp'}) = runrtspserver($verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting RTSP server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'rtsp'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "rtsp-ipv6") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'rtsp-ipv6'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_rtsp_server($verbose, "ipv6")) {
|
|
|
|
|
if(stopserver('rtsp-ipv6')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive RTSP-IPv6 server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'rtsp-ipv6'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'rtsp6'}) = runrtspserver($verbose, "ipv6");
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting RTSP-IPv6 server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'rtsp-ipv6'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what =~ /^(ftp|imap|pop3|smtp)s$/) {
|
|
|
|
|
my $cproto = $1;
|
|
|
|
|
if(!$stunnel) {
|
2025-11-15 00:27:38 +01:00
|
|
|
# we cannot run ftps tests without stunnel
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("no stunnel", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
if($runcert{$what} && ($runcert{$what} ne $certfile)) {
|
|
|
|
|
# stop server when running and using a different cert
|
|
|
|
|
if(stopserver($what)) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping $what server with different cert", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{$cproto} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_pingpong_server($cproto, "", $verbose)) {
|
|
|
|
|
if(stopserver($cproto)) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive $cproto server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{$cproto}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2) = runpingpongserver($cproto, "", $verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting $cproto server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid $cproto => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{$cproto} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
if(!$run{$what}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{$what}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runsecureserver($verbose, "", $certfile, $what,
|
|
|
|
|
protoport($cproto));
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting $what server (stunnel)", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{$what} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "file") {
|
|
|
|
|
# we support it but have no server!
|
|
|
|
|
}
|
2025-04-03 21:51:32 +03:00
|
|
|
elsif($what eq "https" || $what eq "https-mtls") {
|
2023-04-05 17:26:20 -07:00
|
|
|
if(!$stunnel) {
|
2025-11-15 00:27:38 +01:00
|
|
|
# we cannot run https tests without stunnel
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("no stunnel", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2025-04-03 21:51:32 +03:00
|
|
|
if($runcert{$what} && ($runcert{$what} ne $certfile)) {
|
2023-04-05 17:26:20 -07:00
|
|
|
# stop server when running and using a different cert
|
2025-04-03 21:51:32 +03:00
|
|
|
if(stopserver($what)) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping HTTPS server with different cert", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2024-09-18 16:32:07 +02:00
|
|
|
# also stop http server, we do not know which state it is in
|
|
|
|
|
if($run{'http'} && stopserver('http')) {
|
|
|
|
|
return ("failed stopping HTTP server", 3);
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2025-04-03 21:51:32 +03:00
|
|
|
if($run{$what} &&
|
|
|
|
|
!responsive_http_server($what, $verbose, 0,
|
|
|
|
|
protoport($what))) {
|
|
|
|
|
if(stopserver($what)) {
|
2024-09-18 16:32:07 +02:00
|
|
|
return ("failed stopping unresponsive HTTPS server", 3);
|
|
|
|
|
}
|
|
|
|
|
# also stop http server, we do not know which state it is in
|
|
|
|
|
if($run{'http'} && stopserver('http')) {
|
|
|
|
|
return ("failed stopping unresponsive HTTP server", 3);
|
|
|
|
|
}
|
2024-09-09 13:52:44 +02:00
|
|
|
}
|
2024-09-18 16:32:07 +02:00
|
|
|
# check a running http server if we not already checked https
|
2025-04-03 21:51:32 +03:00
|
|
|
if($run{'http'} && !$run{$what} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("http", $verbose, 0,
|
|
|
|
|
protoport('http'))) {
|
|
|
|
|
if(stopserver('http')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive HTTP server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'http'}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("http", $verbose, 0);
|
|
|
|
|
if($pid <= 0) {
|
2026-01-03 18:44:00 +01:00
|
|
|
return ("failed starting HTTP server (for https/https-mtls)", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid http => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2025-04-03 21:51:32 +03:00
|
|
|
if(!$run{$what}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{$what}) =
|
|
|
|
|
runhttpsserver($verbose, $what, "", $certfile);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting HTTPS server (stunnel)", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2025-04-03 21:51:32 +03:00
|
|
|
logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2)
|
2023-04-05 17:26:20 -07:00
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{$what} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-26 14:55:56 +02:00
|
|
|
elsif($what eq "http/2") {
|
2025-11-15 00:27:38 +01:00
|
|
|
# http/2 server proxies to an HTTP server
|
2024-09-26 14:55:56 +02:00
|
|
|
if($run{'http/2'} &&
|
|
|
|
|
!responsive_http_server("https", $verbose, 0, protoport('http2tls'))) {
|
|
|
|
|
logmsg "* restarting unresponsive HTTP/2 server\n";
|
|
|
|
|
if(stopserver('http/2')) {
|
|
|
|
|
return ("failed stopping unresponsive HTTP/2 server", 3);
|
|
|
|
|
}
|
|
|
|
|
# also stop http server, we do not know which state it is in
|
|
|
|
|
if($run{'http'} && stopserver('http')) {
|
|
|
|
|
return ("failed stopping HTTP server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
# check a running http server if we not already checked http/2
|
|
|
|
|
if($run{'http'} && !$run{'http/2'} &&
|
|
|
|
|
!responsive_http_server("http", $verbose, 0,
|
|
|
|
|
protoport('http'))) {
|
|
|
|
|
if(stopserver('http')) {
|
|
|
|
|
return ("failed stopping unresponsive HTTP server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http'}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{'http'}) =
|
|
|
|
|
runhttpserver("http", $verbose, 0);
|
|
|
|
|
if($pid <= 0) {
|
2026-01-03 18:44:00 +01:00
|
|
|
return ("failed starting HTTP server (for http/2)", $serr);
|
2024-09-26 14:55:56 +02:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid http => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http'} = "$pid $pid2";
|
2024-09-26 14:55:56 +02:00
|
|
|
}
|
|
|
|
|
if(!$run{'http/2'}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{"http2"}, $PORT{"http2tls"}) =
|
|
|
|
|
runhttp2server($verbose);
|
|
|
|
|
if($pid <= 0) {
|
|
|
|
|
return ("failed starting HTTP/2 server", $serr);
|
|
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid http/2 => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http/2'} = "$pid $pid2";
|
2024-09-26 14:55:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "http/3") {
|
2025-11-15 00:27:38 +01:00
|
|
|
# http/3 server proxies to an HTTP server
|
2024-09-26 14:55:56 +02:00
|
|
|
if($run{'http/3'} &&
|
|
|
|
|
!responsive_http_server("https", $verbose, 0, protoport('http3'), 1)) {
|
|
|
|
|
logmsg "* restarting unresponsive HTTP/3 server\n";
|
|
|
|
|
if(stopserver('http/3')) {
|
|
|
|
|
return ("failed stopping unresponsive HTTP/3 server", 3);
|
|
|
|
|
}
|
|
|
|
|
# also stop http server, we do not know which state it is in
|
|
|
|
|
if($run{'http'} && stopserver('http')) {
|
|
|
|
|
return ("failed stopping HTTP server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
# check a running http server if we not already checked http/3
|
|
|
|
|
if($run{'http'} && !$run{'http/3'} &&
|
|
|
|
|
!responsive_http_server("http", $verbose, 0,
|
|
|
|
|
protoport('http'))) {
|
|
|
|
|
if(stopserver('http')) {
|
|
|
|
|
return ("failed stopping unresponsive HTTP server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http'}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{'http'}) =
|
|
|
|
|
runhttpserver("http", $verbose, 0);
|
|
|
|
|
if($pid <= 0) {
|
2026-01-03 18:44:00 +01:00
|
|
|
return ("failed starting HTTP server (for http/3)", $serr);
|
2024-09-26 14:55:56 +02:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid http => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http'} = "$pid $pid2";
|
2024-09-26 14:55:56 +02:00
|
|
|
}
|
|
|
|
|
if(!$run{'http/3'}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{"http3"}) = runhttp3server($verbose);
|
|
|
|
|
if($pid <= 0) {
|
|
|
|
|
return ("failed starting HTTP/3 server", $serr);
|
|
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid http/3 => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http/3'} = "$pid $pid2";
|
2024-09-26 14:55:56 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
elsif($what eq "gophers") {
|
|
|
|
|
if(!$stunnel) {
|
2025-11-15 00:27:38 +01:00
|
|
|
# we cannot run TLS tests without stunnel
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("no stunnel", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
if($runcert{'gophers'} && ($runcert{'gophers'} ne $certfile)) {
|
|
|
|
|
# stop server when running and using a different cert
|
|
|
|
|
if(stopserver('gophers')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping GOPHERS server with different cert", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'gopher'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("gopher", $verbose, 0,
|
|
|
|
|
protoport('gopher'))) {
|
|
|
|
|
if(stopserver('gopher')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive GOPHER server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'gopher'}) {
|
|
|
|
|
my $port;
|
2026-06-11 17:22:30 +02:00
|
|
|
($serr, $pid, $pid2, $port) = runhttpserver("gopher", $verbose, 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
$PORT{'gopher'} = $port;
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting GOPHER server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid gopher => %d %d\n", $pid, $pid2) if($verbose);
|
|
|
|
|
logmsg "GOPHERPORT => $port\n" if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'gopher'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
if(!$run{'gophers'}) {
|
|
|
|
|
my $port;
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $port) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpsserver($verbose, "gophers", "", $certfile);
|
|
|
|
|
$PORT{'gophers'} = $port;
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting GOPHERS server (stunnel)", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid gophers => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg "GOPHERSPORT => $port\n" if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'gophers'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "https-proxy") {
|
|
|
|
|
if(!$stunnel) {
|
2025-11-15 00:27:38 +01:00
|
|
|
# we cannot run https-proxy tests without stunnel
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("no stunnel", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
if($runcert{'https-proxy'} &&
|
|
|
|
|
($runcert{'https-proxy'} ne $certfile)) {
|
|
|
|
|
# stop server when running and using a different cert
|
|
|
|
|
if(stopserver('https-proxy')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping HTTPS-proxy with different cert", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# we front the http-proxy with stunnel so we need to make sure the
|
|
|
|
|
# proxy runs as well
|
2023-04-08 17:13:16 -07:00
|
|
|
my ($f, $e) = startservers("http-proxy");
|
2023-04-05 17:26:20 -07:00
|
|
|
if($f) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ($f, $e);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!$run{'https-proxy'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"httpsproxy"}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpsserver($verbose, "https", "proxy", $certfile);
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting HTTPS-proxy (stunnel)", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid https-proxy => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'https-proxy'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-09 09:47:43 +02:00
|
|
|
elsif($what eq "dns") {
|
|
|
|
|
if($run{'dns'} &&
|
|
|
|
|
!responsive_dns_server("", $verbose)) {
|
|
|
|
|
if(stopserver('dns')) {
|
|
|
|
|
return ("failed stopping unresponsive DNS server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'dns'}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{'dns'}) =
|
|
|
|
|
rundnsserver("", $verbose);
|
|
|
|
|
if($pid <= 0) {
|
|
|
|
|
return ("failed starting DNS server", $serr);
|
|
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid dns => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'dns'} = "$pid $pid2";
|
2025-04-09 09:47:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
elsif($what eq "tftp") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'tftp'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_tftp_server("", $verbose)) {
|
|
|
|
|
if(stopserver('tftp')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive TFTP server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'tftp'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'tftp'}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runtftpserver("", $verbose);
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting TFTP server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'tftp'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "tftp-ipv6") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'tftp-ipv6'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_tftp_server("", $verbose, "ipv6")) {
|
|
|
|
|
if(stopserver('tftp-ipv6')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive TFTP-IPv6 server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'tftp-ipv6'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'tftp6'}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runtftpserver("", $verbose, "ipv6");
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting TFTP-IPv6 server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'tftp-ipv6'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "sftp" || $what eq "scp") {
|
|
|
|
|
if(!$run{'ssh'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{'ssh'}) = runsshserver("", $verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting SSH server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'ssh'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "socks4" || $what eq "socks5" ) {
|
|
|
|
|
if(!$run{'socks'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"socks"}) = runsocksserver("", $verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting socks server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'socks'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "socks5unix") {
|
|
|
|
|
if(!$run{'socks5unix'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2) = runsocksserver("2", $verbose, "", "unix");
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting socks5unix server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid socks5unix => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'socks5unix'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "mqtt" ) {
|
2024-09-26 15:00:27 +02:00
|
|
|
if($run{'mqtt'} &&
|
|
|
|
|
!responsive_mqtt_server("mqtt", "", $verbose)) {
|
|
|
|
|
if(stopserver('mqtt')) {
|
|
|
|
|
return ("failed stopping unresponsive MQTT server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
if(!$run{'mqtt'}) {
|
2024-09-26 15:00:27 +02:00
|
|
|
($serr, $pid, $pid2, $PORT{"mqtt"}) = runmqttserver("", $verbose);
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting mqtt server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
2023-04-21 16:21:04 -07:00
|
|
|
logmsg sprintf("* pid mqtt => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'mqtt'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2026-01-17 17:23:44 +01:00
|
|
|
elsif($what eq "mqtts" ) {
|
|
|
|
|
if(!$stunnel) {
|
|
|
|
|
# we cannot run mqtts tests without stunnel
|
|
|
|
|
return ("no stunnel", 4);
|
|
|
|
|
}
|
|
|
|
|
if($run{'mqtt'} &&
|
|
|
|
|
!responsive_mqtt_server("mqtt", "", $verbose)) {
|
|
|
|
|
if(stopserver('mqtt')) {
|
|
|
|
|
return ("failed stopping unresponsive MQTT server", 3);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'mqtt'}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{"mqtt"}) = runmqttserver("", $verbose);
|
|
|
|
|
if($pid <= 0) {
|
|
|
|
|
return ("failed starting mqtt server", $serr);
|
|
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid mqtt => %d %d\n", $pid, $pid2) if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'mqtt'} = "$pid $pid2";
|
2026-01-17 17:23:44 +01:00
|
|
|
}
|
|
|
|
|
if(!$run{$what}) {
|
|
|
|
|
($serr, $pid, $pid2, $PORT{$what}) =
|
|
|
|
|
runhttpsserver($verbose, $what, "", $certfile);
|
|
|
|
|
if($pid <= 0) {
|
|
|
|
|
return ("failed starting MQTTS server (stunnel)", $serr);
|
|
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{$what} = "$pid $pid2";
|
2026-01-17 17:23:44 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-04-05 17:26:20 -07:00
|
|
|
elsif($what eq "http-unix") {
|
2024-09-09 13:52:44 +02:00
|
|
|
if($run{'http-unix'} &&
|
2023-04-05 17:26:20 -07:00
|
|
|
!responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
|
|
|
|
|
if(stopserver('http-unix')) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed stopping unresponsive HTTP-unix server", 3);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(!$run{'http-unix'}) {
|
|
|
|
|
my $unused;
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $unused) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runhttpserver("http", $verbose, "unix", $HTTPUNIXPATH);
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting HTTP-unix server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'http-unix'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "dict") {
|
|
|
|
|
if(!$run{'dict'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"dict"}) = rundictserver($verbose, "");
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting DICT server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid DICT => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'dict'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "smb") {
|
|
|
|
|
if(!$run{'smb'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"smb"}) = runsmbserver($verbose, "");
|
2023-04-05 17:26:20 -07:00
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting SMB server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid SMB => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'smb'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
elsif($what eq "telnet") {
|
|
|
|
|
if(!$run{'telnet'}) {
|
2023-04-08 17:13:16 -07:00
|
|
|
($serr, $pid, $pid2, $PORT{"telnet"}) =
|
2023-04-05 17:26:20 -07:00
|
|
|
runnegtelnetserver($verbose, "");
|
|
|
|
|
if($pid <= 0) {
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("failed starting neg TELNET server", $serr);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
logmsg sprintf ("* pid neg TELNET => %d %d\n", $pid, $pid2)
|
|
|
|
|
if($verbose);
|
2026-06-11 17:22:30 +02:00
|
|
|
$run{'telnet'} = "$pid $pid2";
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2025-11-15 00:27:38 +01:00
|
|
|
warn "we do not support a server for $what";
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("no server for $what", 4);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
}
|
2023-04-08 17:13:16 -07:00
|
|
|
return ("", 0);
|
2023-04-05 17:26:20 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#######################################################################
|
|
|
|
|
# Stop all running test servers
|
|
|
|
|
#
|
|
|
|
|
sub stopservers {
|
|
|
|
|
my $verb = $_[0];
|
|
|
|
|
#
|
|
|
|
|
# kill sockfilter processes for all pingpong servers
|
|
|
|
|
#
|
2023-04-27 11:04:13 -07:00
|
|
|
killallsockfilters("$LOGDIR/$PIDDIR", $verb);
|
2023-04-05 17:26:20 -07:00
|
|
|
#
|
|
|
|
|
# kill all server pids from %run hash clearing them
|
|
|
|
|
#
|
|
|
|
|
my $pidlist;
|
|
|
|
|
foreach my $server (keys %run) {
|
|
|
|
|
if($run{$server}) {
|
|
|
|
|
if($verb) {
|
|
|
|
|
my $prev = 0;
|
|
|
|
|
my $pids = $run{$server};
|
|
|
|
|
foreach my $pid (split(' ', $pids)) {
|
|
|
|
|
if($pid != $prev) {
|
|
|
|
|
logmsg sprintf("* kill pid for %s => %d\n",
|
|
|
|
|
$server, $pid);
|
|
|
|
|
$prev = $pid;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
$pidlist .= "$run{$server} ";
|
|
|
|
|
$run{$server} = 0;
|
|
|
|
|
}
|
|
|
|
|
$runcert{$server} = 0 if($runcert{$server});
|
|
|
|
|
}
|
|
|
|
|
killpid($verb, $pidlist);
|
|
|
|
|
#
|
|
|
|
|
# cleanup all server pid files
|
|
|
|
|
#
|
|
|
|
|
my $result = 0;
|
|
|
|
|
foreach my $server (keys %serverpidfile) {
|
|
|
|
|
my $pidfile = $serverpidfile{$server};
|
|
|
|
|
my $pid = processexists($pidfile);
|
|
|
|
|
if($pid > 0) {
|
|
|
|
|
if($err_unexpected) {
|
|
|
|
|
logmsg "ERROR: ";
|
|
|
|
|
$result = -1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
logmsg "Warning: ";
|
|
|
|
|
}
|
|
|
|
|
logmsg "$server server unexpectedly alive\n";
|
|
|
|
|
killpid($verb, $pid);
|
|
|
|
|
}
|
|
|
|
|
unlink($pidfile) if(-f $pidfile);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-14 17:22:05 -07:00
|
|
|
#######################################################################
|
|
|
|
|
# substitute the variable stuff into either a joined up file or
|
|
|
|
|
# a command, in either case passed by reference
|
|
|
|
|
#
|
|
|
|
|
sub subvariables {
|
|
|
|
|
my ($thing, $testnum, $prefix) = @_;
|
|
|
|
|
my $port;
|
|
|
|
|
|
|
|
|
|
if(!$prefix) {
|
|
|
|
|
$prefix = "%";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# test server ports
|
|
|
|
|
# Substitutes variables like %HTTPPORT and %SMTP6PORT with the server ports
|
2025-04-09 09:47:43 +02:00
|
|
|
foreach my $proto ('DICT', 'DNS',
|
2023-04-14 17:22:05 -07:00
|
|
|
'FTP', 'FTP6', 'FTPS',
|
|
|
|
|
'GOPHER', 'GOPHER6', 'GOPHERS',
|
2025-04-03 21:51:32 +03:00
|
|
|
'HTTP', 'HTTP6', 'HTTPS', 'HTTPS-MTLS',
|
2026-07-04 12:19:47 +02:00
|
|
|
'HTTPSPROXY',
|
2023-04-14 17:22:05 -07:00
|
|
|
'HTTP2', 'HTTP2TLS',
|
|
|
|
|
'HTTP3',
|
|
|
|
|
'IMAP', 'IMAP6', 'IMAPS',
|
2026-01-17 17:23:44 +01:00
|
|
|
'MQTT', 'MQTTS',
|
2023-04-14 17:22:05 -07:00
|
|
|
'NOLISTEN',
|
|
|
|
|
'POP3', 'POP36', 'POP3S',
|
|
|
|
|
'RTSP', 'RTSP6',
|
|
|
|
|
'SMB', 'SMBS',
|
|
|
|
|
'SMTP', 'SMTP6', 'SMTPS',
|
|
|
|
|
'SOCKS',
|
|
|
|
|
'SSH',
|
|
|
|
|
'TELNET',
|
|
|
|
|
'TFTP', 'TFTP6') {
|
|
|
|
|
$port = protoport(lc $proto);
|
|
|
|
|
$$thing =~ s/${prefix}(?:$proto)PORT/$port/g;
|
|
|
|
|
}
|
|
|
|
|
# Special case: for PROXYPORT substitution, use httpproxy.
|
|
|
|
|
$port = protoport('httpproxy');
|
|
|
|
|
$$thing =~ s/${prefix}PROXYPORT/$port/g;
|
|
|
|
|
|
|
|
|
|
# server Unix domain socket paths
|
|
|
|
|
$$thing =~ s/${prefix}HTTPUNIXPATH/$HTTPUNIXPATH/g;
|
|
|
|
|
$$thing =~ s/${prefix}SOCKSUNIXPATH/$SOCKSUNIXPATH/g;
|
|
|
|
|
|
|
|
|
|
# client IP addresses
|
2024-09-25 14:11:01 +02:00
|
|
|
my $nb = $CLIENT6IP;
|
|
|
|
|
$nb =~ s/^\[(.*)\]/$1/; # trim off the brackets
|
|
|
|
|
|
|
|
|
|
$$thing =~ s/${prefix}CLIENT6IP-NB/$nb/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
$$thing =~ s/${prefix}CLIENT6IP/$CLIENT6IP/g;
|
|
|
|
|
$$thing =~ s/${prefix}CLIENTIP/$CLIENTIP/g;
|
|
|
|
|
|
|
|
|
|
# server IP addresses
|
|
|
|
|
$$thing =~ s/${prefix}HOST6IP/$HOST6IP/g;
|
|
|
|
|
$$thing =~ s/${prefix}HOSTIP/$HOSTIP/g;
|
|
|
|
|
|
|
|
|
|
# misc
|
2024-09-30 23:58:35 +02:00
|
|
|
$$thing =~ s/${prefix}PERL/$perlcmd/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
$$thing =~ s/${prefix}CURL/$CURL/g;
|
|
|
|
|
$$thing =~ s/${prefix}LOGDIR/$LOGDIR/g;
|
|
|
|
|
$$thing =~ s/${prefix}PWD/$pwd/g;
|
|
|
|
|
$$thing =~ s/${prefix}VERSION/$CURLVERSION/g;
|
2024-06-26 11:13:54 +02:00
|
|
|
$$thing =~ s/${prefix}VERNUM/$CURLVERNUM/g;
|
2024-06-26 11:20:01 +02:00
|
|
|
$$thing =~ s/${prefix}DATE/$DATE/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
$$thing =~ s/${prefix}TESTNUMBER/$testnum/g;
|
2025-02-24 15:27:35 +01:00
|
|
|
my $resolve = server_exe('resolve', 'TOOL');
|
|
|
|
|
$$thing =~ s/${prefix}RESOLVE/$resolve/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
|
2024-09-29 12:01:37 +02:00
|
|
|
# POSIX/MSYS/Cygwin curl needs: file://localhost/d/path/to
|
|
|
|
|
# Windows native curl needs: file://localhost/D:/path/to
|
2023-04-14 17:22:05 -07:00
|
|
|
my $file_pwd = $pwd;
|
|
|
|
|
if($file_pwd !~ /^\//) {
|
|
|
|
|
$file_pwd = "/$file_pwd";
|
|
|
|
|
}
|
|
|
|
|
my $ssh_pwd = $posix_pwd;
|
|
|
|
|
# this only works after the SSH server has been started
|
|
|
|
|
# TODO: call sshversioninfo early and store $sshdid so this substitution
|
|
|
|
|
# always works
|
2025-07-08 13:59:32 +02:00
|
|
|
if($sshdid && $sshdid =~ /OpenSSH-Windows/) {
|
2023-04-14 17:22:05 -07:00
|
|
|
$ssh_pwd = $file_pwd;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$$thing =~ s/${prefix}FILE_PWD/$file_pwd/g;
|
2025-03-23 16:01:11 +01:00
|
|
|
$$thing =~ s/${prefix}SCP_PWD/$posix_pwd/g;
|
|
|
|
|
$$thing =~ s/${prefix}SFTP_PWD/$ssh_pwd/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
$$thing =~ s/${prefix}SRCDIR/$srcdir/g;
|
runtests: generate certs dynamically, bump to EC-256, tidy up
Before this patch the curl repository and source tarball distribution
contained test certificates as binary blobs. Used by runtests.
Drop these certificates in favor of generating them dynamically as
part of the build process. Both via autotools and CMake.
As part of this, improve certificates, the generator script and process,
file layout, and fix any issue to make it work fast and smooth both in
CI and local builds.
Note, cert generator scripts require OpenSSL >=1.0.2
(or LibreSSL >=3.1.0). Generation requires POSIX shell, also with CMake.
Without a POSIX shell tests relying on TLS (and stunnel) will fail.
Details:
- build: generate certs as part of the test run process.
- build, tests: generate certs in the build directory.
- binarycheck: drop concept of known binary files with hashes.
- binarycheck: move binary check logic into spacecheck and drop this
separate checker tool.
- build: fix to clean all cert files.
- autotools: fix to not run leaf cert generators in parallel. To avoid
confusion when updating the revocation database and counter.
- scripts: drop `scripts` subdir, merge two scripts into one,
auto-generate root cert, allow generating multiple leafs at once.
- scripts: switch to EC-256 keys (was: RSA-2048). For key size and perf.
- scripts: drop `-x` echo, text dumps, most other output. To avoid log
noise and make it quicker in CI.
- scripts: make it non-RSA-specific.
- scripts: delete unused code.
- scripts: use POSIX shell shebang. Some envs don't have bash (Alpine).
- scripts: pass test pseudo-secrets via the command-line. To avoid:
```
+ openssl genrsa -out test-ca.key -passout fd:0 2048
Invalid password argument, starting with "fd:"
```
- cmake: fix to launch generator scripts via the detected POSIX shell.
- cmake: fix `build-certs` rule to not depend on `SRPFILES`
(`srp-verifier-*`).
- cmake: drop `EXCLUDE_FROM_ALL` for the cert subdir. It makes
the Visual Studio generator miss to create the `clean-certs`,
`build-certs` targets. No target depend on them, so they don't execute
implicitly anyway. Fixes:
```
MSBUILD : error MSB1009: Project file does not exist.
Switch: clean-certs.vcxproj
```
- cmake: add `VERBATIM USES_TERMINAL` to `build-certs` target.
- GHA/linux: install openssl on Alpine, for the cert generator scripts.
Follow-up to 556f722fe32e5e9f4e24f0242100c5e9d57c129b #16593
Follow-up to fa461b4eff52b413f88debf543b5350a6cef4724 #14486
Closes #16824
2025-03-24 22:13:29 +01:00
|
|
|
$$thing =~ s/${prefix}CERTDIR/./g;
|
2023-04-14 17:22:05 -07:00
|
|
|
$$thing =~ s/${prefix}USER/$USER/g;
|
2024-10-01 00:41:43 +02:00
|
|
|
$$thing =~ s/${prefix}DEV_NULL/$dev_null/g;
|
2025-07-30 13:15:20 +02:00
|
|
|
my $libtests = $LIBDIR . 'libtests' . exe_ext('TOOL');
|
|
|
|
|
$$thing =~ s/${prefix}LIBTESTS/$libtests/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
|
|
|
|
|
$$thing =~ s/${prefix}SSHSRVMD5/$SSHSRVMD5/g;
|
|
|
|
|
$$thing =~ s/${prefix}SSHSRVSHA256/$SSHSRVSHA256/g;
|
2026-04-02 01:05:54 +02:00
|
|
|
my $keyalgostr = sshkeyalgostr(defined $feature{"sshkeyalgo"} ? $feature{"sshkeyalgo"} : "");
|
|
|
|
|
$$thing =~ s/${prefix}SSHKEYALGO/$keyalgostr/g;
|
2023-04-14 17:22:05 -07:00
|
|
|
|
2024-09-26 16:46:49 +02:00
|
|
|
# The purpose of FTPTIME2 is to provide times that can be
|
2023-04-14 17:22:05 -07:00
|
|
|
# used for time-out tests and that would work on most hosts as these
|
|
|
|
|
# adjust for the startup/check time for this particular host. We needed to
|
2025-11-15 00:27:38 +01:00
|
|
|
# do this to make the test suite run better on slow hosts.
|
2023-09-06 13:38:53 -07:00
|
|
|
my $ftp2 = $ftpchecktime * 8;
|
2023-04-14 17:22:05 -07:00
|
|
|
|
|
|
|
|
$$thing =~ s/${prefix}FTPTIME2/$ftp2/g;
|
|
|
|
|
|
|
|
|
|
# HTTP2
|
|
|
|
|
$$thing =~ s/${prefix}H2CVER/$h2cver/g;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-25 13:53:17 +02:00
|
|
|
sub localhttp {
|
|
|
|
|
return $HOSTIP eq "127.0.0.1";
|
|
|
|
|
}
|
2023-04-14 17:22:05 -07:00
|
|
|
|
2023-04-05 17:26:20 -07:00
|
|
|
1;
|