servers.pm 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012
  1. #***************************************************************************
  2. # _ _ ____ _
  3. # Project ___| | | | _ \| |
  4. # / __| | | | |_) | |
  5. # | (__| |_| | _ <| |___
  6. # \___|\___/|_| \_\_____|
  7. #
  8. # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
  9. #
  10. # This software is licensed as described in the file COPYING, which
  11. # you should have received as part of this distribution. The terms
  12. # are also available at https://curl.se/docs/copyright.html.
  13. #
  14. # You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. # copies of the Software, and permit persons to whom the Software is
  16. # furnished to do so, under the terms of the COPYING file.
  17. #
  18. # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. # KIND, either express or implied.
  20. #
  21. # SPDX-License-Identifier: curl
  22. #
  23. ###########################################################################
  24. # This module contains functions that are useful for managing the lifecycle of
  25. # test servers required when running tests. It is not intended for use within
  26. # those servers, but rather for starting and stopping them.
  27. package servers;
  28. use IO::Socket;
  29. use strict;
  30. use warnings;
  31. BEGIN {
  32. use base qw(Exporter);
  33. our @EXPORT = (
  34. # variables
  35. qw(
  36. $SOCKSIN
  37. $err_unexpected
  38. $debugprotocol
  39. $stunnel
  40. ),
  41. # functions
  42. qw(
  43. initserverconfig
  44. )
  45. );
  46. our @EXPORT_OK = (
  47. # functions
  48. qw(
  49. checkcmd
  50. clearlocks
  51. serverfortest
  52. stopserver
  53. stopservers
  54. subvariables
  55. ),
  56. # for debugging only
  57. qw(
  58. protoport
  59. )
  60. );
  61. }
  62. use serverhelp qw(
  63. serverfactors
  64. servername_id
  65. servername_str
  66. servername_canon
  67. server_pidfilename
  68. server_portfilename
  69. server_logfilename
  70. );
  71. use sshhelp qw(
  72. $hstpubmd5f
  73. $hstpubsha256f
  74. $sshexe
  75. $sftpexe
  76. $sftpconfig
  77. $sshdlog
  78. $sftplog
  79. $sftpcmds
  80. display_sshdconfig
  81. display_sftpconfig
  82. display_sshdlog
  83. display_sftplog
  84. find_sshd
  85. find_ssh
  86. find_sftp
  87. find_httptlssrv
  88. sshversioninfo
  89. );
  90. use pathhelp qw(
  91. exe_ext
  92. os_is_win
  93. sys_native_abs_path
  94. );
  95. use processhelp;
  96. use globalconfig;
  97. use testutil qw(
  98. logmsg
  99. runclient
  100. runclientoutput
  101. );
  102. my %serverpidfile; # all server pid file names, identified by server id
  103. my %serverportfile;# all server port file names, identified by server id
  104. my $sshdvernum; # for socks server, ssh daemon version number
  105. my $sshdverstr; # for socks server, ssh daemon version string
  106. my $sshderror; # for socks server, ssh daemon version error
  107. my %doesntrun; # servers that don't work, identified by pidfile
  108. my %PORT = (nolisten => 47); # port we use for a local non-listening service
  109. my $server_response_maxtime=13;
  110. my $httptlssrv = find_httptlssrv();
  111. my %run; # running server
  112. my %runcert; # cert file currently in use by an ssl running server
  113. my $CLIENTIP="127.0.0.1"; # address which curl uses for incoming connections
  114. my $CLIENT6IP="[::1]"; # address which curl uses for incoming connections
  115. my $posix_pwd=$pwd; # current working directory
  116. my $h2cver = "h2c"; # this version is decided by the nghttp2 lib being used
  117. my $portrange = 999; # space from which to choose a random port
  118. # don't increase without making sure generated port
  119. # numbers will always be valid (<=65535)
  120. my $HOSTIP="127.0.0.1"; # address on which the test server listens
  121. my $HOST6IP="[::1]"; # address on which the test server listens
  122. my $HTTPUNIXPATH; # HTTP server Unix domain socket path
  123. my $SOCKSUNIXPATH; # socks server Unix domain socket path
  124. my $SSHSRVMD5 = "[uninitialized]"; # MD5 of ssh server public key
  125. my $SSHSRVSHA256 = "[uninitialized]"; # SHA256 of ssh server public key
  126. my $USER; # name of the current user
  127. my $sshdid; # for socks server, ssh daemon version id
  128. my $ftpchecktime=1; # time it took to verify our test FTP server
  129. # Variables shared with runtests.pl
  130. our $SOCKSIN="socksd-request.log"; # what curl sent to the SOCKS proxy
  131. our $err_unexpected; # error instead of warning on server unexpectedly alive
  132. our $debugprotocol; # nonzero for verbose server logs
  133. our $stunnel; # path to stunnel command
  134. #######################################################################
  135. # Check for a command in the PATH of the test server.
  136. #
  137. sub checkcmd {
  138. my ($cmd, @extrapaths)=@_;
  139. my $sep = '[:]';
  140. if ($^O eq 'MSWin32' || $^O eq 'dos' || $^O eq 'os2') {
  141. # PATH separator is different
  142. $sep = '[;]';
  143. }
  144. my @paths=(split(m/$sep/, $ENV{'PATH'}), "/usr/sbin", "/usr/local/sbin",
  145. "/sbin", "/usr/bin", "/usr/local/bin", @extrapaths);
  146. for(@paths) {
  147. if( -x "$_/$cmd" . exe_ext('SYS') && ! -d "$_/$cmd" . exe_ext('SYS')) {
  148. # executable bit but not a directory!
  149. return "$_/$cmd";
  150. }
  151. }
  152. return "";
  153. }
  154. #######################################################################
  155. # Create a server socket on a random (unused) port, then close it and
  156. # return the port number
  157. #
  158. sub getfreeport {
  159. my ($ipnum) = @_;
  160. my $server = IO::Socket->new(LocalPort => 0,
  161. Domain => $ipnum == 6 ? AF_INET6 : AF_INET,
  162. Type => SOCK_STREAM,
  163. Reuse => 1,
  164. Listen => 10 )
  165. or die "Couldn't create tcp server socket: $@\n";
  166. return $server->sockport();
  167. }
  168. use File::Temp qw/ tempfile/;
  169. #######################################################################
  170. # Initialize configuration variables
  171. sub initserverconfig {
  172. my ($fh, $socks) = tempfile("curl-socksd-XXXXXXXX", TMPDIR => 1);
  173. close($fh);
  174. unlink($socks);
  175. my ($f2, $http) = tempfile("curl-http-XXXXXXXX", TMPDIR => 1);
  176. close($f2);
  177. unlink($http);
  178. $SOCKSUNIXPATH = $socks; # SOCKS Unix domain socket
  179. $HTTPUNIXPATH = $http; # HTTP Unix domain socket
  180. $stunnel = checkcmd("stunnel4") || checkcmd("tstunnel") || checkcmd("stunnel");
  181. # get the name of the current user
  182. $USER = $ENV{USER}; # Linux
  183. if (!$USER) {
  184. $USER = $ENV{USERNAME}; # Windows
  185. if (!$USER) {
  186. $USER = $ENV{LOGNAME}; # Some Unix (I think)
  187. }
  188. }
  189. init_serverpidfile_hash();
  190. }
  191. #######################################################################
  192. # Load serverpidfile and serverportfile hashes with file names for all
  193. # possible servers.
  194. #
  195. sub init_serverpidfile_hash {
  196. for my $proto (('ftp', 'gopher', 'http', 'imap', 'pop3', 'smtp', 'http/2', 'http/3')) {
  197. for my $ssl (('', 's')) {
  198. for my $ipvnum ((4, 6)) {
  199. for my $idnum ((1, 2, 3)) {
  200. my $serv = servername_id("$proto$ssl", $ipvnum, $idnum);
  201. my $pidf = server_pidfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
  202. $ipvnum, $idnum);
  203. $serverpidfile{$serv} = $pidf;
  204. my $portf = server_portfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
  205. $ipvnum, $idnum);
  206. $serverportfile{$serv} = $portf;
  207. }
  208. }
  209. }
  210. }
  211. for my $proto (('tftp', 'sftp', 'socks', 'ssh', 'rtsp', 'httptls',
  212. 'dict', 'smb', 'smbs', 'telnet', 'mqtt')) {
  213. for my $ipvnum ((4, 6)) {
  214. for my $idnum ((1, 2)) {
  215. my $serv = servername_id($proto, $ipvnum, $idnum);
  216. my $pidf = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
  217. $idnum);
  218. $serverpidfile{$serv} = $pidf;
  219. my $portf = server_portfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
  220. $idnum);
  221. $serverportfile{$serv} = $portf;
  222. }
  223. }
  224. }
  225. for my $proto (('http', 'imap', 'pop3', 'smtp', 'http/2', 'http/3')) {
  226. for my $ssl (('', 's')) {
  227. my $serv = servername_id("$proto$ssl", "unix", 1);
  228. my $pidf = server_pidfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
  229. "unix", 1);
  230. $serverpidfile{$serv} = $pidf;
  231. my $portf = server_portfilename("$LOGDIR/$PIDDIR", "$proto$ssl",
  232. "unix", 1);
  233. $serverportfile{$serv} = $portf;
  234. }
  235. }
  236. }
  237. #######################################################################
  238. # Kill the processes that still have lock files in a directory
  239. #
  240. sub clearlocks {
  241. my $dir = $_[0];
  242. my $done = 0;
  243. if(os_is_win()) {
  244. $dir = sys_native_abs_path($dir);
  245. $dir =~ s/\//\\\\/g;
  246. my $handle = "handle";
  247. if($ENV{"PROCESSOR_ARCHITECTURE"} =~ /64$/) {
  248. $handle = "handle64";
  249. }
  250. if(checkcmd($handle)) {
  251. my @handles = `$handle $dir -accepteula -nobanner`;
  252. for my $tryhandle (@handles) {
  253. # Skip the "No matching handles found." warning when returned
  254. if($tryhandle =~ /^(\S+)\s+pid:\s+(\d+)\s+type:\s+(\w+)\s+([0-9A-F]+):\s+(.+)\r\r/) {
  255. logmsg "Found $3 lock of '$5' ($4) by $1 ($2)\n";
  256. # Ignore stunnel since we cannot do anything about its locks
  257. if("$3" eq "File" && "$1" ne "tstunnel.exe") {
  258. logmsg "Killing IMAGENAME eq $1 and PID eq $2\n";
  259. system("taskkill.exe -f -fi \"IMAGENAME eq $1\" -fi \"PID eq $2\" >nul 2>&1");
  260. $done = 1;
  261. }
  262. }
  263. }
  264. }
  265. }
  266. return $done;
  267. }
  268. #######################################################################
  269. # Check if a given child process has just died. Reaps it if so.
  270. #
  271. sub checkdied {
  272. my $pid = $_[0];
  273. if((not defined $pid) || $pid <= 0) {
  274. return 0;
  275. }
  276. use POSIX ":sys_wait_h";
  277. my $rc = pidwait($pid, &WNOHANG);
  278. return ($rc == $pid)?1:0;
  279. }
  280. ##############################################################################
  281. # This function makes sure the right set of server is running for the
  282. # specified test case. This is a useful design when we run single tests as not
  283. # all servers need to run then!
  284. #
  285. # Returns: a string, blank if everything is fine or a reason why it failed, and
  286. # an integer:
  287. # 0 for success
  288. # 1 for an error starting the server
  289. # 2 for not the first time getting an error starting the server
  290. # 3 for a failure to stop a server in order to restart it
  291. # 4 for an unsupported server type
  292. #
  293. sub serverfortest {
  294. my (@what)=@_;
  295. for(my $i = scalar(@what) - 1; $i >= 0; $i--) {
  296. my $srvrline = $what[$i];
  297. chomp $srvrline if($srvrline);
  298. if($srvrline =~ /^(\S+)((\s*)(.*))/) {
  299. my $server = "${1}";
  300. my $lnrest = "${2}";
  301. my $tlsext;
  302. if($server =~ /^(httptls)(\+)(ext|srp)(\d*)(-ipv6|)$/) {
  303. $server = "${1}${4}${5}";
  304. $tlsext = uc("TLS-${3}");
  305. }
  306. if(! grep /^\Q$server\E$/, @protocols) {
  307. if(substr($server,0,5) ne "socks") {
  308. if($tlsext) {
  309. return ("curl lacks $tlsext support", 4);
  310. }
  311. else {
  312. return ("curl lacks $server server support", 4);
  313. }
  314. }
  315. }
  316. $what[$i] = "$server$lnrest" if($tlsext);
  317. }
  318. }
  319. return &startservers(@what);
  320. }
  321. #######################################################################
  322. # Start a new thread/process and run the given command line in there.
  323. # Return the pids (yes plural) of the new child process to the parent.
  324. #
  325. sub startnew {
  326. my ($cmd, $pidfile, $timeout, $fakepidfile)=@_;
  327. logmsg "startnew: $cmd\n" if ($verbose);
  328. my $child = fork();
  329. if(not defined $child) {
  330. logmsg "startnew: fork() failure detected\n";
  331. return (-1,-1);
  332. }
  333. if(0 == $child) {
  334. # Here we are the child. Run the given command.
  335. # Flush output.
  336. $| = 1;
  337. # Put an "exec" in front of the command so that the child process
  338. # keeps this child's process ID.
  339. exec("exec $cmd") || die "Can't exec() $cmd: $!";
  340. # exec() should never return back here to this process. We protect
  341. # ourselves by calling die() just in case something goes really bad.
  342. die "error: exec() has returned";
  343. }
  344. # Ugly hack but ssh client and gnutls-serv don't support pid files
  345. if ($fakepidfile) {
  346. if(open(my $out, ">", "$pidfile")) {
  347. print $out $child . "\n";
  348. close($out) || die "Failure writing pidfile";
  349. logmsg "startnew: $pidfile faked with pid=$child\n" if($verbose);
  350. }
  351. else {
  352. logmsg "startnew: failed to write fake $pidfile with pid=$child\n";
  353. }
  354. # could/should do a while connect fails sleep a bit and loop
  355. portable_sleep($timeout);
  356. if (checkdied($child)) {
  357. logmsg "startnew: child process has failed to start\n" if($verbose);
  358. return (-1,-1);
  359. }
  360. }
  361. my $pid2 = 0;
  362. my $count = $timeout;
  363. while($count--) {
  364. $pid2 = pidfromfile($pidfile);
  365. if(($pid2 > 0) && pidexists($pid2)) {
  366. # if $pid2 is valid, then make sure this pid is alive, as
  367. # otherwise it is just likely to be the _previous_ pidfile or
  368. # similar!
  369. last;
  370. }
  371. if (checkdied($child)) {
  372. logmsg "startnew: child process has died, server might start up\n"
  373. if($verbose);
  374. # We can't just abort waiting for the server with a
  375. # return (-1,-1);
  376. # because the server might have forked and could still start
  377. # up normally. Instead, just reduce the amount of time we remain
  378. # waiting.
  379. $count >>= 2;
  380. }
  381. sleep(1);
  382. }
  383. # Return two PIDs, the one for the child process we spawned and the one
  384. # reported by the server itself (in case it forked again on its own).
  385. # Both (potentially) need to be killed at the end of the test.
  386. return ($child, $pid2);
  387. }
  388. #######################################################################
  389. # Return the port to use for the given protocol.
  390. #
  391. sub protoport {
  392. my ($proto) = @_;
  393. return $PORT{$proto} || "[not running]";
  394. }
  395. #######################################################################
  396. # Stop a test server along with pids which aren't in the %run hash yet.
  397. # This also stops all servers which are relative to the given one.
  398. #
  399. sub stopserver {
  400. my ($server, $pidlist) = @_;
  401. #
  402. # kill sockfilter processes for pingpong relative server
  403. #
  404. if($server =~ /^(ftp|imap|pop3|smtp)s?(\d*)(-ipv6|)$/) {
  405. my $proto = $1;
  406. my $idnum = ($2 && ($2 > 1)) ? $2 : 1;
  407. my $ipvnum = ($3 && ($3 =~ /6$/)) ? 6 : 4;
  408. killsockfilters("$LOGDIR/$PIDDIR", $proto, $ipvnum, $idnum, $verbose);
  409. }
  410. #
  411. # All servers relative to the given one must be stopped also
  412. #
  413. my @killservers;
  414. if($server =~ /^(ftp|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
  415. # given a stunnel based ssl server, also kill non-ssl underlying one
  416. push @killservers, "${1}${2}";
  417. }
  418. elsif($server =~ /^(ftp|http|imap|pop3|smtp)((\d*)(-ipv6|-unix|))$/) {
  419. # given a non-ssl server, also kill stunnel based ssl piggybacking one
  420. push @killservers, "${1}s${2}";
  421. }
  422. elsif($server =~ /^(socks)((\d*)(-ipv6|))$/) {
  423. # given a socks server, also kill ssh underlying one
  424. push @killservers, "ssh${2}";
  425. }
  426. elsif($server =~ /^(ssh)((\d*)(-ipv6|))$/) {
  427. # given a ssh server, also kill socks piggybacking one
  428. push @killservers, "socks${2}";
  429. }
  430. if($server eq "http" or $server eq "https") {
  431. # since the http2+3 server is a proxy that needs to know about the
  432. # dynamic http port it too needs to get restarted when the http server
  433. # is killed
  434. push @killservers, "http/2";
  435. push @killservers, "http/3";
  436. }
  437. push @killservers, $server;
  438. #
  439. # kill given pids and server relative ones clearing them in %run hash
  440. #
  441. foreach my $server (@killservers) {
  442. if($run{$server}) {
  443. # we must prepend a space since $pidlist may already contain a pid
  444. $pidlist .= " $run{$server}";
  445. $run{$server} = 0;
  446. }
  447. $runcert{$server} = 0 if($runcert{$server});
  448. }
  449. killpid($verbose, $pidlist);
  450. #
  451. # cleanup server pid files
  452. #
  453. my $result = 0;
  454. foreach my $server (@killservers) {
  455. my $pidfile = $serverpidfile{$server};
  456. my $pid = processexists($pidfile);
  457. if($pid > 0) {
  458. if($err_unexpected) {
  459. logmsg "ERROR: ";
  460. $result = -1;
  461. }
  462. else {
  463. logmsg "Warning: ";
  464. }
  465. logmsg "$server server unexpectedly alive\n";
  466. killpid($verbose, $pid);
  467. }
  468. unlink($pidfile) if(-f $pidfile);
  469. }
  470. return $result;
  471. }
  472. #######################################################################
  473. # Return flags to let curl use an external HTTP proxy
  474. #
  475. sub getexternalproxyflags {
  476. return " --proxy $proxy_address ";
  477. }
  478. #######################################################################
  479. # Verify that the server that runs on $ip, $port is our server. This also
  480. # implies that we can speak with it, as there might be occasions when the
  481. # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
  482. # assign requested address")
  483. #
  484. sub verifyhttp {
  485. my ($proto, $ipvnum, $idnum, $ip, $port_or_path) = @_;
  486. my $server = servername_id($proto, $ipvnum, $idnum);
  487. my $bonus="";
  488. # $port_or_path contains a path for Unix sockets, sws ignores the port
  489. my $port = ($ipvnum eq "unix") ? 80 : $port_or_path;
  490. my $verifyout = "$LOGDIR/".
  491. servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
  492. unlink($verifyout) if(-f $verifyout);
  493. my $verifylog = "$LOGDIR/".
  494. servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
  495. unlink($verifylog) if(-f $verifylog);
  496. if($proto eq "gopher") {
  497. # gopher is funny
  498. $bonus="1/";
  499. }
  500. my $flags = "--max-time $server_response_maxtime ";
  501. $flags .= "--output $verifyout ";
  502. $flags .= "--silent ";
  503. $flags .= "--verbose ";
  504. $flags .= "--globoff ";
  505. $flags .= "--unix-socket '$port_or_path' " if $ipvnum eq "unix";
  506. $flags .= "--insecure " if($proto eq 'https');
  507. if($proxy_address) {
  508. $flags .= getexternalproxyflags();
  509. }
  510. $flags .= "\"$proto://$ip:$port/${bonus}verifiedserver\"";
  511. my $cmd = "$VCURL $flags 2>$verifylog";
  512. # verify if our/any server is running on this port
  513. logmsg "RUN: $cmd\n" if($verbose);
  514. my $res = runclient($cmd);
  515. $res >>= 8; # rotate the result
  516. if($res & 128) {
  517. logmsg "RUN: curl command died with a coredump\n";
  518. return -1;
  519. }
  520. if($res && $verbose) {
  521. logmsg "RUN: curl command returned $res\n";
  522. if(open(my $file, "<", "$verifylog")) {
  523. while(my $string = <$file>) {
  524. logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
  525. }
  526. close($file);
  527. }
  528. }
  529. my $data;
  530. if(open(my $file, "<", "$verifyout")) {
  531. while(my $string = <$file>) {
  532. $data = $string;
  533. last; # only want first line
  534. }
  535. close($file);
  536. }
  537. my $pid = 0;
  538. if($data && ($data =~ /WE ROOLZ: (\d+)/)) {
  539. $pid = 0+$1;
  540. }
  541. elsif($res == 6) {
  542. # curl: (6) Couldn't resolve host '::1'
  543. logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
  544. return -1;
  545. }
  546. elsif($data || ($res && ($res != 7))) {
  547. logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
  548. return -1;
  549. }
  550. return $pid;
  551. }
  552. #######################################################################
  553. # Verify that the server that runs on $ip, $port is our server. This also
  554. # implies that we can speak with it, as there might be occasions when the
  555. # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
  556. # assign requested address")
  557. #
  558. sub verifyftp {
  559. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  560. my $server = servername_id($proto, $ipvnum, $idnum);
  561. my $time=time();
  562. my $extra="";
  563. my $verifylog = "$LOGDIR/".
  564. servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
  565. unlink($verifylog) if(-f $verifylog);
  566. if($proto eq "ftps") {
  567. $extra .= "--insecure --ftp-ssl-control ";
  568. }
  569. my $flags = "--max-time $server_response_maxtime ";
  570. $flags .= "--silent ";
  571. $flags .= "--verbose ";
  572. $flags .= "--globoff ";
  573. $flags .= $extra;
  574. if($proxy_address) {
  575. $flags .= getexternalproxyflags();
  576. }
  577. $flags .= "\"$proto://$ip:$port/verifiedserver\"";
  578. my $cmd = "$VCURL $flags 2>$verifylog";
  579. # check if this is our server running on this port:
  580. logmsg "RUN: $cmd\n" if($verbose);
  581. my @data = runclientoutput($cmd);
  582. my $res = $? >> 8; # rotate the result
  583. if($res & 128) {
  584. logmsg "RUN: curl command died with a coredump\n";
  585. return -1;
  586. }
  587. my $pid = 0;
  588. foreach my $line (@data) {
  589. if($line =~ /WE ROOLZ: (\d+)/) {
  590. # this is our test server with a known pid!
  591. $pid = 0+$1;
  592. last;
  593. }
  594. }
  595. if($pid <= 0 && @data && $data[0]) {
  596. # this is not a known server
  597. logmsg "RUN: Unknown server on our $server port: $port\n";
  598. return 0;
  599. }
  600. # we can/should use the time it took to verify the FTP server as a measure
  601. # on how fast/slow this host/FTP is.
  602. my $took = int(0.5+time()-$time);
  603. if($verbose) {
  604. logmsg "RUN: Verifying our test $server server took $took seconds\n";
  605. }
  606. $ftpchecktime = $took>=1?$took:1; # make sure it never is below 1
  607. return $pid;
  608. }
  609. #######################################################################
  610. # Verify that the server that runs on $ip, $port is our server. This also
  611. # implies that we can speak with it, as there might be occasions when the
  612. # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
  613. # assign requested address")
  614. #
  615. sub verifyrtsp {
  616. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  617. my $server = servername_id($proto, $ipvnum, $idnum);
  618. my $verifyout = "$LOGDIR/".
  619. servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
  620. unlink($verifyout) if(-f $verifyout);
  621. my $verifylog = "$LOGDIR/".
  622. servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
  623. unlink($verifylog) if(-f $verifylog);
  624. my $flags = "--max-time $server_response_maxtime ";
  625. $flags .= "--output $verifyout ";
  626. $flags .= "--silent ";
  627. $flags .= "--verbose ";
  628. $flags .= "--globoff ";
  629. if($proxy_address) {
  630. $flags .= getexternalproxyflags();
  631. }
  632. # currently verification is done using http
  633. $flags .= "\"http://$ip:$port/verifiedserver\"";
  634. my $cmd = "$VCURL $flags 2>$verifylog";
  635. # verify if our/any server is running on this port
  636. logmsg "RUN: $cmd\n" if($verbose);
  637. my $res = runclient($cmd);
  638. $res >>= 8; # rotate the result
  639. if($res & 128) {
  640. logmsg "RUN: curl command died with a coredump\n";
  641. return -1;
  642. }
  643. if($res && $verbose) {
  644. logmsg "RUN: curl command returned $res\n";
  645. if(open(my $file, "<", "$verifylog")) {
  646. while(my $string = <$file>) {
  647. logmsg "RUN: $string" if($string !~ /^[ \t]*$/);
  648. }
  649. close($file);
  650. }
  651. }
  652. my $data;
  653. if(open(my $file, "<", "$verifyout")) {
  654. while(my $string = <$file>) {
  655. $data = $string;
  656. last; # only want first line
  657. }
  658. close($file);
  659. }
  660. my $pid = 0;
  661. if($data && ($data =~ /RTSP_SERVER WE ROOLZ: (\d+)/)) {
  662. $pid = 0+$1;
  663. }
  664. elsif($res == 6) {
  665. # curl: (6) Couldn't resolve host '::1'
  666. logmsg "RUN: failed to resolve host ($proto://$ip:$port/verifiedserver)\n";
  667. return -1;
  668. }
  669. elsif($data || ($res != 7)) {
  670. logmsg "RUN: Unknown server on our $server port: $port\n";
  671. return -1;
  672. }
  673. return $pid;
  674. }
  675. #######################################################################
  676. # Verify that the ssh server has written out its pidfile, recovering
  677. # the pid from the file and returning it if a process with that pid is
  678. # actually alive, or a negative value if the process is dead.
  679. #
  680. sub verifyssh {
  681. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  682. my $pidfile = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
  683. $idnum);
  684. my $pid = processexists($pidfile);
  685. if($pid < 0) {
  686. logmsg "RUN: SSH server has died after starting up\n";
  687. }
  688. return $pid;
  689. }
  690. #######################################################################
  691. # Verify that we can connect to the sftp server, properly authenticate
  692. # with generated config and key files and run a simple remote pwd.
  693. #
  694. sub verifysftp {
  695. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  696. my $server = servername_id($proto, $ipvnum, $idnum);
  697. my $verified = 0;
  698. # Find out sftp client canonical file name
  699. my $sftp = find_sftp();
  700. if(!$sftp) {
  701. logmsg "RUN: SFTP server cannot find $sftpexe\n";
  702. return -1;
  703. }
  704. # Find out ssh client canonical file name
  705. my $ssh = find_ssh();
  706. if(!$ssh) {
  707. logmsg "RUN: SFTP server cannot find $sshexe\n";
  708. return -1;
  709. }
  710. # Connect to sftp server, authenticate and run a remote pwd
  711. # command using our generated configuration and key files
  712. my $cmd = "\"$sftp\" -b $LOGDIR/$PIDDIR/$sftpcmds -F $LOGDIR/$PIDDIR/$sftpconfig -S \"$ssh\" $ip > $sftplog 2>&1";
  713. my $res = runclient($cmd);
  714. # Search for pwd command response in log file
  715. if(open(my $sftplogfile, "<", "$sftplog")) {
  716. while(<$sftplogfile>) {
  717. if(/^Remote working directory: /) {
  718. $verified = 1;
  719. last;
  720. }
  721. }
  722. close($sftplogfile);
  723. }
  724. return $verified;
  725. }
  726. #######################################################################
  727. # Verify that the non-stunnel HTTP TLS extensions capable server that runs
  728. # on $ip, $port is our server. This also implies that we can speak with it,
  729. # as there might be occasions when the server runs fine but we cannot talk
  730. # to it ("Failed to connect to ::1: Can't assign requested address")
  731. #
  732. sub verifyhttptls {
  733. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  734. my $server = servername_id($proto, $ipvnum, $idnum);
  735. my $pidfile = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
  736. $idnum);
  737. my $verifyout = "$LOGDIR/".
  738. servername_canon($proto, $ipvnum, $idnum) .'_verify.out';
  739. unlink($verifyout) if(-f $verifyout);
  740. my $verifylog = "$LOGDIR/".
  741. servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
  742. unlink($verifylog) if(-f $verifylog);
  743. my $flags = "--max-time $server_response_maxtime ";
  744. $flags .= "--output $verifyout ";
  745. $flags .= "--verbose ";
  746. $flags .= "--globoff ";
  747. $flags .= "--insecure ";
  748. $flags .= "--tlsauthtype SRP ";
  749. $flags .= "--tlsuser jsmith ";
  750. $flags .= "--tlspassword abc ";
  751. if($proxy_address) {
  752. $flags .= getexternalproxyflags();
  753. }
  754. $flags .= "\"https://$ip:$port/verifiedserver\"";
  755. my $cmd = "$VCURL $flags 2>$verifylog";
  756. # verify if our/any server is running on this port
  757. logmsg "RUN: $cmd\n" if($verbose);
  758. my $res = runclient($cmd);
  759. $res >>= 8; # rotate the result
  760. if($res & 128) {
  761. logmsg "RUN: curl command died with a coredump\n";
  762. return -1;
  763. }
  764. if($res && $verbose) {
  765. logmsg "RUN: curl command returned $res\n";
  766. if(open(my $file, "<", "$verifylog")) {
  767. while(my $string = <$file>) {
  768. logmsg "RUN: $string" if($string !~ /^([ \t]*)$/);
  769. }
  770. close($file);
  771. }
  772. }
  773. my $data;
  774. if(open(my $file, "<", "$verifyout")) {
  775. while(my $string = <$file>) {
  776. $data .= $string;
  777. }
  778. close($file);
  779. }
  780. my $pid = 0;
  781. if($data && ($data =~ /(GNUTLS|GnuTLS)/) && ($pid = processexists($pidfile))) {
  782. if($pid < 0) {
  783. logmsg "RUN: $server server has died after starting up\n";
  784. }
  785. return $pid;
  786. }
  787. elsif($res == 6) {
  788. # curl: (6) Couldn't resolve host '::1'
  789. logmsg "RUN: failed to resolve host (https://$ip:$port/verifiedserver)\n";
  790. return -1;
  791. }
  792. elsif($data || ($res && ($res != 7))) {
  793. logmsg "RUN: Unknown server on our $server port: $port ($res)\n";
  794. return -1;
  795. }
  796. return $pid;
  797. }
  798. #######################################################################
  799. # STUB for verifying socks
  800. #
  801. sub verifysocks {
  802. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  803. my $pidfile = server_pidfilename("$LOGDIR/$PIDDIR", $proto, $ipvnum,
  804. $idnum);
  805. my $pid = processexists($pidfile);
  806. if($pid < 0) {
  807. logmsg "RUN: SOCKS server has died after starting up\n";
  808. }
  809. return $pid;
  810. }
  811. #######################################################################
  812. # Verify that the server that runs on $ip, $port is our server. This also
  813. # implies that we can speak with it, as there might be occasions when the
  814. # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
  815. # assign requested address")
  816. #
  817. sub verifysmb {
  818. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  819. my $server = servername_id($proto, $ipvnum, $idnum);
  820. my $time=time();
  821. my $extra="";
  822. my $verifylog = "$LOGDIR/".
  823. servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
  824. unlink($verifylog) if(-f $verifylog);
  825. my $flags = "--max-time $server_response_maxtime ";
  826. $flags .= "--silent ";
  827. $flags .= "--verbose ";
  828. $flags .= "--globoff ";
  829. $flags .= "-u 'curltest:curltest' ";
  830. $flags .= $extra;
  831. $flags .= "\"$proto://$ip:$port/SERVER/verifiedserver\"";
  832. my $cmd = "$VCURL $flags 2>$verifylog";
  833. # check if this is our server running on this port:
  834. logmsg "RUN: $cmd\n" if($verbose);
  835. my @data = runclientoutput($cmd);
  836. my $res = $? >> 8; # rotate the result
  837. if($res & 128) {
  838. logmsg "RUN: curl command died with a coredump\n";
  839. return -1;
  840. }
  841. my $pid = 0;
  842. foreach my $line (@data) {
  843. if($line =~ /WE ROOLZ: (\d+)/) {
  844. # this is our test server with a known pid!
  845. $pid = 0+$1;
  846. last;
  847. }
  848. }
  849. if($pid <= 0 && @data && $data[0]) {
  850. # this is not a known server
  851. logmsg "RUN: Unknown server on our $server port: $port\n";
  852. return 0;
  853. }
  854. # we can/should use the time it took to verify the server as a measure
  855. # on how fast/slow this host is.
  856. my $took = int(0.5+time()-$time);
  857. if($verbose) {
  858. logmsg "RUN: Verifying our test $server server took $took seconds\n";
  859. }
  860. return $pid;
  861. }
  862. #######################################################################
  863. # Verify that the server that runs on $ip, $port is our server. This also
  864. # implies that we can speak with it, as there might be occasions when the
  865. # server runs fine but we cannot talk to it ("Failed to connect to ::1: Can't
  866. # assign requested address")
  867. #
  868. sub verifytelnet {
  869. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  870. my $server = servername_id($proto, $ipvnum, $idnum);
  871. my $time=time();
  872. my $extra="";
  873. my $verifylog = "$LOGDIR/".
  874. servername_canon($proto, $ipvnum, $idnum) .'_verify.log';
  875. unlink($verifylog) if(-f $verifylog);
  876. my $flags = "--max-time $server_response_maxtime ";
  877. $flags .= "--silent ";
  878. $flags .= "--verbose ";
  879. $flags .= "--globoff ";
  880. $flags .= "--upload-file - ";
  881. $flags .= $extra;
  882. $flags .= "\"$proto://$ip:$port\"";
  883. my $cmd = "echo 'verifiedserver' | $VCURL $flags 2>$verifylog";
  884. # check if this is our server running on this port:
  885. logmsg "RUN: $cmd\n" if($verbose);
  886. my @data = runclientoutput($cmd);
  887. my $res = $? >> 8; # rotate the result
  888. if($res & 128) {
  889. logmsg "RUN: curl command died with a coredump\n";
  890. return -1;
  891. }
  892. my $pid = 0;
  893. foreach my $line (@data) {
  894. if($line =~ /WE ROOLZ: (\d+)/) {
  895. # this is our test server with a known pid!
  896. $pid = 0+$1;
  897. last;
  898. }
  899. }
  900. if($pid <= 0 && @data && $data[0]) {
  901. # this is not a known server
  902. logmsg "RUN: Unknown server on our $server port: $port\n";
  903. return 0;
  904. }
  905. # we can/should use the time it took to verify the server as a measure
  906. # on how fast/slow this host is.
  907. my $took = int(0.5+time()-$time);
  908. if($verbose) {
  909. logmsg "RUN: Verifying our test $server server took $took seconds\n";
  910. }
  911. return $pid;
  912. }
  913. #######################################################################
  914. # Verify that the server that runs on $ip, $port is our server.
  915. # Retry over several seconds before giving up. The ssh server in
  916. # particular can take a long time to start if it needs to generate
  917. # keys on a slow or loaded host.
  918. #
  919. # Just for convenience, test harness uses 'https' and 'httptls' literals
  920. # as values for 'proto' variable in order to differentiate different
  921. # servers. 'https' literal is used for stunnel based https test servers,
  922. # and 'httptls' is used for non-stunnel https test servers.
  923. #
  924. my %protofunc = ('http' => \&verifyhttp,
  925. 'https' => \&verifyhttp,
  926. 'rtsp' => \&verifyrtsp,
  927. 'ftp' => \&verifyftp,
  928. 'pop3' => \&verifyftp,
  929. 'imap' => \&verifyftp,
  930. 'smtp' => \&verifyftp,
  931. 'ftps' => \&verifyftp,
  932. 'pop3s' => \&verifyftp,
  933. 'imaps' => \&verifyftp,
  934. 'smtps' => \&verifyftp,
  935. 'tftp' => \&verifyftp,
  936. 'ssh' => \&verifyssh,
  937. 'socks' => \&verifysocks,
  938. 'socks5unix' => \&verifysocks,
  939. 'gopher' => \&verifyhttp,
  940. 'httptls' => \&verifyhttptls,
  941. 'dict' => \&verifyftp,
  942. 'smb' => \&verifysmb,
  943. 'telnet' => \&verifytelnet);
  944. sub verifyserver {
  945. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  946. my $count = 30; # try for this many seconds
  947. my $pid;
  948. while($count--) {
  949. my $fun = $protofunc{$proto};
  950. $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
  951. if($pid > 0) {
  952. last;
  953. }
  954. elsif($pid < 0) {
  955. # a real failure, stop trying and bail out
  956. return 0;
  957. }
  958. sleep(1);
  959. }
  960. return $pid;
  961. }
  962. #######################################################################
  963. # Single shot server responsiveness test. This should only be used
  964. # to verify that a server present in %run hash is still functional
  965. #
  966. sub responsiveserver {
  967. my ($proto, $ipvnum, $idnum, $ip, $port) = @_;
  968. my $prev_verbose = $verbose;
  969. $verbose = 0;
  970. my $fun = $protofunc{$proto};
  971. my $pid = &$fun($proto, $ipvnum, $idnum, $ip, $port);
  972. $verbose = $prev_verbose;
  973. if($pid > 0) {
  974. return 1; # responsive
  975. }
  976. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  977. logmsg " server precheck FAILED (unresponsive $srvrname server)\n";
  978. return 0;
  979. }
  980. #######################################################################
  981. # start the http server
  982. #
  983. sub runhttpserver {
  984. my ($proto, $verb, $alt, $port_or_path) = @_;
  985. my $ip = $HOSTIP;
  986. my $ipvnum = 4;
  987. my $idnum = 1;
  988. my $exe = "$perl $srcdir/http-server.pl";
  989. my $verbose_flag = "--verbose ";
  990. my $keepalive_secs = 30; # forwarded to sws, was 5 by default which
  991. # led to pukes in CI jobs
  992. if($alt eq "ipv6") {
  993. # if IPv6, use a different setup
  994. $ipvnum = 6;
  995. $ip = $HOST6IP;
  996. }
  997. elsif($alt eq "proxy") {
  998. # basically the same, but another ID
  999. $idnum = 2;
  1000. }
  1001. elsif($alt eq "unix") {
  1002. # IP (protocol) is mutually exclusive with Unix sockets
  1003. $ipvnum = "unix";
  1004. }
  1005. my $server = servername_id($proto, $ipvnum, $idnum);
  1006. my $pidfile = $serverpidfile{$server};
  1007. # don't retry if the server doesn't work
  1008. if ($doesntrun{$pidfile}) {
  1009. return (2, 0, 0, 0);
  1010. }
  1011. my $pid = processexists($pidfile);
  1012. if($pid > 0) {
  1013. stopserver($server, "$pid");
  1014. }
  1015. unlink($pidfile) if(-f $pidfile);
  1016. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1017. my $portfile = $serverportfile{$server};
  1018. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1019. my $flags = "";
  1020. $flags .= "--gopher " if($proto eq "gopher");
  1021. $flags .= "--connect $HOSTIP " if($alt eq "proxy");
  1022. $flags .= "--keepalive $keepalive_secs ";
  1023. $flags .= $verbose_flag if($debugprotocol);
  1024. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1025. $flags .= "--logdir \"$LOGDIR\" ";
  1026. $flags .= "--portfile $portfile ";
  1027. $flags .= "--config $LOGDIR/$SERVERCMD ";
  1028. $flags .= "--id $idnum " if($idnum > 1);
  1029. if($ipvnum eq "unix") {
  1030. $flags .= "--unix-socket '$port_or_path' ";
  1031. } else {
  1032. $flags .= "--ipv$ipvnum --port 0 ";
  1033. }
  1034. $flags .= "--srcdir \"$srcdir\"";
  1035. my $cmd = "$exe $flags";
  1036. my ($httppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1037. if($httppid <= 0 || !pidexists($httppid)) {
  1038. # it is NOT alive
  1039. logmsg "RUN: failed to start the $srvrname server\n";
  1040. stopserver($server, "$pid2");
  1041. $doesntrun{$pidfile} = 1;
  1042. return (1, 0, 0, 0);
  1043. }
  1044. # where is it?
  1045. my $port = 0;
  1046. if(!$port_or_path) {
  1047. $port = $port_or_path = pidfromfile($portfile);
  1048. }
  1049. # Server is up. Verify that we can speak to it.
  1050. my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
  1051. if(!$pid3) {
  1052. logmsg "RUN: $srvrname server failed verification\n";
  1053. # failed to talk to it properly. Kill the server and return failure
  1054. stopserver($server, "$httppid $pid2");
  1055. $doesntrun{$pidfile} = 1;
  1056. return (1, 0, 0, 0);
  1057. }
  1058. $pid2 = $pid3;
  1059. if($verb) {
  1060. logmsg "RUN: $srvrname server is on PID $httppid port $port_or_path\n";
  1061. }
  1062. return (0, $httppid, $pid2, $port);
  1063. }
  1064. #######################################################################
  1065. # start the http2 server
  1066. #
  1067. sub runhttp2server {
  1068. my ($verb) = @_;
  1069. my $proto="http/2";
  1070. my $ipvnum = 4;
  1071. my $idnum = 0;
  1072. my $exe = "$perl $srcdir/http2-server.pl";
  1073. my $verbose_flag = "--verbose ";
  1074. my $server = servername_id($proto, $ipvnum, $idnum);
  1075. my $pidfile = $serverpidfile{$server};
  1076. # don't retry if the server doesn't work
  1077. if ($doesntrun{$pidfile}) {
  1078. return (2, 0, 0, 0, 0);
  1079. }
  1080. my $pid = processexists($pidfile);
  1081. if($pid > 0) {
  1082. stopserver($server, "$pid");
  1083. }
  1084. unlink($pidfile) if(-f $pidfile);
  1085. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1086. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1087. my $flags = "";
  1088. $flags .= "--nghttpx \"$ENV{'NGHTTPX'}\" ";
  1089. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1090. $flags .= "--logdir \"$LOGDIR\" ";
  1091. $flags .= "--connect $HOSTIP:" . protoport("http") . " ";
  1092. $flags .= $verbose_flag if($debugprotocol);
  1093. my $port = getfreeport($ipvnum);
  1094. my $port2 = getfreeport($ipvnum);
  1095. my $aflags = "--port $port --port2 $port2 $flags";
  1096. my $cmd = "$exe $aflags";
  1097. my ($http2pid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1098. if($http2pid <= 0 || !pidexists($http2pid)) {
  1099. # it is NOT alive
  1100. stopserver($server, "$pid2");
  1101. $doesntrun{$pidfile} = 1;
  1102. $http2pid = $pid2 = 0;
  1103. logmsg "RUN: failed to start the $srvrname server\n";
  1104. return (3, 0, 0, 0, 0);
  1105. }
  1106. $doesntrun{$pidfile} = 0;
  1107. if($verb) {
  1108. logmsg "RUN: $srvrname server PID $http2pid ".
  1109. "http-port $port https-port $port2 ".
  1110. "backend $HOSTIP:" . protoport("http") . "\n";
  1111. }
  1112. return (0+!$http2pid, $http2pid, $pid2, $port, $port2);
  1113. }
  1114. #######################################################################
  1115. # start the http3 server
  1116. #
  1117. sub runhttp3server {
  1118. my ($verb, $cert) = @_;
  1119. my $proto="http/3";
  1120. my $ipvnum = 4;
  1121. my $idnum = 0;
  1122. my $exe = "$perl $srcdir/http3-server.pl";
  1123. my $verbose_flag = "--verbose ";
  1124. my $server = servername_id($proto, $ipvnum, $idnum);
  1125. my $pidfile = $serverpidfile{$server};
  1126. # don't retry if the server doesn't work
  1127. if ($doesntrun{$pidfile}) {
  1128. return (2, 0, 0, 0);
  1129. }
  1130. my $pid = processexists($pidfile);
  1131. if($pid > 0) {
  1132. stopserver($server, "$pid");
  1133. }
  1134. unlink($pidfile) if(-f $pidfile);
  1135. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1136. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1137. my $flags = "";
  1138. $flags .= "--nghttpx \"$ENV{'NGHTTPX'}\" ";
  1139. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1140. $flags .= "--logdir \"$LOGDIR\" ";
  1141. $flags .= "--connect $HOSTIP:" . protoport("http") . " ";
  1142. $flags .= "--cert \"$cert\" " if($cert);
  1143. $flags .= $verbose_flag if($debugprotocol);
  1144. my $port = getfreeport($ipvnum);
  1145. my $aflags = "--port $port $flags";
  1146. my $cmd = "$exe $aflags";
  1147. my ($http3pid, $pid3) = startnew($cmd, $pidfile, 15, 0);
  1148. if($http3pid <= 0 || !pidexists($http3pid)) {
  1149. # it is NOT alive
  1150. stopserver($server, "$pid3");
  1151. $doesntrun{$pidfile} = 1;
  1152. $http3pid = $pid3 = 0;
  1153. logmsg "RUN: failed to start the $srvrname server\n";
  1154. return (3, 0, 0, 0);
  1155. }
  1156. $doesntrun{$pidfile} = 0;
  1157. if($verb) {
  1158. logmsg "RUN: $srvrname server PID $http3pid port $port\n";
  1159. }
  1160. return (0+!$http3pid, $http3pid, $pid3, $port);
  1161. }
  1162. #######################################################################
  1163. # start the https stunnel based server
  1164. #
  1165. sub runhttpsserver {
  1166. my ($verb, $proto, $proxy, $certfile) = @_;
  1167. my $ip = $HOSTIP;
  1168. my $ipvnum = 4;
  1169. my $idnum = 1;
  1170. if($proxy eq "proxy") {
  1171. # the https-proxy runs as https2
  1172. $idnum = 2;
  1173. }
  1174. if(!$stunnel) {
  1175. return (4, 0, 0, 0);
  1176. }
  1177. my $server = servername_id($proto, $ipvnum, $idnum);
  1178. my $pidfile = $serverpidfile{$server};
  1179. # don't retry if the server doesn't work
  1180. if ($doesntrun{$pidfile}) {
  1181. return (2, 0, 0, 0);
  1182. }
  1183. my $pid = processexists($pidfile);
  1184. if($pid > 0) {
  1185. stopserver($server, "$pid");
  1186. }
  1187. unlink($pidfile) if(-f $pidfile);
  1188. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1189. $certfile = 'stunnel.pem' unless($certfile);
  1190. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1191. my $flags = "";
  1192. $flags .= "--verbose " if($debugprotocol);
  1193. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1194. $flags .= "--logdir \"$LOGDIR\" ";
  1195. $flags .= "--id $idnum " if($idnum > 1);
  1196. $flags .= "--ipv$ipvnum --proto $proto ";
  1197. $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
  1198. $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
  1199. if($proto eq "gophers") {
  1200. $flags .= "--connect " . protoport("gopher");
  1201. }
  1202. elsif(!$proxy) {
  1203. $flags .= "--connect " . protoport("http");
  1204. }
  1205. else {
  1206. # for HTTPS-proxy we connect to the HTTP proxy
  1207. $flags .= "--connect " . protoport("httpproxy");
  1208. }
  1209. my $port = getfreeport($ipvnum);
  1210. my $options = "$flags --accept $port";
  1211. my $cmd = "$perl $srcdir/secureserver.pl $options";
  1212. my ($httpspid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1213. if($httpspid <= 0 || !pidexists($httpspid)) {
  1214. # it is NOT alive
  1215. # don't call stopserver since that will also kill the dependent
  1216. # server that has already been started properly
  1217. $doesntrun{$pidfile} = 1;
  1218. $httpspid = $pid2 = 0;
  1219. logmsg "RUN: failed to start the $srvrname server\n";
  1220. return (3, 0, 0, 0);
  1221. }
  1222. $doesntrun{$pidfile} = 0;
  1223. # we have a server!
  1224. if($verb) {
  1225. logmsg "RUN: $srvrname server is PID $httpspid port $port\n";
  1226. }
  1227. $runcert{$server} = $certfile;
  1228. return (0+!$httpspid, $httpspid, $pid2, $port);
  1229. }
  1230. #######################################################################
  1231. # start the non-stunnel HTTP TLS extensions capable server
  1232. #
  1233. sub runhttptlsserver {
  1234. my ($verb, $ipv6) = @_;
  1235. my $proto = "httptls";
  1236. my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
  1237. my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
  1238. my $idnum = 1;
  1239. if(!$httptlssrv) {
  1240. return (4, 0, 0);
  1241. }
  1242. my $server = servername_id($proto, $ipvnum, $idnum);
  1243. my $pidfile = $serverpidfile{$server};
  1244. # don't retry if the server doesn't work
  1245. if ($doesntrun{$pidfile}) {
  1246. return (2, 0, 0, 0);
  1247. }
  1248. my $pid = processexists($pidfile);
  1249. if($pid > 0) {
  1250. stopserver($server, "$pid");
  1251. }
  1252. unlink($pidfile) if(-f $pidfile);
  1253. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1254. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1255. my $flags = "";
  1256. $flags .= "--http ";
  1257. $flags .= "--debug 1 " if($debugprotocol);
  1258. $flags .= "--priority NORMAL:+SRP ";
  1259. $flags .= "--srppasswd $srcdir/certs/srp-verifier-db ";
  1260. $flags .= "--srppasswdconf $srcdir/certs/srp-verifier-conf";
  1261. my $port = getfreeport($ipvnum);
  1262. my $allflags = "--port $port $flags";
  1263. my $cmd = "$httptlssrv $allflags > $logfile 2>&1";
  1264. my ($httptlspid, $pid2) = startnew($cmd, $pidfile, 10, 1);
  1265. if($httptlspid <= 0 || !pidexists($httptlspid)) {
  1266. # it is NOT alive
  1267. stopserver($server, "$pid2");
  1268. $doesntrun{$pidfile} = 1;
  1269. $httptlspid = $pid2 = 0;
  1270. logmsg "RUN: failed to start the $srvrname server\n";
  1271. return (3, 0, 0, 0);
  1272. }
  1273. $doesntrun{$pidfile} = 0;
  1274. if($verb) {
  1275. logmsg "RUN: $srvrname server PID $httptlspid port $port\n";
  1276. }
  1277. return (0+!$httptlspid, $httptlspid, $pid2, $port);
  1278. }
  1279. #######################################################################
  1280. # start the pingpong server (FTP, POP3, IMAP, SMTP)
  1281. #
  1282. sub runpingpongserver {
  1283. my ($proto, $id, $verb, $ipv6) = @_;
  1284. # Check the requested server
  1285. if($proto !~ /^(?:ftp|imap|pop3|smtp)$/) {
  1286. logmsg "Unsupported protocol $proto!!\n";
  1287. return (4, 0, 0);
  1288. }
  1289. my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
  1290. my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
  1291. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1292. my $server = servername_id($proto, $ipvnum, $idnum);
  1293. my $pidfile = $serverpidfile{$server};
  1294. my $portfile = $serverportfile{$server};
  1295. # don't retry if the server doesn't work
  1296. if ($doesntrun{$pidfile}) {
  1297. return (2, 0, 0);
  1298. }
  1299. my $pid = processexists($pidfile);
  1300. if($pid > 0) {
  1301. stopserver($server, "$pid");
  1302. }
  1303. unlink($pidfile) if(-f $pidfile);
  1304. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1305. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1306. my $flags = "";
  1307. $flags .= "--verbose " if($debugprotocol);
  1308. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1309. $flags .= "--logdir \"$LOGDIR\" ";
  1310. $flags .= "--portfile \"$portfile\" ";
  1311. $flags .= "--srcdir \"$srcdir\" --proto $proto ";
  1312. $flags .= "--id $idnum " if($idnum > 1);
  1313. $flags .= "--ipv$ipvnum --port 0 --addr \"$ip\"";
  1314. my $cmd = "$perl $srcdir/ftpserver.pl $flags";
  1315. my ($ftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1316. if($ftppid <= 0 || !pidexists($ftppid)) {
  1317. # it is NOT alive
  1318. logmsg "RUN: failed to start the $srvrname server\n";
  1319. stopserver($server, "$pid2");
  1320. $doesntrun{$pidfile} = 1;
  1321. return (1, 0, 0);
  1322. }
  1323. # where is it?
  1324. my $port = pidfromfile($portfile);
  1325. logmsg "PINGPONG runs on port $port ($portfile)\n" if($verb);
  1326. # Server is up. Verify that we can speak to it.
  1327. my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
  1328. if(!$pid3) {
  1329. logmsg "RUN: $srvrname server failed verification\n";
  1330. # failed to talk to it properly. Kill the server and return failure
  1331. stopserver($server, "$ftppid $pid2");
  1332. $doesntrun{$pidfile} = 1;
  1333. return (1, 0, 0);
  1334. }
  1335. $pid2 = $pid3;
  1336. logmsg "RUN: $srvrname server is PID $ftppid port $port\n" if($verb);
  1337. # Assign the correct port variable!
  1338. $PORT{$proto . ($ipvnum == 6? '6': '')} = $port;
  1339. return (0, $pid2, $ftppid);
  1340. }
  1341. #######################################################################
  1342. # start the ftps/imaps/pop3s/smtps server (or rather, tunnel)
  1343. #
  1344. sub runsecureserver {
  1345. my ($verb, $ipv6, $certfile, $proto, $clearport) = @_;
  1346. my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
  1347. my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
  1348. my $idnum = 1;
  1349. if(!$stunnel) {
  1350. return (4, 0, 0, 0);
  1351. }
  1352. my $server = servername_id($proto, $ipvnum, $idnum);
  1353. my $pidfile = $serverpidfile{$server};
  1354. # don't retry if the server doesn't work
  1355. if ($doesntrun{$pidfile}) {
  1356. return (2, 0, 0, 0);
  1357. }
  1358. my $pid = processexists($pidfile);
  1359. if($pid > 0) {
  1360. stopserver($server, "$pid");
  1361. }
  1362. unlink($pidfile) if(-f $pidfile);
  1363. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1364. $certfile = 'stunnel.pem' unless($certfile);
  1365. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1366. my $flags = "";
  1367. $flags .= "--verbose " if($debugprotocol);
  1368. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1369. $flags .= "--logdir \"$LOGDIR\" ";
  1370. $flags .= "--id $idnum " if($idnum > 1);
  1371. $flags .= "--ipv$ipvnum --proto $proto ";
  1372. $flags .= "--certfile \"$certfile\" " if($certfile ne 'stunnel.pem');
  1373. $flags .= "--stunnel \"$stunnel\" --srcdir \"$srcdir\" ";
  1374. $flags .= "--connect $clearport";
  1375. my $port = getfreeport($ipvnum);
  1376. my $options = "$flags --accept $port";
  1377. my $cmd = "$perl $srcdir/secureserver.pl $options";
  1378. my ($protospid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1379. if($protospid <= 0 || !pidexists($protospid)) {
  1380. # it is NOT alive
  1381. # don't call stopserver since that will also kill the dependent
  1382. # server that has already been started properly
  1383. $doesntrun{$pidfile} = 1;
  1384. $protospid = $pid2 = 0;
  1385. logmsg "RUN: failed to start the $srvrname server\n";
  1386. return (3, 0, 0, 0);
  1387. }
  1388. $doesntrun{$pidfile} = 0;
  1389. $runcert{$server} = $certfile;
  1390. if($verb) {
  1391. logmsg "RUN: $srvrname server is PID $protospid port $port\n";
  1392. }
  1393. return (0+!$protospid, $protospid, $pid2, $port);
  1394. }
  1395. #######################################################################
  1396. # start the tftp server
  1397. #
  1398. sub runtftpserver {
  1399. my ($id, $verb, $ipv6) = @_;
  1400. my $ip = $HOSTIP;
  1401. my $proto = 'tftp';
  1402. my $ipvnum = 4;
  1403. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1404. if($ipv6) {
  1405. # if IPv6, use a different setup
  1406. $ipvnum = 6;
  1407. $ip = $HOST6IP;
  1408. }
  1409. my $server = servername_id($proto, $ipvnum, $idnum);
  1410. my $pidfile = $serverpidfile{$server};
  1411. # don't retry if the server doesn't work
  1412. if ($doesntrun{$pidfile}) {
  1413. return (2, 0, 0, 0);
  1414. }
  1415. my $pid = processexists($pidfile);
  1416. if($pid > 0) {
  1417. stopserver($server, "$pid");
  1418. }
  1419. unlink($pidfile) if(-f $pidfile);
  1420. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1421. my $portfile = $serverportfile{$server};
  1422. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1423. my $flags = "";
  1424. $flags .= "--verbose " if($debugprotocol);
  1425. $flags .= "--pidfile \"$pidfile\" ";
  1426. $flags .= "--portfile \"$portfile\" ";
  1427. $flags .= "--logfile \"$logfile\" ";
  1428. $flags .= "--logdir \"$LOGDIR\" ";
  1429. $flags .= "--id $idnum " if($idnum > 1);
  1430. $flags .= "--ipv$ipvnum --port 0 --srcdir \"$srcdir\"";
  1431. my $cmd = "$perl $srcdir/tftpserver.pl $flags";
  1432. my ($tftppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1433. if($tftppid <= 0 || !pidexists($tftppid)) {
  1434. # it is NOT alive
  1435. logmsg "RUN: failed to start the $srvrname server\n";
  1436. stopserver($server, "$pid2");
  1437. $doesntrun{$pidfile} = 1;
  1438. return (1, 0, 0, 0);
  1439. }
  1440. my $port = pidfromfile($portfile);
  1441. # Server is up. Verify that we can speak to it.
  1442. my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
  1443. if(!$pid3) {
  1444. logmsg "RUN: $srvrname server failed verification\n";
  1445. # failed to talk to it properly. Kill the server and return failure
  1446. stopserver($server, "$tftppid $pid2");
  1447. $doesntrun{$pidfile} = 1;
  1448. return (1, 0, 0, 0);
  1449. }
  1450. $pid2 = $pid3;
  1451. if($verb) {
  1452. logmsg "RUN: $srvrname server on PID $tftppid port $port\n";
  1453. }
  1454. return (0, $pid2, $tftppid, $port);
  1455. }
  1456. #######################################################################
  1457. # start the rtsp server
  1458. #
  1459. sub runrtspserver {
  1460. my ($verb, $ipv6) = @_;
  1461. my $ip = $HOSTIP;
  1462. my $proto = 'rtsp';
  1463. my $ipvnum = 4;
  1464. my $idnum = 1;
  1465. if($ipv6) {
  1466. # if IPv6, use a different setup
  1467. $ipvnum = 6;
  1468. $ip = $HOST6IP;
  1469. }
  1470. my $server = servername_id($proto, $ipvnum, $idnum);
  1471. my $pidfile = $serverpidfile{$server};
  1472. my $portfile = $serverportfile{$server};
  1473. # don't retry if the server doesn't work
  1474. if ($doesntrun{$pidfile}) {
  1475. return (2, 0, 0, 0);
  1476. }
  1477. my $pid = processexists($pidfile);
  1478. if($pid > 0) {
  1479. stopserver($server, "$pid");
  1480. }
  1481. unlink($pidfile) if(-f $pidfile);
  1482. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1483. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1484. my $flags = "";
  1485. $flags .= "--verbose " if($debugprotocol);
  1486. $flags .= "--pidfile \"$pidfile\" ";
  1487. $flags .= "--portfile \"$portfile\" ";
  1488. $flags .= "--logfile \"$logfile\" ";
  1489. $flags .= "--logdir \"$LOGDIR\" ";
  1490. $flags .= "--id $idnum " if($idnum > 1);
  1491. $flags .= "--ipv$ipvnum --port 0 --srcdir \"$srcdir\"";
  1492. my $cmd = "$perl $srcdir/rtspserver.pl $flags";
  1493. my ($rtsppid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1494. if($rtsppid <= 0 || !pidexists($rtsppid)) {
  1495. # it is NOT alive
  1496. logmsg "RUN: failed to start the $srvrname server\n";
  1497. stopserver($server, "$pid2");
  1498. $doesntrun{$pidfile} = 1;
  1499. return (1, 0, 0, 0);
  1500. }
  1501. my $port = pidfromfile($portfile);
  1502. # Server is up. Verify that we can speak to it.
  1503. my $pid3 = verifyserver($proto, $ipvnum, $idnum, $ip, $port);
  1504. if(!$pid3) {
  1505. logmsg "RUN: $srvrname server failed verification\n";
  1506. # failed to talk to it properly. Kill the server and return failure
  1507. stopserver($server, "$rtsppid $pid2");
  1508. $doesntrun{$pidfile} = 1;
  1509. return (1, 0, 0, 0);
  1510. }
  1511. $pid2 = $pid3;
  1512. if($verb) {
  1513. logmsg "RUN: $srvrname server PID $rtsppid port $port\n";
  1514. }
  1515. return (0, $rtsppid, $pid2, $port);
  1516. }
  1517. #######################################################################
  1518. # Start the ssh (scp/sftp) server
  1519. #
  1520. sub runsshserver {
  1521. my ($id, $verb, $ipv6) = @_;
  1522. my $ip=$HOSTIP;
  1523. my $proto = 'ssh';
  1524. my $ipvnum = 4;
  1525. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1526. if(!$USER) {
  1527. logmsg "Can't start ssh server due to lack of USER name\n";
  1528. return (4, 0, 0, 0);
  1529. }
  1530. my $server = servername_id($proto, $ipvnum, $idnum);
  1531. my $pidfile = $serverpidfile{$server};
  1532. # don't retry if the server doesn't work
  1533. if ($doesntrun{$pidfile}) {
  1534. return (2, 0, 0, 0);
  1535. }
  1536. my $sshd = find_sshd();
  1537. if($sshd) {
  1538. ($sshdid,$sshdvernum,$sshdverstr,$sshderror) = sshversioninfo($sshd);
  1539. logmsg $sshderror if($sshderror);
  1540. }
  1541. my $pid = processexists($pidfile);
  1542. if($pid > 0) {
  1543. stopserver($server, "$pid");
  1544. }
  1545. unlink($pidfile) if(-f $pidfile);
  1546. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1547. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1548. my $flags = "";
  1549. $flags .= "--verbose " if($verb);
  1550. $flags .= "--debugprotocol " if($debugprotocol);
  1551. $flags .= "--pidfile \"$pidfile\" ";
  1552. $flags .= "--logdir \"$LOGDIR\" ";
  1553. $flags .= "--id $idnum " if($idnum > 1);
  1554. $flags .= "--ipv$ipvnum --addr \"$ip\" ";
  1555. $flags .= "--user \"$USER\"";
  1556. my @tports;
  1557. my $port = getfreeport($ipvnum);
  1558. push @tports, $port;
  1559. my $options = "$flags --sshport $port";
  1560. my $cmd = "$perl $srcdir/sshserver.pl $options";
  1561. my ($sshpid, $pid2) = startnew($cmd, $pidfile, 60, 0);
  1562. # on loaded systems sshserver start up can take longer than the
  1563. # timeout passed to startnew, when this happens startnew completes
  1564. # without being able to read the pidfile and consequently returns a
  1565. # zero pid2 above.
  1566. if($sshpid <= 0 || !pidexists($sshpid)) {
  1567. # it is NOT alive
  1568. stopserver($server, "$pid2");
  1569. $doesntrun{$pidfile} = 1;
  1570. $sshpid = $pid2 = 0;
  1571. logmsg "RUN: failed to start the $srvrname server on $port\n";
  1572. return (3, 0, 0, 0);
  1573. }
  1574. # once it is known that the ssh server is alive, sftp server
  1575. # verification is performed actually connecting to it, authenticating
  1576. # and performing a very simple remote command. This verification is
  1577. # tried only one time.
  1578. $sshdlog = server_logfilename($LOGDIR, 'ssh', $ipvnum, $idnum);
  1579. $sftplog = server_logfilename($LOGDIR, 'sftp', $ipvnum, $idnum);
  1580. if(verifysftp('sftp', $ipvnum, $idnum, $ip, $port) < 1) {
  1581. logmsg "RUN: SFTP server failed verification\n";
  1582. # failed to talk to it properly. Kill the server and return failure
  1583. display_sftplog();
  1584. display_sftpconfig();
  1585. display_sshdlog();
  1586. display_sshdconfig();
  1587. stopserver($server, "$sshpid $pid2");
  1588. $doesntrun{$pidfile} = 1;
  1589. $sshpid = $pid2 = 0;
  1590. logmsg "RUN: failed to verify the $srvrname server on $port\n";
  1591. return (5, 0, 0, 0);
  1592. }
  1593. # we're happy, no need to loop anymore!
  1594. $doesntrun{$pidfile} = 0;
  1595. my $hostfile;
  1596. if(!open($hostfile, "<", "$LOGDIR/$PIDDIR/$hstpubmd5f") ||
  1597. (read($hostfile, $SSHSRVMD5, 32) != 32) ||
  1598. !close($hostfile) ||
  1599. ($SSHSRVMD5 !~ /^[a-f0-9]{32}$/i))
  1600. {
  1601. my $msg = "Fatal: $srvrname pubkey md5 missing : \"$hstpubmd5f\" : $!";
  1602. logmsg "$msg\n";
  1603. stopservers($verb);
  1604. die $msg;
  1605. }
  1606. if(!open($hostfile, "<", "$LOGDIR/$PIDDIR/$hstpubsha256f") ||
  1607. (read($hostfile, $SSHSRVSHA256, 48) == 0) ||
  1608. !close($hostfile))
  1609. {
  1610. my $msg = "Fatal: $srvrname pubkey sha256 missing : \"$hstpubsha256f\" : $!";
  1611. logmsg "$msg\n";
  1612. stopservers($verb);
  1613. die $msg;
  1614. }
  1615. logmsg "RUN: $srvrname on PID $pid2 port $port\n" if($verb);
  1616. return (0, $pid2, $sshpid, $port);
  1617. }
  1618. #######################################################################
  1619. # Start the MQTT server
  1620. #
  1621. sub runmqttserver {
  1622. my ($id, $verb, $ipv6) = @_;
  1623. my $ip=$HOSTIP;
  1624. my $proto = 'mqtt';
  1625. my $port = protoport($proto);
  1626. my $ipvnum = 4;
  1627. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1628. my $server = servername_id($proto, $ipvnum, $idnum);
  1629. my $pidfile = $serverpidfile{$server};
  1630. my $portfile = $serverportfile{$server};
  1631. # don't retry if the server doesn't work
  1632. if ($doesntrun{$pidfile}) {
  1633. return (2, 0, 0);
  1634. }
  1635. my $pid = processexists($pidfile);
  1636. if($pid > 0) {
  1637. stopserver($server, "$pid");
  1638. }
  1639. unlink($pidfile) if(-f $pidfile);
  1640. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1641. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1642. # start our MQTT server - on a random port!
  1643. my $cmd="server/mqttd".exe_ext('SRV').
  1644. " --port 0 ".
  1645. " --pidfile $pidfile".
  1646. " --portfile $portfile".
  1647. " --config $LOGDIR/$SERVERCMD".
  1648. " --logfile $logfile".
  1649. " --logdir $LOGDIR";
  1650. my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
  1651. if($sockspid <= 0 || !pidexists($sockspid)) {
  1652. # it is NOT alive
  1653. logmsg "RUN: failed to start the $srvrname server\n";
  1654. stopserver($server, "$pid2");
  1655. $doesntrun{$pidfile} = 1;
  1656. return (1, 0, 0);
  1657. }
  1658. my $mqttport = pidfromfile($portfile);
  1659. $PORT{"mqtt"} = $mqttport;
  1660. if($verb) {
  1661. logmsg "RUN: $srvrname server is now running PID $pid2 on PORT $mqttport\n";
  1662. }
  1663. return (0, $pid2, $sockspid);
  1664. }
  1665. #######################################################################
  1666. # Start the socks server
  1667. #
  1668. sub runsocksserver {
  1669. my ($id, $verb, $ipv6, $is_unix) = @_;
  1670. my $ip=$HOSTIP;
  1671. my $proto = 'socks';
  1672. my $ipvnum = 4;
  1673. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1674. my $server = servername_id($proto, $ipvnum, $idnum);
  1675. my $pidfile = $serverpidfile{$server};
  1676. # don't retry if the server doesn't work
  1677. if ($doesntrun{$pidfile}) {
  1678. return (2, 0, 0, 0);
  1679. }
  1680. my $pid = processexists($pidfile);
  1681. if($pid > 0) {
  1682. stopserver($server, "$pid");
  1683. }
  1684. unlink($pidfile) if(-f $pidfile);
  1685. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1686. my $portfile = $serverportfile{$server};
  1687. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1688. # start our socks server, get commands from the FTP cmd file
  1689. my $cmd="";
  1690. if($is_unix) {
  1691. $cmd="server/socksd".exe_ext('SRV').
  1692. " --pidfile $pidfile".
  1693. " --reqfile $LOGDIR/$SOCKSIN".
  1694. " --logfile $logfile".
  1695. " --unix-socket $SOCKSUNIXPATH".
  1696. " --backend $HOSTIP".
  1697. " --config $LOGDIR/$SERVERCMD";
  1698. } else {
  1699. $cmd="server/socksd".exe_ext('SRV').
  1700. " --port 0 ".
  1701. " --pidfile $pidfile".
  1702. " --portfile $portfile".
  1703. " --reqfile $LOGDIR/$SOCKSIN".
  1704. " --logfile $logfile".
  1705. " --backend $HOSTIP".
  1706. " --config $LOGDIR/$SERVERCMD";
  1707. }
  1708. my ($sockspid, $pid2) = startnew($cmd, $pidfile, 30, 0);
  1709. if($sockspid <= 0 || !pidexists($sockspid)) {
  1710. # it is NOT alive
  1711. logmsg "RUN: failed to start the $srvrname server\n";
  1712. stopserver($server, "$pid2");
  1713. $doesntrun{$pidfile} = 1;
  1714. return (1, 0, 0, 0);
  1715. }
  1716. my $port = pidfromfile($portfile);
  1717. if($verb) {
  1718. logmsg "RUN: $srvrname server is now running PID $pid2\n";
  1719. }
  1720. return (0, $pid2, $sockspid, $port);
  1721. }
  1722. #######################################################################
  1723. # start the dict server
  1724. #
  1725. sub rundictserver {
  1726. my ($verb, $alt) = @_;
  1727. my $proto = "dict";
  1728. my $ip = $HOSTIP;
  1729. my $ipvnum = 4;
  1730. my $idnum = 1;
  1731. if($alt eq "ipv6") {
  1732. # No IPv6
  1733. }
  1734. my $server = servername_id($proto, $ipvnum, $idnum);
  1735. my $pidfile = $serverpidfile{$server};
  1736. # don't retry if the server doesn't work
  1737. if ($doesntrun{$pidfile}) {
  1738. return (2, 0, 0, 0);
  1739. }
  1740. my $pid = processexists($pidfile);
  1741. if($pid > 0) {
  1742. stopserver($server, "$pid");
  1743. }
  1744. unlink($pidfile) if(-f $pidfile);
  1745. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1746. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1747. my $flags = "";
  1748. $flags .= "--verbose 1 " if($debugprotocol);
  1749. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1750. $flags .= "--id $idnum " if($idnum > 1);
  1751. $flags .= "--srcdir \"$srcdir\" ";
  1752. $flags .= "--host $HOSTIP";
  1753. my $port = getfreeport($ipvnum);
  1754. my $aflags = "--port $port $flags";
  1755. my $cmd = "$srcdir/dictserver.py $aflags";
  1756. my ($dictpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1757. if($dictpid <= 0 || !pidexists($dictpid)) {
  1758. # it is NOT alive
  1759. stopserver($server, "$pid2");
  1760. $doesntrun{$pidfile} = 1;
  1761. $dictpid = $pid2 = 0;
  1762. logmsg "RUN: failed to start the $srvrname server\n";
  1763. return (3, 0, 0, 0);
  1764. }
  1765. $doesntrun{$pidfile} = 0;
  1766. if($verb) {
  1767. logmsg "RUN: $srvrname server PID $dictpid port $port\n";
  1768. }
  1769. return (0+!$dictpid, $dictpid, $pid2, $port);
  1770. }
  1771. #######################################################################
  1772. # start the SMB server
  1773. #
  1774. sub runsmbserver {
  1775. my ($verb, $alt) = @_;
  1776. my $proto = "smb";
  1777. my $ip = $HOSTIP;
  1778. my $ipvnum = 4;
  1779. my $idnum = 1;
  1780. if($alt eq "ipv6") {
  1781. # No IPv6
  1782. }
  1783. my $server = servername_id($proto, $ipvnum, $idnum);
  1784. my $pidfile = $serverpidfile{$server};
  1785. # don't retry if the server doesn't work
  1786. if ($doesntrun{$pidfile}) {
  1787. return (2, 0, 0, 0);
  1788. }
  1789. my $pid = processexists($pidfile);
  1790. if($pid > 0) {
  1791. stopserver($server, "$pid");
  1792. }
  1793. unlink($pidfile) if(-f $pidfile);
  1794. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1795. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1796. my $flags = "";
  1797. $flags .= "--verbose 1 " if($debugprotocol);
  1798. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1799. $flags .= "--id $idnum " if($idnum > 1);
  1800. $flags .= "--srcdir \"$srcdir\" ";
  1801. $flags .= "--host $HOSTIP";
  1802. my $port = getfreeport($ipvnum);
  1803. my $aflags = "--port $port $flags";
  1804. my $cmd = "$srcdir/smbserver.py $aflags";
  1805. my ($smbpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1806. if($smbpid <= 0 || !pidexists($smbpid)) {
  1807. # it is NOT alive
  1808. stopserver($server, "$pid2");
  1809. $doesntrun{$pidfile} = 1;
  1810. $smbpid = $pid2 = 0;
  1811. logmsg "RUN: failed to start the $srvrname server\n";
  1812. return (3, 0, 0, 0);
  1813. }
  1814. $doesntrun{$pidfile} = 0;
  1815. if($verb) {
  1816. logmsg "RUN: $srvrname server PID $smbpid port $port\n";
  1817. }
  1818. return (0+!$smbpid, $smbpid, $pid2, $port);
  1819. }
  1820. #######################################################################
  1821. # start the telnet server
  1822. #
  1823. sub runnegtelnetserver {
  1824. my ($verb, $alt) = @_;
  1825. my $proto = "telnet";
  1826. my $ip = $HOSTIP;
  1827. my $ipvnum = 4;
  1828. my $idnum = 1;
  1829. if($alt eq "ipv6") {
  1830. # No IPv6
  1831. }
  1832. my $server = servername_id($proto, $ipvnum, $idnum);
  1833. my $pidfile = $serverpidfile{$server};
  1834. # don't retry if the server doesn't work
  1835. if ($doesntrun{$pidfile}) {
  1836. return (2, 0, 0, 0);
  1837. }
  1838. my $pid = processexists($pidfile);
  1839. if($pid > 0) {
  1840. stopserver($server, "$pid");
  1841. }
  1842. unlink($pidfile) if(-f $pidfile);
  1843. my $srvrname = servername_str($proto, $ipvnum, $idnum);
  1844. my $logfile = server_logfilename($LOGDIR, $proto, $ipvnum, $idnum);
  1845. my $flags = "";
  1846. $flags .= "--verbose 1 " if($debugprotocol);
  1847. $flags .= "--pidfile \"$pidfile\" --logfile \"$logfile\" ";
  1848. $flags .= "--id $idnum " if($idnum > 1);
  1849. $flags .= "--srcdir \"$srcdir\"";
  1850. my $port = getfreeport($ipvnum);
  1851. my $aflags = "--port $port $flags";
  1852. my $cmd = "$srcdir/negtelnetserver.py $aflags";
  1853. my ($ntelpid, $pid2) = startnew($cmd, $pidfile, 15, 0);
  1854. if($ntelpid <= 0 || !pidexists($ntelpid)) {
  1855. # it is NOT alive
  1856. stopserver($server, "$pid2");
  1857. $doesntrun{$pidfile} = 1;
  1858. $ntelpid = $pid2 = 0;
  1859. logmsg "RUN: failed to start the $srvrname server\n";
  1860. return (3, 0, 0, 0);
  1861. }
  1862. $doesntrun{$pidfile} = 0;
  1863. if($verb) {
  1864. logmsg "RUN: $srvrname server PID $ntelpid port $port\n";
  1865. }
  1866. return (0+!$ntelpid, $ntelpid, $pid2, $port);
  1867. }
  1868. #######################################################################
  1869. # Single shot http and gopher server responsiveness test. This should only
  1870. # be used to verify that a server present in %run hash is still functional
  1871. #
  1872. sub responsive_http_server {
  1873. my ($proto, $verb, $alt, $port_or_path) = @_;
  1874. my $ip = $HOSTIP;
  1875. my $ipvnum = 4;
  1876. my $idnum = 1;
  1877. if($alt eq "ipv6") {
  1878. # if IPv6, use a different setup
  1879. $ipvnum = 6;
  1880. $ip = $HOST6IP;
  1881. }
  1882. elsif($alt eq "proxy") {
  1883. $idnum = 2;
  1884. }
  1885. elsif($alt eq "unix") {
  1886. # IP (protocol) is mutually exclusive with Unix sockets
  1887. $ipvnum = "unix";
  1888. }
  1889. return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port_or_path);
  1890. }
  1891. #######################################################################
  1892. # Single shot pingpong server responsiveness test. This should only be
  1893. # used to verify that a server present in %run hash is still functional
  1894. #
  1895. sub responsive_pingpong_server {
  1896. my ($proto, $id, $verb, $ipv6) = @_;
  1897. my $port;
  1898. my $ip = ($ipv6 && ($ipv6 =~ /6$/)) ? "$HOST6IP" : "$HOSTIP";
  1899. my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
  1900. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1901. my $protoip = $proto . ($ipvnum == 6? '6': '');
  1902. if($proto =~ /^(?:ftp|imap|pop3|smtp)$/) {
  1903. $port = protoport($protoip);
  1904. }
  1905. else {
  1906. logmsg "Unsupported protocol $proto!!\n";
  1907. return 0;
  1908. }
  1909. return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
  1910. }
  1911. #######################################################################
  1912. # Single shot rtsp server responsiveness test. This should only be
  1913. # used to verify that a server present in %run hash is still functional
  1914. #
  1915. sub responsive_rtsp_server {
  1916. my ($verb, $ipv6) = @_;
  1917. my $proto = 'rtsp';
  1918. my $port = protoport($proto);
  1919. my $ip = $HOSTIP;
  1920. my $ipvnum = 4;
  1921. my $idnum = 1;
  1922. if($ipv6) {
  1923. # if IPv6, use a different setup
  1924. $ipvnum = 6;
  1925. $port = protoport('rtsp6');
  1926. $ip = $HOST6IP;
  1927. }
  1928. return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
  1929. }
  1930. #######################################################################
  1931. # Single shot tftp server responsiveness test. This should only be
  1932. # used to verify that a server present in %run hash is still functional
  1933. #
  1934. sub responsive_tftp_server {
  1935. my ($id, $verb, $ipv6) = @_;
  1936. my $proto = 'tftp';
  1937. my $port = protoport($proto);
  1938. my $ip = $HOSTIP;
  1939. my $ipvnum = 4;
  1940. my $idnum = ($id && ($id =~ /^(\d+)$/) && ($id > 1)) ? $id : 1;
  1941. if($ipv6) {
  1942. # if IPv6, use a different setup
  1943. $ipvnum = 6;
  1944. $port = protoport('tftp6');
  1945. $ip = $HOST6IP;
  1946. }
  1947. return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
  1948. }
  1949. #######################################################################
  1950. # Single shot non-stunnel HTTP TLS extensions capable server
  1951. # responsiveness test. This should only be used to verify that a
  1952. # server present in %run hash is still functional
  1953. #
  1954. sub responsive_httptls_server {
  1955. my ($verb, $ipv6) = @_;
  1956. my $ipvnum = ($ipv6 && ($ipv6 =~ /6$/)) ? 6 : 4;
  1957. my $proto = "httptls";
  1958. my $port = protoport($proto);
  1959. my $ip = "$HOSTIP";
  1960. my $idnum = 1;
  1961. if ($ipvnum == 6) {
  1962. $port = protoport("httptls6");
  1963. $ip = "$HOST6IP";
  1964. }
  1965. return &responsiveserver($proto, $ipvnum, $idnum, $ip, $port);
  1966. }
  1967. #######################################################################
  1968. # startservers() starts all the named servers
  1969. #
  1970. # Returns: string with error reason or blank for success, and an integer:
  1971. # 0 for success
  1972. # 1 for an error starting the server
  1973. # 2 for not the first time getting an error starting the server
  1974. # 3 for a failure to stop a server in order to restart it
  1975. # 4 for an unsupported server type
  1976. #
  1977. sub startservers {
  1978. my @what = @_;
  1979. my ($pid, $pid2);
  1980. my $serr; # error while starting a server (as as the return enumerations)
  1981. for(@what) {
  1982. my (@whatlist) = split(/\s+/,$_);
  1983. my $what = lc($whatlist[0]);
  1984. $what =~ s/[^a-z0-9\/-]//g;
  1985. my $certfile;
  1986. if($what =~ /^(ftp|gopher|http|imap|pop3|smtp)s((\d*)(-ipv6|-unix|))$/) {
  1987. $certfile = ($whatlist[1]) ? $whatlist[1] : 'stunnel.pem';
  1988. }
  1989. if(($what eq "pop3") ||
  1990. ($what eq "ftp") ||
  1991. ($what eq "imap") ||
  1992. ($what eq "smtp")) {
  1993. if($torture && $run{$what} &&
  1994. !responsive_pingpong_server($what, "", $verbose)) {
  1995. if(stopserver($what)) {
  1996. return ("failed stopping unresponsive ".uc($what)." server", 3);
  1997. }
  1998. }
  1999. if(!$run{$what}) {
  2000. ($serr, $pid, $pid2) = runpingpongserver($what, "", $verbose);
  2001. if($pid <= 0) {
  2002. return ("failed starting ". uc($what) ." server", $serr);
  2003. }
  2004. logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2) if($verbose);
  2005. $run{$what}="$pid $pid2";
  2006. }
  2007. }
  2008. elsif($what eq "ftp-ipv6") {
  2009. if($torture && $run{'ftp-ipv6'} &&
  2010. !responsive_pingpong_server("ftp", "", $verbose, "ipv6")) {
  2011. if(stopserver('ftp-ipv6')) {
  2012. return ("failed stopping unresponsive FTP-IPv6 server", 3);
  2013. }
  2014. }
  2015. if(!$run{'ftp-ipv6'}) {
  2016. ($serr, $pid, $pid2) = runpingpongserver("ftp", "", $verbose, "ipv6");
  2017. if($pid <= 0) {
  2018. return ("failed starting FTP-IPv6 server", $serr);
  2019. }
  2020. logmsg sprintf("* pid ftp-ipv6 => %d %d\n", $pid,
  2021. $pid2) if($verbose);
  2022. $run{'ftp-ipv6'}="$pid $pid2";
  2023. }
  2024. }
  2025. elsif($what eq "gopher") {
  2026. if($torture && $run{'gopher'} &&
  2027. !responsive_http_server("gopher", $verbose, 0,
  2028. protoport("gopher"))) {
  2029. if(stopserver('gopher')) {
  2030. return ("failed stopping unresponsive GOPHER server", 3);
  2031. }
  2032. }
  2033. if(!$run{'gopher'}) {
  2034. ($serr, $pid, $pid2, $PORT{'gopher'}) =
  2035. runhttpserver("gopher", $verbose, 0);
  2036. if($pid <= 0) {
  2037. return ("failed starting GOPHER server", $serr);
  2038. }
  2039. logmsg sprintf ("* pid gopher => %d %d\n", $pid, $pid2)
  2040. if($verbose);
  2041. $run{'gopher'}="$pid $pid2";
  2042. }
  2043. }
  2044. elsif($what eq "gopher-ipv6") {
  2045. if($torture && $run{'gopher-ipv6'} &&
  2046. !responsive_http_server("gopher", $verbose, "ipv6",
  2047. protoport("gopher"))) {
  2048. if(stopserver('gopher-ipv6')) {
  2049. return ("failed stopping unresponsive GOPHER-IPv6 server", 3);
  2050. }
  2051. }
  2052. if(!$run{'gopher-ipv6'}) {
  2053. ($serr, $pid, $pid2, $PORT{"gopher6"}) =
  2054. runhttpserver("gopher", $verbose, "ipv6");
  2055. if($pid <= 0) {
  2056. return ("failed starting GOPHER-IPv6 server", $serr);
  2057. }
  2058. logmsg sprintf("* pid gopher-ipv6 => %d %d\n", $pid,
  2059. $pid2) if($verbose);
  2060. $run{'gopher-ipv6'}="$pid $pid2";
  2061. }
  2062. }
  2063. elsif($what eq "http/3") {
  2064. if(!$run{'http/3'}) {
  2065. ($serr, $pid, $pid2, $PORT{"http3"}) = runhttp3server($verbose);
  2066. if($pid <= 0) {
  2067. return ("failed starting HTTP/3 server", $serr);
  2068. }
  2069. logmsg sprintf ("* pid http/3 => %d %d\n", $pid, $pid2)
  2070. if($verbose);
  2071. $run{'http/3'}="$pid $pid2";
  2072. }
  2073. }
  2074. elsif($what eq "http/2") {
  2075. if(!$run{'http/2'}) {
  2076. ($serr, $pid, $pid2, $PORT{"http2"}, $PORT{"http2tls"}) =
  2077. runhttp2server($verbose);
  2078. if($pid <= 0) {
  2079. return ("failed starting HTTP/2 server", $serr);
  2080. }
  2081. logmsg sprintf ("* pid http/2 => %d %d\n", $pid, $pid2)
  2082. if($verbose);
  2083. $run{'http/2'}="$pid $pid2";
  2084. }
  2085. }
  2086. elsif($what eq "http") {
  2087. if($torture && $run{'http'} &&
  2088. !responsive_http_server("http", $verbose, 0, protoport('http'))) {
  2089. if(stopserver('http')) {
  2090. return ("failed stopping unresponsive HTTP server", 3);
  2091. }
  2092. }
  2093. if(!$run{'http'}) {
  2094. ($serr, $pid, $pid2, $PORT{'http'}) =
  2095. runhttpserver("http", $verbose, 0);
  2096. if($pid <= 0) {
  2097. return ("failed starting HTTP server", $serr);
  2098. }
  2099. logmsg sprintf ("* pid http => %d %d\n", $pid, $pid2)
  2100. if($verbose);
  2101. $run{'http'}="$pid $pid2";
  2102. }
  2103. }
  2104. elsif($what eq "http-proxy") {
  2105. if($torture && $run{'http-proxy'} &&
  2106. !responsive_http_server("http", $verbose, "proxy",
  2107. protoport("httpproxy"))) {
  2108. if(stopserver('http-proxy')) {
  2109. return ("failed stopping unresponsive HTTP-proxy server", 3);
  2110. }
  2111. }
  2112. if(!$run{'http-proxy'}) {
  2113. ($serr, $pid, $pid2, $PORT{"httpproxy"}) =
  2114. runhttpserver("http", $verbose, "proxy");
  2115. if($pid <= 0) {
  2116. return ("failed starting HTTP-proxy server", $serr);
  2117. }
  2118. logmsg sprintf ("* pid http-proxy => %d %d\n", $pid, $pid2)
  2119. if($verbose);
  2120. $run{'http-proxy'}="$pid $pid2";
  2121. }
  2122. }
  2123. elsif($what eq "http-ipv6") {
  2124. if($torture && $run{'http-ipv6'} &&
  2125. !responsive_http_server("http", $verbose, "ipv6",
  2126. protoport("http6"))) {
  2127. if(stopserver('http-ipv6')) {
  2128. return ("failed stopping unresponsive HTTP-IPv6 server", 3);
  2129. }
  2130. }
  2131. if(!$run{'http-ipv6'}) {
  2132. ($serr, $pid, $pid2, $PORT{"http6"}) =
  2133. runhttpserver("http", $verbose, "ipv6");
  2134. if($pid <= 0) {
  2135. return ("failed starting HTTP-IPv6 server", $serr);
  2136. }
  2137. logmsg sprintf("* pid http-ipv6 => %d %d\n", $pid, $pid2)
  2138. if($verbose);
  2139. $run{'http-ipv6'}="$pid $pid2";
  2140. }
  2141. }
  2142. elsif($what eq "rtsp") {
  2143. if($torture && $run{'rtsp'} &&
  2144. !responsive_rtsp_server($verbose)) {
  2145. if(stopserver('rtsp')) {
  2146. return ("failed stopping unresponsive RTSP server", 3);
  2147. }
  2148. }
  2149. if(!$run{'rtsp'}) {
  2150. ($serr, $pid, $pid2, $PORT{'rtsp'}) = runrtspserver($verbose);
  2151. if($pid <= 0) {
  2152. return ("failed starting RTSP server", $serr);
  2153. }
  2154. logmsg sprintf("* pid rtsp => %d %d\n", $pid, $pid2) if($verbose);
  2155. $run{'rtsp'}="$pid $pid2";
  2156. }
  2157. }
  2158. elsif($what eq "rtsp-ipv6") {
  2159. if($torture && $run{'rtsp-ipv6'} &&
  2160. !responsive_rtsp_server($verbose, "ipv6")) {
  2161. if(stopserver('rtsp-ipv6')) {
  2162. return ("failed stopping unresponsive RTSP-IPv6 server", 3);
  2163. }
  2164. }
  2165. if(!$run{'rtsp-ipv6'}) {
  2166. ($serr, $pid, $pid2, $PORT{'rtsp6'}) = runrtspserver($verbose, "ipv6");
  2167. if($pid <= 0) {
  2168. return ("failed starting RTSP-IPv6 server", $serr);
  2169. }
  2170. logmsg sprintf("* pid rtsp-ipv6 => %d %d\n", $pid, $pid2)
  2171. if($verbose);
  2172. $run{'rtsp-ipv6'}="$pid $pid2";
  2173. }
  2174. }
  2175. elsif($what =~ /^(ftp|imap|pop3|smtp)s$/) {
  2176. my $cproto = $1;
  2177. if(!$stunnel) {
  2178. # we can't run ftps tests without stunnel
  2179. return ("no stunnel", 4);
  2180. }
  2181. if($runcert{$what} && ($runcert{$what} ne $certfile)) {
  2182. # stop server when running and using a different cert
  2183. if(stopserver($what)) {
  2184. return ("failed stopping $what server with different cert", 3);
  2185. }
  2186. }
  2187. if($torture && $run{$cproto} &&
  2188. !responsive_pingpong_server($cproto, "", $verbose)) {
  2189. if(stopserver($cproto)) {
  2190. return ("failed stopping unresponsive $cproto server", 3);
  2191. }
  2192. }
  2193. if(!$run{$cproto}) {
  2194. ($serr, $pid, $pid2) = runpingpongserver($cproto, "", $verbose);
  2195. if($pid <= 0) {
  2196. return ("failed starting $cproto server", $serr);
  2197. }
  2198. logmsg sprintf("* pid $cproto => %d %d\n", $pid, $pid2) if($verbose);
  2199. $run{$cproto}="$pid $pid2";
  2200. }
  2201. if(!$run{$what}) {
  2202. ($serr, $pid, $pid2, $PORT{$what}) =
  2203. runsecureserver($verbose, "", $certfile, $what,
  2204. protoport($cproto));
  2205. if($pid <= 0) {
  2206. return ("failed starting $what server (stunnel)", $serr);
  2207. }
  2208. logmsg sprintf("* pid $what => %d %d\n", $pid, $pid2)
  2209. if($verbose);
  2210. $run{$what}="$pid $pid2";
  2211. }
  2212. }
  2213. elsif($what eq "file") {
  2214. # we support it but have no server!
  2215. }
  2216. elsif($what eq "https") {
  2217. if(!$stunnel) {
  2218. # we can't run https tests without stunnel
  2219. return ("no stunnel", 4);
  2220. }
  2221. if($runcert{'https'} && ($runcert{'https'} ne $certfile)) {
  2222. # stop server when running and using a different cert
  2223. if(stopserver('https')) {
  2224. return ("failed stopping HTTPS server with different cert", 3);
  2225. }
  2226. }
  2227. if($torture && $run{'http'} &&
  2228. !responsive_http_server("http", $verbose, 0,
  2229. protoport('http'))) {
  2230. if(stopserver('http')) {
  2231. return ("failed stopping unresponsive HTTP server", 3);
  2232. }
  2233. }
  2234. if(!$run{'http'}) {
  2235. ($serr, $pid, $pid2, $PORT{'http'}) =
  2236. runhttpserver("http", $verbose, 0);
  2237. if($pid <= 0) {
  2238. return ("failed starting HTTP server", $serr);
  2239. }
  2240. logmsg sprintf("* pid http => %d %d\n", $pid, $pid2) if($verbose);
  2241. $run{'http'}="$pid $pid2";
  2242. }
  2243. if(!$run{'https'}) {
  2244. ($serr, $pid, $pid2, $PORT{'https'}) =
  2245. runhttpsserver($verbose, "https", "", $certfile);
  2246. if($pid <= 0) {
  2247. return ("failed starting HTTPS server (stunnel)", $serr);
  2248. }
  2249. logmsg sprintf("* pid https => %d %d\n", $pid, $pid2)
  2250. if($verbose);
  2251. $run{'https'}="$pid $pid2";
  2252. }
  2253. }
  2254. elsif($what eq "gophers") {
  2255. if(!$stunnel) {
  2256. # we can't run TLS tests without stunnel
  2257. return ("no stunnel", 4);
  2258. }
  2259. if($runcert{'gophers'} && ($runcert{'gophers'} ne $certfile)) {
  2260. # stop server when running and using a different cert
  2261. if(stopserver('gophers')) {
  2262. return ("failed stopping GOPHERS server with different cert", 3);
  2263. }
  2264. }
  2265. if($torture && $run{'gopher'} &&
  2266. !responsive_http_server("gopher", $verbose, 0,
  2267. protoport('gopher'))) {
  2268. if(stopserver('gopher')) {
  2269. return ("failed stopping unresponsive GOPHER server", 3);
  2270. }
  2271. }
  2272. if(!$run{'gopher'}) {
  2273. my $port;
  2274. ($serr, $pid, $pid2, $port) =
  2275. runhttpserver("gopher", $verbose, 0);
  2276. $PORT{'gopher'} = $port;
  2277. if($pid <= 0) {
  2278. return ("failed starting GOPHER server", $serr);
  2279. }
  2280. logmsg sprintf("* pid gopher => %d %d\n", $pid, $pid2) if($verbose);
  2281. logmsg "GOPHERPORT => $port\n" if($verbose);
  2282. $run{'gopher'}="$pid $pid2";
  2283. }
  2284. if(!$run{'gophers'}) {
  2285. my $port;
  2286. ($serr, $pid, $pid2, $port) =
  2287. runhttpsserver($verbose, "gophers", "", $certfile);
  2288. $PORT{'gophers'} = $port;
  2289. if($pid <= 0) {
  2290. return ("failed starting GOPHERS server (stunnel)", $serr);
  2291. }
  2292. logmsg sprintf("* pid gophers => %d %d\n", $pid, $pid2)
  2293. if($verbose);
  2294. logmsg "GOPHERSPORT => $port\n" if($verbose);
  2295. $run{'gophers'}="$pid $pid2";
  2296. }
  2297. }
  2298. elsif($what eq "https-proxy") {
  2299. if(!$stunnel) {
  2300. # we can't run https-proxy tests without stunnel
  2301. return ("no stunnel", 4);
  2302. }
  2303. if($runcert{'https-proxy'} &&
  2304. ($runcert{'https-proxy'} ne $certfile)) {
  2305. # stop server when running and using a different cert
  2306. if(stopserver('https-proxy')) {
  2307. return ("failed stopping HTTPS-proxy with different cert", 3);
  2308. }
  2309. }
  2310. # we front the http-proxy with stunnel so we need to make sure the
  2311. # proxy runs as well
  2312. my ($f, $e) = startservers("http-proxy");
  2313. if($f) {
  2314. return ($f, $e);
  2315. }
  2316. if(!$run{'https-proxy'}) {
  2317. ($serr, $pid, $pid2, $PORT{"httpsproxy"}) =
  2318. runhttpsserver($verbose, "https", "proxy", $certfile);
  2319. if($pid <= 0) {
  2320. return ("failed starting HTTPS-proxy (stunnel)", $serr);
  2321. }
  2322. logmsg sprintf("* pid https-proxy => %d %d\n", $pid, $pid2)
  2323. if($verbose);
  2324. $run{'https-proxy'}="$pid $pid2";
  2325. }
  2326. }
  2327. elsif($what eq "httptls") {
  2328. if(!$httptlssrv) {
  2329. # for now, we can't run http TLS-EXT tests without gnutls-serv
  2330. return ("no gnutls-serv (with SRP support)", 4);
  2331. }
  2332. if($torture && $run{'httptls'} &&
  2333. !responsive_httptls_server($verbose, "IPv4")) {
  2334. if(stopserver('httptls')) {
  2335. return ("failed stopping unresponsive HTTPTLS server", 3);
  2336. }
  2337. }
  2338. if(!$run{'httptls'}) {
  2339. ($serr, $pid, $pid2, $PORT{'httptls'}) =
  2340. runhttptlsserver($verbose, "IPv4");
  2341. if($pid <= 0) {
  2342. return ("failed starting HTTPTLS server (gnutls-serv)", $serr);
  2343. }
  2344. logmsg sprintf("* pid httptls => %d %d\n", $pid, $pid2)
  2345. if($verbose);
  2346. $run{'httptls'}="$pid $pid2";
  2347. }
  2348. }
  2349. elsif($what eq "httptls-ipv6") {
  2350. if(!$httptlssrv) {
  2351. # for now, we can't run http TLS-EXT tests without gnutls-serv
  2352. return ("no gnutls-serv", 4);
  2353. }
  2354. if($torture && $run{'httptls-ipv6'} &&
  2355. !responsive_httptls_server($verbose, "ipv6")) {
  2356. if(stopserver('httptls-ipv6')) {
  2357. return ("failed stopping unresponsive HTTPTLS-IPv6 server", 3);
  2358. }
  2359. }
  2360. if(!$run{'httptls-ipv6'}) {
  2361. ($serr, $pid, $pid2, $PORT{"httptls6"}) =
  2362. runhttptlsserver($verbose, "ipv6");
  2363. if($pid <= 0) {
  2364. return ("failed starting HTTPTLS-IPv6 server (gnutls-serv)", $serr);
  2365. }
  2366. logmsg sprintf("* pid httptls-ipv6 => %d %d\n", $pid, $pid2)
  2367. if($verbose);
  2368. $run{'httptls-ipv6'}="$pid $pid2";
  2369. }
  2370. }
  2371. elsif($what eq "tftp") {
  2372. if($torture && $run{'tftp'} &&
  2373. !responsive_tftp_server("", $verbose)) {
  2374. if(stopserver('tftp')) {
  2375. return ("failed stopping unresponsive TFTP server", 3);
  2376. }
  2377. }
  2378. if(!$run{'tftp'}) {
  2379. ($serr, $pid, $pid2, $PORT{'tftp'}) =
  2380. runtftpserver("", $verbose);
  2381. if($pid <= 0) {
  2382. return ("failed starting TFTP server", $serr);
  2383. }
  2384. logmsg sprintf("* pid tftp => %d %d\n", $pid, $pid2) if($verbose);
  2385. $run{'tftp'}="$pid $pid2";
  2386. }
  2387. }
  2388. elsif($what eq "tftp-ipv6") {
  2389. if($torture && $run{'tftp-ipv6'} &&
  2390. !responsive_tftp_server("", $verbose, "ipv6")) {
  2391. if(stopserver('tftp-ipv6')) {
  2392. return ("failed stopping unresponsive TFTP-IPv6 server", 3);
  2393. }
  2394. }
  2395. if(!$run{'tftp-ipv6'}) {
  2396. ($serr, $pid, $pid2, $PORT{'tftp6'}) =
  2397. runtftpserver("", $verbose, "ipv6");
  2398. if($pid <= 0) {
  2399. return ("failed starting TFTP-IPv6 server", $serr);
  2400. }
  2401. logmsg sprintf("* pid tftp-ipv6 => %d %d\n", $pid, $pid2) if($verbose);
  2402. $run{'tftp-ipv6'}="$pid $pid2";
  2403. }
  2404. }
  2405. elsif($what eq "sftp" || $what eq "scp") {
  2406. if(!$run{'ssh'}) {
  2407. ($serr, $pid, $pid2, $PORT{'ssh'}) = runsshserver("", $verbose);
  2408. if($pid <= 0) {
  2409. return ("failed starting SSH server", $serr);
  2410. }
  2411. logmsg sprintf("* pid ssh => %d %d\n", $pid, $pid2) if($verbose);
  2412. $run{'ssh'}="$pid $pid2";
  2413. }
  2414. }
  2415. elsif($what eq "socks4" || $what eq "socks5" ) {
  2416. if(!$run{'socks'}) {
  2417. ($serr, $pid, $pid2, $PORT{"socks"}) = runsocksserver("", $verbose);
  2418. if($pid <= 0) {
  2419. return ("failed starting socks server", $serr);
  2420. }
  2421. logmsg sprintf("* pid socks => %d %d\n", $pid, $pid2) if($verbose);
  2422. $run{'socks'}="$pid $pid2";
  2423. }
  2424. }
  2425. elsif($what eq "socks5unix") {
  2426. if(!$run{'socks5unix'}) {
  2427. ($serr, $pid, $pid2) = runsocksserver("2", $verbose, "", "unix");
  2428. if($pid <= 0) {
  2429. return ("failed starting socks5unix server", $serr);
  2430. }
  2431. logmsg sprintf("* pid socks5unix => %d %d\n", $pid, $pid2) if($verbose);
  2432. $run{'socks5unix'}="$pid $pid2";
  2433. }
  2434. }
  2435. elsif($what eq "mqtt" ) {
  2436. if(!$run{'mqtt'}) {
  2437. ($serr, $pid, $pid2) = runmqttserver("", $verbose);
  2438. if($pid <= 0) {
  2439. return ("failed starting mqtt server", $serr);
  2440. }
  2441. logmsg sprintf("* pid mqtt => %d %d\n", $pid, $pid2) if($verbose);
  2442. $run{'mqtt'}="$pid $pid2";
  2443. }
  2444. }
  2445. elsif($what eq "http-unix") {
  2446. if($torture && $run{'http-unix'} &&
  2447. !responsive_http_server("http", $verbose, "unix", $HTTPUNIXPATH)) {
  2448. if(stopserver('http-unix')) {
  2449. return ("failed stopping unresponsive HTTP-unix server", 3);
  2450. }
  2451. }
  2452. if(!$run{'http-unix'}) {
  2453. my $unused;
  2454. ($serr, $pid, $pid2, $unused) =
  2455. runhttpserver("http", $verbose, "unix", $HTTPUNIXPATH);
  2456. if($pid <= 0) {
  2457. return ("failed starting HTTP-unix server", $serr);
  2458. }
  2459. logmsg sprintf("* pid http-unix => %d %d\n", $pid, $pid2)
  2460. if($verbose);
  2461. $run{'http-unix'}="$pid $pid2";
  2462. }
  2463. }
  2464. elsif($what eq "dict") {
  2465. if(!$run{'dict'}) {
  2466. ($serr, $pid, $pid2, $PORT{"dict"}) = rundictserver($verbose, "");
  2467. if($pid <= 0) {
  2468. return ("failed starting DICT server", $serr);
  2469. }
  2470. logmsg sprintf ("* pid DICT => %d %d\n", $pid, $pid2)
  2471. if($verbose);
  2472. $run{'dict'}="$pid $pid2";
  2473. }
  2474. }
  2475. elsif($what eq "smb") {
  2476. if(!$run{'smb'}) {
  2477. ($serr, $pid, $pid2, $PORT{"smb"}) = runsmbserver($verbose, "");
  2478. if($pid <= 0) {
  2479. return ("failed starting SMB server", $serr);
  2480. }
  2481. logmsg sprintf ("* pid SMB => %d %d\n", $pid, $pid2)
  2482. if($verbose);
  2483. $run{'smb'}="$pid $pid2";
  2484. }
  2485. }
  2486. elsif($what eq "telnet") {
  2487. if(!$run{'telnet'}) {
  2488. ($serr, $pid, $pid2, $PORT{"telnet"}) =
  2489. runnegtelnetserver($verbose, "");
  2490. if($pid <= 0) {
  2491. return ("failed starting neg TELNET server", $serr);
  2492. }
  2493. logmsg sprintf ("* pid neg TELNET => %d %d\n", $pid, $pid2)
  2494. if($verbose);
  2495. $run{'telnet'}="$pid $pid2";
  2496. }
  2497. }
  2498. elsif($what eq "none") {
  2499. logmsg "* starts no server\n" if ($verbose);
  2500. }
  2501. else {
  2502. warn "we don't support a server for $what";
  2503. return ("no server for $what", 4);
  2504. }
  2505. }
  2506. return ("", 0);
  2507. }
  2508. #######################################################################
  2509. # Stop all running test servers
  2510. #
  2511. sub stopservers {
  2512. my $verb = $_[0];
  2513. #
  2514. # kill sockfilter processes for all pingpong servers
  2515. #
  2516. killallsockfilters("$LOGDIR/$PIDDIR", $verb);
  2517. #
  2518. # kill all server pids from %run hash clearing them
  2519. #
  2520. my $pidlist;
  2521. foreach my $server (keys %run) {
  2522. if($run{$server}) {
  2523. if($verb) {
  2524. my $prev = 0;
  2525. my $pids = $run{$server};
  2526. foreach my $pid (split(' ', $pids)) {
  2527. if($pid != $prev) {
  2528. logmsg sprintf("* kill pid for %s => %d\n",
  2529. $server, $pid);
  2530. $prev = $pid;
  2531. }
  2532. }
  2533. }
  2534. $pidlist .= "$run{$server} ";
  2535. $run{$server} = 0;
  2536. }
  2537. $runcert{$server} = 0 if($runcert{$server});
  2538. }
  2539. killpid($verb, $pidlist);
  2540. #
  2541. # cleanup all server pid files
  2542. #
  2543. my $result = 0;
  2544. foreach my $server (keys %serverpidfile) {
  2545. my $pidfile = $serverpidfile{$server};
  2546. my $pid = processexists($pidfile);
  2547. if($pid > 0) {
  2548. if($err_unexpected) {
  2549. logmsg "ERROR: ";
  2550. $result = -1;
  2551. }
  2552. else {
  2553. logmsg "Warning: ";
  2554. }
  2555. logmsg "$server server unexpectedly alive\n";
  2556. killpid($verb, $pid);
  2557. }
  2558. unlink($pidfile) if(-f $pidfile);
  2559. }
  2560. return $result;
  2561. }
  2562. #######################################################################
  2563. # substitute the variable stuff into either a joined up file or
  2564. # a command, in either case passed by reference
  2565. #
  2566. sub subvariables {
  2567. my ($thing, $testnum, $prefix) = @_;
  2568. my $port;
  2569. if(!$prefix) {
  2570. $prefix = "%";
  2571. }
  2572. # test server ports
  2573. # Substitutes variables like %HTTPPORT and %SMTP6PORT with the server ports
  2574. foreach my $proto ('DICT',
  2575. 'FTP', 'FTP6', 'FTPS',
  2576. 'GOPHER', 'GOPHER6', 'GOPHERS',
  2577. 'HTTP', 'HTTP6', 'HTTPS',
  2578. 'HTTPSPROXY', 'HTTPTLS', 'HTTPTLS6',
  2579. 'HTTP2', 'HTTP2TLS',
  2580. 'HTTP3',
  2581. 'IMAP', 'IMAP6', 'IMAPS',
  2582. 'MQTT',
  2583. 'NOLISTEN',
  2584. 'POP3', 'POP36', 'POP3S',
  2585. 'RTSP', 'RTSP6',
  2586. 'SMB', 'SMBS',
  2587. 'SMTP', 'SMTP6', 'SMTPS',
  2588. 'SOCKS',
  2589. 'SSH',
  2590. 'TELNET',
  2591. 'TFTP', 'TFTP6') {
  2592. $port = protoport(lc $proto);
  2593. $$thing =~ s/${prefix}(?:$proto)PORT/$port/g;
  2594. }
  2595. # Special case: for PROXYPORT substitution, use httpproxy.
  2596. $port = protoport('httpproxy');
  2597. $$thing =~ s/${prefix}PROXYPORT/$port/g;
  2598. # server Unix domain socket paths
  2599. $$thing =~ s/${prefix}HTTPUNIXPATH/$HTTPUNIXPATH/g;
  2600. $$thing =~ s/${prefix}SOCKSUNIXPATH/$SOCKSUNIXPATH/g;
  2601. # client IP addresses
  2602. $$thing =~ s/${prefix}CLIENT6IP/$CLIENT6IP/g;
  2603. $$thing =~ s/${prefix}CLIENTIP/$CLIENTIP/g;
  2604. # server IP addresses
  2605. $$thing =~ s/${prefix}HOST6IP/$HOST6IP/g;
  2606. $$thing =~ s/${prefix}HOSTIP/$HOSTIP/g;
  2607. # misc
  2608. $$thing =~ s/${prefix}CURL/$CURL/g;
  2609. $$thing =~ s/${prefix}LOGDIR/$LOGDIR/g;
  2610. $$thing =~ s/${prefix}PWD/$pwd/g;
  2611. $$thing =~ s/${prefix}POSIX_PWD/$posix_pwd/g;
  2612. $$thing =~ s/${prefix}VERSION/$CURLVERSION/g;
  2613. $$thing =~ s/${prefix}VERNUM/$CURLVERNUM/g;
  2614. $$thing =~ s/${prefix}DATE/$DATE/g;
  2615. $$thing =~ s/${prefix}TESTNUMBER/$testnum/g;
  2616. my $file_pwd = $pwd;
  2617. if($file_pwd !~ /^\//) {
  2618. $file_pwd = "/$file_pwd";
  2619. }
  2620. my $ssh_pwd = $posix_pwd;
  2621. # this only works after the SSH server has been started
  2622. # TODO: call sshversioninfo early and store $sshdid so this substitution
  2623. # always works
  2624. if ($sshdid && $sshdid =~ /OpenSSH-Windows/) {
  2625. $ssh_pwd = $file_pwd;
  2626. }
  2627. $$thing =~ s/${prefix}FILE_PWD/$file_pwd/g;
  2628. $$thing =~ s/${prefix}SSH_PWD/$ssh_pwd/g;
  2629. $$thing =~ s/${prefix}SRCDIR/$srcdir/g;
  2630. $$thing =~ s/${prefix}USER/$USER/g;
  2631. $$thing =~ s/${prefix}SSHSRVMD5/$SSHSRVMD5/g;
  2632. $$thing =~ s/${prefix}SSHSRVSHA256/$SSHSRVSHA256/g;
  2633. # The purpose of FTPTIME2 and FTPTIME3 is to provide times that can be
  2634. # used for time-out tests and that would work on most hosts as these
  2635. # adjust for the startup/check time for this particular host. We needed to
  2636. # do this to make the test suite run better on very slow hosts.
  2637. my $ftp2 = $ftpchecktime * 8;
  2638. my $ftp3 = $ftpchecktime * 12;
  2639. $$thing =~ s/${prefix}FTPTIME2/$ftp2/g;
  2640. $$thing =~ s/${prefix}FTPTIME3/$ftp3/g;
  2641. # HTTP2
  2642. $$thing =~ s/${prefix}H2CVER/$h2cver/g;
  2643. }
  2644. 1;