servers.pm 97 KB

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