crossroads

Git mirror of https://crossroads.e-tunity.com/
git clone git://git.finwo.net/app/crossroads
Log | Files | Refs | LICENSE

commit 2c121acf91c151c71b3bd27451b12c61bd3ac894
parent 5fbb190726d27fc0550fd2aa4a63fa0cc41dbd28
Author: finwo <finwo@pm.me>
Date:   Sat,  3 Jan 2026 19:33:05 +0100

1.46

Diffstat:
MChangeLog | 7+++++++
MMakefile | 1-
Mdoc/Makefile | 9++++++---
Adoc/crossroads-mgr.1 | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/crossroads.html | 341++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
Ddoc/crossroads.man | 3700-------------------------------------------------------------------------------
Mdoc/crossroads.pdf | 0
Mdoc/main/compiling.yo | 39++++++++++++++++++++++++++++++---------
Mdoc/main/crossroads.yo | 9+++++++--
Mdoc/main/intro.yo | 74+++++++++++++++++++++++++++++++++++++-------------------------------------
Mdoc/main/tips.yo | 3+++
Adoc/main/tips/webinterface.yo | 107+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adoc/main/webinterface.yo | 24++++++++++++++++++++++++
Adoc/man/crossroads-mgr.yo | 102+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Metc/Makefile.def | 2+-
Metc/svnrev.txt | 2+-
Aetc/xml-status-short.xslt | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/Makefile | 6++++--
Msrc/crossroads-daemon/Makefile | 1+
Msrc/crossroads-daemon/main.c | 2+-
Asrc/crossroads-mgr/Makefile | 19+++++++++++++++++++
Asrc/crossroads-mgr/crossroads-mgr.in | 411+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/crossroads-mgr/crossroads-mgr.usage | 23+++++++++++++++++++++++
Asrc/crossroads-mgr/crossroads-mgr.xslt | 155+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/crossroads.h | 8+++++++-
Msrc/crossroads/Makefile | 1+
Msrc/crossroads/main.c | 2+-
Msrc/lib/allocreporter.c | 2+-
Msrc/lib/ansistamp.c | 2+-
Msrc/lib/backendavailable.c | 2+-
Msrc/lib/backendconnect.c | 2+-
Msrc/lib/backendcount.c | 2+-
Msrc/lib/choosebackend.c | 2+-
Msrc/lib/configread.c | 2+-
Msrc/lib/configtest.c | 2+-
Msrc/lib/configwrite.c | 2+-
Msrc/lib/copysockets.c | 2+-
Msrc/lib/createcommandlinespace.c | 2+-
Msrc/lib/data.c | 2+-
Msrc/lib/deallocreporter.c | 2+-
Msrc/lib/decrclientcount.c | 2+-
Msrc/lib/dns.c | 2+-
Msrc/lib/error.c | 2+-
Msrc/lib/forktcpservicer.c | 2+-
Msrc/lib/hashpjw.c | 2+-
Msrc/lib/httpcopy.c | 2+-
Msrc/lib/httperror.c | 2+-
Msrc/lib/httpheaderaddheader.c | 2+-
Msrc/lib/httpheaderappendheader.c | 2+-
Msrc/lib/httpheaderconnectiontype.c | 2+-
Msrc/lib/httpheaderfree.c | 2+-
Msrc/lib/httpheaderhascookie.c | 2+-
Msrc/lib/httpheaderhttpver.c | 2+-
Msrc/lib/httpheadernew.c | 2+-
Msrc/lib/httpheaderread.c | 2+-
Msrc/lib/httpheaderremoveheader.c | 2+-
Msrc/lib/httpheadersetheader.c | 2+-
Msrc/lib/httpheaderval.c | 2+-
Msrc/lib/httpheaderwrite.c | 2+-
Msrc/lib/httpinsertheader.c | 2+-
Msrc/lib/httpserve.c | 2+-
Msrc/lib/httpserversocket.c | 2+-
Msrc/lib/httpwrite.c | 2+-
Msrc/lib/incrclientcount.c | 2+-
Msrc/lib/initsockaddr.c | 2+-
Msrc/lib/interrupt.c | 2+-
Msrc/lib/ipfaddallow.c | 2+-
Msrc/lib/ipfadddeny.c | 2+-
Msrc/lib/ipfallowed.c | 2+-
Msrc/lib/ipfdenied.c | 2+-
Msrc/lib/ipfloadfile.c | 2+-
Msrc/lib/ipfmatch.c | 2+-
Msrc/lib/ipfparse.c | 2+-
Msrc/lib/ishexdigit.c | 2+-
Msrc/lib/isspace.c | 2+-
Msrc/lib/lexer.c | 2+-
Msrc/lib/lockreporter.c | 2+-
Msrc/lib/logactivityany.c | 2+-
Msrc/lib/logactivitycontinuation.c | 2+-
Msrc/lib/logactivityend.c | 2+-
Msrc/lib/logactivitystart.c | 2+-
Msrc/lib/makesocket.c | 2+-
Msrc/lib/markactivity.c | 2+-
Msrc/lib/msg.c | 2+-
Msrc/lib/msgdumpbuf.c | 2+-
Msrc/lib/netbuffer.c | 2+-
Msrc/lib/netbufread.c | 2+-
Msrc/lib/netcopy.c | 2+-
Msrc/lib/netread.c | 2+-
Msrc/lib/netwrite.c | 2+-
Msrc/lib/parser.c | 2+-
Msrc/lib/parserclose.c | 2+-
Msrc/lib/parserfilename.c | 2+-
Msrc/lib/parserinput.c | 2+-
Msrc/lib/parseropen.c | 2+-
Msrc/lib/parserrun.c | 2+-
Msrc/lib/parserskipchar.c | 2+-
Msrc/lib/parserskipline.c | 2+-
Msrc/lib/restart.c | 2+-
Msrc/lib/runservice.c | 2+-
Msrc/lib/serve.c | 2+-
Msrc/lib/setproctitle.c | 2+-
Msrc/lib/showconfig.c | 2+-
Msrc/lib/showservices.c | 2+-
Msrc/lib/showstatus.c | 13+++++++++----
Msrc/lib/stagetostring.c | 2+-
Msrc/lib/statetostring.c | 2+-
Msrc/lib/stopdaemon.c | 2+-
Msrc/lib/strcasestr.c | 2+-
Msrc/lib/strexpandformat.c | 2+-
Msrc/lib/stringtostate.c | 2+-
Msrc/lib/strlcat.c | 2+-
Msrc/lib/strprintf.c | 2+-
Msrc/lib/strvprintf.c | 2+-
Msrc/lib/symtabend.c | 2+-
Msrc/lib/symtablookup.c | 2+-
Msrc/lib/symtabset.c | 2+-
Msrc/lib/symtabstart.c | 2+-
Msrc/lib/sysrun.c | 2+-
Msrc/lib/tcpserve.c | 2+-
Msrc/lib/tellservice.c | 13++++++++++---
Msrc/lib/thruputlog.c | 2+-
Msrc/lib/trafficlog.c | 2+-
Msrc/lib/uidassume.c | 2+-
Msrc/lib/uidrestore.c | 2+-
Msrc/lib/unlockreporter.c | 2+-
Msrc/lib/usage.c | 2+-
Msrc/lib/usage.txt | 1+
Msrc/lib/vsyslog.c | 2+-
Msrc/lib/wakeuphandler.c | 2+-
Msrc/lib/warning.c | 2+-
Msrc/lib/writelog.c | 2+-
Msrc/lib/xcalloc.c | 2+-
Msrc/lib/xmalloc.c | 2+-
Msrc/lib/xrealloc.c | 2+-
Msrc/lib/xstrcat.c | 2+-
Msrc/lib/xstrcatch.c | 2+-
Msrc/lib/xstrdup.c | 2+-
Msrc/shared/parseopt.inc | 5++++-
Atools/patch-mgr | 30++++++++++++++++++++++++++++++
140 files changed, 1545 insertions(+), 3963 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,6 +1,13 @@ ChangeLog for Crossroads ------------------------------------------------------------------------------ +1.46 [KK 2007-06-25] + - Flag -X added (for xslt reference embedding) + - "crossroads tell {service} {backend} {state}": state can be + numeric + - Added crossroads-mgr, updated all docs, etc.. + - Fixed "make distclean" + 1.45 [KK 2007-06-12] - Configuration option 'headerinspection {deep|shallow}' implemented. Documentation updated. Several other documentation fixes. diff --git a/Makefile b/Makefile @@ -27,7 +27,6 @@ clean: BASE=$(BASE) $(MAKE) -C doc clean find $(BASE) -type f -name '*~' -exec rm {} \; find $(BASE) -type f -name .gdb_history -exec rm {} \; - rm -f src/c-conf.cache distclean: BASE=$(BASE) $(MAKE) -C src distclean diff --git a/doc/Makefile b/doc/Makefile @@ -6,6 +6,8 @@ foo: defs find main -type f -name '*.yo' -exec ../tools/untab {} \; cd man && yo2man crossroads mv man/crossroads.man crossroads.1 + cd man && yo2man crossroads-mgr + mv man/crossroads-mgr.man crossroads-mgr.1 cd man && yo2man $(YODLINC) crossroads.conf mv man/crossroads.conf.man crossroads.conf.7 cd main && yo2pdf crossroads @@ -27,10 +29,11 @@ defs: dbginstall: install install: - $(BASE)/tools/installdoc $(PREFIX) crossroads.1 crossroads.conf.7 + $(BASE)/tools/installdoc $(PREFIX) crossroads.1 crossroads-mgr.1 \ + crossroads.conf.7 clean: - rm -f crossroads-defs.yo + rm -f crossroads-defs.yo *.man distclean: clean - rm -f *.html *.pdf *.man + rm -f *.html *.pdf *.1 *.7 diff --git a/doc/crossroads-mgr.1 b/doc/crossroads-mgr.1 @@ -0,0 +1,115 @@ +.SH "e-tunity" +.TH "crossroads-mgr" "1" "2005-2007" "crossroads" "" +.SH "NAME" +crossroads-mgr \- Web interface for Crossroads +.PP +.SH "SYNOPSIS" +.IP o +\fBcrossroads-mgr\fP \fI[flags]\fP \fBstart\fP \fIport\fP: starts +the web interface server +.IP o +\fBcrossroads-mgr\fP \fBstop\fP: stops the server +.IP o +\fBcrossroads-mgr\fP \fBstatus\fP: shows whether the server +is running +.PP +.SH "DESCRIPTION" + +.PP +\fBcrossroads-mgr\fP is a self-contained web server, written in +Perl, providing a web interface to control Crossroads\&. The web +interface allows one to: +.PP +.IP o +View the states of back ends, and their usage; +.IP o +Set the states of back ends (e\&.g\&., to take a back end out +of service)\&. +.PP +The web interface cannot be used to configure Crossroads (e\&.g\&., to +add new back ends)\&. This must be done via the configuration file +\fB/etc/crossroads\&.conf\fP\&. Note furthermore that \fBcrossroads status\fP and +\fBcrossroads tell\fP are commandline tools that achieve the same +functionality as \fBcrossroads-mgr\fP\&. +.PP +.SH "OPTIONS" + +.PP +\fBcrossroads-mgr\fP recognizes the following flags: +.PP +.IP o +\fB-b UN:PW\fP: Viewing the status is protected using +simple basic authentication, requiring username \fBUN\fP and +password \fBPW\fP\&. +.IP +For example one may specify: \fB-b user:secret\fP, after which +visitors to the web interface are prompted for a username and +password\&. +.IP +Instead of the username, a colon, and a password, the special +word \fBPROMPT\fP may be used (in caps)\&. In this case, +\fBcrossroads-mgr\fP prompts for the entry of a username and a +password\&. Using \fBPROMPT\fP will have the effect that the +username and password are not shown in a process listing\&. +.IP +.IP o +\fB-B UN:PW\fP: Setting the status of a back end is +protected using simple basic authentication, with username +\fBUN\fP and password \fBPW\fP\&. The special word \fBPROMPT\fP may be +used\&. +.IP +.IP o +\fB-f\fP: \fBcrossroads-mgr\fP stays in the foreground +instead of daemonizing\&. Useful for debugging\&. +.IP +.IP o +\fB-l FILE\fP: Verbose activity (when \fB-v\fP is given) is +written to the stated file\&. Useful for debugging\&. Also, error +messages are written to the file\&. The default is +\fB/tmp/crossroads-mgr\&.log\fP\&. Note that file logging is not +used in \&'foreground\&' mode (flag \fB-f\fP; in that case all +logging goes to terminal)\&. +.IP +.IP o +\fB-v\fP: Verbosity is increased\&. +.IP +.IP o +\fB-x CMD\fP: This specifies how \fBcrossroads-mgr\fP should +invoke \fBcrossroads\fP\&. The default is just \fBcrossroads\fP\&. An +example is: \fB/usr/local/bin/crossroads -c +/alternative/configuration\fP which overrules the default +configuration file name\&. Note that once \fB-x\fP is given, +\fBcrossroads-mgr\fP will no longer search along the PATH\&. When +using \fB-x\fP, the full access path to \fBcrossroads\fP must be +specified\&. +.IP +.IP o +\fB-X XSLT\fP: Causes \fBcrossroads-mgr\fP to send the +specified XSLT file, instead of the built-in\&. Useful for +debugging\&. +.PP +.SH "BUGS" + +.PP +.IP o +Basic authentication headers are logged when \fB-v\fP +is active\&. Make sure that the log file is not in a +world-readable place, or turn off \fB-v\fP\&. +.IP +.IP o +When using basic authentication in the form \fB-b +UN:PW\fP and \fB-B UN:PW\fP, the required credentials are +visible in the process overview list\&. Use \fBPROMPT\fP to +hide these\&. +.IP +.IP o +\fBcrossroads-mgr stop\fP and \fBcrossroads-mgr status\fP +use the process list to see which daemons are active\&. If +you start more than one daemon, then \fBcrossroads-mgr +stop\fP will stop all of them\&. +.PP +.SH "AUTHOR" +.IP o +Author: Karel Kubat +.IP o + Maintainer: Karel Kubat karel@kubat\&.nl diff --git a/doc/crossroads.html b/doc/crossroads.html @@ -1,12 +1,12 @@ <a name="../crossroads-defs"></a><a name="defs"></a><html><head> -<title>Crossroads 1.45</title> +<title>Crossroads 1.46</title> <link rel="stylesheet" type="text/css" href="http://www.e-tunity.com/css/yodl.css"> <link rel="stylesheet" type="text/css" href="http://www.e-tunity.com/css/yodl.css"> <link rev="made" href="mailto:info@e-tunity.com"> </head> <body> <hr> -<h1>Crossroads 1.45</h1> +<h1>Crossroads 1.46</h1> <h2>Karel Kubat <br> Maintained by Karel Kubat (karel@kubat.nl)</h2> @@ -20,8 +20,10 @@ more. Crossroads is service-independent: it is usable for HTTP/HTTPS, SSH, SMTP, DNS, etc. In the case of HTTP balancing, Crossroads can modify HTTP headers, e.g. to - provide 'session stickiness' for back-end processes that need - sessions, but aren't session-aware of other back-ends.</em></blockquote> + provide 'session stickiness' for back end processes that need + sessions, but aren't session-aware of other + back ends. Crossroads is configured via a file and accessible + via a web interface.</em></blockquote> <h1>Table of Contents</h1> <dl> @@ -128,63 +130,67 @@ <dt><a href="#l73">5.11: Linux and ip_conntrack_max</a></dt> <dt><a href="#l74">5.12: Marking back ends as bad after more than one try</a></dt> <dt><a href="#l75">5.13: Scripting Crossroads' back end availability</a></dt> -<dt><a href="#l76">5.14: Rendering Crossroads' status in a web page</a></dt> -<dt><a href="#l77">5.15: Crossroads and DNS caching</a></dt> +<dt><a href="#l76">5.14: Using the Web Interface crossroads-mgr</a></dt> +<dl> +<dt><a href="#l77">5.14.1: Starting crossroads-mgr</a></dt> +</dl> +<dt><a href="#l78">5.15: Rendering Crossroads' status in a web page</a></dt> +<dt><a href="#l79">5.16: Crossroads and DNS caching</a></dt> </dl> -<dt><h3><a href="#l78">6: Benchmarking</a></h3></dt> +<dt><h3><a href="#l80">6: Benchmarking</a></h3></dt> <dl> -<dt><a href="#l79">6.1: Benchmark 1: Accessing a proxy via crossroads or directly</a></dt> +<dt><a href="#l81">6.1: Benchmark 1: Accessing a proxy via crossroads or directly</a></dt> <dl> -<dt><a href="#l80">6.1.1: Results</a></dt> -<dt><a href="#l81">6.1.2: Discussion</a></dt> +<dt><a href="#l82">6.1.1: Results</a></dt> +<dt><a href="#l83">6.1.2: Discussion</a></dt> </dl> -<dt><a href="#l82">6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</a></dt> +<dt><a href="#l84">6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</a></dt> <dl> -<dt><a href="#l83">6.2.1: Environment</a></dt> -<dt><a href="#l84">6.2.2: Tests and results</a></dt> +<dt><a href="#l85">6.2.1: Environment</a></dt> +<dt><a href="#l86">6.2.2: Tests and results</a></dt> </dl> </dl> -<dt><h3><a href="#l85">7: Compiling and Installing</a></h3></dt> +<dt><h3><a href="#l87">7: The Web Interface</a></h3></dt> +<dt><h3><a href="#l88">8: Compiling and Installing</a></h3></dt> <dl> -<dt><a href="#l86">7.1: Prerequisites</a></dt> -<dt><a href="#l87">7.2: Compiling and installing</a></dt> -<dt><a href="#l88">7.3: Configuring crossroads</a></dt> -<dt><a href="#l89">7.4: A boot script</a></dt> +<dt><a href="#l89">8.1: Prerequisites</a></dt> +<dt><a href="#l90">8.2: Compiling and installing</a></dt> +<dt><a href="#l91">8.3: Configuring crossroads</a></dt> +<dt><a href="#l92">8.4: A boot script</a></dt> <dl> -<dt><a href="#l90">7.4.1: SysV Style Startup</a></dt> -<dt><a href="#l91">7.4.2: BSD Style Startup</a></dt> +<dt><a href="#l93">8.4.1: SysV Style Startup</a></dt> +<dt><a href="#l94">8.4.2: BSD Style Startup</a></dt> </dl> <p><hr><p> <p> <a name="l1"></a> <h2>1: Introduction</h2> -<a name="intro"></a>Crossroads is a daemon that basically accepts TCP connections -at preconfigured ports, and given a list of 'back ends' -distributes each incoming connection to one of the back ends, -so that a client request is -served. Additionally, crossroads maintains an internal +<a name="intro"></a>Crossroads is a daemon that basically accepts TCP connections at +preconfigured ports, and given a list of 'back ends' distributes each +incoming connection to one of the back ends, so that a client request +is served. Additionally, crossroads maintains an internal administration of the back end connectivity: if a back end isn't usable, then the client request is handled using another back end. Crossroads will then periodically check whether a previously not -usable back end has come to life yet. Also, crossroads can select -back ends by estimating the load, so that balancing is achieved. +usable back end has come to life yet. Also, crossroads can select back +ends by estimating the load, so that balancing is achieved. <p> Using this approach, crossroads serves as load balancer and fail over -utility. Crossroads will very likely not be as reliable as -hardware based balancers, since it always will require a server to -run on. This server, in turn, may become a new Single Point of -Failure (SPOS). However, in situations where cost efficiency is an issue, -crossroads may be a good choice. Furthermore, crossroads can be -deployed in situations where a hardware based balancing already -exists and augmenting service reliability is needed. Or, crossroads may be -run off a diskless system, which again improves reliability of the +utility. Crossroads will very likely not be as reliable as hardware +based balancers, since it always will require a server to run on. This +server, in turn, may become a new Single Point of Failure (SPOS). +However, in situations where cost efficiency is an issue, crossroads +may be a good choice. Furthermore, crossroads can be deployed in +situations where a hardware based balancing already exists and +augmenting service reliability is needed. Or, crossroads may be run +off a diskless system, which again improves reliability of the underlying hardware. <p> -This document describes how to use crossroads, how to configure it -in order to increase the reliability of your systems, and how to -compile the program from its sources. This document is -also available in <a href="crossroads.pdf">PDF</a> format. +This document describes how to use crossroads, how to configure it in +order to increase the reliability of your systems, and how to compile +the program from its sources. This document is also available +in <a href="crossroads.pdf">PDF</a> format. <p> <a name="l2"></a> <h3>1.1: Obtaining Crossroads</h3> @@ -228,29 +234,28 @@ or bug reports, always include the following: <a name="l4"></a> <h3>1.3: Copyright and Disclaimer</h3> <p> -Crossroads is distributed as-is, without assumptions of fitness -or usability. You are free to use crossroads to your -liking. It's free, and as with everything that's free: there's -also no warranty. +Crossroads is distributed as-is, without assumptions of fitness or +usability. You are free to use crossroads to your liking. It's free, +and as with everything that's free: there's also no warranty. <p> You are allowed to make modifications to the source code of -crossroads, and you are allowed to (re)distribute crossroads, as -long as you include this text, all sources, and if applicable: all -your modifications, with each distribution. -<p> -While you are allowed to make any and all changes to the sources, -I would appreciate hearing about them. If the changes concern new -functionality or bugfixes, then I'll include them in a next -release, stating full credits. If you want to seriously contribute (to -which you are heartily encouraged), then mail me and I'll get you -access to the Crossroads SVN repository, so that you can update and -commit as you like. +crossroads, and you are allowed to (re)distribute crossroads, as long +as you include this text, all sources, and if applicable: all your +modifications, with each distribution. +<p> +While you are allowed to make any and all changes to the sources, I +would appreciate hearing about them. If the changes concern new +functionality or bugfixes, then I'll include them in a next release, +stating full credits. If you want to seriously contribute (to which +you are heartily encouraged), then mail me and I'll get you access to +the Crossroads SVN repository, so that you can update and commit as +you like. <p> <a name="l5"></a> <h3>1.4: Terminology</h3> <p> Throughout this document, the following terms are used: &nbsp;(Many -more meanings of the terms will exist -- yes, I am aware of that. I'm +more meanings of the terms will exist - yes, I am aware of that. I'm using the terms here in a very strict sense.) <p> <dl> @@ -502,7 +507,7 @@ configuration file). The actual usage information is always obtained by typing <code>crossroads</code> without any arguments. Crossroads then displays the allowed arguments. <p> -The installation (see section <a href="crossroads.html#installation">7</a>) installs also a +The installation (see section <a href="crossroads.html#installation">8</a>) installs also a second program called <code>crossroads-daemon</code>. This program is not meant to be started from the command line; it is administered through the front end <code>crossroads</code>. @@ -576,7 +581,7 @@ follows: The flag <code>-x</code> causes the overview to be presented as an XML document. This can be handy if you want to further automate the control over Crossroads, or if you want to show the status via the -web. (See section <a href="crossroads.html#xmlstatus">5.14</a> for more information.) +web. (See section <a href="crossroads.html#xmlstatus">5.15</a> for more information.) <p> <a name="l15"></a> <h3>3.3: Logging-related options</h3> @@ -3322,7 +3327,121 @@ The further implementation of such a mini-daemon that fires up <code>healthcheck</code> is left to the reader. <p> <a name="l76"></a> -<h3>5.14: Rendering Crossroads' status in a web page</h3> <a name="xmlstatus"></a> +<h3>5.14: Using the Web Interface crossroads-mgr</h3> +<a name="tips/webinterface"></a>The mini-webserver <code>crossroads-mgr</code> provides an intuitive web +interface to the state of Crossroads. Once started, an administrator +may view the state of the balancer, and may influence the state of all +back ends. +<p> +As an example, a procedure is described here where a given back end is +gracefully taken out of service. Below is a sample Crossroads +configuration, which distributes requests over three back ends: +<p> +<pre> +service www { + port 80; + type http; + backend one { + server 10.1.1.1:80; + stickycookie "BalancerID=one"; + addclientheader "Set-Cookie: BalancerID=one"; + } + backend two { + server 10.1.1.1:80; + stickycookie "BalancerID=two"; + addclientheader "Set-Cookie: BalancerID=two"; + } + backend three { + server 10.1.1.1:80; + stickycookie "BalancerID=three"; + addclientheader "Set-Cookie: BalancerID=three"; + } +} +</pre> + +<p> +In order to take a given back end gracefully offline (say back end +<code>two</code>), either of the following procedures can be followed: +<p> +<ol> + <li> Back end <code>two</code> is taken down via the commandline, using + <code>crossroads tell www two down</code>. Next we wait for say one hour to + let existing sessions die out. After that, the back end can be turned + off. +<p> +<li> Back end <code>two</code> is taken down via the web interface, by + switching the status from <code>available</code> to <code>down</code>. Next we wait + for say one our, and turn off the back end.</ol> +<p> +The web interface doesn't offer extra functionality over the command +line tools; but all information is available at one glance, and +accessible without a shell access to the balancer. +<p> +<a name="l77"></a> +<strong>5.14.1: Starting crossroads-mgr</strong> +<p> +The basic command to start <code>crossroads-mgr</code> is +<p> +<center><code>crossroads-mgr start</code> <em>portnumber</em></center> +<p> +where the port number specifies to which TCP port the manager will +listen. There is however one important security aspect that needs +attention. Unless specified otherwise, anyone who points their browser +to the balancer and the given port, can view back end states and even +change them. This may be a too lax policy. +<p> +The web interface daemon offers one method to limit access: it can +optionally enforce basic authentication (username and password) when +viewing the status, and/or when switching states. Enforcing basic +authentication is turned off using two command line flags: +<p> +<ul> + <li> Flag <code>-b</code> turns on basic authentication to view the status. + <li> Flag <code>-B</code> turns on basic authentication to change back end + states.</ul> +<p> +Both flags must be followed by the required credentials. The most +simple way to state the credentials, is to postfix the flag with the +required user name, a colon, and the required password. E.g., +<code>-Buser:secret</code> says that anyone who tries to change back end +states, must supply the user name <code>user</code> and the password +<code>secret</code>. +<p> +In this example the full invocation would be e.g.: +<p> +<center><code>crossroads-mgr -Buser:secret start 1000</code></center> +<p> +The disadvantage is here that the credentials are visible for anyone +who has shell access to the balancer. A process overview, generated +with say <code>ps ax | grep crossroads-mgr</code>, would show the required +username and password. In order to avoid such a leak, +<code>crossroads-mgr</code> can be started as follows: +<p> +<center><code>crossroads-mgr -BPROMPT start 1000</code></center> +<p> +The 'magic' word <code>PROMPT</code> instructs <code>crossroads-mgr</code> to read the +username and password from <em>stdin</em>. The invocation can be further +scripted, using something like: +<p> +<center><code>echo user:secret | crossroads-mgr -BPROMPT start 1000</code></center> +<p> +The same trick can be used with the flag <code>-b</code>. When both flags are +present, and both 'magic' words <code>PROMPT</code> occur, then +<code>crossroads-mgr</code> will first ask for the credentials of the 'viewer', +and next for the credentials of the 'modifier' (even when flag <code>-B</code> +is stated first). So the following example starts <code>crossroads-mgr</code> +and requires the user name <code>viewer</code>, with password <code>showme</code> to view the +status, and it requires the user name <code>modifier</code>, with password +<code>changeit</code> to change states: +<p> +<pre> +echo -e 'viewer:showme\nmodifier:changeit' | + crossroads-mgr -bPROMPT -BPROMPT start 1000 +</pre> + +<p> +<a name="l78"></a> +<h3>5.15: Rendering Crossroads' status in a web page</h3> <a name="xmlstatus"></a> <a name="tips/rendering"></a>The Crossroads flag <code>-x</code> causes the status output to be generated as an XML document. This format can be nicely used to render the output as an HTML page. @@ -3391,8 +3510,8 @@ somewhat more liberal. There are basically two options: users belonging to the same group as the Crossroads starter can run <code>crossroads status</code>.</ul> <p> -<a name="l77"></a> -<h3>5.15: Crossroads and DNS caching</h3> +<a name="l79"></a> +<h3>5.16: Crossroads and DNS caching</h3> <a name="tips/dnscaching"></a> The option <code>-d</code> allows you to control Crossroads' built in DNS caching mechanism. Most often you will not need to use this: @@ -3415,13 +3534,13 @@ Crossroads to use its DNS cache to store results. Each result is stored for up to <em>nsec</em> seconds - after that, a new request for the back end will lead to a new DNS lookup. <p> -<a name="l78"></a> +<a name="l80"></a> <h2>6: Benchmarking</h2> <a name="benchmarking"></a>This section shows how crossroads affects the transmitting of HTML data when used as an intermediate 'station' through which all data travels. <p> -<a name="l79"></a> +<a name="l81"></a> <h3>6.1: Benchmark 1: Accessing a proxy via crossroads or directly</h3> <p> The benchmark was run on a system where the following was varied: @@ -3449,7 +3568,7 @@ service HttpProxy { </pre> <p> -<a name="l80"></a> +<a name="l82"></a> <strong>6.1.1: Results</strong> <p> The results of this test are that crossroads causes a negligible @@ -3472,7 +3591,7 @@ sys 0m0.230s </pre> <p> -<a name="l81"></a> +<a name="l83"></a> <strong>6.1.2: Discussion</strong> <p> The above shown results are quite favorable to crossroads. However, @@ -3504,7 +3623,7 @@ seldom in the real world: back end). Again, this processing time will weigh much heavier than the multiple read/writes.</ul> <p> -<a name="l82"></a> +<a name="l84"></a> <h3>6.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)</h3> <p> LVS is a kernel-based balancer that acts like a masquerading @@ -3518,7 +3637,7 @@ LVS isn't aware of downtime of back ends (unless one implements an external heartbeat). Also, crossroads offers more complex balancing than LVS. <p> -<a name="l83"></a> +<a name="l85"></a> <strong>6.2.1: Environment</strong> <p> On the balancer, LVS was run on port 80, its forwarding set up for two @@ -3549,7 +3668,7 @@ service http { </pre> <p> -<a name="l84"></a> +<a name="l86"></a> <strong>6.2.2: Tests and results</strong> <p> In the first test, ports 80 and 81 on the balancer were 'bombed' with @@ -3628,16 +3747,44 @@ are shown in the below table: Again, the results show that crossroads performs just as effectively as LVS, even with large data chunks! <p> -<a name="l85"></a> -<h2>7: Compiling and Installing</h2> <a name="installation"></a> -<a name="compiling"></a><a name="l86"></a> -<h3>7.1: Prerequisites</h3> +<a name="l87"></a> +<h2>7: The Web Interface</h2> +<a name="webinterface"></a>An auxiliary program is distributed with Crossroads, named +<code>crossroads-mgr</code>, providing a web interface to the balancer. With +<code>crossroads-mgr</code>, it is possible to: +<p> +<ul> + <li> View the status of the balancer (availablility of back ends, + their connections, and usage in bytes and seconds); +<p> +<li> Change the availability of back ends (available, unavailable, + down).</ul> +<p> +The program <code>crossroads-mgr</code> is in fact a Perl script, providing a +self-contained web server. It is started as follows: +<p> +<center><code>crossroads-mgr start</code> <em>portnumber</em></center> +<p> +where <em>portnumber</em> is the TCP port. The web interface can then be +accessed using the URL <code>http://</code><em>hostname</em><code>:</code><em>portnumber</em>; +where <em>hostname</em> is the host where the balancer and the web +interface run. +<p> +More information is available via the manual page (see <code>man</code> +<code>crossroads-mgr</code>). +<p> +<a name="l88"></a> +<h2>8: Compiling and Installing</h2> <a name="installation"></a> +<a name="compiling"></a><a name="l89"></a> +<h3>8.1: Prerequisites</h3> <p> The creation of crossroads requires: <p> <ul> - <li> Standard Unix tools, such as <code>sed</code>, <code>awk</code>, <code>Perl</code> - (5.00 or better); + <li> Standard Unix tools, such as <code>sed</code>, <code>awk</code>; +<p> +<li> Perl (5.00 or better). The web interface + <code>crossroads-mgr</code> requires specific modules; <p> <li> A POSIX-compliant C compiler; <p> @@ -3647,8 +3794,8 @@ The creation of crossroads requires: Basically a Linux or Apple MacOSX box will do nicely. To compile and install crossroads, follow these steps. <p> -<a name="l87"></a> -<h3>7.2: Compiling and installing</h3> +<a name="l90"></a> +<h3>8.2: Compiling and installing</h3> <p> <ul> <li> Obtain the source distribution. It can be found on @@ -3701,14 +3848,21 @@ crossroads, follow these steps. <em>pdfdirectory/</em>; where <em>pdfdirectory</em> is the destination directory for your PDF manuals.</ul> <p> +<li> In order to use the web interface <code>crossroads-mgr</code>, + make sure that the following Perl modules are available: + <code>HTTP::Daemon</code>, <code>Getopt::Std</code>, <code>Log::Log4perl</code>, + <code>MIME::Base64</code>. When in doubt, start the commandline tool + <code>cpan</code> and enter <code>install HTTP::Daemon</code>, which will + install the named module if necessary. You can repeat this for + all listed modules. +<p> </ul> <p> -<a name="l88"></a> -<h3>7.3: Configuring crossroads</h3> +<a name="l91"></a> +<h3>8.3: Configuring crossroads</h3> <p> Now that the binary is available on your system, you need to create a -suitable /etc/crossroads.conf. Use this manual or the output of -<code>crossroads samplconf</code> to get started. +suitable /etc/crossroads.conf. Use this manual to get started. <p> Once you have the configuration ready, start crossroads with <code>crossroads start</code>. Test the availability of your services and back @@ -3752,14 +3906,14 @@ which crossroads daemons are running. Finally, the tailing of <code>/var/log/messages</code> shows what's going on -- especially if you have <code>verbosity true</code> statements in the configuration. <p> -<a name="l89"></a> -<h3>7.4: A boot script</h3> +<a name="l92"></a> +<h3>8.4: A boot script</h3> <p> Finally, you may want to create a boot-time startup script. The exact procedure depends on the used Unix flavor. <p> -<a name="l90"></a> -<strong>7.4.1: SysV Style Startup</strong> +<a name="l93"></a> +<strong>8.4.1: SysV Style Startup</strong> <p> On SysV style systems, there's a startup script directory <code>/etc/init.d</code> where bootscripts for all utilities are located. @@ -3774,13 +3928,23 @@ otherwise the steps will resemble the following. <pre> #!/bin/sh /usr/local/bin/crossroads -v $@ +/usr/local/bin/crossroads-mgr start 1000 </pre> <p> The stated directory <code>/usr/local/bin</code> must correspond with - the installation path. The flag <code>-v</code> causes the startup to - be more 'verbose'. However, once daemonized, the verbosity is - controlled by the appropriate statements in the configuration. + the installation path. +<p> +In the first line, The flag <code>-v</code> causes the startup to be + more 'verbose'. However, once daemonized, the verbosity of + Crossroads is controlled by the appropriate statements in the + configuration. +<p> +The second line starts the web interface <code>crossorads-mgr</code> on + TCP port 1000. Access to the web interface is free for all; + add your own flags <code>-b</code> or <code>-B</code> to enforce basic + authentication (see the manual page of <code>crossroads-mgr</code> and + section <a href="crossroads.html#tips/webinterface">5.14</a>). <p> <li> Determine your 'runlevel': usually 3 when your system is running in text-mode only, or 5 when you are using a graphical @@ -3800,8 +3964,8 @@ If your runlevel is 5, then the right <code>cd</code> command is to <code>/etc/rc.d/rc5.d</code>. Alternatively, you can create the symlinks in both runlevel directories.</ul> <p> -<a name="l91"></a> -<strong>7.4.2: BSD Style Startup</strong> +<a name="l94"></a> +<strong>8.4.2: BSD Style Startup</strong> <p> On BSD style systems, daemons are booted directly from <code>/etc/rc</code> and related scripts. Incase you have a file <code>/etc/rc.local</code>, edit it, @@ -3809,6 +3973,7 @@ and add the statement: <p> <pre> /usr/local/bin/crossroads start +/usr/local/bin/crossroads-mgr start 1000 </pre> <p> diff --git a/doc/crossroads.man b/doc/crossroads.man @@ -1,3700 +0,0 @@ -.TH "Crossroads 1\&.42" "2005, 2006, ff\&." -.PP -.SH "Crossroads 1\&.42" -.SH "Karel Kubat" -.SH "e-tunity" -.SH "2005, 2006, ff\&." - -.PP - -.SH "1: Introduction" -Crossroads is a daemon that basically accepts TCP connections -at preconfigured ports, and given a list of \&'back ends\&' -distributes each incoming connection to one of the back ends, -so that a client request is -served\&. Additionally, crossroads maintains an internal -administration of the back end connectivity: if a back end isn\&'t -usable, then the client request is handled using another back -end\&. Crossroads will then periodically check whether a previously not -usable back end has come to life yet\&. Also, crossroads can select -back ends by estimating the load, so that balancing is achieved\&. -.PP -Using this approach, crossroads serves as load balancer and fail over -utility\&. Crossroads will very likely not be as reliable as -hardware based balancers, since it always will require a server to -run on\&. This server, in turn, may become a new Single Point of -Failure (SPOS)\&. However, in situations where cost efficiency is an issue, -crossroads may be a good choice\&. Furthermore, crossroads can be -deployed in situations where a hardware based balancing already -exists and augmenting service reliability is needed\&. Or, crossroads may be -run off a diskless system, which again improves reliability of the -underlying hardware\&. -.PP -This document describes how to use crossroads, how to configure it -in order to increase the reliability of your systems, and how to -compile the program from its sources\&. -.PP - -.SH "1\&.1: Obtaining Crossroads" - -.PP -As quick reference, here are some important URL\&'s for Crossroads: -.PP -.IP o -http:/crossroads\&.e-tunity\&.com is the site that serves -Crossroads\&. You can browse this at leisure -for documentation, sources, and so on\&. -.IP -.IP o -http://freshmeat\&.net/projects/crossr is the -Freshmeat announcement page\&. -.IP -.IP o -svn://svn\&.e-tunity\&.com/crossroads is the SVN -repository; anonymous reading (fetching) is allowed\&. In order -to commit changes, mail me for -credentials\&. -.PP - -.SH "1\&.2: Reporting bugs" - -.PP -Crossroads was thoroughly tested and proven to work\&. However, on -particular Unices with particular needs and network particularities, -bugs may occur\&. -.PP -In such cases you can contact the maintainer to ask for -assistance\&. Visit the site http://crossroads\&.e-tunity\&.com for contact information\&. In questions -or bug reports, always include the following: -.PP -.IP o -A description of the bug: when does it occur, what are -the circumstances, what is the expected behavior, what is the -observed behavior\&. -.IP -.IP o -The Crossroads configuration (normally -\f(CW/etc/crossroads\&.conf\fP) -.IP -.IP o -The version of Crossroads and all compile-time settings, -obtained via \f(CWcrossroads -C\fP\&. -.PP - -.SH "1\&.3: Copyright and Disclaimer" - -.PP -Crossroads is distributed as-is, without assumptions of fitness -or usability\&. You are free to use crossroads to your -liking\&. It\&'s free, and as with everything that\&'s free: there\&'s -also no warranty\&. -.PP -You are allowed to make modifications to the source code of -crossroads, and you are allowed to (re)distribute crossroads, as -long as you include this text, all sources, and if applicable: all -your modifications, with each distribution\&. -.PP -While you are allowed to make any and all changes to the sources, -I would appreciate hearing about them\&. If the changes concern new -functionality or bugfixes, then I\&'ll include them in a next -release, stating full credits\&. If you want to seriously contribute (to -which you are heartily encouraged), then mail me and I\&'ll get you -access to the Crossroads SVN repository, so that you can update and -commit as you like\&. -.PP - -.SH "1\&.4: Terminology" - -.PP -Throughout this document, the following terms are used: \e (Many -more meanings of the terms will exist -- yes, I am aware of that\&. I\&'m -using the terms here in a very strict sense\&.) -.PP -.IP "A client" -is a process that initiates a network connection -to get contact with some service\&. -.IP "A service" -or \fBserver process\fP or \fBlistener\fP -is a central application -that accepts network connections from clients and sevices -them\&. -.IP "Back ends" -are locations where crossroads looks in -order to service its clients\&. Crossroads sits \&'in between\&' -and does its tricks\&. Therefore, as far as the back ends -are concerned, crossroads behaves like a client\&. As far as -the true client is concerned, crossroads behaves like the -service\&. The communication is however transparent: neither -client nor back end are aware of the middle position of -crossroads\&. -.IP "A connection" -is a network conversation between client and service, -where data are transferred to and fro\&. As -far as crossroads is concerned, success means that a -connection can be established without errors on -the network level\&. Crossroads isn\&'t aware of service -pecularities\&. E\&.g\&., when a webserver answers \f(CWHTTP/1\&.0 -500 Server Error\fP then crossroads will see this as a -succesful connection, though the user behind a browser may -think otherwise\&. -.IP "Back end selection algorithms" -are methods by which -crossroads determines which back end it will talk to -next\&. Crossroads has a number of built-in algorithms, -which may be configured per service\&. -.IP "Back end states" -are the statusses of each back end that -is known to crossroads\&. A back end may be available, -(temporarily) unavailble or truly down\&. When a back end is -temporarily unavailable, then crossroads will periodically -check whether the back end has come to life yet (that is, -if configured so)\&. -.IP "A spike" -is a sudden increase in activity, leading to -extra load on a given service\&. When crossroads is in -effect and when the spike occurs in one connection, -then obviously the spike will also appear at one -of the back ends\&. However, crossroads will see the spike -and will make sure that a subsequent request goes to an -other back end\&. In contrast, when several connections -arrive simultaneously and cause a spike, then crossroads -will be able to distribute the connections over several -back ends, thereby \&'flattening out\&' the increase\&. -.IP "Load balancing" -means that incoming client requests are -distributed over more than just one back end (which wouldn\&'t be the -case if you wouldn\&'t be running crossroads)\&. Enabling load -balancing is nothing more than duplicating services over -more than one back end, and having something (in this -case: crossroads) distribute the requests, so that per -back end the load doesn\&'t get too high\&. -.IP "An HTTP session" -is a series of separate network connections -that originate from one browser\&. E\&.g\&., to fill the display -with text and images, the browser hits a website several times\&. -An HTTP session may even span several -screens\&. E\&.g\&., a website registration dialog may involve 3 -screens that when called from the same browser, -form a logical group of some sort\&. -.IP "Headers" -or \fBheader lines\fP are specific parts of an HTTP -message\&. Crossroads has directives to add or modify -headers that are part of the request that a browser sends -to server, or those that are part of the server\&. -.IP "Session stickiness" -means that when a browser starts an -HTTP dialog, the balancer makes sure that it \&'sticks\&' to -the same back end (i\&.e\&., subsequent requests from the -browser are forced to go to the same back end, instead of -being balanced to other ones)\&. -.IP "Back end usage" -is measured by crossroads in order to be -able to determine back end selection\&. Crossroads stores -information about the number of active connections, the -transferred bytes and -about the connection duration\&. These numbers can be used to -estimate which back end is the least used -- and -therefore, presumably, the best candidate for a new -request\&. -.IP "Fail over" -is almost always used when load balancing is in -effect\&. The distributor of client requests (crossroads of -course) can also monitor back ends, so that incase a back -end is \&'down\&', it is no longer accessed\&. -.IP "Service downtime" -normally occurs when a service is -switched off\&. Downtime is obviously avoided when fail over -is in effect: a back end can be taken out of service in a -controlled manner, without any client noticing it\&. - -.PP - -.SH "1\&.5: Porting issues for pre-1\&.43 installations" - -.PP -As of version 1\&.43, the shared memory key calculations are based -on a different algorithm\&. This key is e\&.g\&. necessary when starting -and stopping Crossroads; in both actions, the key must be computed -in the same way\&. -.PP -Therefore, when upgrading Crossroads, make sure that you stop a -running Crossroads daemon using the same binary that started -it\&. After this, install a new binary, and start the daemon using -the new binary\&. -.PP -(Incidentally, this is always a good idea, but especially so when -the \&'old\&' binary is pre-1\&.43 and the \&'new\&' one is post-1\&.43\&.) -.PP - -.SH "1\&.6: Porting issues for pre-1\&.21 installations" - -.PP -As of version 1\&.21, the event-hook directives \f(CWonsuccess\fP and -\f(CWonfailure\fP no longer exists\&. -.PP -.IP o -Please replace \f(CWonsuccess\fP by \f(CWonstart\fP; -.IP o -Please replace \f(CWonfailure\fP bu \f(CWonfail\fP; -.IP o -Note that there is a new hook \f(CWonend\fP\&. -.PP -The commands that are run via \f(CWonstart\fP, \f(CWonend\fP or \f(CWonfail\fP - are subject to format expansion; e\&.g\&., \f(CW%1w\fP is expanded to the - weight of the first back end, etc\&.\&. See section ?? for details\&. -.PP - -.SH "1\&.7: Porting issues for pre-0\&.26 installations" - -.PP -As of version 0\&.26 the syntax of the configuration file has -changed\&. In particular: -.PP -.IP o -The keyword \f(CWmaxconnections\fP is now used instead of -\f(CWmaxclients\fP; -.IP o -The keyword \f(CWconnectiontimeout\fP is now used instead of -\f(CWsessiontimeout\fP\&. -.PP -Therefore when converting configuration files to the new syntax, -the above keywords must be changed\&. (The reason for these changes -is that 0\&.26 introduces \fIsticky HTTP sessions\fP that span -multiple TCP connections, and the term -\fIsession\fP is used strictly in that sense -- and no longer for a -TCP connection\&.) -.PP - -.SH "1\&.8: Porting issues for pre-1\&.08 installations" - -.PP -As of version 1\&.08, the following directives no longer are -supported: -.PP -.IP o -\f(CWinsertstickycookie\fP was replaced by the more generic -directive \f(CWaddclientheader\fP\&. E\&.g\&., instead of -.br -\f(CWinsertstickycookie "XRID=100; Path=/";\fP -.br -the syntax is now -.br -\f(CWaddclientheader "Set-Cookie: XRID=100; Path=/";\fP -.IP -.IP o -\f(CWinsertrealip\fP was replaced by the more generic -directive \f(CWsetserverheader\fP\&. E\&.g\&., instead of -.br -\f(CWinsertrealip on;\fP -.br -the syntax is now -.br -\f(CWsetserverheader "XR-Real-IP: %r";\fP -.br -This incidentally also makes it possible to change the header -name (here: \f(CWXR-Real-IP\fP)\&. -.PP - -.SH "2: Installation for the impatient" -For the impatient, here\&'s the very-quick-but-very-superficial recipy -for getting crossroads up and running: -.PP -.IP o -If you don\&'t have SVN or don\&'t want to use it: -.IP -.IP o -Obtain the crossroads source archive at -http://crossroads\&.e-tunity\&.com\&. -.IP -.IP o -Change-dir to a \&'sources\&' directory on your system and -unpack the archive\&. -.IP -.IP o -Change-dir into the create directory \f(CWcrossroads/\fP\&. -.IP -.IP o -If you have SVN and want to go for the newest snapshot: -.IP -.IP o -Get the latest sources and snapshots using SVN from -.br -\f(CWsvn://svn\&.e-tunity\&.com/crossroads\fP\&. -.IP -.IP o -You\&'ll find the newest alpha version under -\f(CWcrossroads/trunk\fP and the stable versions under -\f(CWcrossroads/tags\fP, -e\&.g\&. \f(CWcrossroads/tags/release-1\&.00\fP\&. -.IP -.IP o -Choose which you want to use: the latest stable -release, or the bleeding edge alpha? In the former case, -change-dir to \f(CWcrossroads/tags/release-\fP\fIX\&.YY\fP, where -\fIX\&.YY\fP is a release ID\&. In the latter case, change-dir to -\f(CWcrossroads/trunk\fP\&. -.IP -.IP o -Type \f(CWmake install\fP\&. This installs the crossroads -binary into \f(CW/usr/local/bin/\fP\&. If the compilation doesn\&'t -work on your system, check \f(CWetc/Makefile\&.def\fP for hints\&. -.IP -.IP o -Create a file \f(CW/etc/crossroads\&.conf\fP\&. In it state -something like: -.IP -.nf -service www { - port 80; - revivinginterval 15; - backend one { - server 10\&.1\&.1\&.100:80; - } - backend two { - server 10\&.1\&.1\&.101:80; - } -} -.fi - -.IP -That\&'s off course assuming that you want to balance HTTP on -port 80 to two back ends at 10\&.1\&.1\&.100 and 10\&.1\&.1\&.101\&. -.IP -.IP o -Type \f(CWcrossroads start\fP\&. -.IP -.IP o -Surf to the machine where crossroads is running\&. You will -see the pages served by the back ends 10\&.1\&.1\&.100 or -10\&.1\&.1\&.101\&. -.IP -.IP o -To monitor the status of crossroads, type \f(CWcrossroads -status\fP\&. - -.PP - -.SH "3: Using Crossroads" -Crossroads is started from the commandline, and highly depends on -\f(CW/etc/crossroads\&.conf\fP (the default configuration file)\&. It -supports a number of flags (e\&.g\&., to overrule the location of the -configuration file)\&. The actual usage information is always obtained -by typing \f(CWcrossroads\fP without any arguments\&. Crossroads then -displays the allowed arguments\&. -.PP -The installation (see section ??) installs also a -second program called \f(CWcrossroads-daemon\fP\&. This program is not meant -to be started from the command line; it is administered through the -front end \f(CWcrossroads\fP\&. -.PP - -.SH "3\&.1: General Commandline Syntax" - -.PP -This section shows the most basic usage\&. As said above, start -\f(CWcrossroads\fP without arguments to view the full listing of options\&. -.PP -.IP o -\f(CWcrossroads start\fP and \f(CWcrossroads stop\fP are typical -actions that are run from system startup scripts\&. The -meaning is self-explanatory\&. -.IP o -\f(CWcrossroads restart\fP is a combination of the former -two\&. Beware that a restart may cause discontinuity in -service; it is just a shorthand for typing the \&'stop\&' and -\&'start\&' actions after one another\&. -.IP o -\f(CWcrossroad status\fP reports on each running -service\&. Per service, the state of each back end is -reported\&. -.IP o -\f(CWcrossroads tell\fP \fIservice backend state\fP is a -command line way of telling crossroads that a given back -end, of a given service, is in a given state\&. Normally -crossroads maintains state information itself, but by -using \f(CWcrossroads tell\fP, a back end can be e\&.g\&. taken -\&'off line\&' for servicing\&. -.IP o -\f(CWcrossroads configtest\fP tells you whether the -configuration is syntactially correct\&. -.IP o -\f(CWcrossroads services\fP reports on the configured -services\&. In contrast to \f(CWcrossroads status\fP, this -option only shows what\&'s configured -- not what\&'s up and -running\&. Therefore, \f(CWcrossroads services\fP doesn\&'t -report on back end states\&. -.IP o -\f(CWcrossroads sampleconf\fP shows a sample configuration on -screen\&. A good way of quicky viewing the configuration -file syntax, or of getting a start for your own -configuration \f(CW/etc/crossroads\&.conf\fP\&. - -.PP - -.SH "3\&.2: Status Reporting" - -.PP -The command \f(CWcrossroads status\fP shows a verbose human-readable -report of how Crossroads is doing\&. When many services are configured, -this can be a somewhat lengthy output\&. If you\&'re interested in the -overview of only one service, you can use \f(CWcrossroads status\fP -\fIservicename\fP, in which case the report will only be shown for the -stated service\&. -.PP -Similarly, if you\&'re interested only in the status of a given back end -of a given service, use \f(CWcrossroads service\fP \fIservicename\fP -\fIbackendname\fP\&. -.PP -The flag \f(CW-t\fP causes the status overview to be abbreviated and -displayed in a parseable format\&. This flag can be used in automated -scripts that check how Crossroads is doing; e\&.g\&., in health checking -scripts\&. When \f(CW-t\fP is used, the format of the status reporter is as -follows: -.PP -.IP o -Service health is reported on one line per service\&. -.IP o -The first string on the line is the service name\&. -.IP o -After this, a series follows of \fIbackendname=state\fP, -where the back end name is the configured name of the back -end, and where state is e\&.g\&. \f(CWavailable\fP, \f(CWDOWN\fP, -\f(CWUNAVAILABLE\fP, \f(CWWAKING\fP\&. All statuses that cause -Crossroads not to use the back end are in caps\&. The series is -repeated for all back ends of the given service\&. -.PP -The flag \f(CW-x\fP causes the overview to be presented as an XML -document\&. This can be handy if you want to further automate the -control over Crossroads, or if you want to show the status via the web\&. -.PP - -.SH "3\&.3: Logging-related options" - -.PP -Two \&'flags\&' of Crossroads are specifically logging-related\&. This -section elaborates on these flags\&. -.PP -First, there\&'s flag \f(CW-a\fP\&. When present, the start and end of -activity is logged using statements like -.PP -\fIYYYY-MM-DD HH/MM/SS starting http from 61\&.45\&.32\&.189 to 10\&.1\&.1\&.1\fP - -.PP -Similarly, there are \&'ending\&' statements\&. Using this flag and -scanning your logs for these statements may be helpful in quickly -determining your system load\&. -.PP -Second, there\&'s flag \f(CW-l\fP\&. This flag selects the \&'facility\&' of -logging and defaults to \f(CWLOG_DAEMON\fP\&. You can supply a number -between 0 and 7 to flag \f(CW-l\fP to select \f(CWLOG_LOCAL0\fP to -\f(CWLOG_LOCAL7\fP\&. This would separate the Crossroads-related logging -from other streams\&. Here\&'s a very short guide; please read your Unix -manpages of \f(CWsyslogd\fP for more information\&. -.PP -.IP o -First edit \f(CW/etc/syslog\&.conf\fP and add a line: -.IP -.nf -local7\&.* /var/log/crossroads\&.log -.fi - -.IP -That instructs \f(CWsyslogd\fP to send \f(CWLOG_LOCAL7\fP requests to the -logfile \f(CW/var/log/crossroads\&.log\fP\&. -.IP -.IP o -Next, restart \f(CWsyslogd\fP\&. On most Unices that\&'s done by -issuing \f(CWkillall -1 syslogd\fP\&. (As a side-note, I tried this once -on an Bull/AIX system, and the box just shut down\&. The \f(CWkillall\fP -command killed every process\&.\&.\&.) -.IP -.IP o -Now start \f(CWcrossroads\fP with the flag \f(CW-l7\fP\&. -.IP -.IP o -Finally, monitor \f(CW/var/log/crossroads\&.log\fP for Crossroads\&' -messages\&. -.PP - -.SH "3\&.4: Reloading Configurations" - -.PP -Crossroads doesn\&'t support the reloading of a configuration while -running (such as other programs, e\&.g\&. Apache do)\&. There are various -technical reasons for this\&. -.PP -However, external lists of allowed or denied IP addresses can be -reloaded by sending a signal -1 (\f(CWSIGHUP\fP) to Crossroads\&. See -section ?? for the details\&. -.PP - -.SH "4: The configuration" -The configuration that crossroads uses is normally stored in the file -\f(CW/etc/crossroads\&.conf\fP\&. This location can be overruled using the -command line flag \f(CW-c\fP\&. -.PP -This section explains the syntax of the configuration file, and what -all settings do\&. -.PP - -.SH "4\&.1: General language elements" - -.PP -This section describes the general elements of the crossroads -configuration language\&. -.PP - -.SH "4\&.1\&.1: Empty lines and comments" - -.PP -Empty lines are of course allowed in the -configuration\&. Crossroads recognizes three formats of comment: -.PP -.IP o -C-style, between \f(CW/*\fP and \f(CW*/\fP, -.IP o -C++-style, starting with \f(CW//\fP and ending with the end -of the text line; -.IP o -Shell-style, starting with \f(CW#\fP and ending with the end -of the text line\&. -.PP -Simply choose your favorite editor and use the comment that \&'looks -best\&'\&.\e (I favor C or C++ comment\&. My favorite editor \fIemacs\fP -can be put in \f(CWcmode\fP and nicely highlight what\&'s comment and what\&'s -not\&. And as a bonus it will auto-indent the configuration!) -.PP - -.SH "4\&.1\&.2: Keywords, numbers, identifiers, generic strings" - -.PP -In a configuration file, statements are identified by \fIkeywords\fP, -such as \f(CWservice\fP, \f(CWverbosity\fP\&. These are reserved words\&. -.PP -Many keywords require an \fIidentifier\fP as the argument\&. E\&.g, a -service has a unique name, which must start with a letter or -underscore, followed by zero or more letters, underscores, or -digits\&. Therefore, in the statement \f(CWservice myservice\fP, the keyword is -\f(CWservice\fP and the identifier is \f(CWmyservice\fP\&. -.PP -Other keywords require a numeric argument\&. Crossroads knows only -non-negative integer numbers, as in \f(CWport 8000\fP\&. Here, \f(CWport\fP is -the keyword and \f(CW8000\fP is the number\&. -.PP -Yet other keywords require \&'generic strings\&', such as hostname -specifications or system commands\&. Such generic strings contain any -characters (including white space) up to the terminating statement -character \f(CW;\fP\&. If a string must contain a semicolon, then it must -be enclosed in single or double quotes: -.PP -.IP o -\f(CWThis is a string;\fP is a string that starts at \f(CWT\fP -and ends with \f(CWg\fP -.IP o -\f(CW"This is a string";\fP is the same, the double quotes -are not necessary -.IP o -\f(CW"This is ; a string";\fP has double quotes to protect -the inner ; -.PP -Finally, an argument can be a \&'boolean\&' value\&. Crossroads knows -\f(CWtrue\fP, \f(CWfalse\fP, \f(CWyes\fP, \f(CWno\fP, \f(CWon\fP, \f(CWoff\fP\&. The keywords -\f(CWtrue\fP, \f(CWyes\fP and \f(CWon\fP all mean the same and can be used -interchangeably; as can the keywords \f(CWfalse\fP, \f(CWno\fP and \f(CWoff\fP\&. -.PP - -.SH "4\&.2: Service definitions" - -.PP -Service definitions are blocks in the configuration file that -state what is for each service\&. A service definition starts with -\f(CWservice\fP, followed by a unique identifier, and by statements in -\f(CW{\fP and \f(CW}\fP\&. For example: -.PP -.nf -// Definition of service \&'www\&': -service www { - \&.\&.\&. - \&.\&.\&. // statements that define the - \&.\&.\&. // service named \&'www\&' - \&.\&.\&. -} -.fi - -.PP -The configuration file can contain many service blocks, as long as the -identifying names differ\&. The following list shows possible -statements\&. Each statement must end with a semicolon, except for the -\f(CWbackend\fP statement, which has is own block (more on this later)\&. -.PP - -.SH "4\&.2\&.1: type - Defining the service type" -.IP "Description:" -The \f(CWtype\fP statement defines how crossroads handles the stated -service\&. There are currently two types: \f(CWany\fP and -\f(CWhttp\fP\&. The type \f(CWany\fP means that crossroads doesn\&'t -interpret the contents of a TCP stream, but only distributes streams -over back ends\&. The type \f(CWhttp\fP means that crossroads has to -analyze what\&'s in the messages, does magical HTTP header tricks, and -so on -- all to ensure that multiple connections are treated as one -session, or that the back end is notified of the client\&'s IP -address\&. -.IP -Unless you really need such special features, use the type \f(CWany\fP (the -default), even for HTTP protocols\&. -.IP "Syntax:" -\f(CWtype\fP \fIspecifier\fP, where \fIspecifier\fP is \f(CWany\fP or -\f(CWhttp\fP -.IP "Default:" -\f(CWany\fP - -.PP - -.SH "4\&.2\&.2: port - Specifying the listen port" -.IP "Description:" -The \f(CWport\fP statement defines to which TCP port a service -\&'listens\&'\&. E\&.g\&. \f(CWport 8000\fP says that this service will accept -connections on port 8000\&. -.IP "Syntax:" -\f(CWport\fP \fInumber\fP -.IP "Default:" -There is no default\&. This is a required setting\&. - -.PP - -.SH "4\&.2\&.3: bindto - Binding to a specific IP address" -.IP "Description:" -The \f(CWbindto\fP statement is used in situations where crossroads -should only listen to the stated port at a given IP address\&. E\&.g\&., -\f(CWbindto 127\&.0\&.0\&.1\fP causes crossroads to \&'bind\&' the service only to -the local IP address\&. Network connections from other hosts won\&'t be -serviced\&. By default, crossroads binds a service to all presently -active IP addresses at the invoking host\&. -.IP "Syntax:" -\f(CWbindto\fP \fIaddress\fP, where \fIaddress\fP is a numeric IP -address, such as 127\&.0\&.0\&.1, or the keyword \f(CWany\fP\&. -.IP "Default:" -\f(CWany\fP - -.PP - -.SH "4\&.2\&.4: verbosity - Controlling debug output" -.IP "Description:" -Verbosity statements come in two forms: \f(CWverbosity on\fP or -\f(CWverbosity off\fP\&. When \&'on\&', log messages to \f(CW/var/log/messages\fP -are generated that show what\&'s going on\&.\e (Actually, the -messages go to \f(CWsyslog(3)\fP, using facility \f(CWLOG_DAEMON\fP and -priority \f(CWLOG_INFO\fP\&. In most (Linux) cases this will mean: output to -\f(CW/var/log/messages\fP\&. On Mac OSX the messages go to -\f(CW/var/log/system\&.log\fP\&.) The keyword \f(CWverbose\fP is an alias for -\f(CWverbosity\fP\&. -.IP "Syntax:" -\f(CWverbosity\fP \fIsetting\fP or \f(CWverbose\fP \fIsetting\fP, where -\fIsetting\fP is \f(CWtrue\fP, \f(CWyes\fP or \f(CWon\fP to turn -verbosity on; or \f(CWfalse\fP, \f(CWno\fP, \f(CWoff\fP to turn it off\&. -.IP "Default:" -\f(CWoff\fP - -.PP - -.SH "4\&.2\&.5: dispatchmode - How are back ends selected" -.IP "Description:" - The dispatch mode controls how crossroads selects a back end from - a list of active back ends\&. The below text shows the bare - syntax\&. See section ?? for a textual explanation\&. -.IP -The settings can be: -.IP -.IP o -\f(CWdispatchmode roundrobin\fP: Simply the \&'next in line\&' is -chosen\&. E\&.g, when 3 back ends are active, then the usage -series is 1, 2, 3, 1, 2, 3, and so on\&. -.IP -Roundrobin dispatching is the default method, when no -\f(CWdispatchmode\fP statement occurs\&. -.IP -.IP o -\f(CWdispatchmode random\fP: Random selection\&. Probably only -for stress testing, though when used with weights (see below) -it is a good distributor of new connections too\&. -.IP -.IP o -\f(CWdispatchmode bysize [ over\fP \fIconnections\fP \f(CW]\fP: -The next back end is the one -that has transferred the least number of bytes\&. This -selection mechanism assumes that the more bytes, the heavier -the load\&. -.IP -The modifier \f(CWover\fP \fIconnections\fP is optional\&. (The square -brackets shown above are not part of the statement but -indicate optionality\&.) When given, -the load is computed as an average of the last stated number of -connections\&. When this modifier is absent, then the load is -computed over all connections since startup\&. -.IP -.IP o -\f(CWdispatchmode byduration [ over\fP \fIconnections\fP \f(CW]\fP: -The next back end is the one -that served connections for the shortest time\&. This mechanism -assumes that the longer the connection, the heavier the load\&. -.IP -.IP o -\f(CWdispatchmode byconnections\fP: The next back end is the one -with the least active connections\&. This mechanism assumes that -each connection to a back end represents load\&. It is usable -for e\&.g\&. database connections\&. -.IP -.IP o -\f(CWdispatchmode byorder\fP: The first back end is selected -every time, unless it\&'s unavailable\&. In that case the second -is taken, and so on\&. -.IP -.IP o -\f(CWdispatchmode byclientip\fP: The client\&'s IP address is -\&'hashed\&' into a number, which is used to pick a back end\&. The -same client IP address will therefore always be dispatched to -the same back end\&. When the back end of choice is down, -\f(CWdispatchmode byconnections\fP is used\&. -.IP -.IP o -\f(CWdispatchmode externalhandler\fP \fIprogram arguments\fP: -This is a special mode, where an external program is delegated -the responsibility to say which back end should be used -next\&. In this case, Crossroads will call the external program, -and this will of course be slower than one of the \&'built-in\&' -dispatch modes\&. However, this is the ultimate escape when -custom-made dispatch modes are needed\&. -.IP -The dispatch mode that uses an \f(CWexternalhandler\fP is - discussed separately in section ??\&. -.IP -The selection algorithm is only used when clients are serviced that -aren\&'t part of a sticky HTTP session\&. This is the case during: -.IP -.IP o -all client requests of a service type \f(CWany\fP; -.IP o -new sessions of a service type \f(CWhttp\fP\&. -.IP -When type \f(CWhttp\fP is in effect and a session is underway, then the -previously used back end is always selected -- regardless of -dispatching mode\&. -.IP -Your \&'right\&' dispatch mode will depend on the type of service\&. Given -the fact that crossroads doesn\&'t know (and doesn\&'t care) how to -estimate load from a network traffic stream, you have to choose an -appropriate dispatch mode to optimize load balancing\&. In most cases, -\f(CWroundrobin\fP or \f(CWbyconnections\fP will do the job just fine\&. -.IP "Syntax:" -\f(CWdispatchmode\fP \fImode\fP (see above for the modes), optionally -followed by \f(CWover\fP \fInumber\fP, or when the \fImode\fP is -\f(CWexternalhandler\fP, followed by \fIprogram\fP\&. -.IP "Default:" -\f(CWroundrobin\fP - -.PP - -.SH "4\&.2\&.6: revivinginterval - Back end wakeup calls" -.IP "Description:" -A reviving interval definition is needed when crossroads -determines that a back end is temporarily unavailable\&. This will -happen when: -.IP -.IP o -The back end cannot be reached (network connection -fails); -.IP o -The network connection to the back end suddenly dies\&. -.IP -An example of the definition is \f(CWrevivinginterval 10\fP\&. When this -reviving interval is given, crossroads will check each 10 seconds -whether unavailable back ends have woken up yet\&. A back end is -considered awake when a network connection to that back end can -succesfully be established\&. -.IP "Syntax:" -\f(CWrevivinginterval\fP \fInumber\fP, where the number is the interval -in seconds\&. -.IP "Default:" -0 (no wakeup calls) - -.PP - -.SH "4\&.2\&.7: maxconnections - Limiting concurrent clients at service level" -.IP "Description:" -The maximum number of connections is specified using -\f(CWmaxconnections\fP\&. There is one argument; the number of concurrent -established connections that may be active within one service\&. -.IP -\&'Throttling\&' the number of connections is a way of preventing Denial of -Service (DOS) attacks\&. Without a limit, numerous network connections -may spawn so many server instances, that the service ultimately breaks -down and becomes unavailable\&. -.IP "Syntax:" -\f(CWmaxconnections\fP \fInumber\fP, where the number specifies the -maximum of concurrent connections to the service\&. -.IP "Default:" -0, meaning that all connections will be accepted\&. - -.PP - -.SH "4\&.2\&.8: backlog - The TCP Back Log size" -.IP "Description:" -The TCP back log size is a number that controls how many -\&'waiting\&' network connections may be queued, before a client simply -cannot connect\&. The syntax is e\&.g\&. \f(CWbacklog 5\fP to cause crossroads -to have 5 waiting connections for 1 active connection\&. -The backlog queue shouldn\&'t be too -high, or clients will experience timeouts before they can actually -connect\&. The queue shouldn\&'t be too small either, because clients -would be simply rejected\&. Your mileage may vary\&. -.IP "Syntax:" -\f(CWbacklog\fP \fInumber\fP -.IP "Default:" -0, which takes the operating system\&'s default -value for socket back log size\&. - -.PP - -.SH "4\&.2\&.9: shmkey - Shared Memory Access" -.IP "Description:" -Different Crossroads -invocations must \&'know\&' of each others activity\&. E\&.g, \f(CWcrossroad -status\fP must be able to get to the actual state information of all -running services\&. This is internally implemented through shared -memory, which is reserved using a key\&. -.IP -Normally crossroads will supply a shared memory key, based on the -service name\&. In situations where this conflicts with existing -keys (of other programs, having their own keys), you may supply a -chosen value\&. -.IP -The actual key value doesn\&'t matter much, as long as it\&'s unique -and as long as each invocation of crossroads uses it\&. -.IP "Syntax:" -\f(CWshmkey\fP \fInumber\fP -.IP "Default:" - 0, which means that crossroads will \&'guess\&' its - own key, based on the service name\&. - - -.SH "4\&.2\&.10: allow* and deny* - Allowing or denying connections" -.IP "Description:" -Crossroads can allow or deny -connections based on the IP address of a client\&. There are four -directives that are relevant: \f(CWallowfrom\fP, \f(CWallowfile\fP, -\f(CWdenyfrom\fP and \f(CWdenyfile\fP\&. When using \f(CWallowfrom\fP and -\f(CWdenyfrom\fP then the IP addresses to allow or deny connections are -stated in \f(CW/etc/crossroads\&.conf\fP\&. -.IP -When \f(CWallow*\fP directives are used, then all connections are denied -unless they match the stated allowed IP\&'s\&. When \f(CWdeny*\fP directives -are used, then all connections are allowed unless they match the -stated disallowed IP\&'s\&. When denying and allowing is both used, -then the Crossroads checks the deny list first\&. -.IP -The statements \f(CWallowfrom\fP and \f(CWdenyfrom\fP are followed by a -list of filter specifications\&. The statements \f(CWallowfile\fP and -\f(CWdenyfile\fP are followed by a filename; Crossroads will read -filter specifications from those external files\&. In both cases, -Crossroads obtains filter specifications and places them in its -lists of allowed or denied IP addresses\&. The difference between -specifying filters in \f(CW/etc/crossroads\&.conf\fP or in external -files, is that Crossroads will reload the external files when it -receives signal 1 (\f(CWSIGHUP\fP), as in \f(CWkillall -1 crossroads\fP\&. -.IP -The filter specifications must obey the following syntax: it -consists of up to -four numbers ranging from 0 to 255 and separated by a decimal -sign\&. Optionally a slash follows, with a bitmask which is also a -decimal number\&. -.IP -This is probably best explained by a few examples: -.IP -.IP o -\f(CWallowfrom 10/8;\fP will allow connections from -\f(CW10\&.*\&.*\&.*\fP (a full Class A network)\&. The mask \f(CW/8\fP means -that the first 8 bits of the number (ie\&., only the \f(CW10\fP) are -significant\&. On the last 3 positions of the IP address, all -numbers are allowed\&. Given this directive, client connections -from e\&.g\&. 10\&.1\&.1\&.1 and 10\&.2\&.3\&.4 will be allowed\&. -.IP -.IP o -\f(CWallowfrom 10\&.3/16;\fP will allow all IP addresses that -start with \f(CW10\&.3\fP\&. -.IP -.IP o -\f(CWallowfrom 10\&.3\&.1/16;\fP is the same as above\&. The third -byte of the IP address is superfluous because the netmask -specifies that only the first 16 bits (2 numbers) are taken -into account\&. -.IP -.IP o -\f(CWallowfrom 10\&.3\&.1\&.15;\fP allows traffic from only the -specified IP address\&. There is no bitmask; all four numbers -are relevant\&. -.IP -.IP o -\f(CWallowfrom 10\&.3\&.1\&.15 10\&.2/16;\fP allows traffic from one -IP address \f(CW10\&.3\&.1\&.15\fP or from a complete Class B network -\f(CW10\&.2\&.*\&.*\fP -.IP -.IP o -\f(CWallowfile /tmp/myfile\&.txt;\fP in combination with a file -\f(CW/tmp/myfile\&.txt\fP, with the contents \f(CW10\&.3\&.1\&.15 10\&.2/16\fP, -is the same as above\&. -.IP "Syntax:" -.IP o -\f(CWallowfrom\fP \fIfilter-specificication(s)\fP -.IP o -\f(CWdenyfrom\fP \fIfilter-specificication(s)\fP -.IP o -\f(CWallowfile\fP \fIfilename\fP -.IP o -\f(CWdenyfile\fP \fIfilename\fP -.IP "Default:" -In absence of these statements, all client IP\&'s are accepted\&. - -.PP - -.SH "4\&.2\&.11: useraccount - Limiting the effective ID of external processes" -.IP "Description:" -Using the directive \f(CWuseraccount\fP, the effective user and group -ID can be restricted\&. This comes into effect when Crossroads runs -external commands, such as: -.IP o -Hooks for \f(CWonstart\fP, \f(CWonend\fP or \f(CWonfail\fP; -.IP o -External dispatchers, when \f(CWdispatchmode -externalhandler\fP is in effect\&. -Once a user name for external commands is specified, Crossroads -assumes the associated user ID and group ID before running those -commands\&. -.IP "Syntax:" -\f(CWuseraccount\fP \fIusername\fP -.IP "Default:" -None; when unspecified, external commands are run with the -ID that was in effect when Crossroads was started\&. - -.PP - -.SH "4\&.3: Backend definitions" - -.PP -Inside the service definitions as are described in the previous -section, \fIbackend definitions\fP must also occur\&. Backend definitions -are started by the keyword \f(CWbackend\fP, followed by an identifier -(the back end name) , and statements inside \f(CW{\fP and \f(CW}\fP: -.PP -.nf -service myservice { - \&.\&.\&. - \&.\&.\&. // statements that define the - \&.\&.\&. // service named \&'myservice\&' - \&.\&.\&. - - backend mybackend { - \&.\&.\&. - \&.\&.\&. // statements that define the - \&.\&.\&. // backend named \&'mybackend\&' - \&.\&.\&. - } -} -.fi - -.PP -Each service definition must have at least one backend -definition\&. There may be more (and probably will, if you want -balancing and fail over) as long as the backend names differ\&. -The statements in the backend definition blocks are described in the -following sections\&. -.PP -Some directives (\f(CWstickycookie\fP etc\&.) only have effect when -Crossroads treats the network traffic as a stream of HTTP messages; -i\&.e\&., when the service is declared with \f(CWtype http\fP\&. Incase of -\f(CWtype any\fP, the HTTP-specific directives have no effect\&. -.PP - -.SH "4\&.3\&.1: server - Specifying the back end address" -.IP "Description:" -Each back end must be identified by the network name -(server name) where it is located\&. For example: \f(CWserver -10\&.1\&.1\&.23\fP, or \f(CWserver web\&.mydomain\&.org\fP\&. A TCP port specifier -can follow the server name, as in \f(CWserver web\&.mydomain\&.org:80\fP\&. -.IP "Syntax:" -.IP o -\f(CWserver\fP \fIservername\fP, where \fIservername\fP is a -network name or IP address; -.IP o -\f(CWserver\fP \fIservername:port\fP -.IP "Default:" -There is no default\&. This is a required setting\&. - -.PP - -.SH "4\&.3\&.2: verbosity - Controlling verbosity at the back end level" -.IP "Description:" -Similar to \f(CWservice\fP specifications, a -\f(CWbackend\fP can have its own verbosity (\f(CWon\fP or \f(CWoff\fP)\&. When -\f(CWon\fP, traffic to and fro this back end is reported\&. -.IP "Syntax:" -.IP o -\f(CWverbosity\fP \fIsetting\fP, or -.IP o -\f(CWverbose\fP \fIsetting\fP, where \fIsetting\fP is \f(CWtrue\fP, -\f(CWyes\fP or \f(CWon\fP, or \f(CWfalse\fP, \f(CWno\fP, \f(CWoff\fP to turn it -off\&. -.IP "Default:" -\f(CWoff\fP - -.PP - -.SH "4\&.3\&.3: retries - Specifying allowed failures" -.IP "Description:" -Back ends that are \&'flaky\&' or on a less reliable network can be -marked as unavailable after not just one failure, but after -e\&.g\&. three\&. You can use this configuration if you suspect that -spurious errors cause otherwise \&'good\&' back ends to be marked as -unavailable, while they in fact still could be used\&. -.IP "Syntax:" -\f(CWretries\fP \fInumber\fP; where \fInumber\fP is the threshold of bad -connections\&. Once exceeded, Crossroads will mark a back end as -unavailable\&. -.IP "Default:" -1; a back end is assumed to be unavailable after the first bad -connection\&. - -.PP - -.SH "4\&.3\&.4: weight - When a back end is more equal than others" -.IP "Description:" -To influence how backends are selected, a backend can specify its -\&'weight\&' in the process\&. The higher the weight, the less likely a -back end will be chosen\&. The default is 1\&. -.IP -The weighing mechanism only applies to the dispatch modes -\f(CWrandom\fP, \f(CWbyconnections\fP, \f(CWbysize\fP and \f(CWbyduration\fP\&. -The weight is in fact a penalty factor\&. E\&.g\&., if backend A has -\f(CWweight 2\fP and backend B has \f(CWweight 1\fP, then backend B will -be selected all the time, until its usage parameter is twice as -large as the parameter of A\&. Think of it as a \&'sluggishness\&' -statement\&. -.IP "Syntax:" -\f(CWweight\fP \fInumber\fP; the higher the number, the more \&'sluggish\&' -a back end is -.IP "Default:" -1; all back ends have equal weight\&. - -.PP - -.SH "4\&.3\&.5: decay - Levelling out activity of a back end" -.IP "Description:" -To make sure that a \&'spike\&' of activity doesn\&'t -influence the perceived load of a back end forever, you may -specify a certain decay\&. E\&.g, the statement \f(CWdecay 10\fP makes -sure that the load that crossroads computes for this back end (be -it in seconds or in bytes) is decreased by 10% each time that -\fBan other\fP back end is hit\&. Decays are not applied to the count -of concurrent connections\&. -.IP -This means that when a given back end is hit, then its usage data -of the transferred bytes and the connection duration are updated -using the actual number of bytes and actual duration\&. However, -when a different back end is hit, then the usage data are -decreased by the specified decay\&. -.IP "Syntax:" -\f(CWdecay\fP \fInumber\fP, where \fInumber\fP is a percentage that -decreases the back end usage data when other back ends are -hit\&. -.IP "Default:" -0, meaning that no decay is applied to usage statistics\&. - -.PP - -.SH "4\&.3\&.6: onstart, onend, onfail - Action Hooks" -.IP "Description:" -The three directives \f(CWonstart\fP, \f(CWonend\fP and \f(CWonfail\fP can be -specified to start system commands (external programs) when a -connection to a back end starts, fails or ends: -.IP o -\f(CWonstart\fP commands will be run when Crossroads -successfully connects to a back end, and starts servicing; -.IP o -\f(CWonend\fP commands will be run when a (previously -established) connection stops; -.IP o -\f(CWonfail\fP commands will be run when Crossroads tries to -contact a back end to serve a client, but the back end can\&'t -be reached\&. -.IP -The format is always \f(CWon\fP\fItype\fP \fIcommand\fP\&. The \fIcommand\fP -is an external program, optionally followed by arguments\&. The -command is expanded according to the following table: -.IP -.IP o -\f(CW%a\fP is the availability of the current back end, when -a current back end is established; -.IP o -\f(CW%1a\fP is the availability of the first back end (0 when -unavailable, 1 if available); \f(CW%2a\fP is the availability of -the second back end, and so on; -.IP o -\f(CW%b\fP is the name of the current back end, when one is -established; -.IP o -\f(CW%1b\fP is the name of the first back end, \f(CW%2b\fP of the -second back end, and so on; -.IP o -\f(CW%e\fP is the count of seconds since start of epoch -(January 1st 1970 GMT); -.IP o -\f(CW%r\fP is the IP address of the client that requests a -connection and for whom the external dispatcher should compute -a back end; -.IP o -\f(CW%s\fP is the name of the current service that the client -connected to; -.IP o -\f(CW%t\fP is the current local time in ASCII format, in -\fIYYYY-MM-DD/hhh:mm:ss\fP; -.IP o -\f(CW%T\fP is the current GMT time in ASCIII format; -.IP o -\f(CW%v\fP is the Crossroads version; -.IP o -Any other chararacter following a \f(CW%\fP sign is taken -literally; e\&.g\&. \f(CW%z\fP is just a z\&. -.IP -.IP "Syntax:" -.IP o -\f(CWonstart\fP \fIcommandline\fP -.IP o -\f(CWonend\fP \fIcommandline\fP -.IP o -\f(CWonfail\fP \fIcommandline\fP -.IP o -\f(CWonsuccess\fP \fIcommandline\fP -.IP "Default:" -There is no default\&. Normally no external programs are run upon -connection, success or failure of a back end\&. - -.PP - -.SH "4\&.3\&.7: trafficlog and throughputlog - Debugging and Performance Aids" -.IP "Description:" -Two directives are available -to log network traffic to files\&. They are \f(CWtrafficlog\fP and -\f(CWthroughputlog\fP\&. -.IP -The \f(CWtrafficlog\fP statement causes all traffic to be logged in -hexadecimal format\&. Each line is prefixed by \f(CWB\fP or \f(CWC\fP, -depending on whether the information was received from the back -end or from the client\&. -.IP -The \f(CWthroughputlog\fP statement writes shorthand transmissions to -its log, accompanied by timings\&. -.IP "Syntax:" -.IP o -\f(CWtrafficlog\fP \fIfilename\fP -.IP o -\f(CWthroughputlog\fP \fIfilename\fP -.IP "Default:" -none - -.PP - -.SH "4\&.3\&.8: stickycookie - Back end selection with an HTTP cookie" -.IP "Description:" -The directive \f(CWstickycookie\fP \fIvalue\fP -causes Crossroads to unpack clients\&' requests, to check for -\fIvalue\fP in the cookies\&. When found, the message is routed to the -back end having the appropriate \f(CWstickycookie\fP directive\&. -.IP -E\&.g\&., consider the following configuration: -.IP -.nf -service \&.\&.\&. { - \&.\&.\&. - backend one { - \&.\&.\&. - stickycookie "BalancerID=first"; - } - backend two { - \&.\&.\&. - stickycookie "BalancerID=second"; - } -} -.fi - -.IP -When clients\&' messages contain cookies named \f(CWBalancerID\fP with -the value \f(CWfirst\fP, then such messages are routed to backend -\f(CWone\fP\&. When the value is \f(CWsecond\fP then they are routed to the -backend \f(CWtwo\fP\&. -.IP -There are basically to provide such cookies to a browser\&. First, a -back end can insert such a cookie into the HTTP response\&. E\&.g\&., -the webserver of back end \f(CWone\fP might insert a cookie named -\f(CWBalancerID\fP, having value \f(CWfirst\fP\&. -Second, Crossroads can insert such cookies using a carefully -crafted directive \f(CWaddclientheader\fP\&. -.IP "Syntax:" -\f(CWstickycookie\fP \fIcookievalue\fP -.IP "Default:" -There is no default\&. - -.PP - -.SH "4\&.3\&.9: HTTP Header Modification Directives" -.IP "Description:" -Crossroads understands the following -header modification directives: \f(CWaddclientheader\fP, -\f(CWappendclientheader\fP, \f(CWsetclientheader\fP, \f(CWaddserverheader\fP, -\f(CWappendserverheader\fP, \f(CWsetserverheader\fP\&. -.IP -The directive names always consist of -\fIAction\fP\fIDestination\fP\f(CWheader\fP, where: -.IP -.IP o -The action is \f(CWadd\fP, \f(CWappend\fP or \f(CWinsert\fP\&. -.IP -.IP o -Action \f(CWadd\fP adds a header, even when headers with -the same name already are present in an HTTP -message\&. Adding headers is useful for e\&.g\&. \f(CWSet-Cookie\fP -headers; a message may contain several of such headers\&. -.IP -.IP o -Action \f(CWappend\fP adds a header if it isn\&'t present -yet in an HTTP message\&. If such a header is already -present, then the value is appended to the pre-existing -header\&. This is useful for e\&.g\&. \f(CWVia\fP headers\&. Imagine -an HTTP message with a header \f(CWVia: someproxy\fP\&. Then the -directive \f(CWappendclientheader "Via: crossroads"\fP will -rewrite the header to \f(CWVia: someproxy; crossroads\fP\&. -.IP -.IP o -Action \f(CWset\fP overwrites headers with the same -name; or adds a new header if no pre-existing is found\&. -This is useful for e\&.g\&. \f(CWHost\fP headers\&. -.IP -.IP o -The destination is one of \f(CWclient\fP or \f(CWserver\fP\&. When -the destination is \f(CWserver\fP, then Crossroads will apply such -directives to HTTP messages that originate from the browser -and are being forwarded to back ends\&. When the destination is -\f(CWclient\fP, then Crossroads will apply such directives to -backend responses that are shuttled to the browser\&. -.IP -The format of the directives is e\&.g\&. \f(CWaddclientheader -"X-Processed-By: Crossroads"\fP\&. The directives expect one -argument; a string, consisting of a header name, a colon, and a -header value\&. As usual, the directive must end with a semicolon\&. -.IP -The header value may contain one of the following formatting -directives: -.IP -.IP o -\f(CW%a\fP is the availability of the current back end, when -a current back end is established; -.IP o -\f(CW%1a\fP is the availability of the first back end (0 when -unavailable, 1 if available); \f(CW%2a\fP is the availability of -the second back end, and so on; -.IP o -\f(CW%b\fP is the name of the current back end, when one is -established; -.IP o -\f(CW%1b\fP is the name of the first back end, \f(CW%2b\fP of the -second back end, and so on; -.IP o -\f(CW%e\fP is the count of seconds since start of epoch -(January 1st 1970 GMT); -.IP o -\f(CW%r\fP is the IP address of the client that requests a -connection and for whom the external dispatcher should compute -a back end; -.IP o -\f(CW%s\fP is the name of the current service that the client -connected to; -.IP o -\f(CW%t\fP is the current local time in ASCII format, in -\fIYYYY-MM-DD/hhh:mm:ss\fP; -.IP o -\f(CW%T\fP is the current GMT time in ASCIII format; -.IP o -\f(CW%v\fP is the Crossroads version; -.IP o -Any other chararacter following a \f(CW%\fP sign is taken -literally; e\&.g\&. \f(CW%z\fP is just a z\&. -.IP -The following examples show common uses of header modifications\&. -.IP -.IP "Enforcing session stickiness:" -By combining -\f(CWstickycookie\fP and \f(CWaddclientheader\fP, HTTP session -stickiness is enforced\&. Consider the following configuration: -.IP -.nf -service \&.\&.\&. { - \&.\&.\&. - backend one { - \&.\&.\&. - addclientheader "Set-Cookie: BalancerID=first; path=/"; - stickycookie "BalancerID=first"; - } - backend two { - \&.\&.\&. - addclientheader "Set-Cookie: BalancerID=second; path=/"; - stickycookie "BalancerID=second"; - } -} -.fi - -.IP -The first request of an HTTP session is balanced to either -backend \f(CWone\fP or \f(CWtwo\fP\&. The server response is enriched -using \f(CWaddclientheader\fP with an appropriate cookie\&. A -subsequent request from the same browser now has that cookie -in place; and is therefore sent to the same back end where the -its predecessors went\&. -.IP -.IP "Hiding the server software version:" -Many servers -(e\&.g\&. Apache) advertize their version, as in \f(CWServer: Apache -1\&.27\fP\&. This potentially provides information to attackers\&. The -following configuration hides such information: -.IP -.nf -service \&.\&.\&. { - \&.\&.\&. - backend one { - \&.\&.\&. - setclientheader "Server: WWW-Server"; - } -} -.fi - -.IP -.IP "Informing the server of the clients\&' IP address:" -Since -Crossroads sits \&'in the middle\&' between a client and a back -end, the back end perceives Crossroads as its client\&. The -following sends the true clients\&' IP address to the server, in -a header \f(CWX-Real-IP\fP: -.IP -.nf -service \&.\&.\&. { - \&.\&.\&. - backend one { - \&.\&.\&. - setserverheader "X-Real-IP: %r"; - } -} -.fi - -.IP -.IP "Keep-Alive Downgrading:" -The directives -\f(CWsetclientheader\fP and \f(CWsetserverheader\fP also play a key -role in downgrading Keep-Alive connections to -\&'single-shot\&'\&. E\&.g\&., the following configuration makes sure -that no Keep-Alive connections occur\&. -.IP -.nf -service \&.\&.\&. { - \&.\&.\&. - backend one { - \&.\&.\&. - setserverheader "Connection: close"; - setclientheader "Connection: close"; - } -} -.fi -.IP "Syntax:" -.IP o -\f(CWaddclientheader\fP \fIHeadername: headervalue\fP to add a -header in the traffic towards the client, even when another -header \fIHeadername\fP exists; -.IP o -\f(CWappendclientheader\fP \fIHeadername: headervalue\fP to -append \fIheadervalue\fP to an existing header \fIHeadername\fP -in the traffic towards the client, -or to add the whole header alltogether; -.IP o -\f(CWsetclientheader\fP \fIHeadername: headervalue\fP to -overwrite an existing header in the traffic towards the -client, or to add such a header; -.IP o -\f(CWaddserverheader\fP \fIHeadername: headervalue\fP to add a -header in the traffic towards the server, even when another -header \fIHeadername\fP exists; -.IP o -\f(CWappendserverheader\fP \fIHeadername: headervalue\fP to -append \fIheadervalue\fP to an existing header \fIHeadername\fP -in the traffic towards the server, -or to add the whole header alltogether; -.IP o -\f(CWsetserverheader\fP \fIHeadername: headervalue\fP to -overwrite an existing header in the traffic towards the -server, or to add such a header\&. -.IP "Default:" -There is no default\&. - -.PP - -.SH "5: Tips, Tricks and Random Remarks" - -The following sections elaborate on the directives as described in -section ?? to illustrate how crossroads works and to help you -achieve the "optimal" balancing configuration\&. -.PP - -.SH "5\&.1: How back ends are selected in load balancing" -In order to tune your load balancing, you\&'ll need to understand how -crossroads computes usage, how weighing works, and so on\&. In this -section we\&'ll focus on the dispatching modes \f(CWbysize\fP, \f(CWbyduration\fP -and \f(CWbyconnections\fP only\&. The other dispatching types are -self-explanatory\&. -.PP - -.SH "5\&.1\&.1: Bysize, byduration or byconnections?" - -.PP -As stated before, crossroads doesn\&'t know \&'what a service does\&' and -how to judge whether a given back end is very busy or not\&. You -must therefore give the right hints: -.PP -.IP o -In general, a service which is CPU bound, will be more -busy when it takes longer to process a request\&. The dispatch -mode \f(CWbyduration\fP is appropriate here\&. -.IP -.IP o -In contrast, a service which is filesystem bound, will be -more busy when more data are transferred\&. The dispatch mode -\f(CWbysize\fP is apppropriate\&. -.IP -.IP o -The dispatch mode \f(CWbyduration\fP can also be used when -network latency is an issue\&. E\&.g\&., if your balancer has back -ends that are geograpically distributed, then \f(CWbyduration\fP -would be a good way to select best available back ends\&. -.IP -.IP o -Furthermore it is noteworthy that \f(CWdispatchmode -byduration\fP is not usable for interactive processes such as -SSH logins\&. Idle time of a -login adds to the duration, while causing (almost) no -load\&. Mode \f(CWbyduration\fP should only be used for automated -processes that don\&'t wait for user interaction (e\&.g\&., SOAP -calls and other HTTP requests)\&. -.IP -.IP o -As a last remark, the dispatching mode \f(CWbyconnections\fP can -be used if you don\&'t have other clues for load -estimations\&. -.IP -E\&.g\&., consider a database connection\&. What\&'s -heavier on the back end, time-consuming connections, or connections -where loads of bytes are transferred? Well, that depends\&. A -tough \f(CWselect\fP query that joins multiple tables can be very -heavy on the back end, though the response set can be quite -small - and hence the number of -transferred bytes\&. That would suggest -dispatching by duration\&. However, \f(CWbyduration\fP -balancing doesn\&'t respresent the true world, when interactive -connections can occur where users have an idle TCP connection to -the database: -this consumes time, but no bytes (see the SSH login example -above)\&. In this case, the dispatch mode \f(CWbyconnections\fP may be -your best bet\&. -.IP - -.SH "5\&.1\&.2: Averaging size and duration" - -.PP -The configuration statement \f(CWdispatchmode bysize\fP or \f(CWbyduration\fP -allows an optional modifier \f(CWover\fP \fInumber\fP, where the stated -number represents a connection count\&. When this modifier is present, then -crossroads will use a moving average over the last \fIn\fP connections to -compute duration and size figures\&. -.PP -In the real world you\&'ll always want this modifier\&. E\&.g\&., consider two -back ends that are running for years now, and one of them is suddenly -overloaded and very busy (it experiences a \&'spike\&' in activity)\&. -When the \f(CWover\fP modifier is absent, then -the sudden load will hardly show up in the usage figures -- it will -flatten out due to the large usage figures already stored in the years -of service\&. -.PP -In contrast, when e\&.g\&. \f(CWover 3\fP is in effect, then a sudden load -does show up -- because it highly contributes to the average of three -connections\&. -.PP - -.SH "5\&.1\&.3: Specifying decays" - -.PP -Decays are also only relevant when crossroads computes the \&'next best -back end\&' by size (bytes) or duration (seconds)\&. E\&.g\&., imagine two -back ends A and B, both averaged over say 3 connections\&. -.PP -Now when back end A is suddenly hit by a spike, -its average would go up accordingly\&. But the back end would never -again be used, unless B also received a similar spike, because A\&'s -\&'usage data\&' over its last three connections would forever be larger than -B\&'s data\&. -.PP -For that reason, you should in real situations probably always -specify a decay, so that the backend selection algorithm recovers from -spikes\&. Note that the usage data of the back end where a decay is -specified, decay when \fBother\fP back ends are hit\&. The decay parameter -is like specifying how fast your body regenerates when someone else -does the work\&. -.PP -The below configuration illustrates this: -.PP -.nf -/* Definition of the service */ -service soap { - /* Local TCP port */ - port 8080; - - /* We\&'ll select back ends by the processing - * duration - */ - dispatchmode byduration over 3; - - /* First back end: */ - backend A { - /* Back end IP address and port */ - server 10\&.1\&.1\&.1:8080; - - /* When this back end is NOT hit because - * the other one was less busy, then the - * usage parameters decay 10% per connection - */ - decay 10; - } - - /* Second back end: */ - backend B { - server 10\&.1\&.1\&.2:8080; - decay 10; - } -} -.fi - -.PP - -.SH "5\&.1\&.4: Adjusting the weights" - -.PP -The back end modifier \f(CWweight\fP is useful in situations where your -back ends differ in respect to performance\&. E\&.g,\&. your back ends may -be geographically distributed, and you know that a given back end is -difficult to reach and often experiences network lag\&. -.PP -Or you may have -one primary back end, a system with a fast CPU and enough memory, and a -small fall-back back end, with a slow CPU and short on memory\&. In that -case you know in advance that the second back end should be used only -rarely\&. Most requests should go to the big server, up to a certain load\&. -.PP -In such cases you will know in advance that the best performing back ends -should be selected the most often\&. Here\&'s where the \f(CWweight\fP -statement comes in: you can simply increase the weight of the back -ends with the least performance, so that they are selected less -frequently\&. -.PP -E\&.g\&., consider the following configuration: -.PP -.nf -service soap { - port 8080; - dispatchmode byduration over 3; - backend A { - server 10\&.1\&.1\&.1:8080; - decay 20; - } - backend B { - server 10\&.1\&.1\&.2:8080; - weight 2; - decay 10; - } - backend C { - server 10\&.1\&.1\&.3:8080; - weight 4; - decay 5; - } -} -.fi - -.PP -This will cause crossroads to select back ends by the processing time, -averaging over the last three connections\&. However, backend B will kick -in only when its usage is half of the usage of A (back end B is -probably only half as fast as A)\&. Backend C will kick in only when its -usage is a quarter of the usage of A, which is half of the usage of B -(back end C is probably very weak, and just a fall-back system incase -both A and B crash)\&. Note also that A\&'s usage data decay much faster -than B\&'s and C\&'s: we\&'re assuming that this big server recovers quicker -than its smaller siblings\&. -.PP - -.SH "5\&.2: Throttling the number of concurrent connections" -If you suspect that your service may occasionally receive \&'spikes\&' of -activity\e (which you should always assume), then it might be a -good idea to protect your service by specifying a maximum number of -concurrent connections\&. This protection can be specified on two levels: -.PP -.IP "On the service level" -a statement like \f(CWmaxconnections -100;\fP states that the service as a whole will never -service more than 100 concurrent connections\&. This means that -all your back ends and the crossroads balancer itself -will be protected from being overloaded\&. -.IP "On the back end level" -a statement like \f(CWmaxconnections 10;\fP -states that this particular back end will never have more -than 10 concurrent connections; regardless of the overall -setting on the service level\&. This means that this -particular back end will be protected from being -overloaded (regardless of what other back ends may -experience)\&. -.PP -The \f(CWmaxconnections\fP statement, combined with a back end selection -algorithm, allows very fine granularity\&. The \f(CWmaxconnections\fP statement -on the back end level is like a hand brake: even when you specify a -back end algorithm that would protect a given back end from being used -too much, a situation may occur where that back end is about to be -hit\&. A \f(CWmaxconnections\fP statement on the level of that back may then -protect it\&. -.PP - -.SH "5\&.3: Using an external program to dispatch" -As mentioned before, Crossroads supports several built-in dispatch -modes\&. However, you are always free to hook-in your own dispatch mode -that determines the next back end using your own specific -algorithm\&. This section explains how to do it\&. -.PP - -.SH "5\&.3\&.1: Configuring the external handler" - -.PP -First, the \f(CWdispatchmode\fP statement needs to inform Crossroads that -an external program will do the job\&. The syntax is: \f(CWdispatchmode -externalhandler\fP \fIprogram arguments\fP\&. The \fIprogram\fP must point to -an executable program that will be started by Crossroads\&. The -specifier \fIarguments\fP can be anything you want; those will be the -arguments to Crossroads\&. You can however use the following special -format specifiers: -.PP -.IP o -\f(CW%a\fP is the availability of the current back end, when -a current back end is established; -.IP o -\f(CW%1a\fP is the availability of the first back end (0 when -unavailable, 1 if available); \f(CW%2a\fP is the availability of -the second back end, and so on; -.IP o -\f(CW%b\fP is the name of the current back end, when one is -established; -.IP o -\f(CW%1b\fP is the name of the first back end, \f(CW%2b\fP of the -second back end, and so on; -.IP o -\f(CW%e\fP is the count of seconds since start of epoch -(January 1st 1970 GMT); -.IP o -\f(CW%r\fP is the IP address of the client that requests a -connection and for whom the external dispatcher should compute -a back end; -.IP o -\f(CW%s\fP is the name of the current service that the client -connected to; -.IP o -\f(CW%t\fP is the current local time in ASCII format, in -\fIYYYY-MM-DD/hhh:mm:ss\fP; -.IP o -\f(CW%T\fP is the current GMT time in ASCIII format; -.IP o -\f(CW%v\fP is the Crossroads version; -.IP o -Any other chararacter following a \f(CW%\fP sign is taken -literally; e\&.g\&. \f(CW%z\fP is just a z\&. -.PP -Note that the format specifiers such as \f(CW%b\fP don\&'t make sense in the -phase in which an external handler is called, since there is no -current back end yet (the job of the handler is to supply one)\&. -.PP - -.SH "5\&.3\&.2: Writing the external handler" - -.PP -The external handler is activated using the arguments that are -specified in \f(CW/etc/crossroads\&.conf\fP\&. The external handler can do -whatever it wants, but ultimately, it must write a back end name on -its \fIstdout\fP\&. Crossroads reads this, and if the back end is -available, uses that back end for the connection\&. -.PP - -.SH "5\&.3\&.3: Examples of external handlers" - -.PP -This section shows some examples of Crossroads configurations -vs\&. external handlers\&. The sample handlers that are shown here, are -also included in the Crossroads distribution, under the directory -\f(CWetc/\fP\&. Also note that the examples shown here are just -quick-and-dirty Perl scripts, meant to illustrate only\&. Your -applications may need other external handlers, but you can use the -shown scripts as a starting point\&. -.PP -.SH "Round-robin dispatching" - -.PP -This example is trivial in the sense that round-robin dispatching is -already built into Crossroads, so -that using an external handler for this purpose only slows down -Crossroads\&. However, it\&'s a good starting example\&. -.PP -The Crossroads configuration is shown below: -.PP -.nf -service test { - port 8001; - verbosity on; - revivinginterval 5; - - dispatchmode externalhandler - /usr/local/src/crossroads/etc/dispatcher-roundrobin - %1b %1a %2b %2a; - - backend testone { - server localhost:3128; - verbosity on; - } - backend testtwo { - server locallhost:3128; - verbosity on; - } -} -.fi - -.PP -The relevant \f(CWdispatchmode\fP statement invokes the external program -\f(CWdispatcher-roundrobin\fP with four arguments: the name of the first -back end (\f(CWtestone\fP), its availability (0 or 1), the name of the -second back end (\f(CWtesttwo\fP) and its availability (0 or 1)\&. -.PP -The external handler, which is also included in the Crossroads -distribution, is shown below\&. It is a Perl script\&. -.PP -.nf -#!/usr/bin/perl - -use strict; - -# Example of a round-robin external dispatcher\&. This is totally -# superfluous, Crossroads has this on-board; if you use the external -# program for determining round-robin dispatching, then you\&'ll only -# slow things down\&. This script is just meant as an example\&. - -# Globals / configuration -# ----------------------- -my $log = \&'/tmp/exthandler\&.log\&'; # Debug log, set to /dev/null to suppress -my $statefile = \&'/tmp/rr\&.last\&'; # Where we keep the last used - -# Logging -# ------- -sub msg { - return if ($log eq \&'/dev/null\&' or $log eq \&'\&'); - open (my $of, ">>$log") or return; - print $of (scalar(localtime()), \&' \&', @_); -} - -# Read the last used back end -# --------------------------- -sub readlast() { - my $ret; - - if (open (my $if, $statefile)) { - $ret = <$if>; - chomp ($ret); - close ($if); - msg ("Last used back end: $ret\en"); - return ($ret); - } - msg ("No last-used back end (yet)\en"); - return (undef); -} - -# Write back the last used back end, reply to Crossroads and stop -# --------------------------------------------------------------- -sub reply ($) { - my $last = shift; - - if (open (my $of, ">$statefile")) { - print $of ("$last\en"); - } - print ("$last\en"); - exit (0); -} - -# Main starts here -# ---------------- - -# Collect the cmdline arguments\&. We expect pairs of backend-name / -# backend-availablility, and we\&'ll store only the available ones\&. -msg ("Dispatch request received\en"); -my @backend; -for (my $i = 0; $i <= $#ARGV; $i += 2) { - push (@backend, $ARGV[$i]) if ($ARGV[$i + 1]); -} -msg ("Available back ends: @backend\en"); - -# Let\&'s see what the last one is\&. If none found, then we return the -# first available back end\&. Otherwise we need to go thru the list of -# back ends, and return the next one in line\&. -my $last = readlast(); -if ($last eq \&'\&') { - msg ("Returning first available back end $backend[0]\en"); - reply ($backend[0]); -} - -# There **was** a last back end\&. Try to match it in the list, -# then return the next-in-line\&. -for (my $i = 0; $i < $#backend; $i++) { - if ($last eq $backend[$i]) { - msg ("Returning next back end ", $backend[$i + 1], "\en"); - reply ($backend[$i + 1]); - } -} - -# No luck\&.\&. run back to the first one\&. -msg ("Returning first back end $backend[0]\en"); -reply ($backend[0]); -.fi - -.PP -The working of the script is basically as follows: -.PP -.IP o -The argument list is scanned\&. Back ends that are -available are collected in an array \f(CW@backend\fP\&. -.IP -.IP o -The script queries a state file \f(CW/tmp/rr\&.last\fP\&. If a -back end name occurs there, then the next back end is looked -up in \f(CW@backend\fP and returned to Crossroads\&. If no last back -is unknown or can\&'t be matched, then the first available back -end (first element of \f(CW@backend\fP) is returned to Crossroads\&. -.IP -.IP o -Informing Crossroads is done via the subroutine -\f(CWreply()\fP\&. This code writes the selected back end to file -\f(CW/tmp/rr\&.last\fP (for future usage) and prints the back end -name to \fIstdout\fP\&. -.IP -.IP o -The script logs its actions to a file -\f(CW/tmp/exthandler\&.log\fP\&. This log file can be inspected for -the script\&'s actions\&. -.PP -.SH "Dispatching by the client IP address" - -.PP -The following example shows a useful real-life situation that -illustrates how dispatching by client IP address works\&. \fBNote that\fP -as of Crossroads 1\&.31, \f(CWdispatchmode byclientip\fP is implemented -- -so that the below description is somewhat superfluous\&. The code -snippets however can help you in modelling your own specific dispatch -modes, aided by external helpers\&. -.PP -The situation is as follows: -.PP -.IP o -Crossroads is used as a single-address point to forward -Remote Desktop requests to a farm of Windows systems, where -users can work via remote access; -.IP -.IP o -However, users may stop their session, and when they -re-connect, they expect to be sent to the Windows system that -they had worked on previously; -.IP -.IP o -Client PC\&'s have their distinct IP addresses, which -distinguishes them\&. -.IP -.IP o -Of four windows systems, two are large servers, and two -are small ones\&. We\&'ll want to assign large servers to clients -when we have a choice\&. -.PP -The requirements resemble session stickiness in HTTP, except that the remote -desktop protocol doesn\&'t support stickiness\&. This situation is a -perfect example of how an external handler can help: -.PP -.IP o -A suitable dispatch mode isn\&'t yet available in -Crossroads, but can be easily coded in an external handler; -.IP -.IP o -The potential delay due to the calling of an external -handler won\&'t even be noticed\&. This is a network service where -the connection time isn\&'t critical; we\&'d expect only a few -(albeit lengthy) TCP connections\&. -.PP -The approach to the solution of this problem uses several external -program hooks: -.PP -.IP o -An external dispatcher handler will be responsible for -suggesting a back end, given a client IP and given the current -timestamp\&. This handler will consult an internal -administration to see whether the stated IP address should -re-use a back end, or to determine which back end is free for usage\&. -.IP o -An external hook \f(CWonstart\fP will be responsible for -updating the internal administration; i\&.e\&., to flag a back end -as \&'occupied\&'\&. -.IP o -The external hooks \f(CWonfailure\fP and \f(CWonend\fP will be -responsible for flagging a back end as \&'free\&' again; i\&.e\&., for -erasing any previous information that states that the back end -was occupied\&. -.PP -The Crossroads configuration is shown below\&. Only four Windows back -ends are shown\&. Each back end is configured on a -given IP address, port 3389, and is limited to one concurrent connection -(otherwise a new user might \&'steal\&' a running desktop session)\&. -.PP -.nf -service rdp { - port 3389; - revivinginterval 5; - - /* rdp-helper dispatch IP STAMP \&.\&.\&. will suggest a back end to use, - * arguments are for all back ends: name, availability, weight */ - dispatchmode externalhandler - /usr/local/src/crossroads/etc/rdp-helper dispatch %r %e - %1b %1a %1w - %2b %2a %2w - %3b %3a %3w - %4b %4a %4w; - - backend win1 { - server 10\&.1\&.1\&.1:3389; - maxconnections 1; - /* rdp-helper start IP STAMP BACKEND will log the actual start - * of a connection; - * rdp-helper end IP will log the ending of a connection */ - onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b; - onend /usr/local/src/crossroads/etc/rdp-helper end %r; - onfail /usr/local/src/crossroads/etc/rdp-helper end %r; - } - backend win2 { - server 10\&.1\&.1\&.2:3389; - maxconnections 1; - onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b; - onend /usr/local/src/crossroads/etc/rdp-helper end %r; - onfail /usr/local/src/crossroads/etc/rdp-helper end %r; - } - backend win3 { - server 10\&.1\&.1\&.3:3389; - maxconnections 1; - weight 2; - onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b; - onend /usr/local/src/crossroads/etc/rdp-helper end %r; - onfail /usr/local/src/crossroads/etc/rdp-helper end %r; - } - backend win4 { - server 10\&.1\&.1\&.4:3389; - maxconnections 1; - weight 3; - onstart /usr/local/src/crossroads/etc/rdp-helper start %r %e %b; - onend /usr/local/src/crossroads/etc/rdp-helper end %r; - onfail /usr/local/src/crossroads/etc/rdp-helper end %r; - } -} -.fi - -.PP -Depending on the dispatcher stage, the exernal handler \f(CWrdp-helper\fP -is invoked in different ways: -.PP -.IP "During dispatching" -the helper is called to suggest a back -end\&. The arguments are an action indicator \f(CWdispatch\fP, the -client\&'s IP address, the timestamp, and four triplets that -represent back ends: per back end its name, its availability, -and its weight\&. The purpose of the helper is to tell -Crossroads which back end to use\&. -.IP -.IP "During connection start" -the helper will be invoked to -inform it of the start of a connection, given a client IP -address\&. -.IP -.IP "When a connection terminates" -the helper will be invoked -to inform it that the connection has ended\&. -.PP -Here\&'s the external handler as Perl script\&. It uses the module -\f(CWGDBM_File\fP which most likely will not be part of standard Perl -distributions, but can be added using CPAN\&. (Alternatively, any other -database module can be used\&.) -.PP -.nf -#!/usr/bin/perl - -use strict; -use GDBM_File; - -# Global variables and configuration -# ---------------------------------- -my $log = \&'/tmp/exthandler\&.log\&'; # Debug log, set to /dev/null to suppress -my $cdb = \&'/tmp/client\&.db\&'; # GDBM database of clients -my %db; # \&.\&. and memory representation of it -my $timeout = 24*60*60; # Timeout of a connection in secs - -# Logging -# ------- -sub msg { - return if ($log eq \&'/dev/null\&' or $log eq \&'\&'); - open (my $of, ">>$log") or return; - print $of (scalar(localtime()), \&' \&', @_); - close ($of); -} - -# Reply a back end to the caller and stop processing\&. -# --------------------------------------------------- -sub reply ($) { - my $b = shift; - msg ("Suggesting $b to Crossroads\&.\en"); - print ("$b\en"); - exit (0); -} - -# Is a value in an array -# ---------------------- -sub inarray { - my $val = shift; - for my $other (@_) { - return (1) if ($other eq $val); - } - return (0); -} - -# A connection is starting -# ------------------------ -sub start { - my ($ip, $stamp, $backend) = @_; - msg ("Logging START of connection for IP $ip on stamp $stamp, ", - "back end $backend\en"); - $db{$ip} = "$backend:$stamp"; -} - -# A connection has ended -# ---------------------- -sub end { - my $ip = shift; - msg ("Logging END of connection for IP $ip\en"); - $db{$ip} = undef; -} - -# Request to determine a back end -# ------------------------------- -sub dispatch { - my $ip = shift; - my $stamp = shift; - - msg ("Request to dispatch IP $ip on stamp $stamp\en"); - - # Read the next arguments\&. They are triplets of - # backend-name / availability / weight\&. Store if the back end is - # available\&. - my (@backends, @weights); - for (my $i = 0; $i < $#_; $i += 3) { - if ($_[$i + 1] != 0) { - push (@backends, $_[$i]); - push (@weights, $_[$i + 2]); - msg ("Candidate back end: $_[$i] with weight ", $_[$i + 2], "\en"); - } - } - - # See if this is a reconnect by a previously seen client IP\&. We\&'ll - # treat this as a reconnect if the timeout wasn\&'t yet exceeded\&. - if ($db{$ip} ne \&'\&') { - my ($last_backend, $last_stamp) = split (/:/, $db{$ip}); - msg ("IP $ip had last connected on $last_stamp to $last_backend\en"); - if ($stamp < $last_stamp + $timeout) { - msg ("Timeout not yet exceeded, this may be a reconnect\en"); - # We\&'ll allow a reconnect only if the stated last_backend is - # free (sanity check)\&. - if (inarray ($last_backend, @backends)) { - msg ("Last back end $last_backend is available, ", - "letting through\en"); - reply ($last_backend); - } else { - msg ("Last used back end isn\&'t free, suggesting a new one\en"); - } - } else { - msg ("Timeout exceeded, suggesting a new back end\en"); - } - } else { - msg ("Np preveious connection data, suggesting a new back end\en"); - } - - my $bestweight = -1; - my $bestbackend; - for (my $i = 0; $i <= $#weights; $i++) { - if ($bestweight == -1 or $bestweight > $weights[$i]) { - $bestweight = $weights[$i]; - $bestbackend = $backends[$i]; - } - } - - msg ("Best back end: $bestbackend (given weight $bestweight)\en"); - reply ($bestbackend); -} - -# Main starts here -# ---------------- -msg ("Start of run, attaching GDBM database \&'$cdb\&'\en"); -tie (%db, \&'GDBM_File\&', $cdb, &GDBM_WRCREAT, 0600); - -# The first argument must be an action \&'dispatch\&', \&'start\&' or \&'end\&'\&. -# Depending on the action, we do stuff\&. -my $action = shift (@ARGV); -if ($action eq \&'dispatch\&') { - dispatch (@ARGV); -} elsif ($action eq \&'start\&') { - start (@ARGV); -} elsif ($action eq \&'end\&') { - end (@ARGV); -} else { - print STDERR ("Usage: rdp-helper {dispatch|start|end} args\en"); - exit (1); -} -.fi - -.PP - -.SH "5\&.4: TCP Session Stickiness" -If you need to make sure that a client that once gets dispatched to a -given back end keeps re-visiting the back end, then Crossroads offers -the dispatch mode \f(CWbyclientip\fP\&. This mode will only work when each -client is seen by Crossroads with its own specific IP address; ie\&., -this method won\&'t work when clients reach Crossroads through a -masquerading firewall (in which case all clients would be seen as -having the firewall\&'s IP address)\&. -.PP -The \f(CWdispatchmode byclientip\fP works as follows: -.PP -.IP o -The client\&'s IP address is taken in its string -representation and \&'hashed\&' into a number\&. -.IP -.IP o -The number is brought back to the number of available -back ends (using a modulo-operation)\&. -.IP -.IP o -The result defines the back end of choice\&. -.PP -If the preferred back end is unavailable, then the action that -Crossroads takes is to dispatch as if \f(CWbyconnections\fP: of the -available back ends, the one with the least connections is taken\&. -.PP - -.SH "5\&.5: HTTP Session Stickiness" -This section focuses on HTTP session stickiness\&. This term refers to -the ability of a balancer to route a conversation between browser and -a backend farm with webservers always to the same back end\&. In other -words: once a back end is selected by the balancer, it will remain the -back end of choice, even for subsequent connections\&. -.PP - -.SH "5\&.5\&.1: Don\&'t use stickiness!" - -.PP -The rule of thumb as far as the balancer is concerned, is: \fBDo not -use HTTP session stickiness unless you really have to\&.\fP Enabling -session stickiness hampers failover, balancing and performance: -.PP -.IP o -Failover is hampered because during the session, -the balancer has to assign new connections to the same back -end that was selected at the start of a session\&. If the back -end suddenly goes \&'down\&', then the session will most likely -crash\&. (Actually, when a back end becomes unreachable in the -middle of a session, Crossroads will assign a new back end to -that session\&. This will most likely result in a malfunction -of the underlying application\&.) -.IP o -Balancing is hampered because at the start of the session, -the balancer has selected the next-best back end\&. But during -the session, that back end may well become overloaded\&. The -balancer however must continue to send the requests there\&. -.IP o -Performance is hampered because crossroads needs to \&'unpack\&' -messages as they are passed to and fro\&. That\&'s because -crossroads needs to check the HTTP headers in the messages -for persistence cookies\&. -.PP -There is a number of measures that you can take to avoid using session -stickiness\&. E\&.g\&., session data can be \&'shared\&' between web back -ends\&. PHP offers functionality to store session data in a database, so -that all PHP applications have access to these data\&. Application -servers such as Websphere can be configured to replicate session data -between nodes\&. -.PP - -.SH "5\&.5\&.2: But if you must\&.\&." - -.PP -If you really need stickiness, think first whether you might use TCP -stickiness (using the client\&'s IP address to dispatch)\&. If you can, -then this is the preferred method, since Crossroads won\&'t have to -unpack TCP streams\&. Below is a short configuration example: -.PP -.nf -service www { - port 80; - type any; - revivinginterval 15; - dispatchmode byclientip; - - backend one { - server 10\&.1\&.1\&.100:80; - } - - backend two { - server 10\&.1\&.1\&.101:80; - } -} -.fi - -.PP -However, if you \fBmust\fP use HTTP-base session stickiness, then -proceed as follows: -.PP -.IP o -At the level of a \f(CWservice\fP description, set the type to -\f(CWhttp\fP\&. -.IP o -At the level of each back end description, configure the -\f(CWstickycookie\fP and a \f(CWaddclientheader\fP directives\&. -.PP -Once crossroads sees that, it will examine each HTTP message that it -shuttles between client and back end: -.PP -.IP o -If there is no persistence cookie in the HTTP headers of a -client\&'s request, then the message must be the first one and -a new session should be established\&. -Crossroads selects an appropriate back -end, sends the message to that back end, catches the reply, -and inserts a \f(CWSet-Cookie\fP directive\&. -.IP o -If there is a persistence cookie in the HTTP headers of a -client\&'s request, then the request is part of an already -established session\&. Crossroads analyzes the cookie and -forwards the request to the appropriate back end\&. -.PP -Below is a short example of a configuration\&. -.PP -.nf -service www { - port 80; - type http; - revivinginterval 15; - dispatchmode byconnections; - - backend one { - server 10\&.1\&.1\&.100:80; - stickycookie XRID=100; - addclientheader "Set-Cookie: XRID=100; Path=/"; - } - - backend two { - server 10\&.1\&.1\&.101:80; - stickycookie XRID=101; - addclientheader "Set-Cookie: XRID=101; Path=/"; - } -} -.fi - -.PP -Note how the cookie names and values in the directives -\f(CWstickycookie\fP and \f(CWaddclientheader\fP match\&. That is obviously a -prerequisite for stickiness\&. -.PP - -.SH "5\&.6: Passing the client\&'s IP address" -Since Crossroads just shuttles bytes to and fro, meta-information of -network connections is lost\&. As far as the back ends are concerned, -their connections originate at the Crossroads junction\&. -For example, standard Apache access logs will show the IP address of -Crossroads\&. -.PP -In order to compensate for this, Crossroads can insert a special -header in HTTP connections, to inform the back end of the original -client\&'s IP address\&. In order to enable this, the Crossroads -configuration must state the following: -.PP -.IP o -The service type must be \f(CWhttp\fP, and not \f(CWany\fP; -.IP o -In the back end definition, the following statement must -occur: -.br -\f(CWaddserverheader "X-Real-IP: %r";\fP -.br -You are of course free to choose the header name; the here -used \f(CWX-Real-IP\fP is a common name for this purpose\&. -.PP -After this, HTTP traffic that arrives at the back ends has a new -header: \f(CWX-Real-IP\fP, holding the client\&'s IP address\&. -\fBNote that\fP once the type is set to \f(CWhttp\fP, Crossroads\&' -performance will be hampered -- all passing messages will have to be -unpacked and analyzed\&. -.PP - -.SH "5\&.6\&.1: Sample Crossroads configuration" - -.PP -The below sample configuration shows two HTTP back ends that receive -the client\&'s IP address: -.PP -.nf - -service www { - port 80; - type http; - revivinginterval 5; - dispatchmode roundrobin; - - backend one { - server 10\&.1\&.1\&.100:80; - addserverheader "X-Real-IP: %r"; - } - - backend two { - server 10\&.1\&.1\&.200:80; - addserverheader "X-Real-IP: %r"; - } -} -.fi - -.PP - -.SH "5\&.6\&.2: Sample Apache configuration" - -.PP -The method by which each back end analyzes the header \f(CWX-Real-IP\fP -will obviously be different per server implementations\&. However, a -common method with the Apache webserver is to log the client\&'s IP -address into the access log\&. -.PP -Often this is accomplished using the log format \f(CWcustom\fP, defined as -follows: -.PP -.nf -LogFormat "%h %l %u %t %D \e"%r\e" %>s %b" common -CustomLog logs/access_log common -.fi - -.PP -The first line defines the format \f(CWcommon\fP, with the remote host -specified by \f(CW%h\fP\&. The second line sends access information to a log -file \f(CWlogs/access_log\fP, using the previously defined format -\f(CWcommon\fP\&. -.PP -Furtunately, Apache\&'s \f(CWLogFormat\fP allows one to log contents of -headers\&. By replacing the \f(CW%h\fP with \f(CW%{X-Real-IP}i\fP, the desired -information is sent to the log\&. Therefore, normally you can simply -redefine the \f(CWcommon\fP format to -.PP -.nf -LogFormat "%{X-Real-IP}i %l %u %t %D \e"%r\e" %>s %b" common -.fi - -.PP - -.SH "5\&.7: Debugging network traffic" -Incase the traffic between -client and backend -must be debugged, the statement \f(CWtrafficlog\fP \fIfilename\fP can -be issued\&. This causes the traffic to be dumped in hexadecimal -format to the stated filename\&. -.PP -Traffic sent by the client is prefixed by a \fBC\fP, traffic sent by -the back end is prefixed by a \fBB\fP\&. Below is a sample traffic -dump of a browser trying to get a HTML page\&. The server replies -that the page was not modified\&. -.PP -.nf -C 0000 47 45 54 20 68 74 74 70 3a 2f 2f 77 77 77 2e 63 GET http://www\&.c -C 0010 73 2e 68 65 6c 73 69 6e 6b 69 2e 66 69 2f 6c 69 s\&.helsinki\&.fi/li -C 0020 6e 75 78 2f 6c 69 6e 75 78 2d 6b 65 72 6e 65 6c nux/linux-kernel -C 0030 2f 32 30 30 31 2d 34 37 2f 30 34 31 37 2e 68 74 /2001-47/0417\&.ht -C 0040 6d 6c 20 48 54 54 50 2f 31 2e 31 0d 0a 43 6f 6e ml HTTP/1\&.1\&.\&.Con -C 0050 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 0d 0a nection: close\&.\&. -\&. -\&. etcetera -\&. -B 0000 48 54 54 50 2f 31 2e 30 20 33 30 34 20 4e 6f 74 HTTP/1\&.0 304 Not -B 0010 20 4d 6f 64 69 66 69 65 64 0d 0a 44 61 74 65 3a Modified\&.\&.Date: -B 0020 20 54 75 65 2c 20 31 32 20 4a 75 6c 20 32 30 30 Tue, 12 Jul 200 -B 0030 35 20 30 39 3a 34 39 3a 34 37 20 47 4d 54 0d 0a 5 09:49:47 GMT\&.\&. -B 0040 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 Content-Type: te -B 0050 78 74 2f 68 74 6d 6c 3b 20 63 68 61 72 73 65 74 xt/html; charset -\&. -\&. etcetera -\&. -.fi - -.PP -Turning on traffic dumps will \fIsignificantly\fP -slow down crossroads\&. -.PP -Besides \f(CWtrafficlog\fP, there is also a directive -\f(CWthroughputlog\fP\&. This directive also takes one argument, a -filename\&. The file is appended, and the following information is -logged: -.PP -.IP o -The process ID of the crossroads image that serves the -TCP connection; -.IP o -The time of the request, in seconds and microseconds -since start of the run; -.IP o -A \fBC\fP when the request originated at the client, or -\fBB\fP when the request originated at the back end; -.IP o -The first 100 bytes of the request\&. -.PP -As an example, consider the following (the lines are shortened for -brevity and prefixed by line numbers for clarity): -.PP -.nf - -1 0000594 0\&.000001 C GET http://public\&.e-tunity\&.com/index\&.html\&.\&.\&. -2 0000594 0\&.173713 B HTTP/1\&.0 200 OK\&.\&.Date: Fri, 18 Nov 2005 0\&.\&.\&. -3 0000594 0\&.278125 B width="100" bgcolor="#e0e0e0" valign="to\&.\&.\&. -4 0000595 0\&.000001 C GET http://public\&.e-tunity\&.com/css/style/\&.\&.\&. -5 0000594 0\&.944339 B /a></td>\&.\&. </tr>\&.</table>\&.</td><td class\&.\&.\&. -6 0000594 0\&.946356 B smallboxdownl">Download</td>\&.\&. <td class\&.\&.\&. -7 0000594 0\&.961102 B td><td class="smallboxodd" valign="top"><\&.\&.\&. -8 0000595 0\&.698215 B HTTP/1\&.0 304 Not Modified\&.\&.Date: Fri, 18 \&.\&.\&. -.fi - -.PP -This tells us that: -.PP -.IP o -Line 1: PID 594 served a request that originated at -the client\&. The corresponding time is (almost) 0 seconds, -so this is really the start of the run\&. -.IP o -Line 2: A back end replied 0\&.17 seconds later, and -0\&.28 seconds later, it was still replying (this is the -third line, again a \fBB\fP-type transmission)\&. -.IP o -Line 4: PID 595 served a request that originated -at the client\&. Again, the corresponding time is (almost) -0 seconds, since this is the first conversation part of -this connection\&. -.IP o -Lines 5 to 7: This is the continuation of line 2\&. Line 7 -is the last line of the \fBB\fP series (not visible from -the example, but trust me, it is), so that we may -conclude that it took the back end 0\&.96 seconds to serve -the file \f(CWindex\&.html\fP requested in line 1\&. -.IP o -Line 8: This is the answer to the client\&'s request of -line 4 (you can tell by the process ID number)\&. -So the back end took 0\&.68 seconds to confirm that -the stylesheet requested in line 4 wasn\&'t modified\&. -.PP -It is also worth while remembering that the start time of a \fBC\fP -request is the time that crossroads sees the activity\&. Any latency -between the true client and crossroads is obviously not -included\&. This is illustrated by the below simple ASCII art: -.PP -.nf - -client ---->---->---->--->*crossroads ====>====>====> - \e - back end - / -client ----<----<----<---< crossroads ====<====<====< - -.fi - -.PP -This simple picture shows a typical HTTP request that originates -at a client, travels to crossroads, and is relayed via the back -end\&. The \fBC\fP entry in a throughput log is the time when -crossroads sees the request, indicated by an asterisk\&. The \fBB\fP -entries are the times that it takes the back end to answer, -indicated by \f(CW===\fP style lines\&. Therefore, the true roundtrip -time will be longer than the number of seconds that are logged in -the throughput log: the latency between client and crossroads -isn\&'t included in that measurement\&. -.PP -Summarizing, the throughput times of a client-back end connection -can be analyzed using the directive \f(CWthroughputlog\fP\&. In a -real-world analysis, you\&'d probably want to write up a script to -analyze the output and to compute round trip times\&. Such scripts -are not (yet) included in Crossroads\&. -.PP - -.SH "5\&.8: IP filtering: Limiting Access by Client IP Address" - - -.SH "5\&.8\&.1: General Examples" - -.PP -The directives \f(CWallowfrom\fP, \f(CWdenyfrom\fP, \f(CWallowfile\fP and -\f(CWdenyfile\fP can be used to instruct Crossroads to specifically allow -access by using a "whitelist" of IP addresses, or to specifically deny -access by using a "blacklist"\&. E\&.g\&., the following configuration -allows access to service \f(CWwebproxy\fP only to \fIlocalhost\fP: -.PP -.nf -service webproxy { - port 8000; - allowfrom 127\&.0\&.0\&.1; - backend one { - \&. - \&. Back end definitions occur here - \&. - } - \&. - \&. Other back ends or other service directives - \&. may occur here - \&. -} -.fi - -.PP -In this example there is a "whitelist" having only one entry: IP -address 127\&.0\&.0\&.1, or \fIlocalhost\fP\&. (Incidentally, the same behaviour -could be accomplished by stating \fIbindto 127\&.0\&.0\&.1\fP, in which case -Crossroads would only listen to the local network device\&.) -.PP -In the same vein, the directive \f(CWallowfrom 127\&.0\&.0\&.1 192\&.168\&.1/24\fP -would allow access to \fIlocalhost\fP and to all IP addresses that start -with 192\&.168\&.1\&. The specifier \f(CW192\&.168\&.1/24\fP states that there are -three network bytes (192, 168 and 1), and 24 bits (or 3 bytes) are -relevant; so that the fourth network byte doesn\&'t matter\&. -.PP - -.SH "5\&.8\&.2: Using External Files" - -.PP -The directives \f(CWallowfile\fP and \f(CWdenyfile\fP allow you to specify IP -addresses in external files\&. The Crossroads configuration states -e\&.g\&. \f(CWallowfile /tmp/allow\&.txt\fP, and the IP addresses are then in -\f(CW/tmp/allow\&.txt\fP\&. The format of \f(CW/tmp/allow\&.txt\fP is as follows: -.PP -.IP o -The specifications follow again \fIp\&.q\&.r\&.s/mask\fP, where -p, q, r and s are network bytes which can be left out on the -right hand side when the mask allows it; -.IP -.IP o -The specifications must be separated by white space -(spaces, tabs or newlines)\&. -.PP -E\&.g\&., the following is a valid example of an external specification -file: -.PP -.nf -127\&.0\&.0\&.1 -192\&.168\&.1/24 -10/8 -.fi - -.PP -When external files are in effect, then the signal \f(CWSIGHUP\fP (1) -causes Crossroads to reload the external file\&. E\&.g\&., while Crossroads -is running, you may edit \f(CW/tmp/allow\&.txt\fP, and then issue \f(CWkillall --1 crossroads\fP\&. The new contents of \f(CW/tmp/allow\&.txt\fP will be -reloaded\&. -.PP - -.SH "5\&.8\&.3: Mixing Directives" - -.PP -Crossroads allows to mix all directives in one service -description\&. However, some mixes are less meaningful than others\&. It\&'s -up to you to take this into account\&. -.PP -The following rules apply: -.PP -.IP o -Blacklisting and whitelisting can be used together\&. When -combined, the blacklist will always be interpreted -first\&. E\&.g\&., consider the following directives: -.IP -.nf -allowfrom 192\&.168\&.1/24 -denyfrom 192\&.168\&.1\&.100 -.fi - -.IP -Given the fact that the deny list is checked first, client -192\&.168\&.1\&.100 won\&'t be able to access Crossroads\&. Then the -allow list will be checked, stating that all clients whose IP -address starts with 192\&.168\&.1 may connect\&. The effect will be -that e\&.g\&., client 192\&.168\&.1\&.1 may connect, 192\&.168\&.1\&.2 may -connect too, 192\&.168\&.1\&.100 will be blocked, and 10\&.1\&.1\&.1 will -be blocked as well\&. -.IP -Now consider the following directives: -.IP -.nf -allowfrom 192\&.168\&.1\&.100 127\&.0\&.0\&.1 -denyfrom 192\&.168\&.1/24 -.fi - -.IP -This will first of all deny access to all IP addresses that -start with 192\&.168\&.1\&. So the rule that allows 192\&.168\&.1\&.100 -won\&'t ever be effective\&. The net result will be that access -will be granted to 127\&.0\&.0\&.1\&. -.IP -.IP o -Blacklisting or whitelisting can be left out\&. -A list is considered empty when no appropriate directives -occur in \f(CW/etc/crossroads\&.conf\fP, or when the directive -points to an empty or non-existent external file\&. -.IP -.IP o -Using \f(CW*from\fP and \f(CW*file\fP statements is allowed, but -doesn\&'t make sense\&. E\&.g\&., the following configuration sample -is such a case: -.IP -.nf -allowfrom 127\&.0\&.0\&.1 192\&.168\&.1/24 -allowfile /tmp/allow\&.txt -.fi - -.IP -There is a technical reason for this\&. Once Crossroads -processes the \f(CWallowfile\fP directive, then the whole -whitelist is cleared (thereby removing the entries 127\&.0\&.0\&.1 -and 192\&.168\&.1/24), and new entries are reloaded from the -file\&. The net result is that the \f(CWallowfrom\fP specification -is overruled\&. -.PP -Crossroads only performs syntactic checking of the configuration\&. Some -of the above samples are syntactically correct, but make no semantic -sense: Crossroads doesn\&'t warn for such situations\&. -.PP - -.SH "5\&.9: Configuration examples" - - - -.SH "5\&.9\&.1: A load balancer for three webserver back ends" - -.PP -The following configuration example binds crossroads to port 80 of the -current server, and distributes the load over three back ends\&. This -configuration shows most of the possible settings\&. -.PP -.nf -service www { - /* We don\&'t need session stickyness\&. */ - type any; - - /* Port on which we\&'ll listen in this service: required\&. */ - port 8000; - - /* What IP address should this service listen? Default is \&'any\&'\&. - * Alternatively you can state an explicit IP address, such as - * 127\&.0\&.0\&.1; that would bind the service only to \&'localhost\&'\&. */ - bindto any; - - /* Verbose reporting or not\&. Default is off\&. */ - verbosity on; - - /* Dispatching mode, or: How to select a back end for an incoming - * request\&. Possible values: - * roundrobin: just the next back end in line - * random: like roundrobin, but at random to make things more - * confusing\&. Probably only good for testing\&. - * bysize: The backend that transferred the least nr of bytes - * is the next in line\&. As a modifier you can say e\&.g\&. - * bysize over 10, meaning that the 10 last connections will - * be used to compute the transfer size, instead of all - * transfers\&. - * byduration: The backend that was active for the shortest time - * is the next in line\&. As a modifier you can say e\&.g\&. - * byduration of 10 to compute over the last 10 connections\&. - * byconnections: The back end with the least active connections - * is the next ine line\&. - * byorder: The first available back end is always taken\&. - */ - dispatchmode byduration over 5; - - /* Interval at which we\&'ll check whether a temporarily unavailable - * backend has woken up\&. - */ - revivinginterval 5; - - /* TCP backlog of connections\&. Default is 0 (no backlog, one - * connection may be active)\&. - */ - backlog 5; - - /* For status reporting: a shared memory key\&. Default is the same - * as the port number, OR-ed by a magic number\&. - */ - shmkey 8000; - - /* This controls when crossroads should consider a connection as - * finished even when the TCP sockets weren\&'t closed\&. This is to - * avoid hanging connections that don\&'t do anything\&. NOTE THAT when - * crossroads cuts off a connection due to timeout exceed, this is - * not marked as a failure, but as a success\&. Default is 0: no timeout\&. - */ - connectiontimeout 300; - - /* The max number of allowed client connections\&. When present, connections - * won\&'t be accepted if the max is about to be exceeded\&. When - * absent, all connections will be accepted, which might be misused - * for a DOS attack\&. - */ - maxconnections 300; - - /* Now let\&'s define a couple of back ends\&. Number 1: */ - backend www_backend_1 { - /* The server and its port, the minimum configuration\&. */ - server httpserver1; - port 9010; - /* The \&'decay\&' of usage data of this back end\&. Only relevant - * when the whole service has \&'dispatchmode bysize\&' or - * \&'byduration\&'\&. The number is a percentage by which the usage - * parameter is decreased upon each connection of an other back - * end\&. - */ - decay 10; - - /* To see what\&'s happening in /var/log/messages: */ - verbosity on; - } - - /* The second one: */ - backend www_backend_2 { - /* Server and port */ - server httpserver2; - port 9011; - - /* Verbosity of reporting when this back end is active */ - verbosity on; - - /* Decay */ - decay 10; - - /* This back end is twice as weak as the first one */ - weight 2; - - /* Event triggers for system commands upon succesful activation - * and upon failure\&. - */ - onsuccess echo \&'success on backend 2\&' | mail root; - onfailure echo \&'failure on backend 2\&' | mail root; - } - - /* And yet another one\&.\&. this time we will dump the traffic - * to a trace file\&. Furthermore we don\&'t want more than 10 concurrent - * connections here\&. Note that there\&'s also a total maxconnections for the - * whole service\&. - */ - backend www_backend_3 { - server httpserver3; - verbosity on; - port 9000; - verbosity on; - decay 10; - trafficlog /tmp/backend\&.3\&.log; - maxconnections 10; - } -} -.fi - -.PP - -.SH "5\&.9\&.2: An HTTP forwarder when travelling" - -.PP -As another example, here\&'s my \f(CWcrossroads\&.conf\fP that I use on my -Unix laptop\&. The problem that I face is that I need many HTTP proxy -configurations (at home, at customers\&' sites and so on) but I\&'m too -lazy to reconfigure browsers all the time\&. -.PP -Here\&'s how it used to be before crossroads: -.PP -.IP o -At home, I would surf through a squid proxy on my local -machine\&. The browser proxy setting is then -\f(CWhttp://localhost:3128\fP\&. -.IP -.IP o -Sometimes I start up an SSH tunnel to our offices\&. The -tunnel has a local port 3129, and connects to a squid proxy on -our e-tunity server\&. Hence, the browser proxy is then -\f(CWhttp://localhost:3129\fP\&. -.IP -.IP o -At a customer\&'s location I need the proxy -\f(CWhttp://10\&.120\&.34\&.113:8080\fP, because they have configured it -so\&. -.IP -.IP o -And in yet other instances, I use a HTTP diagnostic tool -Charles -that sits between browser and website and shows me -what\&'s happening\&. I run charles on my own machine and it -listens to port 8888, behaving like a proxy\&. The browser -configuration for the proxy is then -\f(CWhttp://localhost:8888\fP\&. -.PP -Here\&'s how it works with a crossroads configuration: -.PP -.IP o -I have configured my browsers to use -\f(CWhttp://localhost:8080\fP as the proxy\&. For all situations\&. -.IP -.IP o -I use the following crossroads configuration, and let -crossroads figure out which proxy backend works, and which -doesn\&'t\&. Note two particularities: -.IP -.IP o -The statement \f(CWdispatchmode byorder\fP\&. This -makes sure that once crossroads determines which -backend works, it will stick to it\&. This usage of -crossroads doesn\&'t need to balance over more than one -back end\&. -.IP -.IP o -The statement \f(CWbindto 127\&.0\&.0\&.1\fP makes sure -that requests from other interfaces than loopback -won\&'t get serviced\&. -.IP -.nf -service HttpProxy { - port 8080; - bindto 127\&.0\&.0\&.1; - verbosity on; - dispatchmode byorder; - revivinginterval 15; - - backend Charles { - server localhost:8888; - verbosity on; - } - - backend CustomerProxy { - server 10\&.120\&.34\&.113:8080; - verbosity on; - } - - backend SshTunnel { - server localhost:3129; - } - - backend LocalSquid { - server localhost:3128; - } -} -.fi - -.PP -As a final note, the commandline argument \f(CWtell\fP can be used to -influence crossroad\&'s own detection mechanism of back end availability -detection\&. E\&.g\&., if in the above example the back ends \f(CWSshTunnel\fP -and \f(CWLocalSquid\fP are both active, then \f(CWcrossroads tell httpproxy -sshtunnel down\fP will \&'take down\&' the back end \f(CWSshTunnel\fP -- and -will automatically cause crossroads to switch to \f(CWLocalSquid\fP\&. -.PP - -.SH "5\&.9\&.3: SSH login with enforced idle logout" - -.PP -The following example shows how crossroads \&'throttles\&' SSH -logins\&. Connections are accepted on port -22 (the normal SSH port) and forwarded to the actual SSH daemon -which is running on port 2222\&. -.PP -Note the usage of the -\f(CWconnectiontimeout\fP directive\&. This makes sure that users are logged -out after 10 minutes of inactivity\&. Note also the \f(CWmaxconnections\fP -setting, this makes sure that no more than 10 concurrent logins occur\&. -.PP -.nf -service Ssh { - port 22; - backlog 5; - maxconnections 10; - connectiontimeout 600; - backend TrueSshDaemon { - server localhost:2222; - } -} -.fi - -.PP - -.SH "5\&.10: Linux and ip_conntrack_max" -The kernel value of \f(CWip_conntrack_max\fP is important for routers and -balancers under Linux\&. Basically it\&'s the maximum number of tracked -connections\&. Felix A\&.W\&.O\&. describes the following situation: -.PP -.IP o -Crossroads seems to mark back ends as unavailable, while -in fact nothing is afoot\&. -.IP o -This happens under heavy load\&. -.IP o -In \f(CW/var/log/messages\fP one may see the message: -\f(CWkernel: ip_conntrack: table full, dropping packet\fP\&. -.PP -The reason for Crossroad\&'s behavior is that the kernel refuses to -build up a requested network connection\&. For Crossroads, this looks -just as a non-responding back end\&. Crossroads therefore marks the back -end as unavailable\&. -.PP -The solution is as follows: -.PP -.IP o -Try \f(CWcat /proc/sys/net/ipv4/ip_conntrack_max\fP to see -the current value\&. -.IP o -Add something to the shown value (e\&.g\&., multiply by two), -and inform -the kernel of the new value, using \f(CWecho\fP (new-value) \f(CW> -/proc/sys/net/ipv4/ip_conntrack_max\fP -.IP o -Make sure that the same step occurs somewhere in your -boot sequence as well, or that the new valueit is stated in a -configuration -file such as \f(CW/etc/sysctl\&.conf\fP\&. -.PP -The value for \fInew-value\fP is something that you\&'ll have to figure -out yourself\&. Note however that each count will cause the kernel to -reserve 350 bytes\&. So if you set \f(CWip_conntrack_max\fP to 100\&.000, then -you\&'re already taking 33\&.3Mb off the total available memory\&. -.PP - -.SH "5\&.11: Marking back ends as bad after more than one try" -Crossroads allows you to specify on a per-back end basis how many -retries are needed before a back end is considered unavailable\&. The -default is just one, meaning that after one failed connection, -Crossroads will mark a back end as unavailable (the back end may be -\&'revived\&', if you use \f(CWrevivinginterval\fP)\&. -.PP -Increasing the number is specified using the keyword \f(CWretries\fP\&. The -following configuration defines two back ends; the one on the IP -address 5\&.6\&.7\&.8 is somehow \&'flaky\&', and Crossroads should try -connecting 3 times before crossing it off: -.PP -.nf -service www { - port 80; - backend plugh { - server 1\&.2\&.3\&.4:80; - } - backend xyzzy { - server 5\&.6\&.7\&.8:80; - retries 3; - } -} -.fi - -.PP -There may be several reasons for increasing the retries number: -.PP -.IP o -The network connections to the server may spuriously -hamper, but such rare errors don\&'t mean that the back end server is -down\&. -.IP -.IP o -The back end server is a \&'slow starter\&' and can\&'t handle spikes -very well\&. E\&.g\&., it may be a webserver which starts with only -one daemon; extra capacity is added as network connections -arrive, but adding capacity take a little time\&. -.PP -Whatever the reason, the keyword \f(CWretries\fP might be of help -here\&. This keyword should however be used carefully: Crossroads will -retry connecting with a small one-second delay in between\&. A high -\f(CWretries\fP number means also lots of one-second delays, in which time -a client is kept waiting\&. -.PP - -.SH "5\&.12: Scripting Crossroads\&' back end availability" -The internal reviving model of Crossroads can periodically check -whether back ends that are unavailable have woken up yet\&. The checker -is triggered by a \f(CWrevivinginterval\fP statement of a service -description, as in: -.PP -.nf -service web { - port 80; - revivinginterval 5; - - backend one { - server 10\&.1\&.1\&.1:80; - } - - backend two { - server 10\&.1\&.1\&.2:80; - } -} -.fi - -.PP -This instructs Crossroads to check back ends \f(CWone\fP or \f(CWtwo\fP each 5 -seconds\&. A back end is considered available when it accepts TCP -connections on the given IP address and port\&. -.PP -This approach may not be sufficient in all situations\&. E\&.g\&., a web -server may \&'hang\&': it might accept a connection, but never serve -it\&. Or, an application server may serve simple connections, but if its -database is offline, it will generate internal server errors on pages -that try to access data\&. -.PP -In such situations you may want to replace the internal wakeup service -with your own scripted \&'health check\&'\&. Here\&'s how: -.PP -.IP o -First of all, you take out the \f(CWrevivinginterval\fP -statement of \f(CW/etc/crossroads\&.conf\fP, so that Crossroads\&' -internal check which only verifies TCP connectivity is -disabled\&. -.IP -.IP o -You determine a suitable URL in the applications that can -be queried for the health\&. In our example this will be -\f(CW/areyouthere\&.jsp\fP, a hypothetical page that does some -database access\&. It doesn\&'t even need to return output; just -succeed, or fail\&. -.IP -.IP o -You devise a small script that asks Crossroads the status -of back ends of a given service (in our example, service -\f(CWweb\fP)\&. -.IP -.IP o -The health check script starts by querying Crossroads to -determine whether a given back end is available or not\&. This -can be done via \f(CWcrossroads -t status\fP; the flag \f(CW-t\fP -causes Crossroads to emit easily parsable output\&. -.IP -.IP o -When the service is available, the health check script -hits a given URL and expects an answer \f(CWHTTP/1\&.x 200 -OK\fP\&. When this answer is not present, the back end is marked -unavailable\&. (The reason for e\&.g\&. \f(CWHTTP/1\&.x 500\fP might be a -database failure, as described above\&.) Marking a back end as -unavailable can be done via \f(CWcrossroads tell\fP \fIservice\fP -\fIbackend\fP \f(CWunavailable\fP\&. -.IP -.IP o -When the service is unavailable, then the health check -script hits the same given URL\&. When a \f(CWHTTP/1\&.x 200 OK\fP -answer is returned, then the back end has \&'woken up\&' and can -be marked available (using \f(CWcrossroads tell\fP)\&. -.PP -A sample health check script that does this, is shown below\&. It is -also in the Crossroads distribution as \f(CWetc/healthcheck\fP\&. It expects -three arguments: a testing URL, a service name, and a back end name\&. -.PP -.nf -#!/usr/bin/perl - -use strict; -use LWP::UserAgent; - -# Show usage and stop -sub usage () { - die <<"ENDUSAGE"; - -Usage: healthcheck URL SERVICE BACKEND - -Performs a health check of the stated url and if necessary flips the -state of the stated back end between \&'available\&' and \&'unavailable\&'\&. -Back ends that are \&'down\&' are not affected\&. - -ENDUSAGE -} - -# Test an URL\&. Return whether it\&'s a success\&. -sub testurl() { - my $ua = LWP::UserAgent->new(); - my $req = HTTP::Request->new(GET => $ARGV[0]); - my $res = $ua->request($req); - - if ($res->is_success()) { - print ("URL $ARGV[0] indicates success\en"); - return (1); - } else { - print ("URL $ARGV[0] indicates failure\en"); - return (0); - } -} - -# Main starts here -usage() unless ($#ARGV == 2); - -# Get the current state of the back end -open (my $if, "crossroads -t status \&'$ARGV[1]\&' \&'$ARGV[2]\&' |") - or die ("Cannot run \&'crossroads status\&'\en"); -my $status = <$if>; -close ($if) or die ("\&'crossroads status\&' terminated with error\en"); -chomp ($status); -$status =~ s{\&.*=}{}; -$status =~ s{\es+}{}; - -print ("Back end $ARGV[2] has status $status\en"); -if ($status eq \&'UNAVAILABLE\&') { - if (testurl()) { - print ("Back end $ARGV[2] is now available\en"); - system ("crossroads tell $ARGV[1] $ARGV[2] available") - and die ("\&'crossroads tell\&' terminated with error\en"); - } -} elsif ($status eq \&'available\&') { - if (!testurl()) { - print ("Back end $ARGV[2] is is now UNAVAILABLE\en"); - system ("crossroads tell $ARGV[1] $ARGV[2] UNAVAILABLE") - and die ("\&'crossroads tell\&' terminated with error\en"); - } -} else { - print ("No action given status \&'$status\&'\en"); -} -.fi - -.PP -Once you have the health checker in place, it can be run e\&.g\&. each 10 -seconds in a mini-daemon for back end \f(CWone\fP: -.PP -.nf -while [ 1 ] ; do - healthcheck http://10\&.1\&.1\&.1/areyouthere\&.jsp web one - sleep 10 -done -.fi - -.PP -The same is run for back end \f(CWtwo\fP: -.PP -.nf -while [ 1 ] ; do - healthcheck http://10\&.1\&.1\&.2/areyouthere\&.jsp web two - sleep 10 -done -.fi - -.PP -The further implementation of such a mini-daemon that fires up -\f(CWhealthcheck\fP is left to the reader\&. -.PP - -.SH "5\&.13: Rendering Crossroads\&' status in a web page" -The Crossroads flag \f(CW-x\fP causes the status output to be generated as -an XML document\&. This format can be nicely used to render the output -as an HTML page\&. -.PP -E\&.g\&., the following sample shows how Crossroads reports its status in -XML format: -.PP -.nf -<?xml version="1\&.0" encoding="UTF-8"?> -<status> - <service id="1" name="smtp"> - <connections>1</connections> - <lastbackend>0</lastbackend> - <backend id="0" name="first"> - <availability id="0">available</availability> - <clients>0</clients> - <failures>0</failures> - <connections>2</connections> - <duration sec="0\&.559882">0\&.56s</duration> - <throughput bytes="3564">3\&.48Kb</throughput> - </backend> - <backend id="1" name="second"> - <availability id="0">available</availability> - <clients>0</clients> - <failures>0</failures> - <connections>2</connections> - <duration sec="23\&.7636">23\&.76s</duration> - <throughput bytes="9055">8\&.84Kb</throughput> - </backend> - </service> -</status> -.fi - -.PP -A custom-made XSLT transformation stylesheet can be used to convert -this to any output format - and also to HTML\&. Such a style sheet is -included in the Crossroads distribution as -\f(CWetc/xml-status-to-html\&.xslt\fP\&. The sheet is lengthy, and is -therefore not included in this document\&. (You\&'re welcome to modify it -to suit your specific needs\&. If you have cool tips, send them along to -me and I\&'ll include them in the next distribution!) -.PP -If you want to show this output in a webpage which is generated on -demand by a webserver, then you might run into the following -problem\&. The status reporter (\f(CWcrossroads -x status\fP) -must be able to access the shared memory segment of the running -Crossroads instance\&. By default, the shared memory is protected for -the user that started Crossroads, which will often not be the user who -runs the webserver\&. Under the auspices of the webserver user, -\f(CWcrossroads status\fP might abort with a message: "ERROR: Cannot get -shared memory for service \fIname\fP, key \fInumber\fP: Permission denied\&." -.PP -The solution for this problem is to make the shared memory access -somewhat more liberal\&. There are basically two options: -.PP -.IP o -Start Crossroads with the flag \f(CW-m 0666\fP, which makes -the shared memory segment available to all\&. The octal number -0666 works just like a file permission setting under -Unix\&. Now, any user can run \f(CWcrossroads status\fP\&. -.IP -.IP o -If you want to make the access to Crossroads\&' shared -memory somewhat stricter, then make the user who starts -Crossroads and the user who runs the webserver member of a new -Unix group\&. Start Crossroads with the flag \f(CW-m 0664\fP\&. Now, -users belonging to the same group as the Crossroads starter -can run \f(CWcrossroads status\fP\&. -.PP - -.SH "6: Benchmarking" -This section shows how crossroads affects the -transmitting of HTML data when used as an intermediate \&'station\&' -through which all data travels\&. -.PP - -.SH "6\&.1: Benchmark 1: Accessing a proxy via crossroads or directly" - -.PP -The benchmark was run on a system where the following was varied: -.PP -.IP 1\&. -A website was recursively spidered through a local squid -proxy\&. The spidering was repeated 10 times, the total was recorded\&. -.IP -.IP 2\&. -Crossroads was placed in front of the squid proxy, and -the website was again recursively spidered\&. Again, the -spidering was repeated 10 times and the total was recorded\&. -.PP -The crossroads configuration of the second alternative is shown below: -.PP -.nf -service HttpProxy { - port 8080; - verbosity on; - backend LocalSquid { - server 127\&.0\&.0\&.1; - port 3128; - verbosity on; - } -} -.fi - -.PP - -.SH "6\&.1\&.1: Results" - -.PP -The results of this test are that crossroads causes a negligible -delay, if it is statistically relevant at all\&. Without crossroads, the -timing results are: -.PP -.nf -real 0m8\&.146s -user 0m0\&.130s -sys 0m0\&.253s -.fi - -.PP -When using crossroads as a middle station, the results are: -.PP -.nf -real 0m9\&.481s -user 0m0\&.141s -sys 0m0\&.230s -.fi - -.PP - -.SH "6\&.1\&.2: Discussion" - -.PP -The above shown results are quite favorable to crossroads\&. However, -one should know that situations will exist where crossroads leans -towards the \&'worst case\&' scenario, causing up to 50% -delay\&. -.PP -E\&.g\&., imagine a test where a \f(CWwget\fP command retrieves a -HTML document from an Apache server on \f(CWlocalhost\fP\&. Now we have -(almost) no overhead due to network throttling, hostname lookups and -so on\&. When this test would be run either with or without crossroads -in between, then theoretically, crossroads would cause a much larger -delay, because it has to read from the server, and then write the same -information to \f(CWwget\fP\&. Each read/write occurs twice when crossroads -sits in between\&. -.PP -This worst case scenario will however (fortunately) occur only very -seldom in the real world: -.PP -.IP o -Normally network issues, such as the above mentioned host -name lookups or throughput restrictions, will add -significantly to the duration of a request\&. The \&'twice as -many\&' read/writes caused by crossroads are then relatively -irrelevant\&. -.IP -.IP o -Normally a significant amount of time will be spent in a -back end, due to processing (e\&.g\&., when calling a servlet on a -back end)\&. Again, this processing time will weigh much heavier -than the multiple read/writes\&. -.PP - -.SH "6\&.2: Benchmark 2: Crossroads versus Linux Virtual Server (LVS)" - -.PP -LVS is a kernel-based balancer that acts like a masquerading -firewall: TCP packets that arrive at the balancer are sent to one of -the configured back ends\&. LVS has the advantage over crossroads that -there is no stop-and-go in the transmission; in contrast, crossroads -needs to send data via an internal buffer\&. Crossroads has the -advantage that it offers instantaneous failover because it tries to -contact the back end for upon each new TCP connection; in contrast, -LVS isn\&'t aware of downtime of back ends (unless one implements an -external heartbeat)\&. Also, crossroads offers more complex balancing -than LVS\&. -.PP - -.SH "6\&.2\&.1: Environment" - -.PP -On the balancer, LVS was run on port 80, its forwarding set up for two -equally weighted back ends, using \f(CWipvsadm\fP: -.PP -.nf -ipvsadm -a -t 192\&.168\&.1\&.250:http -r 10\&.1\&.1\&.100:http -m -w 1 -ipvsadm -a -t 192\&.168\&.1\&.250:http -r 10\&.1\&.1\&.101:http -m -w 1 -.fi - -.PP -Crossroads was run on port 81\&. The configuration file is shown below: -.PP -.nf -service http { - port 81; - dispatchmode roundrobin; - revivinginterval 5; - backend one { - server 10\&.1\&.1\&.100; - port 80; - } - backend two { - server 10\&.1\&.1\&.101; - port 80; - } -} -.fi - -.PP - -.SH "6\&.2\&.2: Tests and results" - -.PP -In the first test, ports 80 and 81 on the balancer were \&'bombed\&' with -50 concurrent clients, each requesting a small page 50 times\&. The -following timings where measured: -.PP -.IP o -How long it takes to establish a connection; -.IP o -How long it takes to retrieve the page\&. -.PP -The results of this test were: -.PP -.IP o -On average, each client took 0\&.12 seconds to connect -to LVS, and each page was retrieved in 0\&.14 seconds; -.IP o -On average, each client took 0\&.11 seconds to connect to -crossroads, and each page was retrieved in 0\&.13 seconds\&. -.PP -In this setup there seems to be no difference between the performance -of LVS and crossroads! -.PP -In a second test, the size of the retrieved page was varied from 2\&.000 -to 2\&.000\&.000 bytes\&. This test was taken to see whether crossroads would -show performance degradation when transferring larger amounts of data\&. -.PP -For each page size, 30 concurrent clients were started, that retrieved -the page 50 times\&. Again, the connect times and processing times where -recorded\&. -.PP -The results of the total time (connect time + retrieval time) -are shown in the below table: -.PP -.TS - tab(~); - - - - - - - - - - - - ---- -rrr -rrr -rrr -rrr -rrr ---- -c. -\fBBytes\fP~\fBLVS timing\fP~\fBCrossroads timing\fP -2000~0\&.130741688~0\&.12739582 -20000~0\&.490916224~0\&.50376901 -200000~3\&.799440328~4\&.33125273 -2000000~45\&.25090855~45\&.9600728 - -.TE - -.PP -Again, the results show that crossroads performs just as effectively -as LVS, even with large data chunks! -.PP - -.SH "7: Compiling and Installing" - - -.SH "7\&.1: Prerequisites" - -.PP -The creation of crossroads requires: -.PP -.IP o -Standard Unix tools, such as \f(CWsed\fP, \f(CWawk\fP, \f(CWPerl\fP -(5\&.00 or better); -.IP -.IP o -A POSIX-compliant C compiler; -.IP -.IP o -Support for SYSV IPC, networking and so on\&. - -.PP -Basically a Linux or Apple MacOSX box will do nicely\&. To compile and install -crossroads, follow these steps\&. -.PP - -.SH "7\&.2: Compiling and installing" - -.PP -.IP o -Obtain the source distribution\&. It can be found on -http://crossroads\&.e-tunity\&.com\&. The distribution comes as an -archive \f(CWcrossroads-\fP\fItype\fP\f(CW\&.tar\&.gz\fP, where \fItype\fP is -\f(CWstable\fP or \f(CWdevel\fP\&. -.IP -.IP o -Unpack the archive in a sources directory using \f(CWtar -xzf crossroads-\fP\fIX\&.YY\fP\f(CW\&.tar\&.gz\fP\&. The contents spill into a -subdirectory \f(CWcrossroads-\fP\fIX\&.YY/\fP\&. -.IP -.IP o -Change-dir into the directory\&. -.IP -.IP o -Next, edit \f(CWetc/Makefile\&.def\fP and verify that all -compilation settings are to your likings\&. The settings are -explained in the file\&. \fBNote that\fP the default distribution -of \f(CWMakefile\&.def\fP is suited for Linux or Apple MacOSX -systems\&. On other Unices, or on non-Unix systems, you must -particularly pay attention to \f(CWSET_PROC_TITLE_BY\&.\&.\&.\fP\&. When -in doubt, set the \f(CWSET_PROC_TITLE\&.\&.\&.\fP -settings to 0\&. Crossroads will work nevertheless, but it won\&'t show -nice titles in \f(CWps\fP listings\&. Also there\&'s a macro -\f(CWEXTRA_LIBS\fP to add linkage flags (an example for a Solaris -build is included)\&. -.IP -.IP o -Now crossroads is ready for compilation\&. Do a \f(CWmake -local\fP followed by \f(CWmake install\fP\&. The latter step may have -to be done by the user \f(CWroot\fP if the \f(CWBINDIR\fP setting of -\f(CWetc/Makefile\&.def\fP points to a root-owned directory\&. -.IP -.IP o -The documentation doesn\&'t install in this process\&. If you -want to install the documentation, then proceed as follows: -.IP -.IP o -Optionally, \f(CWcp doc/crossroads\&.html\fP -\fIhtmldirectory/\fP; where \fIhtmldirectory\fP is the destination -directory for your HTML manuals; -.IP -.IP o -Optionally, \f(CWcp doc/crossroads\&.pdf\fP -\fIpdfdirectory/\fP; where \fIpdfdirectory\fP is the -destination directory for your PDF manuals; -.IP -.IP o -Optionally, \f(CWcp doc/crossroads\&.man\fP -\fImanualdirectory\fP\f(CW/crossroads\&.1\fP, where -\fImanualdirectory\fP is e\&.g\&. \f(CW/usr/man/man1\fP, -\f(CW/usr/share/man1\fP, \f(CW/usr/local/man/man1\fP, -\f(CW/usr/local/share/man1\fP\&. Any possibility is valid, as -long as \fImanualdirectory\fP is one of the directories -where manual pages are stored; -.IP -.IP o -If your manual page system supports compressed -manual pages, then you can save some space with -\f(CWgzip\fP \fImanualdirectory\fP\f(CW/crossroads\&.1\fP\&. -.IP - -.SH "7\&.3: Configuring crossroads" - -.PP -Now that the binary is available on your system, you need to create a -suitable \f(CW/etc/crossroads\&.conf\fP\&. Use this manual or the output of -\f(CWcrossroads samplconf\fP to get started\&. -.PP -Once you have the configuration ready, start crossroads with -\f(CWcrossroads start\fP\&. Test the availability of your services and back -ends\&. Monitor how crossroads is doing with: -.PP -.IP o -In one terminal, run the script: -.nf -while [ 1 ] ; do - tput clear - crossroads status - sleep 3 -done -.fi - -.IP -\fBNote\fP that depending on your system you might need -\f(CWsleep 3s\fP, i\&.e\&., with an \f(CWs\fP appended\&. -.IP -.IP o -In another terminal, run: -.nf -while [ 1 ] ; do - tput clear - ps ax | grep crossroads | grep -v grep - sleep 3 -done -.fi - -.IP -\fBNote\fP that depending on your system you might need -\f(CWps -ef\fP instead of \f(CWps ax\fP\&. -.IP -.IP o -In yet another terminal, run \f(CWtail -f -/var/log/messages\fP (supply the appropriate system log file if -\f(CW/var/log/messages\fP doesn\&'t work for you)\&. -.PP -Now thoroughly test the availability of your back ends through -crossroads\&. The status display will show an updated view of which back -ends are selected and how busy they are\&. The process list will show -which crossroads daemons are running\&. Finally, the tailing of -\f(CW/var/log/messages\fP shows what\&'s going on -- especially if you have -\f(CWverbosity true\fP statements in the configuration\&. -.PP - -.SH "7\&.4: A boot script" - -.PP -Finally, you may want to create a boot-time startup script\&. The exact -procedure depends on the used Unix flavor\&. -.PP - -.SH "7\&.4\&.1: SysV Style Startup" - -.PP -On SysV style systems, there\&'s a startup script directory -\f(CW/etc/init\&.d\fP where bootscripts for all utilities are located\&. -You may have the \f(CWchkconfig\fP utility to automate the task of -inserting scripts into the boot sequence, but -otherwise the steps will resemble the following\&. -.PP -.IP o -Create a script \f(CWcrossroads\fP in \f(CW/etc/init\&.d\fP similar to the -following: -.IP -.nf -#!/bin/sh -/usr/local/bin/crossroads -v $@ -.fi - -.IP -The stated directory \f(CW/usr/local/bin\fP must correspond with -the installation path\&. The flag \f(CW-v\fP causes the startup to -be more \&'verbose\&'\&. However, once daemonized, the verbosity is -controlled by the appropriate statements in the configuration\&. -.IP -.IP o -Determine your \&'runlevel\&': usually 3 when your system is -running in text-mode only, or 5 when you are using a graphical -interface\&. If your runlevel is 3, then: -.IP -.nf -root> cd /etc/rc\&.d/rc3\&.d -root> ln -s /etc/init\&.d/crossroads S99crossroads -root> ln -s /etc/init\&.d/crossroads K99crossroads -.fi - -.IP -This creates startup (\f(CWS*\fP) and stop (\f(CWK*\fP) links that -will be run when the system enters or leaves a given runlevel\&. -.IP -If your runlevel is 5, then the right \f(CWcd\fP command is to -\f(CW/etc/rc\&.d/rc5\&.d\fP\&. Alternatively, you can create the -symlinks in both runlevel directories\&. -.PP - -.SH "7\&.4\&.2: BSD Style Startup" - -.PP -On BSD style systems, daemons are booted directly from \f(CW/etc/rc\fP and -related scripts\&. Incase you have a file \f(CW/etc/rc\&.local\fP, edit it, -and add the statement: -.PP -.nf -/usr/local/bin/crossroads start -.fi - -.PP -If your BSD system lacks \f(CW/etc/rc\&.local\fP, then you may need to start -Crossroads from \f(CW/etc/rc\fP\&. Your mileage may vary\&. -.PP diff --git a/doc/crossroads.pdf b/doc/crossroads.pdf Binary files differ. diff --git a/doc/main/compiling.yo b/doc/main/compiling.yo @@ -3,8 +3,10 @@ subsect(Prerequisites) The creation of crossroads requires: itemization( - it() Standard Unix tools, such as tt(sed), tt(awk), tt(Perl) - (5.00 or better); + it() Standard Unix tools, such as tt(sed), tt(awk); + + it() Perl (5.00 or better). The web interface + tt(crossroads-mgr) requires specific modules; it() A POSIX-compliant C compiler; @@ -67,6 +69,14 @@ itemization( it() Optionally, tt(cp doc/crossroads.pdf) em(pdfdirectory/); where em(pdfdirectory) is the destination directory for your PDF manuals.) + + it() In order to use the web interface tt(crossroads-mgr), + make sure that the following Perl modules are available: + tt(HTTP::Daemon), tt(Getopt::Std), tt(Log::Log4perl), + tt(MIME::Base64). When in doubt, start the commandline tool + tt(cpan) and enter tt(install HTTP::Daemon), which will + install the named module if necessary. You can repeat this for + all listed modules. ) @@ -74,8 +84,7 @@ itemization( subsect(Configuring crossroads) Now that the binary is available on your system, you need to create a -suitable DEFAULTCONF(). Use this manual or the output of -tt(crossroads samplconf) to get started. +suitable DEFAULTCONF(). Use this manual to get started. Once you have the configuration ready, start crossroads with tt(crossroads start). Test the availability of your services and back @@ -135,12 +144,22 @@ itemization( verb(\ #!/bin/sh -/usr/local/bin/crossroads -v $@) +/usr/local/bin/crossroads -v $@ +/usr/local/bin/crossroads-mgr start 1000) The stated directory tt(/usr/local/bin) must correspond with - the installation path. The flag tt(-v) causes the startup to - be more 'verbose'. However, once daemonized, the verbosity is - controlled by the appropriate statements in the configuration. + the installation path. + + In the first line, The flag tt(-v) causes the startup to be + more 'verbose'. However, once daemonized, the verbosity of + Crossroads is controlled by the appropriate statements in the + configuration. + + The second line starts the web interface tt(crossorads-mgr) on + TCP port 1000. Access to the web interface is free for all; + add your own flags tt(-b) or tt(-B) to enforce basic + authentication (see the manual page of tt(crossroads-mgr) and + section ref(tips/webinterface)). it() Determine your 'runlevel': usually 3 when your system is running in text-mode only, or 5 when you are using a graphical @@ -164,7 +183,9 @@ On BSD style systems, daemons are booted directly from tt(/etc/rc) and related scripts. Incase you have a file tt(/etc/rc.local), edit it, and add the statement: -verb(/usr/local/bin/crossroads start) +verb(\ +/usr/local/bin/crossroads start +/usr/local/bin/crossroads-mgr start 1000) If your BSD system lacks tt(/etc/rc.local), then you may need to start Crossroads from tt(/etc/rc). Your mileage may vary. diff --git a/doc/main/crossroads.yo b/doc/main/crossroads.yo @@ -10,8 +10,10 @@ abstract(Crossroads is a load balance and fail over utility for TCP more. Crossroads is service-independent: it is usable for HTTP/HTTPS, SSH, SMTP, DNS, etc. In the case of HTTP balancing, Crossroads can modify HTTP headers, e.g. to - provide 'session stickiness' for back-end processes that need - sessions, but aren't session-aware of other back-ends.) + provide 'session stickiness' for back end processes that need + sessions, but aren't session-aware of other + back ends. Crossroads is configured via a file and accessible + via a web interface.) article(Crossroads VER()) (AUTHORNAME() nl() Maintained by MAINTAINERNAME() (MAINTAINEREMAIL())) @@ -37,6 +39,9 @@ includefile(tips) sect(Benchmarking) includefile(benchmarking) +sect(The Web Interface) +includefile(webinterface) + sect(Compiling and Installing) label(installation) includefile(compiling) diff --git a/doc/main/intro.yo b/doc/main/intro.yo @@ -1,29 +1,29 @@ -Crossroads is a daemon that basically accepts TCP connections -at preconfigured ports, and given a list of 'back ends' -distributes each incoming connection to one of the back ends, -so that a client request is -served. Additionally, crossroads maintains an internal +Crossroads is a daemon that basically accepts TCP connections at +preconfigured ports, and given a list of 'back ends' distributes each +incoming connection to one of the back ends, so that a client request +is served. Additionally, crossroads maintains an internal administration of the back end connectivity: if a back end isn't usable, then the client request is handled using another back end. Crossroads will then periodically check whether a previously not -usable back end has come to life yet. Also, crossroads can select -back ends by estimating the load, so that balancing is achieved. +usable back end has come to life yet. Also, crossroads can select back +ends by estimating the load, so that balancing is achieved. Using this approach, crossroads serves as load balancer and fail over -utility. Crossroads will very likely not be as reliable as -hardware based balancers, since it always will require a server to -run on. This server, in turn, may become a new Single Point of -Failure (SPOS). However, in situations where cost efficiency is an issue, -crossroads may be a good choice. Furthermore, crossroads can be -deployed in situations where a hardware based balancing already -exists and augmenting service reliability is needed. Or, crossroads may be -run off a diskless system, which again improves reliability of the +utility. Crossroads will very likely not be as reliable as hardware +based balancers, since it always will require a server to run on. This +server, in turn, may become a new Single Point of Failure (SPOS). +However, in situations where cost efficiency is an issue, crossroads +may be a good choice. Furthermore, crossroads can be deployed in +situations where a hardware based balancing already exists and +augmenting service reliability is needed. Or, crossroads may be run +off a diskless system, which again improves reliability of the underlying hardware. -This document describes how to use crossroads, how to configure it -in order to increase the reliability of your systems, and how to -compile the program from its sources. whenhtml(This document is -also available in url(PDF)(crossroads.pdf) format.) +This document describes how to use crossroads, how to configure it in +order to increase the reliability of your systems, and how to compile +the program from its sources. whenhtml(This document is also available +in url(PDF)(crossroads.pdf) format.) + subsect(Obtaining Crossroads) @@ -41,6 +41,7 @@ itemization( repository; anonymous reading (fetching) is allowed. In order to commit changes, mail the author or maintainer for credentials.) + subsect(Reporting bugs) Crossroads was thoroughly tested and proven to work. However, on @@ -63,30 +64,30 @@ itemization( it() The version of Crossroads and all compile-time settings, obtained via tt(crossroads -C).) + subsect(Copyright and Disclaimer) -Crossroads is distributed as-is, without assumptions of fitness -or usability. You are free to use crossroads to your -liking. It's free, and as with everything that's free: there's -also no warranty. +Crossroads is distributed as-is, without assumptions of fitness or +usability. You are free to use crossroads to your liking. It's free, +and as with everything that's free: there's also no warranty. You are allowed to make modifications to the source code of -crossroads, and you are allowed to (re)distribute crossroads, as -long as you include this text, all sources, and if applicable: all -your modifications, with each distribution. - -While you are allowed to make any and all changes to the sources, -I would appreciate hearing about them. If the changes concern new -functionality or bugfixes, then I'll include them in a next -release, stating full credits. If you want to seriously contribute (to -which you are heartily encouraged), then mail me and I'll get you -access to the Crossroads SVN repository, so that you can update and -commit as you like. +crossroads, and you are allowed to (re)distribute crossroads, as long +as you include this text, all sources, and if applicable: all your +modifications, with each distribution. + +While you are allowed to make any and all changes to the sources, I +would appreciate hearing about them. If the changes concern new +functionality or bugfixes, then I'll include them in a next release, +stating full credits. If you want to seriously contribute (to which +you are heartily encouraged), then mail me and I'll get you access to +the Crossroads SVN repository, so that you can update and commit as +you like. subsect(Terminology) Throughout this document, the following terms are used: footnote(Many -more meanings of the terms will exist -- yes, I am aware of that. I'm +more meanings of the terms will exist - yes, I am aware of that. I'm using the terms here in a very strict sense.) description( @@ -253,4 +254,4 @@ subsubsect(Porting issues for pre-1.08 installations) tt(setserverheader "XR-Real-IP: %r";) nl() This incidentally also makes it possible to change the header name (here: tt(XR-Real-IP)).) - -\ No newline at end of file + diff --git a/doc/main/tips.yo b/doc/main/tips.yo @@ -41,6 +41,9 @@ includefile(tips/retries) subsect(Scripting Crossroads' back end availability) includefile(tips/scripting) +subsect(Using the Web Interface crossroads-mgr) +includefile(tips/webinterface) + subsect(Rendering Crossroads' status in a web page) label(xmlstatus) includefile(tips/rendering) diff --git a/doc/main/tips/webinterface.yo b/doc/main/tips/webinterface.yo @@ -0,0 +1,107 @@ +The mini-webserver tt(crossroads-mgr) provides an intuitive web +interface to the state of Crossroads. Once started, an administrator +may view the state of the balancer, and may influence the state of all +back ends. + +As an example, a procedure is described here where a given back end is +gracefully taken out of service. Below is a sample Crossroads +configuration, which distributes requests over three back ends: + +verb(\ +service www { + port 80; + type http; + backend one { + server 10.1.1.1:80; + stickycookie "BalancerID=one"; + addclientheader "Set-Cookie: BalancerID=one"; + } + backend two { + server 10.1.1.1:80; + stickycookie "BalancerID=two"; + addclientheader "Set-Cookie: BalancerID=two"; + } + backend three { + server 10.1.1.1:80; + stickycookie "BalancerID=three"; + addclientheader "Set-Cookie: BalancerID=three"; + } +}) + +In order to take a given back end gracefully offline (say back end +tt(two)), either of the following procedures can be followed: + +enumeration( + eit() Back end tt(two) is taken down via the commandline, using + tt(crossroads tell www two down). Next we wait for say one hour to + let existing sessions die out. After that, the back end can be turned + off. + + eit() Back end tt(two) is taken down via the web interface, by + switching the status from tt(available) to tt(down). Next we wait + for say one our, and turn off the back end.) + +The web interface doesn't offer extra functionality over the command +line tools; but all information is available at one glance, and +accessible without a shell access to the balancer. + + +subsubsect(Starting crossroads-mgr) + +The basic command to start tt(crossroads-mgr) is + +center(tt(crossroads-mgr start) em(portnumber)) + +where the port number specifies to which TCP port the manager will +listen. There is however one important security aspect that needs +attention. Unless specified otherwise, anyone who points their browser +to the balancer and the given port, can view back end states and even +change them. This may be a too lax policy. + +The web interface daemon offers one method to limit access: it can +optionally enforce basic authentication (username and password) when +viewing the status, and/or when switching states. Enforcing basic +authentication is turned off using two command line flags: + +itemization( + it() Flag tt(-b) turns on basic authentication to view the status. + it() Flag tt(-B) turns on basic authentication to change back end + states.) + +Both flags must be followed by the required credentials. The most +simple way to state the credentials, is to postfix the flag with the +required user name, a colon, and the required password. E.g., +tt(-Buser:secret) says that anyone who tries to change back end +states, must supply the user name tt(user) and the password +tt(secret). + +In this example the full invocation would be e.g.: + +center(tt(crossroads-mgr -Buser:secret start 1000)) + +The disadvantage is here that the credentials are visible for anyone +who has shell access to the balancer. A process overview, generated +with say tt(ps ax | grep crossroads-mgr), would show the required +username and password. In order to avoid such a leak, +tt(crossroads-mgr) can be started as follows: + +center(tt(crossroads-mgr -BPROMPT start 1000)) + +The 'magic' word tt(PROMPT) instructs tt(crossroads-mgr) to read the +username and password from em(stdin). The invocation can be further +scripted, using something like: + +center(tt(echo user:secret | crossroads-mgr -BPROMPT start 1000)) + +The same trick can be used with the flag tt(-b). When both flags are +present, and both 'magic' words tt(PROMPT) occur, then +tt(crossroads-mgr) will first ask for the credentials of the 'viewer', +and next for the credentials of the 'modifier' (even when flag tt(-B) +is stated first). So the following example starts tt(crossroads-mgr) +and requires the user name tt(viewer), with password tt(showme) to view the +status, and it requires the user name tt(modifier), with password +tt(changeit) to change states: + +verb(\ +echo -e 'viewer:showme\nmodifier:changeit' | + crossroads-mgr -bPROMPT -BPROMPT start 1000) diff --git a/doc/main/webinterface.yo b/doc/main/webinterface.yo @@ -0,0 +1,24 @@ +An auxiliary program is distributed with Crossroads, named +tt(crossroads-mgr), providing a web interface to the balancer. With +tt(crossroads-mgr), it is possible to: + +itemization( + it() View the status of the balancer (availablility of back ends, + their connections, and usage in bytes and seconds); + + it() Change the availability of back ends (available, unavailable, + down).) + +The program tt(crossroads-mgr) is in fact a Perl script, providing a +self-contained web server. It is started as follows: + +center(tt(crossroads-mgr start) em(portnumber)) + +where em(portnumber) is the TCP port. The web interface can then be +accessed using the URL tt(http://)em(hostname)tt(:)em(portnumber); +where em(hostname) is the host where the balancer and the web +interface run. + +More information is available via the manual page (see tt(man) +tt(crossroads-mgr)). + diff --git a/doc/man/crossroads-mgr.yo b/doc/man/crossroads-mgr.yo @@ -0,0 +1,102 @@ +includefile(../crossroads-defs) +manpage(crossroads-mgr)(1)(YEARS())(crossroads)() +manpagename(crossroads-mgr)(Web interface for Crossroads) + +manpagesynopsis() + itemization( + it() bf(crossroads-mgr) em([flags]) bf(start) em(port): starts + the web interface server + it() bf(crossroads-mgr) bf(stop): stops the server + it() bf(crossroads-mgr) bf(status): shows whether the server + is running) + +manpagedescription() + + bf(crossroads-mgr) is a self-contained web server, written in + Perl, providing a web interface to control Crossroads. The web + interface allows one to: + + itemization( + it() View the states of back ends, and their usage; + it() Set the states of back ends (e.g., to take a back end out + of service).) + + The web interface cannot be used to configure Crossroads (e.g., to + add new back ends). This must be done via the configuration file + bf(DEFAULTCONF()). Note furthermore that bf(crossroads status) and + bf(crossroads tell) are commandline tools that achieve the same + functionality as bf(crossroads-mgr). + +manpageoptions() + + bf(crossroads-mgr) recognizes the following flags: + + itemization( + + it() bf(-b UN:PW): Viewing the status is protected using + simple basic authentication, requiring username bf(UN) and + password bf(PW). + + For example one may specify: bf(-b user:secret), after which + visitors to the web interface are prompted for a username and + password. + + Instead of the username, a colon, and a password, the special + word bf(PROMPT) may be used (in caps). In this case, + bf(crossroads-mgr) prompts for the entry of a username and a + password. Using bf(PROMPT) will have the effect that the + username and password are not shown in a process listing. + + it() bf(-B UN:PW): Setting the status of a back end is + protected using simple basic authentication, with username + bf(UN) and password bf(PW). The special word bf(PROMPT) may be + used. + + it() bf(-f): bf(crossroads-mgr) stays in the foreground + instead of daemonizing. Useful for debugging. + + it() bf(-l FILE): Verbose activity (when bf(-v) is given) is + written to the stated file. Useful for debugging. Also, error + messages are written to the file. The default is + bf(/tmp/crossroads-mgr.log). Note that file logging is not + used in 'foreground' mode (flag bf(-f); in that case all + logging goes to terminal). + + it() bf(-v): Verbosity is increased. + + it() bf(-x CMD): This specifies how bf(crossroads-mgr) should + invoke bf(crossroads). The default is just bf(crossroads). An + example is: bf(/usr/local/bin/crossroads -c + /alternative/configuration) which overrules the default + configuration file name. Note that once bf(-x) is given, + bf(crossroads-mgr) will no longer search along the PATH. When + using bf(-x), the full access path to bf(crossroads) must be + specified. + + it() bf(-X XSLT): Causes bf(crossroads-mgr) to send the + specified XSLT file, instead of the built-in. Useful for + debugging.) + + +manpagebugs() + + itemization( + + it() Basic authentication headers are logged when bf(-v) + is active. Make sure that the log file is not in a + world-readable place, or turn off bf(-v). + + it() When using basic authentication in the form bf(-b + UN:PW) and bf(-B UN:PW), the required credentials are + visible in the process overview list. Use bf(PROMPT) to + hide these. + + it() bf(crossroads-mgr stop) and bf(crossroads-mgr status) + use the process list to see which daemons are active. If + you start more than one daemon, then bf(crossroads-mgr + stop) will stop all of them.) + +manpageauthor() + itemization( + it() Author: AUTHORNAME() + it() Maintainer: MAINTAINERNAME() MAINTAINEREMAIL()) diff --git a/etc/Makefile.def b/etc/Makefile.def @@ -6,7 +6,7 @@ # Versioning. This defines the overall version ID and must match the topmost # entry in the ChangeLog. -VER = 1.45 +VER = 1.46 # Years that Crossroads has been 'round. YEARS = 2005-2007 diff --git a/etc/svnrev.txt b/etc/svnrev.txt @@ -1 +1 @@ -170 +177 diff --git a/etc/xml-status-short.xslt b/etc/xml-status-short.xslt @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> + +<xsl:template match="/"> + <html> + <head> + <title>Crossroads Status Overview</title> + </head> + <body> + <h1>Crossroads Status Overview</h1> + <xsl:apply-templates/> + </body> + </html> +</xsl:template> + +<xsl:template match="/status"> + <table> + <xsl:apply-templates/> + </table> +</xsl:template> + +<xsl:template match="/status/service"> + <tr> + <td> <b> Service <xsl:value-of select="@name"/> </b> </td> + <td align="right"> <xsl:value-of select="connections"/> </td> + <td> connections </td> + </tr> + <xsl:apply-templates/> + <tr> </tr> +</xsl:template> + +<xsl:template match="/status/service/backend"> + <tr> + <td> </td> + <td> Backend </td> + <td> <b> <xsl:value-of select="@name"/> </b> </td> + <td> + is <xsl:value-of select="availability"/> + </td> + <td> </td> + </tr> + <tr> + <td> </td> + <td> </td> + <td> Clients: </td> + <td> + total <xsl:value-of select="connections"/>, + <xsl:value-of select="failures"/> failures + </td> + </tr> + <tr> + <td> </td> + <td> </td> + <td> Usage: </td> + <td> + <xsl:value-of select="throughput"/> in + <xsl:value-of select="duration"/>, + <xsl:value-of select="clients"/> active connections + </td> + </tr> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="*"/> + +</xsl:stylesheet> diff --git a/src/Makefile b/src/Makefile @@ -1,6 +1,6 @@ include ../etc/Makefile.def -DIRS = lib crossroads crossroads-daemon +DIRS = lib crossroads crossroads-daemon crossroads-mgr all: prep for d in ${DIRS}; do \ @@ -29,13 +29,15 @@ clean: echo BASE=$(BASE) make -C $$d clean; \ BASE=$(BASE) make -C $$d clean || exit 1; \ done + rm -f c-conf.cache -distclean: clean +distclean: for d in ${DIRS}; do \ echo "Making distclean in $$d"; \ echo BASE=$(BASE) make -C $$d distclean; \ BASE=$(BASE) make -C $$d distclean || exit 1; \ done + rm -f c-conf.cache prep: ../tools/gettools e-ver e-txt2c c-conf diff --git a/src/crossroads-daemon/Makefile b/src/crossroads-daemon/Makefile @@ -9,6 +9,7 @@ dbginstall: all $(BINDIR)/$(BIN) install: all $(BINDIR)/$(BIN) strip $(BINDIR)/$(BIN) +distclean: clean clean: rm -f *.o $(BIN) diff --git a/src/crossroads-daemon/main.c b/src/crossroads-daemon/main.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/crossroads-mgr/Makefile b/src/crossroads-mgr/Makefile @@ -0,0 +1,19 @@ +include $(BASE)/etc/Makefile.def + +all: crossroads-mgr +crossroads-mgr: crossroads-mgr.in Makefile $(BASE)/tools/patch-mgr \ + crossroads-mgr.xslt $(BASE)/etc/Makefile.def \ + crossroads-mgr.usage + $(BASE)/tools/patch-mgr $(VER)/$(REVVER) \ + crossroads-mgr.xslt crossroads-mgr.usage < $< > $@ + chmod +x $@ + +dbginstall: install +install: $(BINDIR)/crossroads-mgr +$(BINDIR)/crossroads-mgr: crossroads-mgr + cp crossroads-mgr $(BINDIR)/crossroads-mgr + chmod +x $(BINDIR)/crossroads-mgr + +distclean: clean +clean: + rm -f crossroads-mgr diff --git a/src/crossroads-mgr/crossroads-mgr.in b/src/crossroads-mgr/crossroads-mgr.in @@ -0,0 +1,411 @@ +#!/usr/bin/perl + +__WARNING__ + +use strict; +use HTTP::Daemon; +use Getopt::Std; +use Log::Log4perl qw(:easy); +use Posix qw(:sys_wait_h setsid); +use MIME::Base64; + +# The built in XSLT. +my $builtin_xslt = <<'END_XSLT'; +__XSLT__ +END_XSLT + +# The version ID +my $VER = "__VER__"; + +# Main starts here +my $prog; +$prog = Program->new(); +my $daemon = Daemon->new (); +$daemon->start ($prog->port()); # doesn't return + + +# All program-related functions +{ + package Program; + use strict; + + # Instantiate program handler. Parse the commandline. + sub new { + my $proto = shift; + my $self = {}; + my %opts; + + # Get the commandline options. + ::getopts ('vfl:x:X:b:B:', \%opts) or usage(); + + # Act according to argument; 'start' is handled here. + if ($ARGV[0] eq 'stop' and $#ARGV == 0) { + stop(); + exit (0); + } elsif ($ARGV[0] eq 'status' and $#ARGV == 0) { + status(); + exit (0); + } elsif ($ARGV[0] ne 'start' or $#ARGV != 1) { + usage(); + exit (0); + } + + # ARGV[0] was 'start' and there is one more argument $ARGV[1], port + $self->{port} = sprintf ("%d", $ARGV[1]); + $self->{verbose} = $opts{v} ? 1 : 0; + $self->{foreground} = $opts{f} ? 1 : 0; + $self->{isdaemon} = 0; + $self->{xsltfile} = $opts{X} if ($opts{X}); + if ($opts{b}) { + if ($opts{b} eq 'PROMPT') { + print ("Enter username:password for status authentication: ") + if (-t STDIN); + $opts{b} = <STDIN>; + chomp ($opts{b}); + } + $self->{statuscred} = ::encode_base64($opts{b}); + chomp ($self->{statuscred}); + } + if ($opts{B}) { + if ($opts{B} eq 'PROMPT') { + print ("Enter username:password for updating authentication: ") + if (-t STDIN); + $opts{B} = <STDIN>; + chomp ($opts{B}); + } + $self->{setcred} = ::encode_base64($opts{B}); + chomp ($self->{setcred}); + } + if ($opts{x}) { + $self->{call} = $opts{x}; + } else { + $self->{call} = ''; + for my $p (split /:/, $ENV{PATH}) { + if (-x "$p/crossroads") { + $self->{call} = "$p/crossroads"; + last; + } + } + die ("Failed to locate crossroads program on PATH\n") + if ($self->{call} eq ''); + } + die ("Argument $ARGV[0] is not a port number\n") unless ($self->{port}); + my $file = "/tmp/crossroads-mgr.log"; + $file = $opts{l} if ($opts{l}); + Log::Log4perl->easy_init ({level => $::DEBUG, file => $file}); + + bless ($self, $proto); + return ($self); + } + + # Return the necessary un/pw for status viewing, in Base64 encoding + sub authstatus { + return ($_[0]->{statuscred}); + } + + # Return the necessary un/pw for status setting, in Base64 encoding + sub authset { + return ($_[0]->{setcred}); + } + + # Show usage and stop. + sub usage { + die <<"ENDUSAGE"; + +__USAGE__ + +ENDUSAGE + } + + # Stop the daemon. NOTE: Class-less, called from the constructor. + sub stop { + my @pids = pids() + or die ("crossroads-mgr is not running\n"); + kill (2, @pids); + } + + # Report on the status. NOTE: Class-less, called from the constructor. + sub status { + my @pids; + if (@pids = pids()) { + print ("crossroads-mgr is running (pids @pids)\n"); + } else { + print ("crossroads-mgr is NOT running\n"); + } + } + + # Return the PID's where the manager is running. NOTE: Class-less. + sub pids { + my %ps = (Darwin => 'ps ax', + linux => 'ps ax', + SunOS => 'ps -eo \'pid args\''); + my $uname = `uname`; + chomp ($uname); + die ("Failed to get uname of this system\n") if ($uname eq ''); + die ("No 'ps' command configured for uname '$uname'\n") + unless ($ps{$uname}); + open (my $if, "$ps{$uname} |") + or die ("Failed to start '$ps{$uname}'\n"); + my @ret; + while (my $line = <$if>) { + next unless ($line =~ /perl/ and $line =~ /crossroads-mgr/); + my $pid = sprintf ("%d", $line); + next if ($pid == $$); + push (@ret, $pid); + } + return (@ret); + } + + # Get or set the listening port. + sub port { + $_[0]->{port} = $_[1] if ($_[1]); + return ($_[0]->{port}); + } + + # Issue an error + sub error { + my $self = shift; + if (! $self->{isdaemon}) { + die (@_, "\n"); + } else { + ::ERROR (@_); + die (@_); + } + } + + # Return a Crossroads command + sub call { + my $self = shift; + my $ret = $self->{call}; + for my $a (@_) { + $ret .= " $a"; + } + return ($ret); + } + + # Log a verbose message. + sub msg { + my $self = shift; + return unless ($self->{verbose}); + if (! $self->{isdaemon}) { + print (@_, "\n"); + } else { + ::DEBUG (@_); + } + } + + # Get/set verbosity + sub verbose { + $_[0]->{verbose} = $_[1] if ($_[1]); + return ($_[0]->{verbose}); + } + + # Get/set foreground mode + sub foreground { + $_[0]->{foreground} = $_[1] if ($_[1]); + return ($_[0]->{foreground}); + } + + # Daemonize + sub daemonize { + my $self = shift; + return if ($self->{foreground}); + if (my $pid = fork()) { + $self->msg ("Daemon is running as pid $pid"); + sleep (2); + exit (0); + } + $self->msg ("Daemonizing."); + $self->{isdaemon} = 1; + open (STDIN, "/dev/null") + or $self->error ("Cannot read /dev/null: $!"); + open (STDOUT, ">/dev/null") + or $self->error ("Cannot write /dev/null: $!"); + open (STDERR, ">&STDOUT") + or $self->error ("Cannot dup stdout: $!"); + } + + # The XSLT stylesheet + sub xslt { + my $self = shift; + if (! $self->{xsltfile}) { + $self->msg ("Returning built-in XSLT"); + return ($builtin_xslt); + } else { + $self->msg ("Returning contents of ", $self->{xsltfile}, + " as XSLT"); + open (my $if, $self->{xsltfile}) + or die ("Cannot read ", $self->{xsltfile}, ": $!"); + my $ret = ''; + while (my $line = <$if>) { + $ret .= $line; + } + return ($ret); + } + } +} + +# Daemon-related stuff +{ + package Daemon; + use strict; + + # Instantiate a daemon and start serving. + sub new { + my $proto = shift; + my $self = {}; + $self->{request} = ''; + $self->{conn} = ''; + bless ($self, $proto); + $prog->msg ("HTTP daemon instantiated."); + return ($self); + } + + sub start { + my ($self, $port) = @_; + $prog->msg ("Starting HTTP daemon on port $port"); + my $daemon = HTTP::Daemon->new (LocalPort => $port, + ReuseAddr => 1) + or $prog->error ("Failed to start HTTP daemon. ", + "Maybe the address is in use?"); + $prog->daemonize(); + $prog->msg ("Open for business"); + while (1) { + my ($conn, $peer) = $daemon->accept() or next; + $prog->msg ("Accepted new connection, spawning handler"); + next if (my $pid = fork()); + $SIG{2} = 'IGNORE'; + my $req = Request->new(); + eval { $req->serve ($conn); }; + $conn->send_error (500, $@) if ($@); + exit (0); + } + } +} + +# Request related stuff +{ + package Request; + use strict; + + sub new { + my $proto = shift; + my $self = {}; + bless ($self, $proto); + return ($self); + } + + # Serve a request. + sub serve { + my ($self, $conn) = @_; + + # Receive the request. + $self->receive ($conn); + } + + # Check authentication. + sub checkauth { + my ($self, $required, $desc) = @_; + return (1) if ($required eq ''); + my $h = $self->{request}->header ('Authorization') + or return ($self->prompt_auth($desc)); + $h =~ s/^\s*Basic\s*//i; + if ($h eq $required) { + $prog->msg ("Required authentication '$required' matched"); + return (1); + } + $prog->msg ("Required authentication '$required' does not ", + "match passed '$h'"); + return ($self->prompt_auth($desc)); + } + + # Prompt for authentication + sub prompt_auth { + my ($self, $desc) = @_; + $prog->msg ("Prompting for authentication ($desc)"); + my $r = HTTP::Response->new (401, 'Authentication Required'); + $r->header ('WWW-Authenticate' => + "Basic realm=\"Crossroads Load Balancer: $desc\""); + $self->{conn}->send_response ($r); + return (undef); + } + + # Receive client's request. + sub receive { + my ($self, $conn) = @_; + $self->{conn} = $conn; + $self->{request} = $conn->get_request() + or die ("Failed to receive request"); + die ("Bad request, only GET supported") + if ($self->{request}->method() ne 'GET'); + my $uri = $self->{request}->uri(); + $prog->msg ("Requested URI: ", $uri); + + # Take action depending on the URI. + if ($uri eq '/') { + $self->act_status (); + } elsif ($uri eq '/xslt') { + $self->act_xslt (); + } elsif ($uri =~ m{^/set/}) { + $self->act_set($uri); + } else { + die ("No action on URI ", $uri, "\n"); + } + } + + # Status setter + sub act_set { + my ($self, $uri) = @_; + + # The uri is /set/{service}/{backend}/{numericalstate} + # Get the variables, and run crossroads tell. + $self->checkauth ($prog->authset(), "Status Modification") + or return; + my (undef, undef, $service, $backend, $nr) = split (/\//, $uri); + $prog->msg ("Setting service $service, ", + "backend $backend to state $nr"); + system ($prog->call ("tell $service $backend $nr")) + and die ("Failed to tell service $service, backend $backend, ", + "new state $nr\n"); + + # Status is updated. Redirect to the overview page. + $prog->msg ("Redirecting to status overview page"); + my $r = HTTP::Response->new (302, 'Moved Temporarily'); + $r->header ('Location' => '/'); + $r->header ('Cache-Control' => 'no-cache'); + $self->{conn}->send_response ($r); + } + + # Status overview actor + sub act_status { + my $self = shift; + + $prog->msg ("Serving status overview page"); + $self->checkauth ($prog->authstatus(), "Status Retrieval") + or return; + open (my $if, $prog->call ('-x -Xxslt status') . '|') + or die ("Failed to run status retrieval"); + my $buf = ''; + while (my $line = <$if>) { + $buf .= $line; + } + + my $r = HTTP::Response->new (200, 'OK'); + $r->header ('Content-Type' => 'text/xml'); + $r->header ('Cache-Control' => 'no-cache'); + $r->content ($buf); + $self->{conn}->send_response ($r); + } + + # XSLT server + sub act_xslt { + my $self = shift; + + $prog->msg ("Serving XSLT"); + my $r = HTTP::Response->new (200, 'OK'); + $r->header ('Content-Type' => 'text/xml'); + $r->header ('Cache-Control' => 'no-cache'); + $r->content ($prog->xslt()); + $self->{conn}->send_response ($r); + } +} diff --git a/src/crossroads-mgr/crossroads-mgr.usage b/src/crossroads-mgr/crossroads-mgr.usage @@ -0,0 +1,23 @@ +This is crossroads-mgr V$VER, a web interface for Crossroads. +Usage: crossroads-mgr [flags] start PORT (starts on tcp port) + or: crossroads-msg stop (stops the manager) + or: crossroads-msg status (shows if it's running) + +Controls a mini-webserver to monitor Crossroads. +Supported flags during 'start' are: + -b UN:PW Viewing the Crossroads status will be protected using basic + authentication, UN is the username, PW is the password. + Use PROMPT to be prompted for the username/password. + -B UN:PW Modifying back end states will be protected using authentication, + use PROMPT to be prompted for the username/password. + -f crossroads-mgr stays in the foreground instead of daemonizing + (for debugging). + -l FILE States the log file of the daemon, default is + /tmp/crossroads-mgr.log. + -v Verbosity is increased, either to the log file or to stdout + (in -f mode). + -x CMD States how crossroads should be invoked, default is 'crossroads'. + Set to e.g. '/opt/xr/bin/crossroads -c /opt/xr/conf/xr.conf' if + your Crossroads is in an atypical location and if we should not use + configuration /etc/crossroads.conf. + -X XSLT Serves XSLT file, instead of built-in xslt. diff --git a/src/crossroads-mgr/crossroads-mgr.xslt b/src/crossroads-mgr/crossroads-mgr.xslt @@ -0,0 +1,155 @@ +<?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet version="1.0" + xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> +<xsl:output method="html"/> + +<xsl:template match="/"> + <html> + <head> + <title>Crossroads Status Overview</title> + <script type="text/javascript"> + function set (target, index) { + document.location = '/set/' + target + '/' + index; + } + </script> + <style type="text/css"> + h1 { + font-family: Verdana,Helvetica; + font-size: 12pt; + color: blue; + } + body { + font-family: Verdana,Helvetica; + font-size: 8pt; + } + td { + font-family: Verdana,Helvetica; + font-size: 10pt; + } + .service { background-color: #ffff33; } + .backend { background-color: #ffff99; } + .info { font-size: 8pt; } + .footer { color: gray; } + </style> + </head> + <body> + <h1>Crossroads Status Overview</h1> + <hr/> + <form> + <xsl:apply-templates/> + </form> + <hr/> + <div class="footer"> + <i> + Generated by Crossroads __VER__. + Visit + <a href="http://crossroads.e-tunity.com">http://crossroads.e-tunity.com</a> + for documentation and downloads. <br/> + </i> + </div> + </body> + </html> +</xsl:template> + +<xsl:template match="/status"> + <table width="100%"> + <xsl:apply-templates/> + </table> +</xsl:template> + +<xsl:template match="/status/service"> + <tr> + <td class="service"> <b> Service <xsl:value-of select="@name"/> </b> </td> + <td class="service" colspan="3"> + <xsl:value-of select="connections"/> connections + </td> + </tr> + <xsl:apply-templates/> + <tr> </tr> +</xsl:template> + +<xsl:template match="/status/service/backend"> + <tr> + <td> </td> + <td class="backend"> Back end </td> + <td class="backend"> <b> <xsl:value-of select="@name"/> </b> </td> + <td class="backend"> + is + <select onchange="set('{../@name}/{@name}', this.selectedIndex);"> + <xsl:choose> + <xsl:when test="availability/@id = 0"> + <option value="available" selected="1">available</option> + </xsl:when> + <xsl:otherwise> + <option value="available">available</option> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="availability/@id = 1"> + <option value="unavailable" selected="1">UNAVAILABLE</option> + </xsl:when> + <xsl:otherwise> + <option value="unavailable">unavailable</option> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="availability/@id = 2"> + <option value="down" selected="1">down</option> + </xsl:when> + <xsl:otherwise> + <option value="down">down</option> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="availability/@id = 3"> + <option value="waking" selected="1">waking</option> + </xsl:when> + <xsl:otherwise> + <option value="waking">waking</option> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="availability/@id = 4"> + <option value="intermediate" selected="1">intermediate</option> + </xsl:when> + <xsl:otherwise> + <option value="intermediate">intermediate</option> + </xsl:otherwise> + </xsl:choose> + <xsl:choose> + <xsl:when test="availability/@id = 5"> + <option value="unknown" selected="1">unknown</option> + </xsl:when> + <xsl:otherwise> + <option value="unknown">unknown</option> + </xsl:otherwise> + </xsl:choose> + </select> + </td> + <td> </td> + </tr> + <tr> + <td class="info"/> + <td class="info"/> + <td class="info"> Connections: </td> + <td class="info"> + Total <xsl:value-of select="connections"/> + (<xsl:value-of select="failures"/> failures, + <xsl:value-of select="clients"/> active) + </td> + </tr> + <tr> + <td class="info"/> + <td class="info"/> + <td class="info"> Usage: </td> + <td class="info"> + Throughput <xsl:value-of select="throughput"/> in + <xsl:value-of select="duration"/> + </td> + </tr> + <xsl:apply-templates/> +</xsl:template> + +<xsl:template match="*"/> + +</xsl:stylesheet> diff --git a/src/crossroads.h b/src/crossroads.h @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -331,6 +331,7 @@ EXTERN int tabular_status; /* -t: tabular status overview */ EXTERN int tcp_bufsz; /* -B: TCP buffer size */ EXTERN int uid_org, uid_set; /* original uid, flag: changed? */ EXTERN int xml_status; /* -x: XML status overview */ +EXTERN char *xml_xslt; /* -X: XSLT refrence for XML output */ EXTERN FILE *yyin; /* config file handle */ EXTERN int yylineno; /* input line number */ EXTERN char *yyerrmsg; /* parsing error msg */ @@ -472,3 +473,8 @@ extern void vsyslog (int fac, char const *fmt, va_list args); #if HAVE_STRCASESTR == 0 extern char *strcasestr (char const *big, char const *little); #endif + +/* setproctitle() if it's missing on this system */ +#if HAVE_SETPROCTITLE == 0 +extern void setproctitle (char const *fmt, ...); +#endif diff --git a/src/crossroads/Makefile b/src/crossroads/Makefile @@ -9,6 +9,7 @@ dbginstall: all $(BINDIR)/$(BIN) install: all $(BINDIR)/$(BIN) strip $(BINDIR)/$(BIN) +distclean: clean clean: rm -f *.o $(BIN) diff --git a/src/crossroads/main.c b/src/crossroads/main.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/allocreporter.c b/src/lib/allocreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ansistamp.c b/src/lib/ansistamp.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/backendavailable.c b/src/lib/backendavailable.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/backendconnect.c b/src/lib/backendconnect.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/backendcount.c b/src/lib/backendcount.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/choosebackend.c b/src/lib/choosebackend.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/configread.c b/src/lib/configread.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/configtest.c b/src/lib/configtest.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/configwrite.c b/src/lib/configwrite.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/copysockets.c b/src/lib/copysockets.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/createcommandlinespace.c b/src/lib/createcommandlinespace.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/data.c b/src/lib/data.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/deallocreporter.c b/src/lib/deallocreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/decrclientcount.c b/src/lib/decrclientcount.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/dns.c b/src/lib/dns.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/error.c b/src/lib/error.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/forktcpservicer.c b/src/lib/forktcpservicer.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/hashpjw.c b/src/lib/hashpjw.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpcopy.c b/src/lib/httpcopy.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httperror.c b/src/lib/httperror.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderaddheader.c b/src/lib/httpheaderaddheader.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderappendheader.c b/src/lib/httpheaderappendheader.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderconnectiontype.c b/src/lib/httpheaderconnectiontype.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderfree.c b/src/lib/httpheaderfree.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderhascookie.c b/src/lib/httpheaderhascookie.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderhttpver.c b/src/lib/httpheaderhttpver.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheadernew.c b/src/lib/httpheadernew.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderread.c b/src/lib/httpheaderread.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderremoveheader.c b/src/lib/httpheaderremoveheader.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheadersetheader.c b/src/lib/httpheadersetheader.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderval.c b/src/lib/httpheaderval.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpheaderwrite.c b/src/lib/httpheaderwrite.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpinsertheader.c b/src/lib/httpinsertheader.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpserve.c b/src/lib/httpserve.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpserversocket.c b/src/lib/httpserversocket.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/httpwrite.c b/src/lib/httpwrite.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/incrclientcount.c b/src/lib/incrclientcount.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/initsockaddr.c b/src/lib/initsockaddr.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/interrupt.c b/src/lib/interrupt.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfaddallow.c b/src/lib/ipfaddallow.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfadddeny.c b/src/lib/ipfadddeny.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfallowed.c b/src/lib/ipfallowed.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfdenied.c b/src/lib/ipfdenied.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfloadfile.c b/src/lib/ipfloadfile.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfmatch.c b/src/lib/ipfmatch.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ipfparse.c b/src/lib/ipfparse.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/ishexdigit.c b/src/lib/ishexdigit.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/isspace.c b/src/lib/isspace.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/lexer.c b/src/lib/lexer.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/lockreporter.c b/src/lib/lockreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/logactivityany.c b/src/lib/logactivityany.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/logactivitycontinuation.c b/src/lib/logactivitycontinuation.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/logactivityend.c b/src/lib/logactivityend.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/logactivitystart.c b/src/lib/logactivitystart.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/makesocket.c b/src/lib/makesocket.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/markactivity.c b/src/lib/markactivity.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/msg.c b/src/lib/msg.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/msgdumpbuf.c b/src/lib/msgdumpbuf.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/netbuffer.c b/src/lib/netbuffer.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/netbufread.c b/src/lib/netbufread.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/netcopy.c b/src/lib/netcopy.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/netread.c b/src/lib/netread.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/netwrite.c b/src/lib/netwrite.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parser.c b/src/lib/parser.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserclose.c b/src/lib/parserclose.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserfilename.c b/src/lib/parserfilename.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserinput.c b/src/lib/parserinput.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parseropen.c b/src/lib/parseropen.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserrun.c b/src/lib/parserrun.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserskipchar.c b/src/lib/parserskipchar.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/parserskipline.c b/src/lib/parserskipline.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/restart.c b/src/lib/restart.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/runservice.c b/src/lib/runservice.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/serve.c b/src/lib/serve.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/setproctitle.c b/src/lib/setproctitle.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/showconfig.c b/src/lib/showconfig.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/showservices.c b/src/lib/showservices.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/showstatus.c b/src/lib/showstatus.c @@ -1,8 +1,9 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ + #include "../crossroads.h" static char *timestr (double nsec) { @@ -55,9 +56,13 @@ static char *bytestr (double nbytes) { int show_status (int ac, char **av) { int i, j, services_shown = 0; - if (xml_status) - printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<status>\n"); + if (xml_status) { + printf ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + if (xml_xslt) + printf ("<?xml-stylesheet type=\"text/xsl\" " + "href=\"%s\"?>\n", xml_xslt); + printf ("<status>\n"); + } for (i = 0; i < nservice; i++) { if (ac > 1 && strcmp (service[i].name, av[0])) diff --git a/src/lib/stagetostring.c b/src/lib/stagetostring.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/statetostring.c b/src/lib/statetostring.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/stopdaemon.c b/src/lib/stopdaemon.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/strcasestr.c b/src/lib/strcasestr.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/strexpandformat.c b/src/lib/strexpandformat.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/stringtostate.c b/src/lib/stringtostate.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/strlcat.c b/src/lib/strlcat.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/strprintf.c b/src/lib/strprintf.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/strvprintf.c b/src/lib/strvprintf.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/symtabend.c b/src/lib/symtabend.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/symtablookup.c b/src/lib/symtablookup.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/symtabset.c b/src/lib/symtabset.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/symtabstart.c b/src/lib/symtabstart.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/sysrun.c b/src/lib/sysrun.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/tcpserve.c b/src/lib/tcpserve.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/tellservice.c b/src/lib/tellservice.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ @@ -12,6 +12,7 @@ int tell_service (int ac, char **av) { Backendavail avail; + /* Locate service */ for (i = 0; i < nservice; i++) if (!strcasecmp (service[i].name, av[0])) { target_service = service + i; @@ -21,6 +22,7 @@ int tell_service (int ac, char **av) { error ("Service '%s' isn't known. " "Maybe the configuration has changed?", av[0]); + /* Locate back end */ for (i = 0; i < target_service->nbackend; i++) if (!strcasecmp (target_service->backend[i].name, av[1])) { target_backend = i; @@ -30,14 +32,19 @@ int tell_service (int ac, char **av) { error ("Backend '%s' of service '%s' isn't known. " "Maybe the configuration has changed?", av[1], av[0]); - if ( (avail = string_to_state (av[2])) == st_unknown ) + /* Locate new state: either the direct number, or alpha name */ + if (sscanf (av[2], "%d", &avail) > 0) { + if (avail < st_available || avail > st_unknown) + error ("Bad state number '%s'", av[2]); + } else if ( (avail = string_to_state (av[2])) == st_unknown ) error ("Incorrect state '%s'.", av[2]); + /* Got all data. Poke the new state into shared memory. */ alloc_reporter (target_service, 0); servicereport->backendstate[target_backend].avail = avail; servicereport->backendstate[target_backend].fail = 0; msg ("Marked backend %s of service %s as %s.", - av[1], av[0], av[2]); + av[1], av[0], state_to_string (avail)); return (1); } diff --git a/src/lib/thruputlog.c b/src/lib/thruputlog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/trafficlog.c b/src/lib/trafficlog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/uidassume.c b/src/lib/uidassume.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/uidrestore.c b/src/lib/uidrestore.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/unlockreporter.c b/src/lib/unlockreporter.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/usage.c b/src/lib/usage.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/usage.txt b/src/lib/usage.txt @@ -36,6 +36,7 @@ Supported flags: is busy, Crossroads will wait for it to become free). -t: 'status' output is shown as a tabular availability view -x: 'status' output is shown as an XML document + -X XSLT: Embed reference to XSLT in 'crossroads -x status' -v: Enables verbosity upon startup. Other verbosity (services and back ends) is controlled in the configuration. -V: Shows the version ID and stops. diff --git a/src/lib/vsyslog.c b/src/lib/vsyslog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/wakeuphandler.c b/src/lib/wakeuphandler.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/warning.c b/src/lib/warning.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/writelog.c b/src/lib/writelog.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/xcalloc.c b/src/lib/xcalloc.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/xmalloc.c b/src/lib/xmalloc.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/xrealloc.c b/src/lib/xrealloc.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/xstrcat.c b/src/lib/xstrcat.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/xstrcatch.c b/src/lib/xstrcatch.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/lib/xstrdup.c b/src/lib/xstrdup.c @@ -1,5 +1,5 @@ /************************************************************************* - * This file is part of Crosroads 1.45, a load balancer and fail over + * This file is part of Crosroads 1.46, a load balancer and fail over * utility for TCP. Copyright (c) Karel Kubat, distributed under GPL. * Visit http://crossroads.e-tunity.com for information. *************************************************************************/ diff --git a/src/shared/parseopt.inc b/src/shared/parseopt.inc @@ -5,7 +5,7 @@ * - doc/main/using.yo * - doc/man/crossroads.yo */ - while ( (opt = getopt (argc, argv, "bB?c:fhvi:Val:stCm:xd:")) > 0 ) + while ( (opt = getopt (argc, argv, "bB?c:fhvi:Val:stCm:xd:X:")) > 0 ) switch (opt) { case 'a': log_activity++; @@ -81,6 +81,9 @@ case 'x': xml_status++; break; + case 'X': + xml_xslt = optarg; + break; case 'C': #ifdef TARGET_CROSSROADS show_config(); diff --git a/tools/patch-mgr b/tools/patch-mgr @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +use strict; + +die ("Usage: $0 <version> <xsltfile> <usageblock> <input >output\n") + if ($#ARGV != 2); + +while (my $line = <STDIN>) { + if ($line =~ /__XSLT__/) { + open (my $if, $ARGV[1]) or die ("Cannot read $ARGV[1]: $!\n"); + while (my $x = <$if>) { + $x =~ s/__VER__/$ARGV[0]/; + print ($x); + } + } elsif ($line =~ /__USAGE__/) { + open (my $if, $ARGV[2]) or die ("Cannot read $ARGV[2]: $!\n"); + while (my $x = <$if>) { + $x =~ s/__VER__/$ARGV[0]/; + print ($x); + } + } elsif ($line =~ /__WARNING__/) { + print ("# Do not make changes in this file.\n", + "# They will be overwritten in the next installation.\n", + "# For changes, see crossroads-mgr.in in the Crossroads ", + "source tree.\n"); + } else { + $line =~ s/__VER__/$ARGV[0]/; + print ($line); + } +}